源文件
This commit is contained in:
36
jeepay-ui-merchant/src/views/applyment/ChangeConfig.vue
Normal file
36
jeepay-ui-merchant/src/views/applyment/ChangeConfig.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
<!-- 商户信息变更 弹层模式 -->
|
||||
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="商户信息变更"
|
||||
width="45%"
|
||||
@close="vdata.visible = false"
|
||||
>
|
||||
<JeepayApplymentAppChangeConfig v-if="vdata.visible" :configMode="'mchApplyment'" ref="jeepayApplymentAppChangeConfigRef" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, reactive, nextTick} from 'vue'
|
||||
|
||||
const jeepayApplymentAppChangeConfigRef = ref()
|
||||
|
||||
const vdata : any = reactive({
|
||||
applyId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (data) { // 弹层打开事件)
|
||||
vdata.applyId = data.applyId
|
||||
vdata.visible = true
|
||||
|
||||
nextTick(() => {
|
||||
jeepayApplymentAppChangeConfigRef.value.pageRender(data)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
325
jeepay-ui-merchant/src/views/applyment/ChangeDetail.vue
Normal file
325
jeepay-ui-merchant/src/views/applyment/ChangeDetail.vue
Normal file
@@ -0,0 +1,325 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="变更详情"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="50%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;" v-if="vdata.modifyApplyType == 1">基本信息详情</a-divider>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;" v-if="vdata.modifyApplyType == 2">结算变更详情</a-divider>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;" v-if="vdata.modifyApplyType == 6">结算类型详情</a-divider>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;" v-if="vdata.modifyApplyType == 7">退款账户详情</a-divider>
|
||||
<a-row justify="space-between" type="flex" v-if="vdata.modifyApplyType == 1 || vdata.modifyApplyType == 6">
|
||||
<a-col :sm="12" v-if="vdata.modifyApplyType == 1">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户简称">
|
||||
{{ vdata.detailData.mchShortName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12" v-if="vdata.modifyApplyType == 6">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算变更类型">
|
||||
{{ vdata.detailData.settlementType }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex" v-if="vdata.modifyApplyType == 2">
|
||||
<a-col :sm="12" >
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算账号类型">
|
||||
<span v-if="vdata.detailData.settAccountType == 'C'">对私</span>
|
||||
<span v-else-if="vdata.detailData.settAccountType == 'B'">对公</span>
|
||||
<span v-else>{{ vdata.detailData.settAccountType || '' }}</span>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12" v-if="vdata.detailData.settAccountType == 'C'">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="是否法人结算">
|
||||
<a-radio-group v-model:value="vdata.detailData.illegal" :disabled="true">
|
||||
<a-radio value="N">法人</a-radio>
|
||||
<a-radio value="Y">非法人</a-radio>
|
||||
</a-radio-group>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-form ref="stepForm3Ref" :label-col="{ span: 6 }" :model="vdata.detailData"
|
||||
:wrapper-col="{ span: 12 }" layout="vertical" >
|
||||
|
||||
<a-divider/>
|
||||
|
||||
<a-form ref="stepForm2Ref" v-if="vdata.detailData.settAccountType =='C'" :label-col="{ span: 14 }" :model="vdata.detailData"
|
||||
:wrapper-col="{ span: 14 }" layout="vertical" >
|
||||
|
||||
<div v-if="vdata.detailData.illegal === 'Y'">
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">结算人信息</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算人身份证人像面照片">
|
||||
<a-image v-if="vdata.detailData['settAccountIdcard1Img']" class="img" :src="vdata.detailData['settAccountIdcard1Img']" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算人身份证国徽面照片">
|
||||
<a-image v-if="vdata.detailData['settAccountIdcard2Img']" class="img" :src="vdata.detailData['settAccountIdcard2Img']" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="结算人名称">
|
||||
{{vdata.detailData.settAccountName}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="结算卡身份证号">
|
||||
{{vdata.detailData.settAccountIdcardNo}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="身份证有效期开始时间">
|
||||
{{vdata.detailData.settAccountIdcardEffectBegin}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="身份证有效期截止时间">
|
||||
{{vdata.detailData.settAccountIdcardEffectEnd}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">结算账户信息</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算卡图片">
|
||||
<a-image v-if="vdata.detailData['settAccountLicenseImg']" class="img" :src="vdata.detailData['settAccountLicenseImg']" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12" v-if="vdata.detailData.illegal === 'Y'">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="非法人结算授权函">
|
||||
<a-image v-if="vdata.detailData['nonLegSettleAuthPic']" class="img" :src="vdata.detailData['nonLegSettleAuthPic']" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12" v-if="vdata.detailData.illegal === 'N'">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="结算账户名">
|
||||
<a-image v-if="vdata.detailData['settAccountName']" class="img" :src="vdata.detailData['settAccountName']" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="结算账号">
|
||||
{{vdata.detailData.settAccountNo}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="银行预留手机号">
|
||||
{{vdata.detailData.phone}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="开户银行名称">
|
||||
{{vdata.detailData.settAccountBankName}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="开户银行名称">
|
||||
{{vdata.detailData.settAccountBankBranchAreaName}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<!-- <a-col :span="12">-->
|
||||
<!-- <a-descriptions >-->
|
||||
<!-- <a-descriptions-item label="开户支行">-->
|
||||
<!-- {{vdata.detailData.bankSubCode}}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
</a-row>
|
||||
|
||||
</a-form>
|
||||
|
||||
<a-form ref="stepForm3Ref" v-if="vdata.detailData.settAccountType =='B'" :label-col="{ span: 12 }" :model="vdata.detailData"
|
||||
:wrapper-col="{ span: 12 }" layout="vertical" >
|
||||
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">结算账户信息</a-divider>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="开户许可证">
|
||||
<a-image v-if="vdata.detailData['settAccountLicenseImg']" class="img" :src="vdata.detailData['settAccountLicenseImg']" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="结算账户名">
|
||||
{{vdata.detailData.settAccountName}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="结算账号">
|
||||
{{vdata.detailData.settAccountNo}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="银行预留手机号">
|
||||
{{vdata.detailData.phone}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="开户行省市县">
|
||||
{{vdata.detailData.settAccountBankBranchAreaName}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="开户银行名称">
|
||||
{{vdata.detailData.settAccountBankName}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-descriptions >
|
||||
<a-descriptions-item label="开户支行">
|
||||
{{vdata.detailData.bankSubCode}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
</a-row>
|
||||
|
||||
</a-form>
|
||||
|
||||
</a-form>
|
||||
|
||||
</a-row>
|
||||
|
||||
<a-row justify="space-between" type="flex" v-if="vdata.modifyApplyType == 7">
|
||||
<a-col :sm="24" >
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算类型">
|
||||
{{ vdata.detailData.refundWay || '' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24" >
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收单机构编号">
|
||||
{{ vdata.detailData.channelMchNo || '' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24" >
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="终端号">
|
||||
{{ vdata.detailData.termNo || '' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {API_URL_MCH_APPLYMENT_LIST, req, $getMerchantChangeModifyApply, $getMerchantInformation} from '@/api/manage'
|
||||
import {defineProps,reactive, getCurrentInstance} from 'vue'
|
||||
const { $hasAgentEnt, $SYS_NAME_MAP } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata:any = reactive({
|
||||
btnLoading: false,
|
||||
modifyApplyType:0,
|
||||
detailData: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
vdata.detailData = { } // 数据清空
|
||||
// if (this.$refs.infoFormModel !== undefined) {
|
||||
// this.$refs.infoFormModel.resetFields()
|
||||
// }
|
||||
|
||||
vdata.recordId = recordId
|
||||
|
||||
$getMerchantChangeModifyApply(recordId).then((res) => {
|
||||
console.log(res,'resresresresres')
|
||||
vdata.modifyApplyType = res.modifyApplyType
|
||||
let applyDetailInfo =''
|
||||
console.log(res.applyDetailInfo,'res.originDetailInfo')
|
||||
if(res.applyDetailInfo){
|
||||
applyDetailInfo = JSON.parse(res.applyDetailInfo)
|
||||
}
|
||||
vdata.detailData = applyDetailInfo
|
||||
console.log(vdata.detailData,'vdata.detailData')
|
||||
})
|
||||
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
.img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
224
jeepay-ui-merchant/src/views/applyment/Detail.vue
Normal file
224
jeepay-ui-merchant/src/views/applyment/Detail.vue
Normal file
@@ -0,0 +1,224 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="进件信息"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="40%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户号">
|
||||
{{ vdata.detailData.mchNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商号">
|
||||
{{ vdata.detailData.isvNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="$hasAgentEnt()" :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="代理商号">
|
||||
{{ vdata.detailData.agentNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="$hasAgentEnt()" :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="顶级代理商号">
|
||||
{{ vdata.detailData.topAgentNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="接口名称">
|
||||
{{ vdata.detailData.ifName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付接口代码">
|
||||
{{ vdata.detailData.ifCode }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-divider />
|
||||
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户全称">
|
||||
{{ vdata.detailData.mchFullName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户简称">
|
||||
{{ vdata.detailData.mchShortName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户类型">
|
||||
{{ vdata.detailData.merchantType == 1?'小微':vdata.detailData.merchantType == 2?'个体':vdata.detailData.merchantType == 1?'企业':'其他' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="进件状态">
|
||||
<a-tag v-if="vdata.detailData.state === 0" color="default"> 草稿 </a-tag>
|
||||
<a-tag v-if="vdata.detailData.state === 1" color="warning"> 审核中 </a-tag>
|
||||
<a-tag v-if="vdata.detailData.state === 2" color="success"> 进件成功 </a-tag>
|
||||
<a-tag v-if="vdata.detailData.state === 3" color="error"> 驳回待修改 </a-tag>
|
||||
<a-tag v-if="vdata.detailData.state === 4" color="processing"> 待验证 </a-tag>
|
||||
<a-tag v-if="vdata.detailData.state === 5" color="processing"> 待签约 </a-tag>
|
||||
<a-tag v-if="vdata.detailData.state === 6" color="success"> 签约完成 </a-tag>
|
||||
<a-tag v-if="vdata.detailData.state === 7" color="warning"> 等待系统预审核 </a-tag>
|
||||
<a-tag v-if="vdata.detailData.state === 8" color="error"> 预审核拒绝 </a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="联系人姓名">
|
||||
{{ vdata.detailData.contactName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="联系人手机号">
|
||||
{{ vdata.detailData.contactPhone }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户拓展员ID">
|
||||
{{ vdata.detailData.epUserId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="进件来源">
|
||||
<span v-if="vdata.detailData.applyPageType == 'PLATFORM_WEB'">运营平台系统</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'AGENT_WEB'">代理商系统</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'AGENT_APP'">{{ $SYS_NAME_MAP.AGENT_APP }}APP</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'AGENT_LITE'">{{ $SYS_NAME_MAP.AGENT_APP }}小程序</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'MCH_WEB'">商户系统</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'MCH_APP'">{{ $SYS_NAME_MAP.MCH_APP }}APP</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'MCH_LITE'">{{ $SYS_NAME_MAP.MCH_APP }}小程序</span>
|
||||
<span v-else>{{ vdata.detailData.applyPageType || '' }}</span>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="系统申请单号">
|
||||
{{ vdata.detailData.applyId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道申请单号">
|
||||
{{ vdata.detailData.channelApplyNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道自定义商户号">
|
||||
{{ vdata.detailData.channelDiyMchNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<span style="color: black;">渠道响应参数:</span>
|
||||
<a-form-item label="">
|
||||
<a-textarea
|
||||
v-model:value="vdata.detailData.succResParameter"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black; margin-top: 10px;"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<span style="color: black;">渠道拓展参数1:</span>
|
||||
<a-form-item label="">
|
||||
<a-textarea
|
||||
v-model:value="vdata.detailData.channelVar1"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black; margin-top: 10px;"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<span style="color: black;">渠道拓展参数2:</span>
|
||||
<a-form-item label="">
|
||||
<a-textarea
|
||||
v-model:value="vdata.detailData.channelVar2"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black; margin-top: 10px;"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<span style="color: black;">响应提示信息:</span>
|
||||
<a-form-item label="">
|
||||
<a-textarea
|
||||
v-model:value="vdata.detailData.applyErrorInfo"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black; margin-top: 10px;"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MCH_APPLYMENT_LIST, req } from '@/api/manage'
|
||||
import {defineProps,reactive, getCurrentInstance} from 'vue'
|
||||
const { $hasAgentEnt, $SYS_NAME_MAP } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata:any = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
vdata.detailData = { 'state': 1, 'type': 1 } // 数据清空
|
||||
// if (this.$refs.infoFormModel !== undefined) {
|
||||
// this.$refs.infoFormModel.resetFields()
|
||||
// }
|
||||
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_MCH_APPLYMENT_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
656
jeepay-ui-merchant/src/views/applyment/MchApplymentList.vue
Normal file
656
jeepay-ui-merchant/src/views/applyment/MchApplymentList.vue
Normal file
@@ -0,0 +1,656 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<!-- 列表页 -->
|
||||
<a-card v-show="!vdata.currentApplyPage.component" class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="resetFunc">
|
||||
<!-- 时间搜索控件 -->
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker
|
||||
ref="dateRangePicker"
|
||||
v-model:value="vdata.searchData['queryDateRange']"
|
||||
customDateRangeType="date"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- <jeepay-text-up v-model:value="vdata.searchData['unionSearchId']" :placeholder="'申请单号/进件商户名'" />-->
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchApplyName']" :placeholder="'商户号/商户名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['ifName']" :placeholder="'支付通道'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['isvNo']" :placeholder="'渠道名称/渠道号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['autoConfigMchAppId']" :placeholder="'应用名称/应用ID'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.range" placeholder="应用类型" >
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">线下场景</a-select-option>
|
||||
<a-select-option value="1">线上场景</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.merchantType" placeholder="商户类型" >
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="1">小微</a-select-option>
|
||||
<a-select-option value="2">个体</a-select-option>
|
||||
<a-select-option value="3">企业</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<JeepaySelect ref="stateRef" placeholder="进件状态" :value="vdata.searchData.state" >
|
||||
<a-select v-model:value="vdata.searchData.state" @change="stateRef.textupHandle()" >
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">草稿</a-select-option>
|
||||
<a-select-option value="1">审核中</a-select-option>
|
||||
<a-select-option value="2">进件成功</a-select-option>
|
||||
<a-select-option value="3">驳回待修改</a-select-option>
|
||||
<a-select-option value="4">待验证</a-select-option>
|
||||
<a-select-option value="5">待签约</a-select-option>
|
||||
<a-select-option value="12">待通道复审</a-select-option>
|
||||
<a-select-option value="7">等待预审</a-select-option>
|
||||
<a-select-option value="8">预审拒绝</a-select-option>
|
||||
<a-select-option value="20">已风控</a-select-option>
|
||||
<a-select-option value="21">已冻结</a-select-option>
|
||||
<a-select-option value="100">进件请求中</a-select-option>
|
||||
</a-select>
|
||||
</JeepaySelect>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="applyId"
|
||||
>
|
||||
<!-- 表格顶部按钮行插槽 -->
|
||||
<template #topBtnSlot>
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APPLYMENT_ADD')" type="primary"-->
|
||||
<!-- @click="addFunc('')"><plus-outlined />发起进件</a-button>-->
|
||||
<a-button
|
||||
v-if="$access('ENT_MCH_APPLYMENT_ADD')"
|
||||
type="primary"
|
||||
@click="getVisibleAdd()"
|
||||
><plus-outlined />发起进件</a-button
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- body 渲染插槽 -->
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'state'">
|
||||
<a-badge v-if="record.state == 0" status="default" text="草稿" />
|
||||
<a-badge
|
||||
v-if="record.state == 1"
|
||||
status="warning"
|
||||
text="等待审核结果"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 2"
|
||||
status="success"
|
||||
text="进件成功"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 3"
|
||||
status="error"
|
||||
text="驳回待修改"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 4"
|
||||
status="processing"
|
||||
text="待验证"
|
||||
/>
|
||||
<a-badge @click="nextBizsDrawerRef.show(record.applyId)"
|
||||
v-if="record.state == 5"
|
||||
status="processing"
|
||||
text="待签约"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 7"
|
||||
status="processing"
|
||||
text="等待预审"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 8"
|
||||
status="error"
|
||||
text="预审拒绝"
|
||||
/>
|
||||
<a-badge v-if="record.state == 20" status="error" text="已风控" />
|
||||
<a-badge v-if="record.state == 21" status="error" text="已冻结" />
|
||||
<a-badge
|
||||
v-if="record.state == 100"
|
||||
status="warning"
|
||||
text="进件请求中"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 12"
|
||||
status="warning"
|
||||
text="待通道复审"
|
||||
/>
|
||||
<link-outlined v-if="record.state == 5" @click="nextBizsDrawerRef.show(record.applyId)" style="font-size: 16px; padding-left: 5px;color: #1965FF" />
|
||||
|
||||
<a-tooltip v-if="record.applyErrorInfo && record.state == 3 || record.state == 8 " :title="record.applyErrorInfo">
|
||||
<info-circle-outlined style="font-size: 16px; padding-left: 5px;color: #FF0000"/>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-if="record.ifCode == 'kqpay' && record.state == 12" title="快钱通道营业执照商户支持先开通后审核,复审期间的交易会在人工审批完成后结算,复审时间一般为1个工作日。">
|
||||
<info-circle-outlined style="font-size: 16px; padding-left: 5px;color: #FF0000"/>
|
||||
</a-tooltip>
|
||||
|
||||
<QrcodeOutlined v-if=" (record.state == 4) && (record.ifCode === 'wxpay' || record.ifCode === 'sftpay') " style="font-size: 16px; margin-left: 10px" @click="showQrImgFunc(record)" />
|
||||
|
||||
<reload-outlined
|
||||
@click="queryChannelState(record.applyId, record.state)"
|
||||
style="color: #1890ff; margin-left: 10px"
|
||||
v-if="(record.state == 1 || record.state == 4 || record.state == 7 || record.state == 5 || record.state == 12) && $access('ENT_MCH_APPLYMENT_GET_INFO') " />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'type'">
|
||||
<a-tag :color="record.type === 1 ? 'green' : 'orange'">
|
||||
{{ record.type === 1 ? "普通商户" : "特约商户" }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'autoConfigMchAppId'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>应用名称:{{record.appName}}</span><br>
|
||||
<span>应用ID:{{record.autoConfigMchAppId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.appName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchShortName'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>商户全称:{{record.mchFullName}}</span><br>
|
||||
<span>商户简称:{{record.mchShortName}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchShortName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'isvNo'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>渠道名称:{{record.isvName}}</span><br>
|
||||
<span>渠道号:{{record.isvNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.isvName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key == 'range'">
|
||||
<a-tag v-if="record.range == 0" color="orange">线下场景</a-tag>
|
||||
<a-tag v-if="record.range == 1" color="green">线上场景</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'applyId'">
|
||||
<a-popover placement="top" style="background: #0c2640 !important;" v-if="record.state == 1 || record.state == 3">
|
||||
<template #content style="background: #ff0 !important;">
|
||||
<p>商户号:{{ record.applyId }}</p>
|
||||
<p>上游通道请求单号:{{ record.channelApplyNo }}</p>
|
||||
</template>
|
||||
<a @click="detailFunc(record.applyId)" v-if="$access('ENT_MCH_APPLYMENT_ADVANCE')"><b>{{ record.applyId }}</b></a>
|
||||
<a v-if="!$access('ENT_MCH_APPLYMENT_ADVANCE')"><b>{{ record.applyId }}</b></a>
|
||||
</a-popover>
|
||||
<view v-else>
|
||||
<a @click="detailFunc(record.applyId)" v-if="$access('ENT_MCH_APPLYMENT_ADVANCE')"><b>{{ record.applyId }}</b></a>
|
||||
<a v-if="!$access('ENT_MCH_APPLYMENT_ADVANCE')"><b>{{ record.applyId }}</b></a>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'merchantType'">
|
||||
{{
|
||||
record.merchantType === 1
|
||||
? "小微"
|
||||
: record.merchantType === 2
|
||||
? "个体"
|
||||
: record.merchantType === 3
|
||||
? "企业"
|
||||
: "其他组织"
|
||||
}}
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 商户系统: 修改按钮多一个 8 预审拒接的判断, 没有参数配置。 其他是通用的。 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button
|
||||
v-if="
|
||||
$access('ENT_MCH_APPLYMENT_EDIT') &&
|
||||
(record.state == 3 || record.state == 8)
|
||||
"
|
||||
type="link"
|
||||
@click="editOrViewFunc(record.applyId, false)"
|
||||
>修改</a-button
|
||||
>
|
||||
<a-button
|
||||
v-if="$access('ENT_MCH_APPLYMENT_VIEW') && (record.state == 2 || record.state == 5)"
|
||||
type="link"
|
||||
@click="editOrViewFunc(record.applyId, true)"
|
||||
>详情</a-button
|
||||
>
|
||||
<a-button
|
||||
v-if="$access('ENT_MCH_APPLYMENT_EDIT') && record.state == 0"
|
||||
type="link"
|
||||
@click="editOrViewFunc(record.applyId, false)"
|
||||
>继续填写</a-button
|
||||
>
|
||||
<a-button
|
||||
v-if="$access('ENT_MCH_APPLYMENT_ADVANCE')"
|
||||
type="link"
|
||||
@click="detailFunc(record.applyId)"
|
||||
>进件信息</a-button
|
||||
>
|
||||
<a-button
|
||||
v-if="$access('ENT_MCH_APPLYMENT_COPY')"
|
||||
type="link"
|
||||
@click="
|
||||
toCopySelectIfCodePage(
|
||||
record.range,
|
||||
record.applyId,
|
||||
record.mchNo
|
||||
)
|
||||
"
|
||||
>复用信息</a-button
|
||||
>
|
||||
|
||||
<!-- 审核中、 待验证、 签约完成 -->
|
||||
<a-button
|
||||
v-if="
|
||||
$access('ENT_MCH_APPLYMENT_GET_INFO') &&
|
||||
(record.state == 1 || record.state == 4 || record.state == 5)
|
||||
"
|
||||
type="link"
|
||||
@click="queryChannelState(record.applyId, record.state)"
|
||||
>
|
||||
获取最新结果
|
||||
</a-button>
|
||||
|
||||
<!-- 2进件成功、 4待验证、 5待签约、 6签约完成/审核成功 -->
|
||||
<a-button @click="oauthFuncButton(record.applyId,record.state)" v-if="record.ifCode != 'zftpay' && $access('ENT_MCH_APPLYMENT_SIGN') && ( record.state == 2 || record.state == 4 || record.state == 5 || record.state == 6 || record.state == 100)" type="link" >
|
||||
<span v-if="record.state == 2" >实名认证</span>
|
||||
<span v-else >签约开通</span>
|
||||
</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
|
||||
<a-modal
|
||||
v-model:visible="vdata.qrCodeVisible"
|
||||
title="商户签约二维码"
|
||||
:footer="null"
|
||||
:width="250"
|
||||
@ok="() => (vdata.qrCodeVisible = false)"
|
||||
>
|
||||
<QrcodeVue :value="vdata.confirmUrl" :size="200" />
|
||||
</a-modal>
|
||||
<!-- 微信签约弹窗 -->
|
||||
<a-modal
|
||||
v-model:visible="vdata.wxQrCodeVisible"
|
||||
title="二维码"
|
||||
:footer="null"
|
||||
:width="250"
|
||||
@ok="() => (vdata.wxQrCodeVisible = false)"
|
||||
>
|
||||
<span>请超级管理员使用微信扫描二维码,根据页面指引完成签约</span>
|
||||
<img :src="vdata.confirmUrl" style="width: 200px; height: 200px" />
|
||||
</a-modal>
|
||||
<!-- 收付通签约弹窗 -->
|
||||
<a-modal
|
||||
v-model:visible="vdata.sftQrCodeVisible"
|
||||
title="二维码"
|
||||
:footer="null"
|
||||
:width="250"
|
||||
@ok="() => (vdata.sftQrCodeVisible = false)"
|
||||
>
|
||||
<span>请超级管理员使用微信扫描二维码,根据页面指引完成签约</span>
|
||||
<QrcodeVue
|
||||
:value="vdata.confirmUrl"
|
||||
style="padding-top: 10px"
|
||||
:size="200"
|
||||
/>
|
||||
</a-modal>
|
||||
</a-card>
|
||||
|
||||
<!-- 定义组件分为: 第一步和第二步 -->
|
||||
<a-card>
|
||||
<component
|
||||
:is="vdata.currentApplyPage.component"
|
||||
:channelNo="111111"
|
||||
:channelAppId="66666"
|
||||
ref="applyPageComponentRef"
|
||||
@switchApplyPage="switchApplyPage"
|
||||
/>
|
||||
</a-card>
|
||||
|
||||
<!-- 签约开通 弹层 -->
|
||||
<NextBizsDrawer ref="nextBizsDrawerRef" />
|
||||
|
||||
<!-- 详情页面组件 -->
|
||||
<InfoDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
|
||||
<a-modal
|
||||
v-model:visible="vdata.visibleAdd"
|
||||
title=""
|
||||
:footer="null"
|
||||
width="50%"
|
||||
@cancel="handleCancel"
|
||||
class="set-img-box"
|
||||
>
|
||||
<div class="state-box-div">
|
||||
<div>
|
||||
<img :src="vdata.banerapps" alt="" />
|
||||
<div class="left-bottom">
|
||||
<a-button type="primary" @click="addFunc('', 1)"
|
||||
>发起进件
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="state-box-div">
|
||||
<div class="state-box">
|
||||
<img :src="vdata.xianxiaImg" alt="" />
|
||||
</div>
|
||||
<div class="state-box">
|
||||
<img :src="vdata.xianshangImg" alt="" />
|
||||
<div class="right-bottom">
|
||||
<a-button type="primary" @click="addFunc('', 2)">发起进件</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</page-header-wrapper>
|
||||
|
||||
<JeepayMchOauth2 v-show="vdata.visibleOauth2" ref="jeepayMchOauth2Ref" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
API_URL_MCH_APPLYMENT_LIST,
|
||||
req,
|
||||
$getMchApplymentChannelState,
|
||||
} from "@/api/manage";
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
getCurrentInstance,
|
||||
nextTick,
|
||||
provide,
|
||||
computed,
|
||||
} from "vue";
|
||||
import QrcodeVue from "qrcode.vue";
|
||||
import ApplySelectMchAndIfcode from "@/components/link/JeepayUIComponents/JeepayMchApplyment/JeepayMchApplymentSelectMchAndIfcode.vue";
|
||||
import ApplyMchDetailInfoEntry from "@/components/link/JeepayUIComponents/JeepayMchApplyment/JeepayMchApplymentDetailInfoEntry.vue";
|
||||
import NextBizsDrawer from "./NextBizsDrawer.vue";
|
||||
// import InfoDetail from "./Detail.vue";
|
||||
import InfoDetail from "./NewDetail.vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const router = useRouter(); //这是全部路由
|
||||
/** 定义全部组件 **/
|
||||
const allApplyPage = {
|
||||
list: { name: "列表", component: null },
|
||||
applySelectMchAndIfcode: {
|
||||
name: "选择进件渠道",
|
||||
component: ApplySelectMchAndIfcode,
|
||||
},
|
||||
applyMchDetailInfoEntry: {
|
||||
name: "填写进件资料",
|
||||
component: ApplyMchDetailInfoEntry,
|
||||
},
|
||||
};
|
||||
|
||||
// 动态组件
|
||||
const jeepayMchOauth2Ref = ref();
|
||||
const applyPageComponentRef = ref();
|
||||
const nextBizsDrawerRef = ref();
|
||||
const infoDetail = ref();
|
||||
const stateRef = ref();
|
||||
const dateRangePicker = ref();
|
||||
|
||||
const { $infoBox, $access } =
|
||||
getCurrentInstance()!.appContext.config.globalProperties;
|
||||
|
||||
const infoTable = ref();
|
||||
let tableColumns = reactive([
|
||||
{ key: "applyId", dataIndex: "applyId", fixed: "left", title: "商户号", align: "center" },
|
||||
{ key: "mchShortName", title: "商户简称", dataIndex: "mchShortName" },
|
||||
{ key: "ifName", title: "支付通道", dataIndex: "ifName" },
|
||||
{ key: "isvNo", title: "所属渠道", dataIndex: "isvNo" },
|
||||
{ key: "merchantType", title: "商户类型", dataIndex: "merchantType" },
|
||||
{ key: "state", title: "进件状态" },
|
||||
{ key: "autoConfigMchAppId",title: "所属应用", dataIndex: "autoConfigMchAppId",},
|
||||
{ key: "range", title: "应用类型" },
|
||||
{ key: "lastApplyAt", dataIndex: "lastApplyAt", title: "最后提交日期" },
|
||||
{ key: "createdAt", dataIndex: "createdAt", title: "创建日期" },
|
||||
{ key: "operation", title: "操作", fixed: "right", align: "center" },
|
||||
]);
|
||||
|
||||
let vdata: any = reactive({
|
||||
visibleOauth2:false,
|
||||
banerapps:
|
||||
"https://syb-manage.oss-cn-hangzhou.aliyuncs.com/shouyinbei/banerapps.png",
|
||||
xianxiaImg:
|
||||
"https://syb-manage.oss-cn-hangzhou.aliyuncs.com/shouyinbei/xianxia.png",
|
||||
xianshangImg:
|
||||
"https://syb-manage.oss-cn-hangzhou.aliyuncs.com/shouyinbei/xianshang.png",
|
||||
visibleAdd: false,
|
||||
searchData: { queryDateRange: "" }, // 搜索条件
|
||||
|
||||
currentApplyPage: allApplyPage.list, // 当前的步骤组件 null表示列表页
|
||||
backupApplyPage: null, // 备份: 用作快速恢复
|
||||
|
||||
mchApplymentData: {}, //商户进件资料
|
||||
|
||||
isView: false, // 是否预览模式
|
||||
|
||||
copyInfoSourceApplyId: "", // 副本资料
|
||||
sceneType: 1, //1 线下默认应用 2线上有应用
|
||||
});
|
||||
|
||||
vdata.banerapps = vdata.banerapps + "?time=" + Date.now();
|
||||
vdata.xianxiaImg = vdata.xianxiaImg + "?time=" + Date.now();
|
||||
vdata.xianshangImg = vdata.xianshangImg + "?time=" + Date.now();
|
||||
|
||||
function handleCancel(e) {
|
||||
vdata.visibleAdd = false;
|
||||
}
|
||||
// 清空搜索项
|
||||
const resetFunc = () => {
|
||||
dateRangePicker.value.returnSelectModel();
|
||||
vdata.searchData = {};
|
||||
};
|
||||
|
||||
// 向所有子组件注入参数 (子组件可直接更改此值)
|
||||
provide(
|
||||
"mchApplymentData",
|
||||
computed(() => vdata.mchApplymentData)
|
||||
);
|
||||
provide(
|
||||
"isView",
|
||||
computed(() => vdata.isView)
|
||||
);
|
||||
|
||||
// 向所有子组件注入参数: 配置模式: mgrApplyment / agentApplyment / mchApplyment
|
||||
provide("configMode", "mchApplyment");
|
||||
|
||||
// 向所有子组件注入参数 副本资料来源ID
|
||||
provide(
|
||||
"copyInfoSourceApplyId",
|
||||
computed(() => vdata.copyInfoSourceApplyId)
|
||||
);
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params: any) {
|
||||
return req.list(API_URL_MCH_APPLYMENT_LIST, params);
|
||||
}
|
||||
|
||||
// 点击【查询】按钮点击事件
|
||||
function searchFunc() {
|
||||
infoTable.value.refTable(true);
|
||||
}
|
||||
|
||||
// 切换步骤: 不清空数据
|
||||
function switchApplyPage(page) {
|
||||
if (page == "applyAddApps") {
|
||||
router.push({
|
||||
path: "/apps",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
vdata.backupApplyPage = vdata.currentApplyPage;
|
||||
vdata.currentApplyPage = allApplyPage[page];
|
||||
if(page == 'list'){
|
||||
vdata.currentApplyPage.component = false
|
||||
}
|
||||
|
||||
if (vdata.currentApplyPage && vdata.currentApplyPage.component) {
|
||||
nextTick(() => {
|
||||
applyPageComponentRef.value.pageRender(vdata.sceneType);
|
||||
});
|
||||
} else {
|
||||
//列表页
|
||||
searchFunc(); // 刷新
|
||||
}
|
||||
}
|
||||
function getVisibleAdd() {
|
||||
vdata.visibleAdd = true;
|
||||
}
|
||||
function detailFunc(recordId: any) {
|
||||
// 进件详情页
|
||||
|
||||
vdata.copyInfoSourceApplyId = ""; // 副本清空。
|
||||
|
||||
infoDetail.value.show(recordId);
|
||||
}
|
||||
|
||||
// 点击【发起进件】的操作
|
||||
function addFunc(copyInfoSourceApplyId = "", sceneType = 0) {
|
||||
vdata.visibleAdd = false;
|
||||
vdata.sceneType = sceneType;
|
||||
vdata.copyInfoSourceApplyId = copyInfoSourceApplyId;
|
||||
|
||||
vdata.backupApplyPage = null; // 再次点击进件将无法再次恢复
|
||||
vdata.mchApplymentData = {};
|
||||
req
|
||||
.list(API_URL_MCH_APPLYMENT_LIST, { pageNumber: "1", pageSize: 1 })
|
||||
.then((res) => {
|
||||
if (res.records.length > 0) {
|
||||
vdata.mchApplymentData = { mchNo: res.records[0].mchNo };
|
||||
}
|
||||
|
||||
//进件数据重置
|
||||
vdata.isView = false;
|
||||
switchApplyPage("applySelectMchAndIfcode");
|
||||
});
|
||||
}
|
||||
|
||||
// 修改资料 然后重新发起进件操作
|
||||
function editOrViewFunc(applyId, isView) {
|
||||
vdata.copyInfoSourceApplyId = ""; // 副本清空。
|
||||
|
||||
vdata.backupApplyPage = null; // 再次点击进件将无法再次恢复
|
||||
vdata.isView = isView;
|
||||
|
||||
req
|
||||
.getById(API_URL_MCH_APPLYMENT_LIST, applyId, {
|
||||
originData: vdata.isView ? "0" : "1",
|
||||
})
|
||||
.then((res) => {
|
||||
let { applyId, channelApplyNo, mchNo, ifCode, applyDetailInfo, applyErrorInfo, state, isvNo, autoConfigMchAppId, range, } = res;
|
||||
vdata.mchApplymentData = {
|
||||
applyId, channelApplyNo, mchNo, ifCode, applyDetailInfo, applyErrorInfo, state, isvNo, autoConfigMchAppId, range, };
|
||||
switchApplyPage("applyMchDetailInfoEntry");
|
||||
});
|
||||
}
|
||||
|
||||
// 查询最新状态
|
||||
function queryChannelState(applyId, currState) {
|
||||
$getMchApplymentChannelState(applyId).then((res) => {
|
||||
if (currState != res.state) {
|
||||
$infoBox.message.success("状态已更新");
|
||||
searchFunc(); // 更新列表
|
||||
} else {
|
||||
$infoBox.message.info("状态无变化");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 显示二维码图片
|
||||
function showQrImgFunc(record) {
|
||||
if (record.ifCode == "wxpay") {
|
||||
vdata.wxQrCodeVisible = true;
|
||||
} else if (record.ifCode == "sftpay") {
|
||||
vdata.sftQrCodeVisible = true;
|
||||
} else if (record.ifCode == "fuioupay") {
|
||||
vdata.qrCodeVisible = true;
|
||||
vdata.confirmUrl = JSON.parse(record.applyErrorInfo).signUrl;
|
||||
return;
|
||||
} else {
|
||||
vdata.qrCodeVisible = true;
|
||||
}
|
||||
vdata.confirmUrl = record.applyErrorInfo;
|
||||
}
|
||||
|
||||
// 副本 copySourceApplyId : 需要copy的资料来源。
|
||||
function toCopySelectIfCodePage(range, copySourceApplyId, mchNo) {
|
||||
const sceneType = parseInt(range) + 1;
|
||||
vdata.searchData.mchNo = mchNo;
|
||||
addFunc(copySourceApplyId, sceneType);
|
||||
}
|
||||
function oauthFunc(applyId) {
|
||||
vdata.visibleOauth2 = true;
|
||||
jeepayMchOauth2Ref.value.show(applyId);
|
||||
}
|
||||
|
||||
function oauthFuncButton(applyId,state){
|
||||
if(state == 2){
|
||||
oauthFunc(applyId)
|
||||
}else{
|
||||
nextBizsDrawerRef.value.show(applyId)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.state-box-div {
|
||||
width: 100%;
|
||||
padding: unset !important;
|
||||
}
|
||||
.state-box-div img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.set-img-box .ant-modal-body {
|
||||
padding: unset !important;
|
||||
}
|
||||
.state-box {
|
||||
padding: unset !important;
|
||||
}
|
||||
|
||||
.state-box {
|
||||
width: 50%;
|
||||
}
|
||||
.state-box img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.visibleAdd-img {
|
||||
//display: flex;
|
||||
}
|
||||
.ant-modal-content svg {
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
font-size: 25px;
|
||||
}
|
||||
.left-bottom {
|
||||
border-radius: 10px;
|
||||
position: absolute;
|
||||
left: 5%;
|
||||
bottom: 5%;
|
||||
}
|
||||
.left-bottom button {
|
||||
border-radius: 10px;
|
||||
}
|
||||
.right-bottom {
|
||||
position: absolute;
|
||||
right: 35%;
|
||||
bottom: 5%;
|
||||
}
|
||||
.right-bottom button {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
275
jeepay-ui-merchant/src/views/applyment/MchApplymentListOne.vue
Normal file
275
jeepay-ui-merchant/src/views/applyment/MchApplymentListOne.vue
Normal file
@@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="resetFunc">
|
||||
<!-- 时间搜索控件 -->
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']"
|
||||
customDateRangeType="date" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['modifyApplyId']" :placeholder="'申请单号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchShortName']" :placeholder="'商户号/名称'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.modifyApplyType" placeholder="申请单类型">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="1">基本资料变更</a-select-option>
|
||||
<a-select-option value="2">结算信息变更</a-select-option>
|
||||
<!-- <a-select-option value="3">费率信息变更</a-select-option>-->
|
||||
<a-select-option value="6">结算类型变更</a-select-option>
|
||||
<a-select-option value="7">退款账户绑定</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="申请单状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">草稿</a-select-option>
|
||||
<a-select-option value="1">审核中</a-select-option>
|
||||
<a-select-option value="2">审核成功</a-select-option>
|
||||
<a-select-option value="3">驳回</a-select-option>
|
||||
<a-select-option value="5">待签约</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
@btnLoadClose="vdata.btnLoading = false"
|
||||
rowKey="storeId"
|
||||
>
|
||||
|
||||
<!-- body 渲染插槽 -->
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'state'">
|
||||
<a-badge v-if="record.state == 0" status="default" text="草稿" />
|
||||
<a-badge v-if="record.state == 1" status="warning" text="审核中" />
|
||||
<a-badge v-if="record.state == 2" status="success" text="审核成功" />
|
||||
<a-badge v-if="record.state == 4" status="error" text="操作未完成" />
|
||||
<a-badge v-if="record.state == 3" status="error" text="驳回" />
|
||||
<a-badge v-if="record.state == 9" status="warning" text="已通过未生效" />
|
||||
<a-badge v-if="record.state == 5" status="processing" text="待签约" />
|
||||
<a-badge v-if="record.state == 6" status="processing" text="签约完成" />
|
||||
<a-badge v-if="record.state == 30" status="processing" text="待商户授权" />
|
||||
<!-- <a-badge v-if="record.state == 7" status="processing" text="等待预审" />-->
|
||||
<!-- <a-badge v-if="record.state == 8" status="processing" text="预审拒绝" />-->
|
||||
<!-- <a-badge v-if="record.state == 20" status="error" text="已风控" /> -->
|
||||
<!-- <a-badge v-if="record.state == 21" status="error" text="已冻结" /> -->
|
||||
<link-outlined v-if="record.state == 5 || record.state == 6" @click="oauthFuncButton(record)" style="font-size: 16px; padding-left: 5px;color: #1965FF" />
|
||||
<reload-outlined @click="queryChannelState(record, record.state)" style="color: #1890ff; margin-left: 10px" v-if="record.state == 5" />
|
||||
<a-tooltip v-if="record.state == 3" :title="record.applyErrorInfo">
|
||||
<info-circle-outlined style="color:#F00;margin-left: 5px"/>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-if="record.state == 9" title="次日生效">
|
||||
<info-circle-outlined style="color:#F00;margin-left: 5px"/>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-if="record.state == 4" title="操作未完成,请联系平台">
|
||||
<info-circle-outlined style="color:#F00;margin-left: 5px"/>
|
||||
</a-tooltip>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<template v-if="column.key === 'modifyApplyType'">
|
||||
|
||||
<a-tag
|
||||
:key="record.modifyApplyType"
|
||||
:color="record.modifyApplyType === 1?'blue':record.modifyApplyType === 2?'orange':record.modifyApplyType === 3?'green':record.modifyApplyType === 6?'green':record.modifyApplyType === 7?'cyan':'volcano'"
|
||||
>
|
||||
{{ record.modifyApplyType === 1?'基本资料变更':record.modifyApplyType === 2?'结算信息变更':record.modifyApplyType === 3?'费率信息变更':record.modifyApplyType === 6?'结算类型变更':record.modifyApplyType === 7?'退款账户绑定':'其他' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" @click="getMchAuth(record,true)" v-if="record.state == 30">授权</a-button>
|
||||
<a-button type="link" @click="getMchAuth(record,false)" v-if="record.state == 30">拒绝授权</a-button>
|
||||
<!-- <a-button type="link" @click="getChanageConfigFunc(record.modifyApplyId)" v-if="record.state == 3 || record.state == 0">变更修改</a-button>-->
|
||||
<a-button type="link" @click="getChanageDetailFunc(record.modifyApplyId)" >详情</a-button>
|
||||
</jeepaytablecolumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
</page-header-wrapper>
|
||||
|
||||
<!-- 签约开通 弹层 -->
|
||||
<NextBizsDrawer ref="nextBizsDrawerRef" />
|
||||
|
||||
<!-- 详情页面组件 -->
|
||||
<JeepMchApplyChangeDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
<JeepayMchChangeConfig ref="jeepayMchChangeConfigRef" v-if="vdata.visibleMchChange" />
|
||||
|
||||
<SigningConfig ref="signingConfigRef" v-show="vdata.visibleSigningConfig" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
API_URL_MCH_STORE_LIST,
|
||||
req,
|
||||
reqLoad,
|
||||
API_ALIPAY_SHOP,
|
||||
API_URL_MCH_MODIFY_APPLYMENT_LIST,
|
||||
$getMchApplymentsModifyApplyId,
|
||||
$getMerchantChangeModifyApply,
|
||||
$getMchIncomingRefresh,
|
||||
API_URL_MCH_QR_CODE_LIST, $getMchApplymentRefreshAudit, $getMchModifyApplyments
|
||||
} from "@/api/manage";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import {
|
||||
onMounted,
|
||||
ref,
|
||||
reactive,
|
||||
getCurrentInstance,
|
||||
nextTick,
|
||||
provide,
|
||||
computed,
|
||||
} from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import NextBizsDrawer from './NextBizsDrawer.vue'
|
||||
import InfoDetail from './ChangeDetail.vue'
|
||||
import SigningConfig from "./SigningConfig.vue";
|
||||
// 获取全局函数
|
||||
const { $infoBox, $access } =
|
||||
getCurrentInstance()!.appContext.config.globalProperties;
|
||||
|
||||
const userStore = useUserStore();
|
||||
const router = useRouter(); //这是全部路由
|
||||
|
||||
|
||||
|
||||
// tableColumns 顺序不可随意修改 (关联下方列显示)
|
||||
const tableColumns = reactive([
|
||||
{ key: 'modifyApplyType', dataIndex: 'modifyApplyType', title: '申请单类型' },
|
||||
{ key: 'modifyApplyId', title: '申请单号', dataIndex: 'modifyApplyId', },
|
||||
{ key: 'applyId', title: '商户号', dataIndex: 'applyId', },
|
||||
{ key: 'mchShortName', title: '商户简称', dataIndex: 'mchShortName', },
|
||||
{ key: 'ifName', title: '支付通道', dataIndex: 'ifName', },
|
||||
{ key: 'state', title: '申请单状态', fixed: 'right',},
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '申请时间', },
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center' }
|
||||
]);
|
||||
|
||||
// 如果用户类型为店长、店员时
|
||||
if (
|
||||
userStore.userInfo["userType"] == 11 ||
|
||||
userStore.userInfo["userType"] == 12
|
||||
) {
|
||||
// 删除是否默认的列展示
|
||||
tableColumns.splice(2, 1);
|
||||
}
|
||||
|
||||
const infoDetail = ref();
|
||||
const infoTable = ref();
|
||||
const jeepayMchChangeConfigRef = ref()
|
||||
const nextBizsDrawerRef = ref()
|
||||
const signingConfigRef = ref();
|
||||
|
||||
|
||||
const vdata: any = reactive({
|
||||
visibleMchChange:false,
|
||||
visibleSigningConfig:false,
|
||||
visibleNotes: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {
|
||||
mchApplyId: "",
|
||||
},
|
||||
btnLoading: false,
|
||||
notes: {
|
||||
appid: "",
|
||||
value: "",
|
||||
},
|
||||
});
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params) {
|
||||
return req.list(API_URL_MCH_MODIFY_APPLYMENT_LIST, params);
|
||||
}
|
||||
|
||||
const resetFunc = () => {
|
||||
vdata.searchData = {};
|
||||
};
|
||||
function searchFunc() {
|
||||
// 点击【查询】按钮点击事件
|
||||
vdata.btnLoading = true; // 打开查询按钮的loading
|
||||
infoTable.value.refTable(true);
|
||||
}
|
||||
//变更详情
|
||||
function getChanageConfigFunc(applyId){
|
||||
vdata.visibleMchChange = true
|
||||
jeepayMchChangeConfigRef.value.show(applyId)
|
||||
}
|
||||
//详情
|
||||
function getChanageDetailFunc(recordId : any) { // 进件详情页
|
||||
|
||||
vdata.copyInfoSourceApplyId = '' // 副本清空。
|
||||
|
||||
infoDetail.value.show(recordId)
|
||||
}
|
||||
//签约
|
||||
function oauthFuncButton(data){
|
||||
vdata.visibleChangeConfig = true;
|
||||
signingConfigRef.value.show(data);
|
||||
}
|
||||
// 查询最新状态
|
||||
|
||||
// 查询最新状态
|
||||
function queryChannelState(record, currState) {
|
||||
$getMchApplymentsModifyApplyId(record.modifyApplyId).then((res) => {
|
||||
// let str ='modifyApplyType='+vdata.searchData.modifyApplyType+'&mchApplyId='+record.modifyApplyId
|
||||
$getMchModifyApplyments(record.modifyApplyId).then((resData) => {
|
||||
if (currState != resData.state) {
|
||||
$infoBox.message.success("状态已更新");
|
||||
searchFunc(); // 更新列表
|
||||
} else {
|
||||
$infoBox.message.info("状态无变化");
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
//商户授权
|
||||
function getMchAuth(record,state){
|
||||
console.log(record,'recordrecordrecord')
|
||||
$infoBox.confirmDanger('是否确认授权当前变更?', '', () => {
|
||||
$getMchApplymentRefreshAudit({
|
||||
modifyApplymentId:record.modifyApplyId,
|
||||
state:true,
|
||||
remark:state?"商户同意授权变更":"商户拒绝授权变更",
|
||||
}).then(res => {
|
||||
$infoBox.message.success('提交成功,等待审核')
|
||||
vdata.btnLoading = false
|
||||
searchFunc()
|
||||
}).catch(err => {
|
||||
console.log(err,'err')
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.two-lines {
|
||||
color: #1965ff;
|
||||
max-width: 150px;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.my-tooltip .ant-btn {
|
||||
width: 600px !important;
|
||||
background-color: #f0f0f0;
|
||||
color: #333;
|
||||
border: 1px solid #ddd;
|
||||
padding: 5px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.ant-dropdown-menu-item-only-child{
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
752
jeepay-ui-merchant/src/views/applyment/MchBusinessList.vue
Normal file
752
jeepay-ui-merchant/src/views/applyment/MchBusinessList.vue
Normal file
@@ -0,0 +1,752 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<!-- 列表页 -->
|
||||
<a-card v-show="!vdata.currentApplyPage.component" class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="resetFunc">
|
||||
<!-- 时间搜索控件 -->
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="date" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchApplyName']" :placeholder="'商户号/商户名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['ifName']" :placeholder="'支付通道'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['isvNo']" :placeholder="'渠道名称/渠道号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['autoConfigMchAppId']" :placeholder="'应用名称/应用ID'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.range" placeholder="应用类型" >
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">线下场景</a-select-option>
|
||||
<a-select-option value="1">线上场景</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.merchantType" placeholder="商户类型" >
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="1">小微</a-select-option>
|
||||
<a-select-option value="2">个体</a-select-option>
|
||||
<a-select-option value="3">企业</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.authenticationState" placeholder="认证状态" >
|
||||
<a-select-option value="4">全部已认证</a-select-option>
|
||||
<a-select-option value="2">微信未认证</a-select-option>
|
||||
<a-select-option value="3">支付宝未认证</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.settlementType" placeholder="结算类型" >
|
||||
<a-select-option value="T1">T1</a-select-option>
|
||||
<a-select-option value="D1">D1</a-select-option>
|
||||
<a-select-option value="D0">D0</a-select-option>
|
||||
<a-select-option value="定时结算">定时结算</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="商户状态" >
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<!-- <a-select-option value="0">草稿</a-select-option> -->
|
||||
<!-- <a-select-option value="1">审核中</a-select-option> -->
|
||||
<a-select-option value="2">进件成功</a-select-option>
|
||||
<!-- <a-select-option value="3">驳回待修改</a-select-option> -->
|
||||
<!-- <a-select-option value="4">待验证</a-select-option> -->
|
||||
<!-- <a-select-option value="5">待签约</a-select-option> -->
|
||||
<!-- <a-select-option value="7">等待预审</a-select-option> -->
|
||||
<!-- <a-select-option value="8">预审拒绝</a-select-option> -->
|
||||
<a-select-option value="20">已风控</a-select-option>
|
||||
<a-select-option value="21">已冻结</a-select-option>
|
||||
<a-select-option value="22">已注销</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:scroll="{ x: 1000 }"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="applyId"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'verify'">
|
||||
<Tooltip color="#3b4146">
|
||||
<template #title>
|
||||
<div style="color: #ffffff">提示内容</div>
|
||||
</template>
|
||||
<div style="cursor: pointer; width: 100%">
|
||||
认证状态
|
||||
<a-tooltip
|
||||
title="支付宝微信必须认证后才可以交易,如遇列表认证状态未自动更新,可以点击认证状态展开详情页更新。"
|
||||
><question-circle-outlined style="padding-left: 10px"
|
||||
/></a-tooltip>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'settlementType'">
|
||||
<Tooltip color="#3b4146">
|
||||
<template #title>
|
||||
<div style="color: #ffffff">提示内容</div>
|
||||
</template>
|
||||
<div style="cursor: pointer; width: 100%">
|
||||
结算类型
|
||||
<a-tooltip>
|
||||
<template #title>
|
||||
<p>T1:工作日次日到账,交易资金于周末和法定节假日次日的6点-12点自动结算至银行卡</p>
|
||||
<p>D1:自然日次日到账,全年365天(不分节假日)的交易资金于自然日的次日6点-12点自动结算至银行卡</p>
|
||||
<p>D0:实时到账,全年365天24小时(不分节假日)的交易资金笔笔实时秒到至银行卡,更放心更快捷</p>
|
||||
<p>定时结算,在一天24个整点时辰,根据入账需求选择结算范围,可任意指定一个或多个结算时间点</p>
|
||||
</template>
|
||||
<question-circle-outlined style="padding-left: 10px"/>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 表格顶部按钮行插槽 -->
|
||||
<template #topBtnSlot>
|
||||
<a-button
|
||||
v-if="$access('ENT_MCH_APPLYMENT_ADD')"
|
||||
type="primary"
|
||||
@click="addFuncUrl()"
|
||||
><plus-outlined />发起进件</a-button
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- body 渲染插槽 -->
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'contactName'">
|
||||
{{ record.contactName }} {{ record.contactPhone }}
|
||||
</template>
|
||||
<template v-if="column.key === 'notes'" >
|
||||
<span @click="remarkFunc(record)" class="two-lines" v-if="$access('ENT_MCH_BUSINESS_REMARK')" >
|
||||
<b>{{ record.remark != "" ? record.remark : "--" }}</b>
|
||||
<EditOutlined @click="remarkFunc(record)" />
|
||||
</span>
|
||||
|
||||
<span class="two-lines" v-if="!$access('ENT_MCH_BUSINESS_REMARK')" >
|
||||
<b>{{ record.remark != "" ? record.remark : "--" }}</b>
|
||||
</span>
|
||||
|
||||
</template>
|
||||
<template v-if="column.key === 'settlementType'">
|
||||
<a @click="getChangeConfigRef(record)" v-if="$access('ENT_MCH_BUSINESS_SETTLE ')"><b>{{ record.settlementType }}</b>
|
||||
|
||||
<EditOutlined @click="getChangeConfigRef(record)" />
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'range'">
|
||||
<a-tag v-if="record.range == 0" color="orange">线下场景</a-tag>
|
||||
<a-tag v-if="record.range == 1" color="green">线上场景</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'mchShortName'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>商户全称:{{record.mchFullName}}</span><br>
|
||||
<span>商户简称:{{record.mchShortName}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchShortName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'autoConfigMchAppId'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>应用名称:{{record.appName}}</span><br>
|
||||
<span>应用ID:{{record.autoConfigMchAppId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.appName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'isvNo'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>渠道名称:{{record.isvName}}</span><br>
|
||||
<span>渠道号:{{record.isvNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.isvName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'applyId'">
|
||||
|
||||
<a @click="detailFunc(record.applyId)" v-if="$access('ENT_MCH_BUSINESS_DETAIL')" ><b>{{ record.applyId }}</b></a>
|
||||
<a v-if="!$access('ENT_MCH_BUSINESS_DETAIL')" ><b>{{ record.applyId }}</b></a>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'merchantType'">
|
||||
{{
|
||||
record.merchantType === 1
|
||||
? "小微"
|
||||
: record.merchantType === 2
|
||||
? "个体"
|
||||
: record.merchantType === 3
|
||||
? "企业"
|
||||
: "其他组织"
|
||||
}}
|
||||
</template>
|
||||
|
||||
|
||||
<template v-if="column.key === 'state'">
|
||||
<a-badge v-if="record.state == 0" status="default" text="草稿" />
|
||||
<a-badge
|
||||
v-if="record.state == 1"
|
||||
status="warning"
|
||||
text="等待审核结果"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 2"
|
||||
status="success"
|
||||
text="进件成功"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 3"
|
||||
status="error"
|
||||
text="驳回待修改"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 4"
|
||||
status="processing"
|
||||
text="待验证"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 5"
|
||||
status="processing"
|
||||
text="待签约"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 7"
|
||||
status="processing"
|
||||
text="等待预审"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 8"
|
||||
status="processing"
|
||||
text="预审拒绝"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 20"
|
||||
status="processing"
|
||||
text="已被风控"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 21"
|
||||
status="processing"
|
||||
text="已冻结"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.state == 12"
|
||||
status="warning"
|
||||
text="待通道复审"
|
||||
/>
|
||||
<a-tooltip v-if="record.ifCode == 'kqpay' && record.state == 12" title="快钱通道营业执照商户支持先开通后审核,复审期间的交易会在人工审批完成后结算,复审时间一般为1个工作日。">
|
||||
<info-circle-outlined style="font-size: 16px; padding-left: 5px;color: #FF0000"/>
|
||||
</a-tooltip>
|
||||
<reload-outlined @click="queryChannelState(record.applyId, record.state)" style="color: #1890ff; margin-left: 5px" v-if="(record.state == 1 || record.state == 4 || record.state == 7 || record.state == 5 || record.state == 12) && $access('ENT_MCH_APPLYMENT_GET_INFO') " />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'storeNumber'">
|
||||
<a href="javascript:void(0)" @click="getStore(record.applyId)">{{ record.storeNumber ? record.storeNumber : 0 }}</a>
|
||||
</template>
|
||||
<template v-if="column.key === 'verify'">
|
||||
<div @click="oauthFunc(record.applyId)" v-if="$access('ENT_MCH_BUSINESS_AUTH') && record.ifCode !='zftpay'">
|
||||
<p class="verify_box">
|
||||
微信:
|
||||
<a-badge
|
||||
v-if="record.wxAuthenticationState == 1"
|
||||
status="success"
|
||||
text="已认证"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.wxAuthenticationState == 0"
|
||||
status="default"
|
||||
text="未认证"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.wxAuthenticationState == -1"
|
||||
status="default"
|
||||
text="未知"
|
||||
/>
|
||||
</p>
|
||||
<p class="verify_box">
|
||||
支付宝:
|
||||
<a-badge
|
||||
v-if="record.zfbAuthenticationState == 1"
|
||||
status="success"
|
||||
text="已认证"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.zfbAuthenticationState == 0"
|
||||
status="default"
|
||||
text="未认证"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.zfbAuthenticationState == -1"
|
||||
status="default"
|
||||
text="未知"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="!$access('ENT_MCH_BUSINESS_AUTH') && record.ifCode !='zftpay'">
|
||||
<p class="verify_box">
|
||||
微信:
|
||||
<a-badge
|
||||
v-if="record.wxAuthenticationState == 1"
|
||||
status="success"
|
||||
text="已认证"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.wxAuthenticationState == 0"
|
||||
status="default"
|
||||
text="未认证"
|
||||
/>
|
||||
</p>
|
||||
<p class="verify_box">
|
||||
支付宝:
|
||||
<a-badge
|
||||
v-if="record.zfbAuthenticationState == 1"
|
||||
status="success"
|
||||
text="已认证"
|
||||
/>
|
||||
<a-badge
|
||||
v-if="record.zfbAuthenticationState == 0"
|
||||
status="default"
|
||||
text="未认证"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="record.ifCode =='zftpay'">
|
||||
<a-badge status="success" text="已认证" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 商户系统: 修改按钮多一个 8 预审拒接的判断, 没有参数配置。 其他是通用的。 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_MCH_BUSINESS_STORE')" type="link" @click="getStore(record.applyId)" >门店管理</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_BUSINESS_DETAIL')" type="link" @click="deviceFunc(record.applyId)">设备管理</a-button>
|
||||
|
||||
<a-button v-if="$access('ENT_MCH_BUSINESS_CHANGE_EDIT')" type="link" @click="getChangeConfigRef(record)" >变更修改</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_BUSINESS_AUTH') && record.ifCode != 'zftpay'" type="link" @click="oauthFunc(record.applyId)" >实名认证</a-button>
|
||||
|
||||
<a-button v-if="$access('ENT_MCH_BUSINESS_CONFIGURATION')" type="link" @click="oauthDeployFunc(record.applyId)" >参数配置</a-button >
|
||||
<a-button v-if="$access('ENT_MCH_BUSINESS_MANGE_ADD')" type="link" @click="getOperator()">添加管理员</a-button>
|
||||
|
||||
<a-button v-if="$access('ENT_MCH_BUSINESS_DETAIL')" type="link" @click="editOrViewFunc(record.applyId, true)">详情</a-button>
|
||||
<!-- 审核中、 待验证、 签约完成 -->
|
||||
<!-- <a-button
|
||||
v-if="$access('ENT_MCH_APPLYMENT_GET_INFO') && (record.state == 1 || record.state == 4 || record.state == 5)"
|
||||
type="link" @click="queryChannelState(record.applyId, record.state)">
|
||||
获取最新结果
|
||||
</a-button> -->
|
||||
|
||||
<!-- 1审核中、 2进件成功、 4待验证、 5待签约、 6签约完成/审核成功 -->
|
||||
<!-- <a-button
|
||||
v-if="$access('ENT_MCH_APPLYMENT_SIGN') && (record.state == 1 || record.state == 2 || record.state == 4 || record.state == 5 || record.state == 6)"
|
||||
type="link" @click="nextBizsDrawerRef.show(record.applyId)">
|
||||
签约开通
|
||||
</a-button> -->
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 定义组件分为: 第一步和第二步 -->
|
||||
<a-card>
|
||||
<component
|
||||
:is="vdata.currentApplyPage.component"
|
||||
ref="applyPageComponentRef"
|
||||
@switchApplyPage="switchApplyPage"
|
||||
/>
|
||||
</a-card>
|
||||
|
||||
<!-- 签约开通 弹层 -->
|
||||
<NextBizsDrawer ref="nextBizsDrawerRef" />
|
||||
<ChangeConfig ref="changeConfigRef" v-show="vdata.visibleChangeConfig" />
|
||||
|
||||
<!-- 详情页面组件 -->
|
||||
<InfoDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
|
||||
<a-modal
|
||||
v-model:visible="vdata.visibleNotes"
|
||||
title="编辑备注"
|
||||
:footer="null"
|
||||
width="50%"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<div style="height: 20vh; overflow: auto">
|
||||
<div
|
||||
class="code code-layout-item"
|
||||
style="display: flex; justify-content: center"
|
||||
>
|
||||
<a-form-item label="备注" required style="width: 80%">
|
||||
<a-textarea
|
||||
v-model:value="vdata.notes.value"
|
||||
placeholder="请输入备注"
|
||||
:auto-size="{ minRows: 3, maxRows: 5 }"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 34px">
|
||||
<a-button
|
||||
type="primary"
|
||||
:disabled="vdata.isDisabled"
|
||||
@click="sendNotes()"
|
||||
>
|
||||
确定
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- <JeepayMchChangeConfig v-if="vdata.visibleMchChange" ref="jeepayMchChangeConfigRef" />-->
|
||||
<JeepayOauth2DeployConfig v-show="vdata.visibleOauth2Deploy" configMode="mchApplyment" ref="jeepayOauth2DeployConfigRef"/>
|
||||
<JeepayMchOauth2 v-show="vdata.visibleOauth2" ref="jeepayMchOauth2Ref" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
API_URL_MCH_APPLYMENT_LIST,
|
||||
req,
|
||||
$getMchApplymentChannelState,
|
||||
API_MCH_APPLYMENT_REMARK,
|
||||
} from "@/api/manage";
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
getCurrentInstance,
|
||||
nextTick,
|
||||
provide,
|
||||
computed,
|
||||
} from "vue";
|
||||
import QrcodeVue from "qrcode.vue";
|
||||
import ApplySelectMchAndIfcode from "@/components/link/JeepayUIComponents/JeepayMchApplyment/JeepayMchApplymentSelectMchAndIfcode.vue";
|
||||
import ApplyMchDetailInfoEntry from "@/components/link/JeepayUIComponents/JeepayMchApplyment/JeepayMchApplymentDetailInfoEntry.vue";
|
||||
import NextBizsDrawer from "./NextBizsDrawer.vue";
|
||||
import ChangeConfig from "./ChangeConfig.vue";
|
||||
import InfoDetail from "./NewDetail.vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import GlobalLoad from "@/components/GlobalLoad/GlobalLoad.vue";
|
||||
|
||||
/** 定义全部组件 **/
|
||||
const allApplyPage = {
|
||||
list: { name: "列表", component: null },
|
||||
applySelectMchAndIfcode: {
|
||||
name: "选择进件渠道",
|
||||
component: ApplySelectMchAndIfcode,
|
||||
},
|
||||
applyMchDetailInfoEntry: {
|
||||
name: "填写进件资料",
|
||||
component: ApplyMchDetailInfoEntry,
|
||||
},
|
||||
};
|
||||
|
||||
const router = useRouter(); //这是全部路由
|
||||
// 动态组件
|
||||
|
||||
const jeepayMchOauth2Ref = ref();
|
||||
const jeepayOauth2DeployConfigRef = ref();
|
||||
const jeepayMchChangeConfigRef = ref();
|
||||
const applyPageComponentRef = ref();
|
||||
const nextBizsDrawerRef = ref();
|
||||
const changeConfigRef = ref();
|
||||
const infoDetail = ref();
|
||||
const stateRef = ref();
|
||||
const dateRangePicker = ref();
|
||||
|
||||
const { $infoBox, $access } =
|
||||
getCurrentInstance()!.appContext.config.globalProperties;
|
||||
|
||||
const infoTable = ref();
|
||||
let tableColumns = reactive([
|
||||
{ key: "applyId", dataIndex: "applyId", title: "商户号", width: 100 },
|
||||
{ key: "mchShortName", title: "商户简称", dataIndex: "mchShortName" },
|
||||
{ key: "ifName", title: "支付通道", dataIndex: "ifName" },
|
||||
{ key: "isvNo", title: "所属渠道", dataIndex: "isvNo" },
|
||||
{ key: "merchantType", title: "商户类型", dataIndex: "merchantType",align: "center" },
|
||||
{ key: "contactName", title: "商户联系人", dataIndex: "contactName" },
|
||||
{ key: "verify",title: "认证状态",dataIndex: "verify",align: "center"},
|
||||
{ key: "autoConfigMchAppId",title: "所属应用", dataIndex: "autoConfigMchAppId",},
|
||||
{ key: "range", title: "应用类型" },
|
||||
{ key: "settlementType", title: "结算类型", dataIndex: "settlementType",align: "center" },
|
||||
{ key: "state", title: "商户状态", dataIndex: "state" },
|
||||
{ key: "storeNumber", title: "门店总数", dataIndex: "storeNumber",align: "center" },
|
||||
{ key: "notes", title: "备注", dataIndex: "notes" ,align: "center" },
|
||||
{ key: "createdAt", dataIndex: "createdAt", title: "创建日期" },
|
||||
{ key: "operation", title: "操作", fixed: "right", dataIndex: "operation", align: "center", width: 200,},
|
||||
]);
|
||||
|
||||
let vdata: any = reactive({
|
||||
visibleChangeConfig: false,
|
||||
visibleNotes: false,
|
||||
visibleOauth2: false,
|
||||
visibleOauth2Deploy: false,
|
||||
visibleMchChange: false,
|
||||
notes: {
|
||||
appid: "",
|
||||
value: "",
|
||||
},
|
||||
searchData: { queryDateRange: "" }, // 搜索条件
|
||||
|
||||
currentApplyPage: allApplyPage.list, // 当前的步骤组件 null表示列表页
|
||||
backupApplyPage: null, // 备份: 用作快速恢复
|
||||
|
||||
mchApplymentData: {}, //商户进件资料
|
||||
|
||||
isView: false, // 是否预览模式
|
||||
|
||||
copyInfoSourceApplyId: "", // 副本资料
|
||||
});
|
||||
|
||||
// 清空搜索项
|
||||
const resetFunc = () => {
|
||||
dateRangePicker.value.returnSelectModel();
|
||||
vdata.searchData = { queryDateRange: "" };
|
||||
};
|
||||
|
||||
// 向所有子组件注入参数 (子组件可直接更改此值)
|
||||
provide(
|
||||
"mchApplymentData",
|
||||
computed(() => vdata.mchApplymentData)
|
||||
);
|
||||
provide(
|
||||
"isView",
|
||||
computed(() => vdata.isView)
|
||||
);
|
||||
|
||||
// 向所有子组件注入参数: 配置模式: mgrApplyment / agentApplyment / mchApplyment
|
||||
provide("configMode", "mchApplyment");
|
||||
|
||||
// 向所有子组件注入参数 副本资料来源ID
|
||||
provide(
|
||||
"copyInfoSourceApplyId",
|
||||
computed(() => vdata.copyInfoSourceApplyId)
|
||||
);
|
||||
|
||||
// 请求table接口数据
|
||||
async function reqTableDataFunc(params: any) {
|
||||
if (!vdata.searchData.state) {
|
||||
params.state = 99;
|
||||
}
|
||||
let res = await req.list(API_URL_MCH_APPLYMENT_LIST, params);
|
||||
var records = res.records;
|
||||
for (let i = 0; i < res.records.length; i++) {
|
||||
res.records[i]["contactName"] = maskedName(res.records[i]["contactName"]);
|
||||
res.records[i]["contactPhone"] = maskedMobile(
|
||||
res.records[i]["contactPhone"]
|
||||
);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
function maskedName(fullName) {
|
||||
if (fullName.length >= 2) {
|
||||
const firstName = fullName.charAt(0);
|
||||
const maskedPart = "*".repeat(fullName.length - 1);
|
||||
return firstName + maskedPart;
|
||||
}
|
||||
return fullName;
|
||||
}
|
||||
|
||||
function maskedMobile(phoneNumber) {
|
||||
if (phoneNumber.length === 11) {
|
||||
const prefix = phoneNumber.slice(0, 3);
|
||||
const suffix = phoneNumber.slice(-4);
|
||||
const maskedPart = "*".repeat(4);
|
||||
return prefix + maskedPart + suffix;
|
||||
}
|
||||
return phoneNumber;
|
||||
}
|
||||
function deviceFunc(mchApplyId){
|
||||
router.push({
|
||||
path: "/qrCodes",
|
||||
query:{mchApplyId:mchApplyId}
|
||||
});
|
||||
}
|
||||
function remarkFunc(data) {
|
||||
vdata.notes.appid = data.applyId;
|
||||
vdata.notes.value = data.remark ?? "";
|
||||
vdata.visibleNotes = true;
|
||||
}
|
||||
|
||||
function getStore(applyId) {
|
||||
router.push({
|
||||
path: "/store",
|
||||
query: { applyId: applyId },
|
||||
});
|
||||
}
|
||||
function getOperator() {
|
||||
router.push({
|
||||
path: "/users",
|
||||
});
|
||||
}
|
||||
|
||||
// 弹层取消
|
||||
function handleCancel(e) {
|
||||
vdata.visibleNotes = false;
|
||||
}
|
||||
|
||||
// 点击【查询】按钮点击事件
|
||||
function searchFunc() {
|
||||
infoTable.value.refTable(true);
|
||||
}
|
||||
|
||||
// 切换步骤: 不清空数据
|
||||
function switchApplyPage(page) {
|
||||
vdata.backupApplyPage = vdata.currentApplyPage;
|
||||
vdata.currentApplyPage = allApplyPage[page];
|
||||
|
||||
if (vdata.currentApplyPage && vdata.currentApplyPage.component) {
|
||||
nextTick(() => {
|
||||
applyPageComponentRef.value.pageRender();
|
||||
});
|
||||
} else {
|
||||
//列表页
|
||||
searchFunc(); // 刷新
|
||||
}
|
||||
}
|
||||
function detailFunc(recordId: any) {
|
||||
// 进件详情页
|
||||
|
||||
vdata.copyInfoSourceApplyId = ""; // 副本清空。
|
||||
|
||||
infoDetail.value.show(recordId);
|
||||
}
|
||||
|
||||
function addFuncUrl() {
|
||||
router.push({
|
||||
path: "/applyments",
|
||||
});
|
||||
}
|
||||
// 点击【发起进件】的操作
|
||||
function addFunc(copyInfoSourceApplyId = "") {
|
||||
vdata.copyInfoSourceApplyId = copyInfoSourceApplyId;
|
||||
|
||||
vdata.backupApplyPage = null; // 再次点击进件将无法再次恢复
|
||||
|
||||
//进件数据重置
|
||||
vdata.mchApplymentData = {};
|
||||
vdata.isView = false;
|
||||
switchApplyPage("applySelectMchAndIfcode");
|
||||
}
|
||||
|
||||
// 修改资料 然后重新发起进件操作
|
||||
function editOrViewFunc(applyId, isView) {
|
||||
vdata.copyInfoSourceApplyId = ""; // 副本清空。
|
||||
|
||||
vdata.backupApplyPage = null; // 再次点击进件将无法再次恢复
|
||||
vdata.isView = isView;
|
||||
|
||||
req
|
||||
.getById(API_URL_MCH_APPLYMENT_LIST, applyId, {
|
||||
originData: vdata.isView ? "0" : "1",
|
||||
})
|
||||
.then((res) => {
|
||||
let {
|
||||
applyId,
|
||||
channelApplyNo,
|
||||
mchNo,
|
||||
ifCode,
|
||||
applyDetailInfo,
|
||||
applyErrorInfo,
|
||||
state,
|
||||
isvNo,
|
||||
autoConfigMchAppId,
|
||||
range,
|
||||
} = res;
|
||||
vdata.mchApplymentData = {
|
||||
applyId,
|
||||
channelApplyNo,
|
||||
mchNo,
|
||||
ifCode,
|
||||
applyDetailInfo,
|
||||
applyErrorInfo,
|
||||
state,
|
||||
isvNo,
|
||||
autoConfigMchAppId,
|
||||
range,
|
||||
};
|
||||
switchApplyPage("applyMchDetailInfoEntry");
|
||||
});
|
||||
}
|
||||
|
||||
// 查询最新状态
|
||||
function queryChannelState(applyId, currState) {
|
||||
$getMchApplymentChannelState(applyId).then((res) => {
|
||||
if (currState != res.state) {
|
||||
$infoBox.message.success("状态已更新");
|
||||
searchFunc(); // 更新列表
|
||||
} else {
|
||||
$infoBox.message.info("状态无变化");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 显示二维码图片
|
||||
function showQrImgFunc(record) {
|
||||
if (record.ifCode == "wxpay") {
|
||||
vdata.wxQrCodeVisible = true;
|
||||
} else if (record.ifCode == "sftpay") {
|
||||
vdata.sftQrCodeVisible = true;
|
||||
} else if (record.ifCode == "fuioupay") {
|
||||
vdata.qrCodeVisible = true;
|
||||
vdata.confirmUrl = JSON.parse(record.applyErrorInfo).signUrl;
|
||||
return;
|
||||
} else {
|
||||
vdata.qrCodeVisible = true;
|
||||
}
|
||||
vdata.confirmUrl = record.applyErrorInfo;
|
||||
}
|
||||
|
||||
// 副本 copySourceApplyId : 需要copy的资料来源。
|
||||
function toCopySelectIfCodePage(copySourceApplyId, mchNo) {
|
||||
vdata.searchData.mchNo = mchNo;
|
||||
addFunc(copySourceApplyId);
|
||||
}
|
||||
|
||||
function sendNotes() {
|
||||
req
|
||||
.add(API_MCH_APPLYMENT_REMARK, {
|
||||
remark: vdata.notes.value,
|
||||
applyId: vdata.notes.appid,
|
||||
})
|
||||
.then((msg) => {
|
||||
console.log(msg, "resresres");
|
||||
$infoBox.message.success("编辑成功");
|
||||
searchFunc(); // 更新列表
|
||||
vdata.visibleNotes = false;
|
||||
});
|
||||
}
|
||||
|
||||
function oauthDeployFunc(applyId) {
|
||||
vdata.visibleOauth2Deploy = true;
|
||||
jeepayOauth2DeployConfigRef.value.show(applyId);
|
||||
}
|
||||
|
||||
function oauthFunc(applyId) {
|
||||
vdata.visibleOauth2 = true;
|
||||
jeepayMchOauth2Ref.value.show(applyId);
|
||||
}
|
||||
function getChangeConfigRef(data) {
|
||||
vdata.visibleChangeConfig = true;
|
||||
changeConfigRef.value.show(data);
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.verify_box {
|
||||
text-align: center;
|
||||
}
|
||||
.two-lines {
|
||||
color: #1965ff;
|
||||
max-width: 150px;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
164
jeepay-ui-merchant/src/views/applyment/NewDetail.vue
Normal file
164
jeepay-ui-merchant/src/views/applyment/NewDetail.vue
Normal file
@@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="进件信息"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="50%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">基本信息</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户号">
|
||||
{{ vdata.detailData.applyId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收单机构编号">
|
||||
{{ vdata.detailData.channelMchNo??"暂未进件"}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24" v-if="vdata.detailData.ifCode == 'lklspay'">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="终端号">
|
||||
{{ vdata.termNo ??"暂未进件"}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="$hasAgentEnt()" :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="拓展服务商">
|
||||
{{ vdata.detailData.agentNoName }} {{ vdata.detailData.agentPhone }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="进件来源">
|
||||
<span v-if="vdata.detailData.applyPageType == 'PLATFORM_WEB'">运营平台系统</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'AGENT_WEB'">代理商系统</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'AGENT_APP'">{{ $SYS_NAME_MAP.AGENT_APP }}APP</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'AGENT_LITE'">{{ $SYS_NAME_MAP.AGENT_APP }}小程序</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'MCH_WEB'">商户系统</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'MCH_APP'">{{ $SYS_NAME_MAP.MCH_APP }}APP</span>
|
||||
<span v-else-if="vdata.detailData.applyPageType == 'MCH_LITE'">{{ $SYS_NAME_MAP.MCH_APP }}小程序</span>
|
||||
<span v-else>{{ vdata.detailData.applyPageType || '' }}</span>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付通道">
|
||||
{{ vdata.detailData.ifName }}
|
||||
<!-- [ {{ vdata.detailData.ifCode }} ]-->
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="所属渠道">
|
||||
{{ vdata.detailData.isvName }} [ {{ vdata.detailData.isvNo }} ]
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<!-- <a-divider />-->
|
||||
</a-row>
|
||||
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">商户信息</a-divider>
|
||||
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户全称">
|
||||
{{ vdata.detailData.mchFullName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户简称">
|
||||
{{ vdata.detailData.mchShortName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户类型">
|
||||
{{ vdata.detailData.merchantType == 1?'小微':vdata.detailData.merchantType == 2?'个体':vdata.detailData.merchantType == 1?'企业':'其他' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算状态">
|
||||
{{vdata.detailData.settlementType??"暂未进件"}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="联系人姓名">
|
||||
{{ vdata.detailData.contactName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="联系人手机号">
|
||||
{{ vdata.detailData.contactPhone }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MCH_APPLYMENT_LIST, req } from '@/api/manage'
|
||||
import {defineProps,reactive, getCurrentInstance} from 'vue'
|
||||
const { $hasAgentEnt, $SYS_NAME_MAP } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata:any = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
termNo: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
vdata.detailData = { 'state': 1, 'type': 1 } // 数据清空
|
||||
// if (this.$refs.infoFormModel !== undefined) {
|
||||
// this.$refs.infoFormModel.resetFields()
|
||||
// }
|
||||
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_MCH_APPLYMENT_LIST, recordId).then(res => {
|
||||
if(res.succResParameter){
|
||||
const succResParameter = JSON.parse(res.succResParameter)
|
||||
vdata.termNo = succResParameter.termNo
|
||||
}else{
|
||||
vdata.termNo = "暂未进件"
|
||||
}
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
40
jeepay-ui-merchant/src/views/applyment/NextBizsDrawer.vue
Normal file
40
jeepay-ui-merchant/src/views/applyment/NextBizsDrawer.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
<!-- 签约开通 弹层模式 -->
|
||||
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="签约开通"
|
||||
width="70%"
|
||||
@close="vdata.visible = false"
|
||||
>
|
||||
<JeepayApplymentNextBizs v-if="vdata.visible" ref="jeepayApplymentNextBizsRef" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, reactive, nextTick} from 'vue'
|
||||
|
||||
const jeepayApplymentNextBizsRef = ref()
|
||||
|
||||
const vdata : any = reactive({
|
||||
type:null,
|
||||
applyId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (applyId,type="status") { // 弹层打开事件
|
||||
|
||||
vdata.applyId = applyId
|
||||
vdata.type = type
|
||||
vdata.visible = true
|
||||
// const text = applyId+"=**="+type;
|
||||
|
||||
nextTick(() => {
|
||||
jeepayApplymentNextBizsRef.value.pageRender(applyId)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
36
jeepay-ui-merchant/src/views/applyment/SigningConfig.vue
Normal file
36
jeepay-ui-merchant/src/views/applyment/SigningConfig.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
<!-- 商户信息变更 弹层模式 -->
|
||||
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="合同签约"
|
||||
width="45%"
|
||||
@close="vdata.visible = false"
|
||||
>
|
||||
<JeepayApplymentAppSigningConfig v-if="vdata.visible" ref="jeepayApplymentAppSigningConfigRef" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, reactive, nextTick} from 'vue'
|
||||
|
||||
const jeepayApplymentAppSigningConfigRef = ref()
|
||||
|
||||
const vdata : any = reactive({
|
||||
applyId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (data) { // 弹层打开事件)
|
||||
vdata.applyId = data.applyId
|
||||
vdata.visible = true
|
||||
|
||||
nextTick(() => {
|
||||
jeepayApplymentAppSigningConfigRef.value.pageRender(data)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
173
jeepay-ui-merchant/src/views/applyment/dgpay/DgConfigRef.vue
Normal file
173
jeepay-ui-merchant/src/views/applyment/dgpay/DgConfigRef.vue
Normal file
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="自主签约"
|
||||
width="55%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-tabs v-model:activeKey="vdata.currentStep">
|
||||
<a-tab-pane key="1" tab="微信实名认证" force-render>
|
||||
<a-form
|
||||
ref="stepForm1Ref"
|
||||
:model="vdata.applyData"
|
||||
:label-col="{ span: 4 }"
|
||||
:wrapper-col="{ span: 8 }"
|
||||
:rules="vdata.step1Rules"
|
||||
>
|
||||
<a-form-item label="商户实名认证">
|
||||
{{ vdata.wxOpenInfo.state || '异常[' + vdata.wxOpenInfo.errInfo + ']' }}
|
||||
<a-button :loading="vdata.wxOpenInfoBtnLoading" size="small" style="margin-left: 20px;" type="primary" @click="getMchApplymentWxOpenInfoFunc"><reload-outlined />刷新</a-button>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="vdata.wxOpenInfo.errInfo" label="驳回原因">
|
||||
<a-alert :message="vdata.wxOpenInfo.errInfo" type="error" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.wxOpenInfo.signUrl" style="margin-left: 10%;" label="">
|
||||
<p>商户联系人使用已绑定银行卡的微信扫下面的二维码:</p>
|
||||
<!-- <img :src="'data:image/jpg;base64,' + vdata.wxOpenInfo.signUrl" class="qrcode" style="width: 200px"> -->
|
||||
<QrcodeVue :value="vdata.wxOpenInfo.signUrl" :size="200" />
|
||||
<br>
|
||||
<p class="jeepay-tip-text">(温馨提示:自助认证不限制谁来操作认证,但建议是商户联系人进行认证,以免后期需要扫码找不到微信认证管理员)</p>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane v-if="vdata.alipayOpenInfo.signUrl" key="2" tab="支付宝实名认证" force-render>
|
||||
<a-form
|
||||
ref="stepForm3Ref"
|
||||
:model="vdata.applyData"
|
||||
:label-col="{ span: 4 }"
|
||||
:wrapper-col="{ span: 8 }"
|
||||
>
|
||||
<a-form-item label="商户实名状态">
|
||||
{{ vdata.alipayOpenInfo.state || '异常[' + vdata.alipayOpenInfo.errInfo + ']' }}
|
||||
<!-- <a-button :loading="vdata.alipayOpenInfoBtnLoading" size="small" style="margin-left: 20px;" type="primary" @click="getMchApplymentAlipayOpenInfoFunc"><reload-outlined />刷新</a-button> -->
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="vdata.alipayOpenInfo.signUrl" style="margin-left: 10%;" label="">
|
||||
<p>商户联系人使用已绑定银行卡的支付宝扫下面的二维码:</p>
|
||||
<QrcodeVue v-if="vdata.alipayOpenInfo.imgType == 'qrContent'" :value="vdata.alipayOpenInfo.signUrl" :size="200" class="qrcode" />
|
||||
<br>
|
||||
<!-- <p class="jeepay-tip-text">(温馨提示:自助认证不限制谁来操作认证,但建议是商户联系人进行认证,以免后期需要扫码找不到微信认证管理员)</p> -->
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MCH_APPLYMENT_LIST, req, $dgpayWxRealName, $getMchApplymentWxOpenInfo, $getMchApplymentAlipayOpenInfo } from '@/api/manage'
|
||||
import { getCurrentInstance, reactive, ref } from 'vue'
|
||||
import ruleGenerator from '@/utils/ruleGenerator'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
// 获取当前实例的代理对象
|
||||
const { proxy } : any = getCurrentInstance()
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default:null }
|
||||
})
|
||||
|
||||
const vdata : any = reactive({
|
||||
currentStep: ref('1'),
|
||||
recordId: null, // 更新对象ID
|
||||
applyData: {} as any, // 进件资料对象
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
wxConfList: [] as any,
|
||||
aliConfList: [] as any,
|
||||
wxOpenInfo: {}, // 微信开户意愿信息
|
||||
alipayOpenInfo: {}, // 支付宝认证信息
|
||||
step1Rules: {
|
||||
idcard1Img: [ ruleGenerator.requiredUpload('法人身份证人像面照片') ],
|
||||
idcard2Img: [ ruleGenerator.requiredUpload('法人身份证国徽面照片') ],
|
||||
idcardName: [ ruleGenerator.requiredInput('法人姓名') ],
|
||||
idcardNo: [ ruleGenerator.requiredInput('法人身份证号') ],
|
||||
contactPhone: [ ruleGenerator.requiredInput('联系人手机号') ],
|
||||
areaCode: [ ruleGenerator.requiredSelect('位置编码', 'array') ],
|
||||
address: [ ruleGenerator.requiredInput('经营地址') ],
|
||||
mchShortName: [ ruleGenerator.requiredInput('门店名称') ],
|
||||
storeOuterImg: [ ruleGenerator.requiredUpload('门头照') ],
|
||||
storeInnerImg: [ ruleGenerator.requiredUpload('店内环境照片') ],
|
||||
}
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
|
||||
vdata.currentStep = ref('1')
|
||||
|
||||
vdata.recordId = recordId
|
||||
|
||||
req.getById(API_URL_MCH_APPLYMENT_LIST, recordId, { originData: '1' }).then( (res) => {
|
||||
|
||||
vdata.applyData = JSON.parse(res.applyDetailInfo)
|
||||
if(vdata.applyData.wxConfList) {
|
||||
vdata.wxConfList = vdata.applyData.wxConfList
|
||||
}
|
||||
if(vdata.applyData.aliConfList) {
|
||||
vdata.aliConfList = vdata.applyData.aliConfList
|
||||
}
|
||||
|
||||
vdata.visible = true
|
||||
|
||||
getMchApplymentWxOpenInfoFunc()
|
||||
|
||||
getMchApplymentAlipayOpenInfoFunc()
|
||||
})
|
||||
}
|
||||
|
||||
// 微信实名认证查询
|
||||
function getMchApplymentWxOpenInfoFunc(){
|
||||
vdata.wxOpenInfoBtnLoading = true
|
||||
$getMchApplymentWxOpenInfo(vdata.recordId).then(res => {
|
||||
vdata.wxOpenInfo = res
|
||||
}).finally(() => {
|
||||
vdata.wxOpenInfoBtnLoading = false
|
||||
})
|
||||
}
|
||||
|
||||
// 微信实名认证
|
||||
function onSubmitWxRealName() {
|
||||
proxy.$refs['stepForm1Ref'].validate().then(() => {
|
||||
vdata.btnLoading = true
|
||||
$dgpayWxRealName(vdata.recordId, vdata.applyData).then(() => {
|
||||
$infoBox.message.success('审核中')
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.btnLoading = false
|
||||
}).catch(() => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 支付宝认证状态查询
|
||||
function getMchApplymentAlipayOpenInfoFunc(){
|
||||
vdata.alipayOpenInfoBtnLoading = true
|
||||
$getMchApplymentAlipayOpenInfo(vdata.recordId).then(res => {
|
||||
vdata.alipayOpenInfo = res || {}
|
||||
}).finally(() => {
|
||||
vdata.alipayOpenInfoBtnLoading = false
|
||||
})
|
||||
console.log(vdata.alipayOpenInfo)
|
||||
}
|
||||
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
// 图片识别的回调函数
|
||||
function ocrScanFunc(orcObject: any){
|
||||
if(orcObject){
|
||||
Object.assign(vdata.applyData, orcObject)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
.form-item-content{
|
||||
width: 70%
|
||||
}
|
||||
|
||||
</style>
|
||||
186
jeepay-ui-merchant/src/views/applyment/fuiou/FuiouSign.vue
Normal file
186
jeepay-ui-merchant/src/views/applyment/fuiou/FuiouSign.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="进件后续流程"
|
||||
width="50%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-steps :current="vdata.currentStep - 1" type="navigation">
|
||||
<a-step title="电子协议签署" />
|
||||
<a-step title="上传图片&提交审核" />
|
||||
</a-steps>
|
||||
<a-divider />
|
||||
|
||||
<a-span v-if="vdata.currentStep == 1">
|
||||
<a-form v-if="!vdata.isSign">
|
||||
<a-form-item v-if="vdata.signData.contractNo" label="协议编号">
|
||||
<p style="margin-top: 5px;">{{ vdata.signData.contractNo }}</p>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="vdata.signData.signUrl" label="协议地址">
|
||||
<p style="margin-top: 5px;"><a :href="vdata.signData.signUrl" target="_blank">{{ vdata.signData.signUrl }}</a></p>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="vdata.signData.signUrl" label="协议地址快捷访问二维码">
|
||||
<QrcodeVue :value="vdata.signData.signUrl" :size="150" class="qrcode" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="vdata.signData.expireTs" label="协议失效时间">
|
||||
<p style="margin-top: 5px;">{{ vdata.signData.expireTs }}</p>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<p v-else>协议已审核通过</p>
|
||||
</a-span>
|
||||
|
||||
<a-form v-if="vdata.currentStep == 2" :model="vdata.applyData" style="padding-bottom: 30px;" :label-col="{ span: 6 }" :wrapper-col="{ span: 12 }">
|
||||
<a-form-item v-if="vdata.applyData.licenseImg" label="营业执照照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.licenseImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.idcard1Img" label="法人身份证人像面照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.idcard1Img" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.idcard2Img" label="法人身份证国徽面照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.idcard2Img" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.storeOuterImg" label="门头照">
|
||||
<JeepayUpload v-model:src="vdata.applyData.storeOuterImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.storeInnerImg" label="店内环境照">
|
||||
<JeepayUpload v-model:src="vdata.applyData.storeInnerImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.settAccountLicenseImg" label="结算银行卡照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.settAccountLicenseImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.companyAccountLicenseImg" label="开户许可证照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.companyAccountLicenseImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.settAccountIdcard1Img" label="入账账户身份证人像照">
|
||||
<JeepayUpload v-model:src="vdata.applyData.settAccountIdcard1Img" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.settAccountIdcard2Img" label="入账账户身份证国徽面照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.settAccountIdcard2Img" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.acntArtifImg" label="入账非法人证明照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.acntArtifImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.organizationImg" label="组织机构代码证照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.organizationImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.taxRegistrationImg" label="税务登记证照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.taxRegistrationImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.handCertificateImg" label="手持证件照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.handCertificateImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.applyData.additionImg" label="补充资料照片">
|
||||
<JeepayUpload v-model:src="vdata.applyData.additionImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose"><close-outlined />关闭</a-button>
|
||||
<a-button v-if="vdata.currentStep == 1" type="primary" :loading="vdata.btnLoading" @click="onSubmit"><check-outlined />确认签署</a-button>
|
||||
<a-button v-if="vdata.currentStep == 2" type="primary" :loading="vdata.btnLoading" @click="onSubmit"><check-outlined />上传&提审</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MCH_APPLYMENT_LIST, req, $elecContractGenerate, $elecContractSign, $fuiouUpload } from '@/api/manage'
|
||||
import moment from 'moment'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
import { getCurrentInstance, reactive } from 'vue'
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default:null }
|
||||
})
|
||||
|
||||
const vdata : any = reactive({
|
||||
currentStep: 1,
|
||||
recordId: null, // 更新对象ID
|
||||
applyData: {} as any, // 进件资料对象
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
signData: {} as any, // 电子协议对象
|
||||
isSign: false, // 是否已签署电子协议
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
|
||||
vdata.recordId = recordId
|
||||
|
||||
req.getById(API_URL_MCH_APPLYMENT_LIST, recordId).then( (res) => {
|
||||
|
||||
vdata.applyData = JSON.parse(res.applyDetailInfo)
|
||||
|
||||
// 待签约,发起电子协议签署
|
||||
if(res.state == 5) {
|
||||
vdata.currentStep = 1
|
||||
elecContractGenerate()
|
||||
|
||||
// 签约完成,上传图片
|
||||
}else if(res.state == 6) {
|
||||
vdata.currentStep = 2
|
||||
}
|
||||
|
||||
vdata.visible = true
|
||||
})
|
||||
}
|
||||
|
||||
function elecContractGenerate() {
|
||||
$elecContractGenerate(vdata.recordId).then( (res) => {
|
||||
vdata.detailData = res
|
||||
if (vdata.detailData.storeSuccResParameter.includes('协议已审核通过')) {
|
||||
vdata.isSign = true
|
||||
}else if(vdata.detailData.storeSuccResParameter) {
|
||||
vdata.signData = JSON.parse(vdata.detailData.storeSuccResParameter)
|
||||
|
||||
var dateArr = vdata.signData.expireTs.split(' ')
|
||||
vdata.signData.expireTs = moment(dateArr[0]).format('yyyy-MM-DD') + ' ' + dateArr[1]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
vdata.btnLoading = true
|
||||
|
||||
if (vdata.currentStep == 1) {
|
||||
$elecContractSign(vdata.recordId).then(() => {
|
||||
$infoBox.message.success('签署成功')
|
||||
vdata.currentStep = 2
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.btnLoading = false
|
||||
}).catch(() => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
|
||||
} else if (vdata.currentStep == 2) {
|
||||
$fuiouUpload(vdata.recordId).then(() => {
|
||||
$infoBox.message.success('操作成功')
|
||||
vdata.currentStep = 3
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.btnLoading = false
|
||||
}).catch(() => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
.form-item-content{
|
||||
width: 70%
|
||||
}
|
||||
|
||||
</style>
|
||||
244
jeepay-ui-merchant/src/views/applyment/yspay/YsConfigRef.vue
Normal file
244
jeepay-ui-merchant/src/views/applyment/yspay/YsConfigRef.vue
Normal file
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="上传图片&提交审核"
|
||||
width="50%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form
|
||||
v-if="vdata.currentStep == 1"
|
||||
:model="vdata.applyData"
|
||||
style="padding-bottom: 30px;"
|
||||
:label-col="{ span: 6 }"
|
||||
:wrapper-col="{ span: 12 }"
|
||||
:rules="vdata.rules"
|
||||
>
|
||||
<div v-if="vdata.applyData.merchantType != '1'">
|
||||
<a-col :offset="1"><a-divider orientation="left" style="color: #1A66FF;">执照信息</a-divider></a-col>
|
||||
<a-form-item label="营业执照照片" name="licenseImg">
|
||||
<JeepayUpload v-model:src="vdata.applyData.licenseImg" bizType="applyment" />
|
||||
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A001'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
<a-col :offset="1"><a-divider orientation="left" style="color: #1A66FF;">法人信息</a-divider></a-col>
|
||||
<a-form-item label="法人身份证人像面照片" name="idcard1Img">
|
||||
<JeepayUpload v-model:src="vdata.applyData.idcard1Img" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A002'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="法人身份证国徽面照片" name="idcard2Img">
|
||||
<JeepayUpload v-model:src="vdata.applyData.idcard2Img" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A003'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="手持证件照片" name="idcardInHandImg">
|
||||
<JeepayUpload v-model:src="vdata.applyData.idcardInHandImg" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A009'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-col :offset="1"><a-divider orientation="left" style="color: #1A66FF;">商户信息</a-divider></a-col>
|
||||
<a-form-item label="门头照" name="storeOuterImg">
|
||||
<JeepayUpload v-model:src="vdata.applyData.storeOuterImg" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A006'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="店内环境照" name="storeInnerImg">
|
||||
<JeepayUpload v-model:src="vdata.applyData.storeInnerImg" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A007'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="收银台照" name="storeCashierImg">
|
||||
<JeepayUpload v-model:src="vdata.applyData.storeCashierImg" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A008'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-col :offset="1"><a-divider orientation="left" style="color: #1A66FF;">结算信息</a-divider></a-col>
|
||||
|
||||
<a-form-item label="结算银行卡正面照片" name="settAccountLicenseImg">
|
||||
<JeepayUpload v-model:src="vdata.applyData.settAccountLicenseImg" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A004'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="结算银行卡反面照片" name="settAccountBankImg2">
|
||||
<JeepayUpload v-model:src="vdata.applyData.settAccountBankImg2" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A005'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<div v-if="vdata.applyData.merchantType == '3'">
|
||||
<a-form-item label="开户许可证照片" name="companyAccountLicenseImg">
|
||||
<JeepayUpload v-model:src="vdata.applyData.companyAccountLicenseImg" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A011'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
<div v-if="vdata.applyData.codeLegalPersonAcc =='0'">
|
||||
<a-form-item label="入账账户身份证人像面照片" name="settAccountIdcard1Img">
|
||||
<JeepayUpload v-model:src="vdata.applyData.settAccountIdcard1Img" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A013'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="入账账户身份证国徽面照片" name="settAccountIdcard2Img">
|
||||
<JeepayUpload v-model:src="vdata.applyData.settAccountIdcard2Img" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A014'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="结算授权证书照片" name="settleAuthLetterPhoto">
|
||||
<JeepayUpload v-model:src="vdata.applyData.settleAuthLetterPhoto" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='B005'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
<a-col :offset="1"><a-divider orientation="left" style="color: #1A66FF;">其他信息</a-divider></a-col>
|
||||
<a-form-item label="收单协议盖章页照片" name="acquiringAgreementPhoto">
|
||||
<JeepayUpload v-model:src="vdata.applyData.acquiringAgreementPhoto" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='A010'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item label="其他材料照片" name="other1">
|
||||
<JeepayUpload v-model:src="vdata.applyData.other1" bizType="applyment" />
|
||||
<div v-for="(item, config) in vdata.imgUploadArr" :key="config" :span="8" :offset="1">
|
||||
<span v-if="item.picType=='B008'" class="jeepay-tip-text">{{ item.note }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose"><close-outlined />关闭</a-button>
|
||||
<a-button v-if="vdata.currentStep == 1" type="primary" :loading="vdata.btnLoading" @click="onSubmit"><check-outlined />上传&提审</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MCH_APPLYMENT_LIST, req, $elecContractGenerate, $elecContractSign, $yspayUpload } from '@/api/manage'
|
||||
import moment from 'moment'
|
||||
import { getCurrentInstance, reactive } from 'vue'
|
||||
import ruleGenerator from '@/utils/ruleGenerator'
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default:null }
|
||||
})
|
||||
|
||||
const vdata : any = reactive({
|
||||
currentStep: 1,
|
||||
recordId: null, // 更新对象ID
|
||||
applyData: {} as any, // 进件资料对象
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
signData: {} as any, // 电子协议对象
|
||||
isSign: false, // 是否已签署电子协议
|
||||
rules: {
|
||||
licenseImg: [ ruleGenerator.requiredUpload('营业执照照片') ],
|
||||
idcard1Img: [ ruleGenerator.requiredUpload('法人身份证人像面照片') ],
|
||||
idcard2Img: [ ruleGenerator.requiredUpload('法人身份证国徽面照片') ],
|
||||
idcardInHandImg: [ ruleGenerator.requiredUpload('手持身份证照片') ],
|
||||
storeOuterImg: [ ruleGenerator.requiredUpload('门头照') ],
|
||||
storeInnerImg: [ ruleGenerator.requiredUpload('内景照') ],
|
||||
storeCashierImg: [ ruleGenerator.requiredUpload('收银台照') ],
|
||||
settAccountLicenseImg: [ ruleGenerator.requiredUpload('结算银行卡正面照片') ],
|
||||
settAccountBankImg2: [ ruleGenerator.requiredUpload('结算银行卡反面照片') ],
|
||||
companyAccountLicenseImg: [ ruleGenerator.requiredUpload('开户许可证照片') ],
|
||||
settAccountIdcard1Img: [ ruleGenerator.requiredUpload('入账账户身份证人像面照片') ],
|
||||
settAccountIdcard2Img: [ ruleGenerator.requiredUpload('入账账户身份证国徽面照片') ],
|
||||
settleAuthLetterPhoto: [ ruleGenerator.requiredUpload('结算授权证书照片') ],
|
||||
},
|
||||
imgUploadArr: [], // 图片上传结果
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
|
||||
vdata.recordId = recordId
|
||||
|
||||
req.getById(API_URL_MCH_APPLYMENT_LIST, recordId, { originData: '1' }).then( (res) => {
|
||||
// 图片上传结果置空
|
||||
vdata.imgUploadArr = []
|
||||
|
||||
vdata.applyData = JSON.parse(res.applyDetailInfo)
|
||||
|
||||
// 签约完成,上传图片
|
||||
vdata.currentStep = 1
|
||||
|
||||
vdata.visible = true
|
||||
})
|
||||
}
|
||||
|
||||
function elecContractGenerate() {
|
||||
$elecContractGenerate(vdata.recordId).then( (res) => {
|
||||
vdata.detailData = res
|
||||
if (vdata.detailData.storeSuccResParameter.includes('协议已审核通过')) {
|
||||
vdata.isSign = true
|
||||
}else if(vdata.detailData.storeSuccResParameter) {
|
||||
vdata.signData = JSON.parse(vdata.detailData.storeSuccResParameter)
|
||||
|
||||
var dateArr = vdata.signData.expireTs.split(' ')
|
||||
vdata.signData.expireTs = moment(dateArr[0]).format('yyyy-MM-DD') + ' ' + dateArr[1]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
vdata.btnLoading = true
|
||||
|
||||
if (vdata.currentStep == 1) {
|
||||
$yspayUpload(vdata.recordId, vdata.applyData).then((res) => {
|
||||
if(res) {
|
||||
vdata.imgUploadArr = JSON.parse(res)
|
||||
}
|
||||
|
||||
$infoBox.message.success('操作成功')
|
||||
vdata.currentStep = 1
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.btnLoading = false
|
||||
vdata.visible = false
|
||||
}).catch(() => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
.form-item-content{
|
||||
width: 70%
|
||||
}
|
||||
|
||||
</style>
|
||||
153
jeepay-ui-merchant/src/views/cashierUrl/CashierUrl.vue
Normal file
153
jeepay-ui-merchant/src/views/cashierUrl/CashierUrl.vue
Normal file
@@ -0,0 +1,153 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-card style="box-sizing:border-box;padding:30px">
|
||||
<!-- 选择下单的应用列表 -->
|
||||
<a-form>
|
||||
<div style="display:flex;flex-direction:row">
|
||||
<!-- <p style="margin-top:9px;margin-right:10px;"></p> -->
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<span>应用:</span>
|
||||
<a-select v-model:value="vdata.appId" style="width:300px" @change="changeAppId">
|
||||
<a-select-option key="">应用APPID</a-select-option>
|
||||
<a-select-option v-for="(item) in vdata.mchAppList" :key="item.appId">{{ item.appName }} [{{ item.appId }}]</a-select-option>
|
||||
</a-select>
|
||||
<span style="margin-left: 30px;">门店:</span>
|
||||
<a-select v-model:value="vdata.storeId" style="width:300px;" @change="changeStoreId">
|
||||
<a-select-option key="">选择门店</a-select-option>
|
||||
<a-select-option v-for="(item) in vdata.mchStoreList" :key="item.storeId">{{ item.storeName }} [{{ item.storeId }}]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-form>
|
||||
|
||||
<!-- 未配置支付方式提示框 -->
|
||||
<a-divider v-if="!vdata.appId">请选择应用APPID</a-divider>
|
||||
<a-divider v-else-if="vdata.noConfigText">您尚未配置任何支付方式</a-divider>
|
||||
<a-divider v-else />
|
||||
|
||||
<div v-if="vdata.cashierUrl && vdata.isShowCashier">
|
||||
<div>
|
||||
<span>收银台地址链接:</span><br>
|
||||
<a :href="vdata.cashierUrl" target="_blank">{{ vdata.cashierUrl }}</a>
|
||||
<a-button v-clipboard:copy="vdata.cashierUrl" v-clipboard:success="() => $infoBox.message.success('复制成功')" style="margin-left: 10px;margin-bottom: 10px;" size="small" type="primary">复制</a-button>
|
||||
</div>
|
||||
<div>
|
||||
<span>收银台地址二维码:</span>
|
||||
<div style="padding: 10px 0 30px 0px;"><QrcodeVue :value="vdata.cashierUrl" :size="200" /></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 支付测试面板 v-if=""-->
|
||||
<!-- <a-button v-if="$access('ENT_MCH_GET_CASHIER_URL')" style="padding:5px 20px;background-color: #1953ff;border-radius: 5px;color:#fff" @click="immediatelyPay">创建收银台</a-button> -->
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_APP, API_URL_MCH_STORE_LIST, req, $payTest, $payTestCreateCashier } from '@/api/manage' // 接口
|
||||
import {ref, onMounted, reactive, getCurrentInstance,nextTick} from 'vue'
|
||||
import {useRoute} from 'vue-router'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
// 获取全局函数
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
const route = useRoute()
|
||||
const vdata = reactive({
|
||||
mchAppList: [] as any, // app列表
|
||||
mchStoreList: [] as any, // 门店列表
|
||||
appId: '', // 已选择的appId
|
||||
storeId: '', // 已选择的门店ID
|
||||
appPaywayList: [] as any, // 商户app支持的支付方式
|
||||
noConfigText: false, // 尚无任何配置分割线提示文字
|
||||
cashierUrl: '', // 收银台地址
|
||||
isShowCashier: true as any
|
||||
|
||||
})
|
||||
const payTestBarCode =ref()
|
||||
const payTestModal = ref()
|
||||
onMounted(()=>{
|
||||
// 获取传入的参数,如果参数存在,则为appId 重新赋值
|
||||
const appId = route.params.appId as string
|
||||
|
||||
if (appId) {
|
||||
vdata.appId = appId // appId赋值
|
||||
|
||||
// appPaywayListHandle(appId) // 调用appPaywayListHandle,展示支付方式
|
||||
}
|
||||
|
||||
// 请求接口,获取所有的appid,只有此处进行pageSize=-1传参
|
||||
req.list(API_URL_MCH_APP, { pageSize: -1, state: 1 }).then(res => {
|
||||
vdata.mchAppList = res.records
|
||||
if (vdata.mchAppList.length > 0) {
|
||||
// 赋予默认值
|
||||
//vdata.appId = vdata.mchAppList[0].appId
|
||||
//TODO
|
||||
if(vdata.appId == '') vdata.appId = vdata.mchAppList[0].appId
|
||||
// 根据appId的值,动态显示支付方式
|
||||
// appPaywayListHandle(vdata.appId)
|
||||
one()
|
||||
}
|
||||
|
||||
})
|
||||
function one (){
|
||||
// 请求接口,获取商户所有门店,只有次数进行pageSize=-1传参
|
||||
req.list(API_URL_MCH_STORE_LIST, { pageSize: -1 }).then(res => {
|
||||
vdata.mchStoreList = res.records
|
||||
if (vdata.mchStoreList.length > 0) {
|
||||
// 赋予默认值
|
||||
if(vdata.storeId == '') vdata.storeId = vdata.mchStoreList[0].storeId
|
||||
two()
|
||||
}
|
||||
})
|
||||
}
|
||||
function two (){
|
||||
$payTestCreateCashier({
|
||||
appId: vdata.appId, // appId
|
||||
storeId: vdata.storeId, // storeId
|
||||
}).then(res => {
|
||||
vdata.cashierUrl = res
|
||||
}).catch(() => {
|
||||
payTestBarCode.value.processCatch()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 变更 appId的事件
|
||||
function changeAppId (value) {
|
||||
immediatelyPay()
|
||||
}
|
||||
// 变更 门店ID的事件
|
||||
function changeStoreId (value) {
|
||||
immediatelyPay()
|
||||
}
|
||||
// 立即支付按钮
|
||||
function immediatelyPay () {
|
||||
|
||||
// 判断是否选择门店
|
||||
if (vdata.appId === '') {
|
||||
vdata.isShowCashier = false
|
||||
return false
|
||||
}
|
||||
// 判断是否选择门店
|
||||
if (vdata.storeId === '') {
|
||||
vdata.isShowCashier = false
|
||||
return false
|
||||
}
|
||||
|
||||
vdata.isShowCashier = true
|
||||
$payTestCreateCashier({
|
||||
appId: vdata.appId, // appId
|
||||
storeId: vdata.storeId, // storeId
|
||||
}).then(res => {
|
||||
vdata.cashierUrl = res
|
||||
}).catch(() => {
|
||||
payTestBarCode.value.processCatch()
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="css">
|
||||
@import './payTest.css';
|
||||
</style>
|
||||
128
jeepay-ui-merchant/src/views/cashierUrl/payTest.css
Normal file
128
jeepay-ui-merchant/src/views/cashierUrl/payTest.css
Normal file
@@ -0,0 +1,128 @@
|
||||
.paydemo .content {
|
||||
max-width: 1120px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.paydemo .paydemo-type-content {
|
||||
padding:20px 0;
|
||||
margin-bottom:20px;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.paydemo .paydemo-type-name {
|
||||
font-size: 16px;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.paydemo .paydemo-type-body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.paydemo .paydemo-type {
|
||||
padding: 12px;
|
||||
border: solid 1px #e2e2e2;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.paydemo .paydemo-type-h5 {
|
||||
padding: 12px;
|
||||
border: solid 1px #e2e2e2;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.paydemo .codeImg_wx_h5 {
|
||||
position: absolute;
|
||||
z-index:1001;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: #ffffff;
|
||||
width: 160px;
|
||||
}
|
||||
.paydemo .paydemo-type-img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
vertical-align: center;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.paydemo .this {
|
||||
color: #1953ff;
|
||||
border-color: #1953ff;
|
||||
}
|
||||
.paydemo .layui-input {
|
||||
width: 50%;
|
||||
display: inline;
|
||||
font-size: 14px;
|
||||
}
|
||||
.paydemo .paydemo-form-item {
|
||||
height: 38px;
|
||||
margin-bottom: 5px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.paydemo .layui-form-radio i:hover, .layui-form-radioed i {
|
||||
color: #1953ff;
|
||||
}
|
||||
.paydemo .layui-anim.layui-icon {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.paydemo .layui-form-radio {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.paydemo .paydemo-scan {
|
||||
padding-top: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.paydemo .layui-laypage .layui-laypage-curr .layui-laypage-em {
|
||||
background-color: #1953ff;
|
||||
}
|
||||
.paydemo .layui-laypage a:hover {
|
||||
color: #1953ff;
|
||||
}
|
||||
.paydemo-type-content p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.paydemo .layui-table-view .layui-table {
|
||||
width: 100%;
|
||||
}
|
||||
.paydemo .paydemo-btn {
|
||||
border: 1px solid #e2e2e2;
|
||||
background-color: #ffffff;
|
||||
color:#000000;
|
||||
margin-left: 8px;
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.paydemo #paydemo-amount {
|
||||
display: flex;
|
||||
align-items: inherit;
|
||||
}
|
||||
.paydemo #paydemo-amount .layui-unselect{
|
||||
margin-right:15px
|
||||
}
|
||||
|
||||
#randomOrderNo:hover {
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.paydemo-form-item label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right:15px;
|
||||
flex-wrap:wrap
|
||||
}
|
||||
.paydemo-form-item label input {
|
||||
margin-left:3px;
|
||||
}
|
||||
|
||||
.paydemo .article-title {
|
||||
font-weight: 600
|
||||
}
|
||||
187
jeepay-ui-merchant/src/views/current/AvatarModal.vue
Normal file
187
jeepay-ui-merchant/src/views/current/AvatarModal.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="data.visible"
|
||||
title="修改头像"
|
||||
:mask-closable="false"
|
||||
:confirm-loading="data.confirmLoading"
|
||||
:width="800"
|
||||
:footer="null"
|
||||
@cancel="cancelHandel"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :xs="24" :md="12" :style="{height: '350px'}">
|
||||
<vue-cropper
|
||||
ref="cropper"
|
||||
:img="data.options.img"
|
||||
:info="true"
|
||||
:auto-crop="data.options.autoCrop"
|
||||
:auto-crop-width="data.options.autoCropWidth"
|
||||
:auto-crop-height="data.options.autoCropHeight"
|
||||
:fixed-box="data.options.fixedBox"
|
||||
@realTime="realTime"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :xs="24" :md="12" :style="{height: '350px'}">
|
||||
<div class="avatar-upload-preview">
|
||||
<img :src="data.previews.url" :style="data.previews.img">
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<br>
|
||||
<a-row>
|
||||
<a-col :lg="2" :md="2">
|
||||
<a-upload name="file" :before-upload="beforeUpload" :show-upload-list="false">
|
||||
<a-button>
|
||||
<upload-outlined />
|
||||
选择图片
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</a-col>
|
||||
<a-col :lg="{span: 1, offset: 2}" :md="2">
|
||||
<a-button icon="plus" @click="changeScale(1)" />
|
||||
</a-col>
|
||||
<a-col :lg="{span: 1, offset: 1}" :md="2">
|
||||
<a-button icon="minus" @click="changeScale(-1)" />
|
||||
</a-col>
|
||||
<a-col :lg="{span: 1, offset: 1}" :md="2">
|
||||
<a-button icon="undo" @click="rotateLeft" />
|
||||
</a-col>
|
||||
<a-col :lg="{span: 1, offset: 1}" :md="2">
|
||||
<a-button icon="redo" @click="rotateRight" />
|
||||
</a-col>
|
||||
<a-col :lg="{span: 2, offset: 6}" :md="2">
|
||||
<a-button type="primary" @click="finish('blob')">
|
||||
保存
|
||||
</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { upload, $updateUserInfo } from '@/api/manage'
|
||||
import {reactive,ref} from 'vue'
|
||||
import {message} from 'ant-design-vue'
|
||||
import {useUserStore} from '@/store/modules/user'
|
||||
const emit = defineEmits(['ok'])
|
||||
const cropper = ref()
|
||||
const data =reactive({
|
||||
recordId: useUserStore().userInfo.sysUserId, // 拿到ID
|
||||
userLoad: upload.avatar, // 图片上传地址
|
||||
visible: false,
|
||||
id: null,
|
||||
confirmLoading: false,
|
||||
fileList: [],
|
||||
uploading: false,
|
||||
options: {
|
||||
// img: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||
img:'' as any ,
|
||||
autoCrop: true,
|
||||
autoCropWidth: 200,
|
||||
autoCropHeight: 200,
|
||||
fixedBox: true
|
||||
},
|
||||
previews: {} as any
|
||||
})
|
||||
|
||||
defineExpose({edit,okHandel})
|
||||
function edit (id) {
|
||||
data.visible = true
|
||||
data.id = id
|
||||
/* 获取原始头像 */
|
||||
}
|
||||
function close () {
|
||||
data.id = null
|
||||
data.visible = false
|
||||
}
|
||||
function cancelHandel () {
|
||||
close()
|
||||
}
|
||||
function changeScale (num) {
|
||||
num = num || 1
|
||||
cropper.value.changeScale(num)
|
||||
}
|
||||
function rotateLeft () {
|
||||
cropper.value.rotateLeft()
|
||||
}
|
||||
function rotateRight () {
|
||||
cropper.value.rotateRight()
|
||||
}
|
||||
function beforeUpload (file) {
|
||||
const reader = new FileReader()
|
||||
// 把Array Buffer转化为blob 如果是base64不需要
|
||||
// 转化为base64
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = () => {
|
||||
data.options.img = reader.result
|
||||
}
|
||||
// 转化为blob
|
||||
// reader.readAsArrayBuffer(file)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 上传图片(点击上传按钮)
|
||||
function finish (type) {
|
||||
console.log('finish')
|
||||
|
||||
// 创建一个空对象
|
||||
const reqData:any ={}
|
||||
// 输出
|
||||
if (type === 'blob') {
|
||||
cropper.value.getCropBlob((data) => {
|
||||
// 通过该方法可以获取当前文件的一个内存URL
|
||||
const img = window.URL.createObjectURL(data)
|
||||
data.model = true
|
||||
data.modelSrc = img
|
||||
reqData.avatarUrl = img
|
||||
// this.$http.post('https://www.mocky.io/v2/5cc8019d300000980a055e76', reqData, { contentType: false, processData: false, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
|
||||
$updateUserInfo(reqData).then((response) => {
|
||||
message.success('上传成功')
|
||||
emit('ok', response.url)
|
||||
data.visible = false
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
console.log(data.userLoad, data.recordId, data.modelSrc)
|
||||
})
|
||||
} else {
|
||||
cropper.value.getCropData((data) => {
|
||||
data.model = true
|
||||
data.modelSrc = data
|
||||
})
|
||||
}
|
||||
}
|
||||
function okHandel () {
|
||||
|
||||
data.confirmLoading = true
|
||||
setTimeout(() => {
|
||||
data.confirmLoading = false
|
||||
close()
|
||||
message.success('上传头像成功')
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
function realTime (data) {
|
||||
data.previews = data
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.avatar-upload-preview {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(50%, -50%);
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
476
jeepay-ui-merchant/src/views/current/UserinfoPage.vue
Normal file
476
jeepay-ui-merchant/src/views/current/UserinfoPage.vue
Normal file
@@ -0,0 +1,476 @@
|
||||
<template>
|
||||
<div :key="data.updateKey" style="background: #fff;border-radius:10px">
|
||||
<a-tabs v-model:activeKey="data.tableKey" @change="selectTabs">
|
||||
<a-tab-pane key="1" :disabled="data.isPwdExpired" tab="基本信息">
|
||||
<div class="account-settings-info-view">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="16" :lg="16">
|
||||
<a-form ref="infoFormModel" :model="data.saveObject" :label-col="{span: 9}" :wrapper-col="{span: 10}" :rules="data.rules">
|
||||
<a-form-item label="用户登录名:">
|
||||
<a-input v-model:value="data.saveObject.loginUsername" disabled />
|
||||
</a-form-item>
|
||||
<a-form-item label="用户姓名:" name="realname">
|
||||
<a-input v-model:value="data.saveObject.realname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="手机号:" name="telphone">
|
||||
<a-input v-model:value="data.saveObject.telphone" disabled />
|
||||
</a-form-item>
|
||||
<a-form-item label="请选择性别:">
|
||||
<a-radio-group v-model:value="data.saveObject.sex">
|
||||
<a-radio :value="1">
|
||||
男
|
||||
</a-radio>
|
||||
<a-radio :value="2">
|
||||
女
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-form-item class="bottom-btn">
|
||||
<a-button type="primary" :loading="data.btnLoading" @click="changeInfo">
|
||||
<check-circle-outlined />
|
||||
更新基本信息
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :lg="8" :style="{ minHeight: '180px',margin:'0 auto' }">
|
||||
<!-- 原始的头像上传,带有图片裁剪功能 -->
|
||||
<!-- <div class="ant-upload-preview" @click="$refs.modal.edit(1)" > -->
|
||||
<div class="ant-upload-preview">
|
||||
<!-- <a-icon type="cloud-upload-o" class="upload-icon"/> -->
|
||||
<!-- <div class="mask">
|
||||
<a-icon type="plus" />
|
||||
</div> -->
|
||||
<img
|
||||
:src="data.saveObject.avatarUrl"
|
||||
style="border: 1px solid rgba(0,0,0,0.08)"
|
||||
>
|
||||
|
||||
<JeepayUpload
|
||||
v-model:src="data.saveObject.avatarUrl"
|
||||
bizType="avatar"
|
||||
style="margin-top:10px"
|
||||
:showUploadList="false"
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<!-- 图片裁剪组件 <avatar-modal ref="modal" @ok="setavatar"/> -->
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" tab="安全信息">
|
||||
<a-tabs v-model:activeKey="data.tableKey2" tab-position="left" @change="selectTabsSub">
|
||||
<a-tab-pane key="password" tab="修改密码">
|
||||
<div class="account-settings-info-view">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="16" :lg="16">
|
||||
<a-form ref="pwdFormModel" :model="data.updateObject" :label-col="{span: 9}" :wrapper-col="{span: 10}" :rules="data.rulesPass">
|
||||
<a-form-item label="原密码:" name="originalPwd">
|
||||
<a-input-password v-model:value="data.updateObject.originalPwd" autocomplete="new-password" placeholder="请输入原密码" />
|
||||
</a-form-item>
|
||||
<a-form-item label="新密码:" name="newPwd">
|
||||
<a-input-password v-model:value="data.updateObject.newPwd" autocomplete="new-password" placeholder="请输入新密码" />
|
||||
</a-form-item>
|
||||
<a-form-item label="确认新密码:" name="confirmPwd">
|
||||
<a-input-password v-model:value="data.updateObject.confirmPwd" autocomplete="new-password" placeholder="确认新密码" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-form-item class="bottom-btn">
|
||||
<a-button type="primary" :loading="data.btnLoading" @click="confirm">
|
||||
<check-circle-outlined />
|
||||
更新密码
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="mfaVer" tab="MFA认证" :disabled="data.isPwdExpired">
|
||||
<div class="account-settings-info-view">
|
||||
<a-row v-if="data.mfaInfo.mfaBindState == '0'" :gutter="12" justify="start">
|
||||
<a-col :push="2">
|
||||
<QrcodeVue :value="data.mfaInfo.mfaBindUrl" :size="200" />
|
||||
</a-col>
|
||||
<a-col :push="3">
|
||||
<a-alert message="" type="warning">
|
||||
<template #description>
|
||||
1.请使用MFA工具
|
||||
<a-popover placement="bottom">
|
||||
<template #content>
|
||||
<p>推荐使用以下工具:</p>
|
||||
<p>1. 阿里云或腾讯云手机客户端</p>
|
||||
<p>2. 微信小程序:二次验证码</p>
|
||||
</template>
|
||||
<question-circle-outlined />
|
||||
</a-popover>
|
||||
,扫描左侧二维码进行绑定。<br><br>
|
||||
2.扫描完成后,输入工具内对应的验证码。<br><br>
|
||||
注:不能扫码?
|
||||
<a-popover placement="bottom">
|
||||
<template #content>
|
||||
<p>输入以下账号、秘钥进行绑定:</p>
|
||||
<p>账号:{{ data.saveObject.telphone }}</p>
|
||||
<p>秘钥:{{ data.mfaInfo.mfaSecretKey }}</p>
|
||||
</template>
|
||||
<question-circle-outlined />
|
||||
</a-popover>
|
||||
</template>
|
||||
</a-alert>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-else>
|
||||
<a-col :push="2">
|
||||
<a-alert message="" type="success">
|
||||
<template #description>
|
||||
已完成MFA认证。
|
||||
</template>
|
||||
</a-alert>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="12" justify="start" type="flex" style="margin-top: 30px;">
|
||||
<a-col :md="6" :lg="6">
|
||||
<a-form ref="mfaFormModel" :model="data.mfaInfo" :rules="data.rulesCode">
|
||||
<a-form-item label="验证码" name="verCode">
|
||||
<a-input v-model:value="data.mfaInfo.verCode" placeholder="请输入验证码" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-form-item class="bottom-btn">
|
||||
<a-button v-if="data.mfaInfo.mfaBindState=='0'" type="primary" :loading="data.btnLoading" @click="mfaBindConfirm">
|
||||
<check-circle-outlined />
|
||||
确认绑定
|
||||
</a-button>
|
||||
<a-button v-else type="primary" danger :loading="data.btnLoading" @click="mfaRelieveConfirm">
|
||||
<check-circle-outlined />
|
||||
确认解绑
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="msg" tab="预留信息">
|
||||
<div class="account-settings-info-view">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="16" :lg="16">
|
||||
<a-form :label-col="{span: 9}" :wrapper-col="{span: 10}">
|
||||
<a-form-item label="预留信息:" name="">
|
||||
<a-input v-model:value="data.safeWord" placeholder="请输入新的预留信息" show-count :maxlength="10" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-form-item class="bottom-btn" style="margin-bottom: 90px;">
|
||||
<a-button type="primary" :loading="data.btnLoading" @click="safeWordUpdate">
|
||||
<check-circle-outlined />
|
||||
确认更新
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { $getUserInfo, $updateUserInfo, $getMFAInfo, $mfaBind, $mfaRelieve, $updateUserPass, upload, $getPasswordRules } from '@/api/manage'
|
||||
import AvatarModal from './AvatarModal.vue'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
// import store from '@/store'
|
||||
import {useUserStore} from '@/store/modules/user'
|
||||
import { Base64 } from 'js-base64'
|
||||
import {ref, reactive,onMounted,getCurrentInstance,toRaw} from 'vue'
|
||||
import {message} from 'ant-design-vue'
|
||||
import { getCurrentUserInfo } from '@/api/login'
|
||||
import { useRoute } from 'vue-router'
|
||||
const infoFormModel = ref()
|
||||
const pwdFormModel = ref()
|
||||
const mfaFormModel = ref()
|
||||
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const data = reactive({
|
||||
action: upload.avatar, // 上传图标地址
|
||||
btnLoading: false,
|
||||
groupKey: 'password',
|
||||
passwordRules: /^$/, //密码规则
|
||||
passwordRulesText: '', //密码规则提示文字
|
||||
safeWord:'', //预留信息
|
||||
saveObject: {
|
||||
loginUsername: '', // 登录名
|
||||
realname: '', // 真实姓名
|
||||
telphone: '',
|
||||
sex: '',
|
||||
avatarUrl: '' // 用户头像
|
||||
},
|
||||
mfaInfo: {
|
||||
mfaBindUrl: '',
|
||||
mfaBindState: '',
|
||||
mfaSecretKey: '',
|
||||
verCode: ''
|
||||
},
|
||||
updateKey:0, //刷新键
|
||||
confirmLoading:false,
|
||||
// avatarUrl: useUserStore().userInfo.avatarImgPath,
|
||||
updateObject: {
|
||||
originalPwd: '', // 原密码
|
||||
newPwd: '', // 新密码
|
||||
confirmPwd: '' // 确认密码
|
||||
} as any,
|
||||
recordId: useUserStore().userInfo.sysUserId, // 拿到ID
|
||||
rules: {
|
||||
realname: [{ required: true, message: '请输入真实姓名', trigger: 'blur' }]
|
||||
},
|
||||
rulesCode: {
|
||||
verCode: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
|
||||
},
|
||||
rulesPass: {
|
||||
originalPwd: [{ required: true, message: '请输入原密码', trigger: 'blur' }],
|
||||
newPwd: [
|
||||
{ required: false, trigger: 'blur' },{
|
||||
validator: (rule, value) => {
|
||||
if (!data.passwordRules.test(data.updateObject.newPwd)) {
|
||||
return Promise.reject(data.passwordRulesText)
|
||||
} else if(data.updateObject.newPwd !== data.updateObject.confirmPwd) {
|
||||
return Promise.reject('新密码与确认新密码不一致')
|
||||
} else return Promise.resolve()
|
||||
}
|
||||
}
|
||||
],
|
||||
confirmPwd: [{ required: false, trigger: 'blur' }, {
|
||||
validator: (rule, value) => {
|
||||
if (!data.passwordRules.test(data.updateObject.confirmPwd)) {
|
||||
return Promise.reject(data.passwordRulesText)
|
||||
} else if(data.updateObject.newPwd !== data.updateObject.confirmPwd) {
|
||||
return Promise.reject('新密码与确认新密码不一致')
|
||||
} else return Promise.resolve()
|
||||
}
|
||||
}]
|
||||
},
|
||||
|
||||
tableKey: '1',
|
||||
tableKey2:'password', //子tabkey
|
||||
isPwdExpired: false, //是否强制改密码
|
||||
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
|
||||
if(useRoute().query.isPwdExpired == '1'){
|
||||
data.isPwdExpired = true
|
||||
data.tableKey = '2'
|
||||
}
|
||||
if(useRoute().query.type === 'msg'){
|
||||
data.tableKey = '2'
|
||||
data.tableKey2 = 'msg'
|
||||
}
|
||||
|
||||
detail()
|
||||
getPasswordRules()
|
||||
})
|
||||
function detail () { // 获取基本信息
|
||||
|
||||
$getUserInfo().then(res => {
|
||||
data.saveObject = res
|
||||
data.safeWord = res.safeWord
|
||||
})
|
||||
}
|
||||
function getPasswordRules () { // 获取密码规则
|
||||
$getPasswordRules().then(res => {
|
||||
data.passwordRules = new RegExp(res.regexpRules)
|
||||
data.passwordRulesText = res.errTips
|
||||
})
|
||||
}
|
||||
function changeInfo () { // 更新基本信息事件
|
||||
infoFormModel.value.validate().then(valid =>{
|
||||
|
||||
$infoBox.confirmPrimary('确认更新信息吗?', '', () => {
|
||||
data.btnLoading = true // 打开按钮上的 loading
|
||||
// that.$store.commit('showLoading') // 关闭全局刷新
|
||||
// 请求接口
|
||||
$updateUserInfo(toRaw(data.saveObject)).then(res => {
|
||||
data.btnLoading = false // 关闭按钮刷新
|
||||
//$store.commit('hideLoading') // 关闭全局刷新
|
||||
return getCurrentUserInfo()
|
||||
}).then(bizData => {
|
||||
bizData.avatarUrl = data.saveObject.avatarUrl
|
||||
bizData.realname = data.saveObject.realname
|
||||
useUserStore().refUserInfo() // 刷新用户信息
|
||||
// store.commit('SET_USER_INFO', bizData) // 调用vuex设置用户基本信息
|
||||
message.success('修改成功')
|
||||
}).catch(res => {
|
||||
// that.$store.commit('hideLoading') // 关闭全局刷新
|
||||
data.btnLoading = false
|
||||
console.log(res)
|
||||
message.error('修改失败')
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
function confirm (e) { // 确认更新密码
|
||||
pwdFormModel.value.validate().then(valid=>{
|
||||
$infoBox.confirmPrimary('确认更新密码吗?', '', () => {
|
||||
// 请求接口
|
||||
data.btnLoading = true // 打开按钮上的 loading
|
||||
data.confirmLoading = true // 显示loading
|
||||
data.updateObject.recordId = data.recordId // 用户ID
|
||||
const copyUpdateObject = JSON.parse(JSON.stringify(data.updateObject))
|
||||
copyUpdateObject.originalPwd = Base64.encode(copyUpdateObject.originalPwd)
|
||||
copyUpdateObject.confirmPwd = Base64.encode(copyUpdateObject.confirmPwd)
|
||||
|
||||
$updateUserPass(copyUpdateObject).then(res => {
|
||||
message.success('修改成功')
|
||||
// 退出登录
|
||||
useUserStore().logout()
|
||||
}).catch(res => {
|
||||
data.confirmLoading = false
|
||||
data.btnLoading = false
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
function selectTabs () { // 清空必填提示
|
||||
data.updateObject.originalPwd = ''
|
||||
data.updateObject.newPwd = ''
|
||||
data.updateObject.confirmPwd = ''
|
||||
console.log(data.updateObject)
|
||||
}
|
||||
// 上传文件成功回调方法,参数value为文件地址,name是自定义参数
|
||||
function uploadSuccess (value, name) {
|
||||
data.saveObject.avatarUrl = value
|
||||
console.log(data.saveObject.avatarUrl)
|
||||
data.updateKey += 1
|
||||
}
|
||||
function selectTabsSub (key) { // 清空必填提示
|
||||
if (key) {
|
||||
data.groupKey = key
|
||||
detail()
|
||||
}
|
||||
// 获取MFA信息
|
||||
if(data.groupKey == 'mfaVer') {
|
||||
getMFAInfo()
|
||||
}
|
||||
}
|
||||
|
||||
function getMFAInfo() {
|
||||
$getMFAInfo().then(res => {
|
||||
data.mfaInfo = res
|
||||
})
|
||||
}
|
||||
|
||||
// MFA绑定
|
||||
function mfaBindConfirm() {
|
||||
mfaFormModel.value.validate().then(valid =>{
|
||||
$infoBox.confirmPrimary('确认绑定MFA认证吗?', '', () => {
|
||||
// 请求接口
|
||||
data.btnLoading = true // 打开按钮上的 loading
|
||||
data.confirmLoading = true // 显示loading
|
||||
$mfaBind({verCode: data.mfaInfo.verCode}).then(res => {
|
||||
data.confirmLoading = false
|
||||
data.btnLoading = false
|
||||
|
||||
getMFAInfo()
|
||||
message.success('绑定成功')
|
||||
// 退出登录
|
||||
// useUserStore().logout()
|
||||
}).catch(res => {
|
||||
data.confirmLoading = false
|
||||
data.btnLoading = false
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// MFA解绑
|
||||
function mfaRelieveConfirm() {
|
||||
mfaFormModel.value.validate().then(valid =>{
|
||||
$infoBox.confirmPrimary('确认解绑MFA认证吗?', '', () => {
|
||||
// 请求接口
|
||||
data.btnLoading = true // 打开按钮上的 loading
|
||||
data.confirmLoading = true // 显示loading
|
||||
$mfaRelieve({verCode: data.mfaInfo.verCode}).then(res => {
|
||||
data.confirmLoading = false
|
||||
data.btnLoading = false
|
||||
|
||||
getMFAInfo()
|
||||
message.success('解绑成功')
|
||||
// 退出登录
|
||||
// useUserStore().logout()
|
||||
}).catch(res => {
|
||||
data.confirmLoading = false
|
||||
data.btnLoading = false
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
function safeWordUpdate(){
|
||||
if(!data.safeWord){
|
||||
return message.error('信息内容不可为空')
|
||||
}
|
||||
$updateUserInfo({safeWord:data.safeWord}).then(res =>{
|
||||
message.success('更新成功')
|
||||
})
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
.avatar-upload-wrapper {
|
||||
height: 200px;
|
||||
width: 100%;
|
||||
}
|
||||
.bottom-btn{
|
||||
/deep/ div{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.ant-upload-preview {
|
||||
text-align:center ;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
// max-width: 180px;
|
||||
border-radius: 50%;
|
||||
// box-shadow: 0 0 4px #ccc;
|
||||
|
||||
.upload-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 10px;
|
||||
font-size: 1.4rem;
|
||||
padding: 0.5rem;
|
||||
background: rgba(222, 221, 221, 0.7);
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.mask {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
background: rgba(0,0,0,0.4);
|
||||
cursor: pointer;
|
||||
transition: opacity 0.4s;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 2rem;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-left: -1rem;
|
||||
margin-top: -1rem;
|
||||
color: #d6d6d6;
|
||||
}
|
||||
}
|
||||
|
||||
img, .mask {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
94
jeepay-ui-merchant/src/views/current/postList.vue
Normal file
94
jeepay-ui-merchant/src/views/current/postList.vue
Normal file
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<a-list size="large" :data-source="vdata.noticeList" :pagination="pagination">
|
||||
<template #renderItem="{ item }">
|
||||
<a-list-item class="list-ltem" @click="showDrawer(item.articleId)">
|
||||
<span>{{ item.title }}</span>
|
||||
<a style="color: #707070;">{{ item.createdAt }} <right-outlined :style="{fontSize: '12px', color: '#707070',marginLeft:'10px'}" /> </a>
|
||||
</a-list-item>
|
||||
</template>
|
||||
<template #header>
|
||||
<div class="title">全部公告</div>
|
||||
</template>
|
||||
</a-list>
|
||||
</div>
|
||||
<JeepayNoticeViewer ref="noticeViewer" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { defineComponent,onMounted,reactive,ref } from 'vue'
|
||||
import { API_URL_NOTICELIST, req } from '@/api/manage'
|
||||
const vdata = reactive({
|
||||
noticeList:[],
|
||||
content:''//文章内容
|
||||
})
|
||||
const noticeViewer = ref()
|
||||
const visible = ref<boolean>(false)
|
||||
onMounted(() =>{
|
||||
reqTableDataFunc({
|
||||
pageSize:10,
|
||||
pageNumber:1
|
||||
}).then(res =>{
|
||||
console.log(res)
|
||||
vdata.noticeList = res.records
|
||||
pagination.total = res.total
|
||||
})
|
||||
})
|
||||
function reqTableDataFunc(params: any) { // 请求table接口数据
|
||||
return req.list(API_URL_NOTICELIST, Object.assign(params,{articleType:1}))
|
||||
}
|
||||
|
||||
const showDrawer =async (articleId) => {
|
||||
noticeViewer.value.showDrawer(articleId)
|
||||
|
||||
}
|
||||
|
||||
const pagination = {
|
||||
onChange: (page: number) => {
|
||||
let params = {
|
||||
pageSize:10,
|
||||
pageNumber:page
|
||||
}
|
||||
reqTableDataFunc(params).then(res =>{
|
||||
vdata.noticeList = res.records
|
||||
pagination.total = res.total
|
||||
})
|
||||
},
|
||||
pageSize: 10,
|
||||
total:0
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-list-pagination){
|
||||
margin-bottom: 10px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.card{
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
.list-ltem{
|
||||
padding-left: 30px;
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
height: 60px;
|
||||
span{
|
||||
&:nth-child(1){
|
||||
cursor:pointer;
|
||||
|
||||
}
|
||||
&:hover{
|
||||
color: #2691FF;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
.title{
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
padding-left: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
692
jeepay-ui-merchant/src/views/dashboard/Analysis.vue
Normal file
692
jeepay-ui-merchant/src/views/dashboard/Analysis.vue
Normal file
@@ -0,0 +1,692 @@
|
||||
<template>
|
||||
<div id="chart-card">
|
||||
<div class="amount">
|
||||
<div style="background-color: rgb(85, 85, 85)">
|
||||
<a-skeleton :loading="skeletonIsShow" active :paragraph="{ rows: 6 }" />
|
||||
|
||||
<div v-show="!skeletonIsShow">
|
||||
<div
|
||||
v-if="$access('ENT_MCH_MAIN_PAY_DAY_COUNT') && !$hasMemberEnt()"
|
||||
class="amount-top"
|
||||
>
|
||||
<div class="amount-date">
|
||||
<div
|
||||
:class="{ 'amount-date-active': amountDate === 'today' }"
|
||||
@click="amountDateHandle('today')"
|
||||
>
|
||||
今日交易
|
||||
</div>
|
||||
<div
|
||||
:class="{ 'amount-date-active': amountDate === 'yesterday' }"
|
||||
@click="amountDateHandle('yesterday')"
|
||||
>
|
||||
昨日交易
|
||||
</div>
|
||||
</div>
|
||||
<p>成交金额(元)</p>
|
||||
<p style="font-size: 50px; margin-bottom: 35px; color: #fff">
|
||||
{{ payAmountDataAll.payAmount }}
|
||||
</p>
|
||||
<div class="amount-list">
|
||||
<div>
|
||||
<p>成交笔数</p>
|
||||
<span>{{ payAmountDataAll.payCount }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<p>退款金额(元)</p>
|
||||
<span>{{ payAmountDataAll.refundAmount }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<p>退款笔数</p>
|
||||
<span>{{ payAmountDataAll.refundCount }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="$access('ENT_MCH_MAIN_PAY_DAY_COUNT') && $hasMemberEnt()"
|
||||
class="amount-top"
|
||||
>
|
||||
<div class="amount-date">
|
||||
<div
|
||||
:class="{ 'amount-date-active': amountDate === 'today' }"
|
||||
@click="amountDateHandle('today')"
|
||||
>
|
||||
今日交易
|
||||
</div>
|
||||
<div
|
||||
:class="{ 'amount-date-active': amountDate === 'yesterday' }"
|
||||
@click="amountDateHandle('yesterday')"
|
||||
>
|
||||
昨日交易
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin-bottom: 0">成交金额(元)</p>
|
||||
<a-tooltip placement="top" color="#fff">
|
||||
<template #title>
|
||||
<p style="font-size: 20px; margin-bottom: 0; color: #000">
|
||||
{{ payAmountDataAll.payAmount }}
|
||||
</p>
|
||||
</template>
|
||||
<p
|
||||
style="
|
||||
font-size: 40px;
|
||||
margin-bottom: 0;
|
||||
color: #fff;
|
||||
width: max-content;
|
||||
"
|
||||
>
|
||||
{{ amountHandle(payAmountDataAll.payAmount)
|
||||
}}<span
|
||||
v-if="payAmountDataAll.payAmount >= 100000000"
|
||||
style="
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-left: 5px;
|
||||
vertical-align: middle;
|
||||
"
|
||||
>亿</span
|
||||
><span
|
||||
v-else-if="payAmountDataAll.payAmount >= 10000000"
|
||||
style="
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-left: 5px;
|
||||
vertical-align: middle;
|
||||
"
|
||||
>万</span
|
||||
>
|
||||
</p>
|
||||
</a-tooltip>
|
||||
<div class="amount-list">
|
||||
<div>
|
||||
<p>成交笔数</p>
|
||||
<span>{{ payAmountDataAll.payCount }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<p>退款金额(元)</p>
|
||||
<span>{{ payAmountDataAll.refundAmount }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<p>退款笔数</p>
|
||||
<span>{{ payAmountDataAll.refundCount }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<p>会员充值(元)</p>
|
||||
<span>{{ (memberData.payAmount / 100).toFixed(2) }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<p>会员消费(元)</p>
|
||||
<span>{{
|
||||
(Math.abs(memberData.changeAmount) / 100).toFixed(2)
|
||||
}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<p>会员消费笔数</p>
|
||||
<span>{{ memberData.changeCount }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="amount-line" />
|
||||
<a-skeleton v-show="skeletonIsShow" active :paragraph="{ rows: 6 }" />
|
||||
<div v-show="!skeletonIsShow" v-if="$access('ENT_MCH_MAIN_PAY_TREND_COUNT')" class="amount-bottom" style="width: 100%">
|
||||
<div class="echart-title">
|
||||
<div style="display: flex;">
|
||||
<b style="color: #fff">趋势</b>
|
||||
<a-tooltip class="tooltip">
|
||||
<template #title>近期成交金额</template>
|
||||
<i class="bi bi-info-circle" style="color:rgba(255, 255, 255, 0.6)" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<a-select v-model:value="amountSelectDate" class="date amount-date" placeholder="近30天" @change="amountSelectHandle">
|
||||
<a-select-option value="30">近30天</a-select-option>
|
||||
<a-select-option value="7">近7天</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div v-show="!payAmountEmpty" id="pay-amount" style="width: 100%;" />
|
||||
<a-empty v-show="payAmountEmpty" :image="emptyImg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="personal">
|
||||
<a-skeleton :loading="skeletonIsShow" active :paragraph="{ rows: 5 }" />
|
||||
<div v-show="!skeletonIsShow">
|
||||
<div class="before-msg">
|
||||
<p>
|
||||
<span>预留信息:</span
|
||||
><a style="color: #2691ff; margin-right: 5px" @click="setMsg">{{
|
||||
safeWord ? safeWord : "未设置"
|
||||
}}</a>
|
||||
<a-tooltip
|
||||
placement="right"
|
||||
title="此信息为你在本站预留的个性信息,用以鉴别假冒、钓鱼网站。如未看到此信息,请立即停止访问并修改密码。如需修改内容请前往个人中心"
|
||||
>
|
||||
<question-circle-outlined />
|
||||
</a-tooltip>
|
||||
</p>
|
||||
<!-- <span>商户简称:</span><span>{{ shortName?shortName:'计全科技商户' }}</span> -->
|
||||
</div>
|
||||
<div class="personal-line" />
|
||||
<div class="latest-post">
|
||||
<div class="title">
|
||||
<span>最新公告</span>
|
||||
<a style="color: #2691ff" @click="toList"
|
||||
>更多
|
||||
<right-outlined :style="{ fontSize: '12px', color: '#2691ff' }"
|
||||
/></a>
|
||||
</div>
|
||||
<div class="post-list">
|
||||
<div
|
||||
v-for="(item, index) in notice.noticeList"
|
||||
:key="index"
|
||||
class="post-item"
|
||||
@click="toDetail(item.articleId)"
|
||||
>
|
||||
<span class="title">{{ item.title }}</span>
|
||||
<span
|
||||
>{{ item ? item.createdAt.slice(0, 10) : "" }}
|
||||
<right-outlined :style="{ fontSize: '12px', color: '#707070' }"
|
||||
/></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="personal-line" />
|
||||
<div class="quick-start">
|
||||
<p>快速开始</p>
|
||||
<ul>
|
||||
<li v-for="menu in quickMenuList" :key="menu.entId">
|
||||
<router-link :to="menu!.menuUri">{{ menu.entName }}</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method">
|
||||
<a-skeleton :loading="skeletonIsShow" active :paragraph="{ rows: 5 }" />
|
||||
<div
|
||||
v-show="!skeletonIsShow"
|
||||
v-if="$access('ENT_MCH_MAIN_PAY_TYPE_COUNT')"
|
||||
>
|
||||
<div class="echart-title">
|
||||
<b>支付方式</b>
|
||||
<JeepayDateRangePicker
|
||||
v-model:value="payMethodDate"
|
||||
class="date"
|
||||
customDateRangeType="date"
|
||||
:allTimeIsShow="false"
|
||||
@update:value="payMethodDateHandle"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-show="!payMethodEmpty"
|
||||
id="pay-method"
|
||||
style="width: 100%; height: 100%"
|
||||
/>
|
||||
<a-empty v-show="payMethodEmpty" :image="emptyImg" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="pay-statistics">
|
||||
<a-skeleton :loading="skeletonIsShow" active :paragraph="{ rows: 5 }" />
|
||||
<div v-show="!skeletonIsShow" v-if="$access('ENT_MCH_MAIN_PAY_COUNT')">
|
||||
<b>交易统计</b>
|
||||
<JeepayDateRangePicker
|
||||
v-model:value="payStatisticsDate"
|
||||
class="date"
|
||||
customDateRangeType="date"
|
||||
:statisticalTimeIsShow="true"
|
||||
@update:value="statisticsHandle"
|
||||
/>
|
||||
<div
|
||||
v-show="!payStatisticsEmpty"
|
||||
id="pay-statistics"
|
||||
style="width: 100%; height: 100%"
|
||||
/>
|
||||
<a-empty v-show="payStatisticsEmpty" :image="emptyImg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<JeepayNoticeViewer ref="noticeViewer" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
nextTick,
|
||||
ref,
|
||||
computed,
|
||||
watch,
|
||||
getCurrentInstance,
|
||||
onMounted,
|
||||
reactive,
|
||||
} from "vue";
|
||||
import * as echarts from "echarts"; // 引入图标组件
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import {
|
||||
$getPayTrendCount,
|
||||
$getNumCount,
|
||||
$getPayCount,
|
||||
$getPayType,
|
||||
$getUserInfo,
|
||||
API_URL_NOTICELIST,
|
||||
req,
|
||||
$memberInfoCount,
|
||||
} from "@/api/manage";
|
||||
import {
|
||||
pieEcharts,
|
||||
statisticsEcharts,
|
||||
amountEcharts,
|
||||
} from "./echartsConfig.js"; // 图标配置项组件
|
||||
import { Empty } from "ant-design-vue"; // 缺省图
|
||||
const { $infoBox, $access, $hasMemberEnt } =
|
||||
getCurrentInstance()!.appContext.config.globalProperties;
|
||||
console.log("hasMemberEnt", $hasMemberEnt());
|
||||
|
||||
const userStore = useUserStore();
|
||||
// 获取到路由对象
|
||||
const router = useRouter(); //这是全部路由
|
||||
const safeWord = ref(); //预留信息
|
||||
const shortName = ref(); //简称
|
||||
const memberData: any = reactive({});
|
||||
const noticeViewer = ref();
|
||||
const notice = reactive({
|
||||
noticeList: [] as any,
|
||||
});
|
||||
|
||||
//公告列表页
|
||||
const toList = () => {
|
||||
router.push({
|
||||
path: "/notices",
|
||||
});
|
||||
};
|
||||
//设置信息
|
||||
const setMsg = () => {
|
||||
router.push({
|
||||
path: "/currentUserinfo",
|
||||
query: { type: "msg" },
|
||||
});
|
||||
};
|
||||
onMounted(() => {
|
||||
$getUserInfo().then((res) => {
|
||||
safeWord.value = res.safeWord;
|
||||
shortName.value = res.shortName;
|
||||
});
|
||||
reqTableDataFunc({
|
||||
pageSize: 3,
|
||||
pageNumber: 1,
|
||||
}).then((res) => {
|
||||
console.log(res);
|
||||
notice.noticeList = res.records;
|
||||
});
|
||||
});
|
||||
function reqTableDataFunc(params: any) {
|
||||
// 请求table接口数据
|
||||
return req.list(
|
||||
API_URL_NOTICELIST,
|
||||
Object.assign(params, { articleType: 1 })
|
||||
);
|
||||
}
|
||||
// 切换今日昨日金额数据
|
||||
let amountDate = ref("today"); // 默认为今日
|
||||
const amountDateHandle = (param) => {
|
||||
amountDate.value = param;
|
||||
numCountHandle(); // 切换后调用请求
|
||||
|
||||
if ($hasMemberEnt()) {
|
||||
getMemberData();
|
||||
}
|
||||
};
|
||||
let payAmountDataAll: any = ref({}); // 成交金额总数据(今天和昨天)
|
||||
const payAmountGetDateData = (res) => {
|
||||
//数据赋值
|
||||
// 分转元显示
|
||||
Object.keys(res.dayCount).forEach((item) => {
|
||||
if (item == "payCount" || item == "refundCount") {
|
||||
return;
|
||||
} else {
|
||||
res.dayCount[item] = (res.dayCount[item] / 100).toFixed(2);
|
||||
}
|
||||
});
|
||||
payAmountDataAll.value = res.dayCount;
|
||||
};
|
||||
// 成交金额请求数据
|
||||
const numCountHandle = () => {
|
||||
$getNumCount({ queryDateRange: amountDate.value }).then((res) => {
|
||||
payAmountGetDateData(res);
|
||||
});
|
||||
};
|
||||
|
||||
let payMethod; // 支付方式饼图
|
||||
let payMethodEmpty = ref(false); // 支付方式饼图缺省图
|
||||
let payMethodDate = ref("near2now_30"); // 饼图日期查询
|
||||
// 当支付方式自定义日期格式中不包含N ,则代表选择了正确的日期格式
|
||||
const payMethodDateHandle = () => {
|
||||
let flag = payMethodDate.value.indexOf("N") === -1;
|
||||
if (payMethodDate.value && flag) {
|
||||
payMethodHandle(payMethodDate.value);
|
||||
}
|
||||
};
|
||||
// 饼图数据赋值
|
||||
const payMethodGetData = (res) => {
|
||||
let payTypeData = [];
|
||||
res[0].length === 0
|
||||
? (payMethodEmpty.value = true)
|
||||
: (payMethodEmpty.value = false);
|
||||
res[0].forEach((item) => {
|
||||
payTypeData.push({
|
||||
value: (item.totalSuccAmt / 100).toFixed(2), // 分转元
|
||||
name: item.name,
|
||||
} as never);
|
||||
});
|
||||
pieEcharts.series[0].data = payTypeData; // 饼图数据赋值
|
||||
nextTick(() => {
|
||||
payMethod = echarts.init(
|
||||
document.getElementById("pay-method") as HTMLElement
|
||||
);
|
||||
payMethod.setOption(pieEcharts); // 数据填充
|
||||
});
|
||||
};
|
||||
// 饼图请求数据
|
||||
const payMethodHandle = (data) => {
|
||||
$getPayType(data)
|
||||
.then((res) => {
|
||||
payMethodGetData(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
let payStatistics; // 交易统计折线图
|
||||
let payStatisticsDate = ref("near2now_30"); // 交易统计折线图日期查询
|
||||
let payStatisticsEmpty = ref(false); // 交易统计折线图缺省图
|
||||
const statisticsHandle = () => {
|
||||
let flag = payStatisticsDate.value.indexOf("N") === -1;
|
||||
if (payStatisticsDate.value && flag) {
|
||||
payStatisticsHandle(payStatisticsDate.value);
|
||||
}
|
||||
};
|
||||
// 交易统计折线图数据赋值
|
||||
const payStatisticsGetData = (res) => {
|
||||
Object.keys(res).length === 0
|
||||
? (payStatisticsEmpty.value = true)
|
||||
: (payStatisticsEmpty.value = false);
|
||||
statisticsEcharts.xAxis.data = res.resDateArr; // x轴日期
|
||||
let payAmountArr = [];
|
||||
res.resPayAmountArr.forEach((item) =>
|
||||
payAmountArr.push((item / 100).toFixed(2) as never)
|
||||
); // 成交金额分转元
|
||||
statisticsEcharts.series[0].data = payAmountArr; // 成交金额
|
||||
statisticsEcharts.series[1].data = res.resPayCountArr; // 订单笔数
|
||||
let refAmountArr = [];
|
||||
res.resRefAmountArr.forEach((item) =>
|
||||
refAmountArr.push((item / 100).toFixed(2) as never)
|
||||
); // 退款金额分转元
|
||||
statisticsEcharts.series[2].data = refAmountArr; // 退款金额
|
||||
nextTick(() => {
|
||||
payStatistics = echarts.init(
|
||||
document.getElementById("pay-statistics") as HTMLElement
|
||||
);
|
||||
payStatistics.setOption(statisticsEcharts); // 数据填充
|
||||
});
|
||||
};
|
||||
// 交易统计折线图请求数据
|
||||
const payStatisticsHandle = (data) => {
|
||||
$getPayCount(data)
|
||||
.then((res) => {
|
||||
payStatisticsGetData(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
// 今日金额折线图日期选择
|
||||
const amountSelectHandle = (value: string) => {
|
||||
payAmountHandle(value);
|
||||
};
|
||||
let payAmount; // 金额板块折线图
|
||||
let payAmountEmpty = ref(false); // 金额折线图缺省图是否展示
|
||||
let amountSelectDate = ref("近30天"); // 交易统计折线图日期查询
|
||||
// 成交金额 数据赋值
|
||||
const payAmountGetData = (res) => {
|
||||
amountEcharts.xAxis.data = res.dateList || ["01-03", "01-04", "01-05", "01-06", "01-07", "01-08", "01-09", "01-10", "01-11", "01-12", "01-13", "01-14", "01-15", "01-16", "01-17", "01-18", "01-19", "01-20", "01-21", "01-22", "01-23", "01-24", "01-25", "01-26", "01-27", "01-28", "01-29", "01-30", "01-31",'02-01'];
|
||||
res.dateList.length === 0
|
||||
? (payAmountEmpty.value = true)
|
||||
: (payAmountEmpty.value = false);
|
||||
let payAmountList = [];
|
||||
res.payAmountList.forEach((item) => {
|
||||
payAmountList.push((item / 100).toFixed(2) as never);
|
||||
});
|
||||
amountEcharts.series[0].data = payAmountList || ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"]; // 数据赋值
|
||||
console.log(payAmountList);
|
||||
nextTick(() => {
|
||||
payAmount = echarts.init(
|
||||
document.getElementById("pay-amount") as HTMLElement
|
||||
);
|
||||
payAmount.setOption(amountEcharts);
|
||||
});
|
||||
};
|
||||
// 金额板块折线图请求数据
|
||||
const payAmountHandle = (date) => {
|
||||
$getPayTrendCount(date)
|
||||
.then((res) => {
|
||||
payAmountGetData(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
// 请求会员统计数据
|
||||
const getMemberData = () => {
|
||||
$memberInfoCount({ queryDateRange: amountDate.value }).then((res) => {
|
||||
Object.assign(memberData, res);
|
||||
});
|
||||
};
|
||||
|
||||
if ($hasMemberEnt()) {
|
||||
getMemberData();
|
||||
}
|
||||
|
||||
// 缺省图片的样式
|
||||
const emptyImg = Empty.PRESENTED_IMAGE_SIMPLE;
|
||||
|
||||
// 骨架屏是否展示
|
||||
let skeletonIsShow = ref(true);
|
||||
|
||||
// 首页骨架屏隐藏采用 promise all,只有本页面5个请求全部获得数据才会隐藏, 请求顺序依次为:成交金额, 趋势折线图, 支付方式, 交易统计
|
||||
Promise.all([
|
||||
$getNumCount({ queryDateRange: amountDate.value }),
|
||||
$getPayTrendCount(30),
|
||||
$getPayType(payMethodDate.value),
|
||||
$getPayCount(payStatisticsDate.value),
|
||||
])
|
||||
.then((res) => {
|
||||
skeletonIsShow.value = false; // 骨架屏取消
|
||||
payAmountGetDateData(res[0]); // 成交金额
|
||||
console.log(res[1], "res[1]");
|
||||
payAmountGetData(res[1]); // 趋势折线图
|
||||
payMethodGetData(res[2]); // 饼图
|
||||
payStatisticsGetData(res[3]); // 交易统计
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
|
||||
// 所有图表根据屏幕大小 图表自适应
|
||||
window.addEventListener("resize", () => {
|
||||
payMethod.resize();
|
||||
payStatistics.resize();
|
||||
payAmount.resize();
|
||||
});
|
||||
|
||||
// 问候语句
|
||||
const nextAge = computed(() => {
|
||||
const time = new Date();
|
||||
const hour = time.getHours();
|
||||
return hour < 9
|
||||
? "早上好"
|
||||
: hour <= 11
|
||||
? "上午好"
|
||||
: hour <= 13
|
||||
? "中午好"
|
||||
: hour < 20
|
||||
? "下午好"
|
||||
: "晚上好";
|
||||
});
|
||||
|
||||
// 快速菜单集合
|
||||
const quickMenuList: any = computed(() => {
|
||||
const result = [];
|
||||
|
||||
const putResult = function (item) {
|
||||
for (let i = 0; i < item.length; i++) {
|
||||
if (item[i].menuUri && item[i].quickJump === 1) {
|
||||
result.push(item[i] as never);
|
||||
}
|
||||
if (item[i].children) {
|
||||
putResult(item[i].children);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
putResult(userStore.userInfo["allMenuRouteTree"]);
|
||||
return result;
|
||||
});
|
||||
|
||||
// layout传过来的值,用于监听菜单的收起与展开,此时折线图板块应跟随宽度进行变化
|
||||
const props = defineProps({
|
||||
proLayoutObject: { type: Object, default: () => {} },
|
||||
});
|
||||
|
||||
// 因为菜单的收起与展开有一定的过渡时间,所以采用了定时器
|
||||
watch(
|
||||
() => props.proLayoutObject.collapsed,
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
payStatistics.resize();
|
||||
payAmount.resize();
|
||||
}, 350);
|
||||
}
|
||||
);
|
||||
//公告详情
|
||||
function toDetail(articleId) {
|
||||
noticeViewer.value.showDrawer(articleId);
|
||||
}
|
||||
// 金额处理 超过1000万时拼接万 超过亿时 拼接亿
|
||||
const amountHandle = (amount) => {
|
||||
if (amount >= 100000000) {
|
||||
return parseFloat((amount / 100000000).toFixed(2));
|
||||
} else if (amount >= 10000000) {
|
||||
return parseFloat((amount / 10000).toFixed(2));
|
||||
} else {
|
||||
return amount;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@import "./index.less"; // 响应式布局
|
||||
// 成交金额折线图 日期选择器样式
|
||||
// /deep/ .ant-select-selector {
|
||||
// background: rgba(255, 255, 255, 0.05) !important;
|
||||
// color: rgba(255, 255, 255, 0.7) !important;
|
||||
|
||||
// }
|
||||
// /deep/ .ant-select-arrow {
|
||||
// color: rgba(255, 255, 255, 0.7) !important;
|
||||
// }
|
||||
// 个人信息页标题
|
||||
.personal-title {
|
||||
display: flex;
|
||||
img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
}
|
||||
& > div {
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
p {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 个人信息 快速开始
|
||||
.quick-start {
|
||||
p {
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-right: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
// 通用图表标题
|
||||
.echart-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
b {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.date {
|
||||
width: 215px;
|
||||
flex-shrink: unset;
|
||||
}
|
||||
}
|
||||
|
||||
// 交易统计图表标题
|
||||
.pay-statistics {
|
||||
& > div {
|
||||
position: relative;
|
||||
& > b,
|
||||
& > .date {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
z-index: 9;
|
||||
}
|
||||
& > b {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-right: 10px;
|
||||
top: 36px;
|
||||
}
|
||||
& > .date {
|
||||
width: 215px;
|
||||
right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
// 缺省图的样式
|
||||
/deep/ .ant-empty-normal {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
#chart-card .amount > div .amount-line[data-v-5391d79e] {
|
||||
border-left: none !important;
|
||||
}
|
||||
</style>
|
||||
495
jeepay-ui-merchant/src/views/dashboard/OrderLxLargeScreen.vue
Normal file
495
jeepay-ui-merchant/src/views/dashboard/OrderLxLargeScreen.vue
Normal file
@@ -0,0 +1,495 @@
|
||||
<template>
|
||||
<!-- 交易路由概况-->
|
||||
<div id="chart-card">
|
||||
<div class="amount">
|
||||
<div style="background-color: rgb(85, 85, 85);">
|
||||
<a-skeleton :loading="skeletonIsShow" active :paragraph="{ rows: 6 }" />
|
||||
<div v-show="!skeletonIsShow" v-if="$access('ENT_C_MAIN_PAY_DAY_COUNT')" class="amount-top">
|
||||
<div class="amount-date">
|
||||
<div :class="{'amount-date-active': amountDate === 'today'}" @click="amountDateHandle('today')">今日交易</div>
|
||||
<div :class="{'amount-date-active': amountDate === 'yesterday'}" @click="amountDateHandle('yesterday')">昨日交易</div>
|
||||
</div>
|
||||
<p>成交金额(元)</p>
|
||||
<a-tooltip placement="top" color="#fff">
|
||||
<template #title>
|
||||
<p style="font-size: 20px; margin-bottom: 0;color:#000">{{ payAmountDataAll.payAmount }}</p>
|
||||
</template>
|
||||
<p style="font-size: 40px;margin-bottom: 35px;color:#fff;width: max-content;">
|
||||
{{ amountHandle(payAmountDataAll.payAmount) }}<span v-if="payAmountDataAll.payAmount >=100000000" style="font-size: 20px;font-weight: 600;margin-left: 5px;vertical-align: middle;">亿</span><span v-else-if="payAmountDataAll.payAmount >=10000000" style="font-size: 20px;font-weight: 600;margin-left: 5px;vertical-align: middle;">万</span>
|
||||
</p>
|
||||
</a-tooltip>
|
||||
<div class="amount-list">
|
||||
<div><p>成交笔数</p><span>{{ payAmountDataAll.payCount }}</span></div>
|
||||
<div><p>手续费金额(元)</p><span>{{ payAmountDataAll.refundAmount }}</span></div>
|
||||
<!-- <div><p>退款笔数</p><span>{{ payAmountDataAll.refundCount }}</span></div>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="amount-line" />
|
||||
<a-skeleton v-show="skeletonIsShow" active :paragraph="{ rows: 6 }" />
|
||||
<div v-show="!skeletonIsShow" v-if="$access('ENT_C_MAIN_PAY_TREND_COUNT')" class="amount-bottom" style="width: 100%">
|
||||
<div class="echart-title">
|
||||
<div style="display: flex;">
|
||||
<b style="color: #fff">趋势</b>
|
||||
<a-tooltip class="tooltip">
|
||||
<template #title>近期成交金额</template>
|
||||
<i class="bi bi-info-circle" style="color:rgba(255, 255, 255, 0.6)" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- -->
|
||||
<a-select id="selet-date" v-model:value="amountSelectDate" class="date amount-date" placeholder="近30天" @change="amountSelectHandle">
|
||||
<a-select-option value="30">近30天</a-select-option>
|
||||
<a-select-option value="7">近7天</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div v-show="!payAmountEmpty" id="pay-amount" style="width: 100%;" />
|
||||
<a-empty v-show="payAmountEmpty" :image="emptyImg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="personal">
|
||||
<div class="h_opt_p_r">
|
||||
<div class="h_title_box" style="cursor: pointer;"><span class="h_tit_name">账户概况</span></div>
|
||||
<div class="h_opt_p_r_l h_opt_p_r_l_1">
|
||||
<div>总交易金额(元)</div>
|
||||
<div class="ant-statistic">
|
||||
<div class="ant-statistic-content" style="color: rgb(255, 255, 255); font-size: 20px;"><span
|
||||
class="ant-statistic-content-value"><span
|
||||
class="ant-statistic-content-value-int">6,261</span><span
|
||||
class="ant-statistic-content-value-decimal">.67</span></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h_opt_p_r_l h_opt_p_r_l_2">
|
||||
<div>手续费余额(元)</div>
|
||||
<div class="ant-statistic">
|
||||
<div class="ant-statistic-content" style="color: rgb(255, 255, 255); font-size: 20px;"><span
|
||||
class="ant-statistic-content-value"><span
|
||||
class="ant-statistic-content-value-int">6,261</span><span
|
||||
class="ant-statistic-content-value-decimal">.67</span></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h_opt_p_r_l h_opt_p_r_l_3">
|
||||
<div>支付宝费率(%):0.2</div>
|
||||
<div>银行卡费率(%):0.3</div>
|
||||
<!-- <div class="ant-statistic">-->
|
||||
<!-- <div class="ant-statistic-content" style="color: rgb(255, 255, 255); font-size: 20px;"><span-->
|
||||
<!-- class="ant-statistic-content-value"><span class="ant-statistic-content-value-int">0</span><span-->
|
||||
<!-- class="ant-statistic-content-value-decimal">.00</span></span></div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" class="ant-btn ant-btn-primary ant-btn-lg" style="margin-right: 3%;">
|
||||
<span>充 值</span></button>
|
||||
<button type="button" class="ant-btn ant-btn-default ant-btn-lg" style="margin-right: 3%;">
|
||||
<span>结 算</span></button>
|
||||
<!-- <button type="button" class="ant-btn ant-btn-primary ant-btn-lg"><span>计算器</span></button>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method">
|
||||
<a-skeleton :loading="skeletonIsShow" active :paragraph="{ rows: 6 }" />
|
||||
<div v-show="!skeletonIsShow" v-if="$access('ENT_C_MAIN_PAY_TYPE_COUNT')">
|
||||
<div class="echart-title">
|
||||
<b>支付方式</b>
|
||||
<JeepayDateRangePicker v-model:value="payMethodDate" class="date" customDateRangeType="date" :allTimeIsShow="false" @update:value="payMethodDateHandle" />
|
||||
</div>
|
||||
<div v-show="!payMethodEmpty" id="pay-method" style="width: 100%;height: 100%" />
|
||||
<a-empty v-show="payMethodEmpty" :image="emptyImg" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="pay-statistics">
|
||||
<a-skeleton :loading="skeletonIsShow" active :paragraph="{ rows: 6 }" />
|
||||
<div v-show="!skeletonIsShow" v-if="$access('ENT_C_MAIN_PAY_COUNT')">
|
||||
<b>交易统计</b>
|
||||
<!-- <JeepayDateRangePicker v-model:value="payStatisticsDate" class="date" customDateRangeType="date" :statisticalTimeIsShow="true" @update:value="statisticsHandle" />-->
|
||||
<div v-show="!payStatisticsEmpty" id="pay-statistics" style="width: 100%;height: 100%" />
|
||||
<a-empty v-show="payStatisticsEmpty" :image="emptyImg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, ref, computed, onMounted,getCurrentInstance } from 'vue'
|
||||
import * as echarts from 'echarts' // 引入图标组件
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { $getPayTrendCount, $getIsvAndMchCount, $getNumCount, $getPayCount, $getPayType,$getUserInfo } from '@/api/manage'
|
||||
import {pieEcharts, statisticsEcharts, amountEcharts} from './echartsConfig.js' // 图标配置项组件
|
||||
import { Empty } from 'ant-design-vue' // 缺省图
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const { $infoBox, $access, $hasAgentEnt } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const userStore = useUserStore()
|
||||
// 获取到路由对象
|
||||
const router = useRouter() //这是全部路由
|
||||
// 特约商户 普通商户文字显示与隐藏
|
||||
let normalMchIsShow = ref(false) // 普通商户
|
||||
let subMchIsShow = ref(false) // 特约商户
|
||||
const safeWord = ref('')
|
||||
onMounted(() =>{
|
||||
$getUserInfo().then(res =>{
|
||||
safeWord.value = res.safeWord
|
||||
})
|
||||
})
|
||||
// 切换今日昨日金额数据
|
||||
let amountDate = ref('today') // 默认为今日
|
||||
const amountDateHandle = (param) => {
|
||||
amountDate.value = param
|
||||
numCountHandle() // 切换后调用请求
|
||||
}
|
||||
|
||||
let payAmountDataAll: any = ref({}) // 成交金额总数据(今天和昨天)
|
||||
const payAmountGetDateData = ( res ) => { //数据赋值
|
||||
// 分转元显示
|
||||
Object.keys(res.dayCount).forEach(item => {
|
||||
if ((item == 'payCount') || (item == 'refundCount')) {
|
||||
return
|
||||
} else {
|
||||
res.dayCount[item] = (res.dayCount[item] / 100).toFixed(2)
|
||||
}
|
||||
|
||||
})
|
||||
payAmountDataAll.value = res.dayCount
|
||||
}
|
||||
// 成交金额请求数据
|
||||
const numCountHandle = () => {
|
||||
$getNumCount({queryDateRange: amountDate.value}).then(res => {
|
||||
payAmountGetDateData(res)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
//设置信息
|
||||
const setSafeWord = () =>{
|
||||
router.push({
|
||||
path:'/currentUserinfo',
|
||||
query:{type:'msg'}
|
||||
})
|
||||
}
|
||||
// 商户数量
|
||||
let isvAndMchCount: any = ref({})
|
||||
const isvAndMchGetData = (res) => {
|
||||
isvAndMchCount.value = res
|
||||
}
|
||||
|
||||
let payMethod // 支付方式饼图
|
||||
let payMethodEmpty = ref(false) // 支付方式饼图缺省图
|
||||
let payMethodDate = ref('near2now_30') // 饼图日期查询
|
||||
// 当支付方式自定义日期格式中不包含N ,则代表选择了正确的日期格式
|
||||
const payMethodDateHandle = () => {
|
||||
let flag = payMethodDate.value.indexOf('N') === -1
|
||||
if (payMethodDate.value && flag) {
|
||||
payMethodHandle(payMethodDate.value)
|
||||
}
|
||||
}
|
||||
// 饼图数据赋值
|
||||
const payMethodGetData = (res) => {
|
||||
let payTypeData = []
|
||||
res[0].length === 0 ? payMethodEmpty.value = true : payMethodEmpty.value = false
|
||||
res[0].forEach(item => {
|
||||
payTypeData.push({
|
||||
value: (item.typeAmount / 100).toFixed(2), // 分转元
|
||||
name: item.typeName,
|
||||
} as never)
|
||||
})
|
||||
|
||||
pieEcharts.series[0].data = payTypeData // 饼图数据赋值
|
||||
nextTick(() => {
|
||||
payMethod = echarts.init(document.getElementById('pay-method') as HTMLElement)
|
||||
payMethod.setOption(pieEcharts) // 数据填充
|
||||
})
|
||||
}
|
||||
// 饼图请求数据
|
||||
const payMethodHandle = (data) => {
|
||||
$getPayType(data).then(res => {
|
||||
payMethodGetData(res)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
let payStatistics // 交易统计折线图
|
||||
let payStatisticsDate = ref('near2now_30') // 交易统计折线图日期查询
|
||||
let payStatisticsEmpty = ref(false) // 交易统计折线图缺省图
|
||||
const statisticsHandle = () => {
|
||||
let flag = payStatisticsDate.value.indexOf('N') === -1
|
||||
if (payStatisticsDate.value && flag) {
|
||||
payStatisticsHandle(payStatisticsDate.value)
|
||||
}
|
||||
}
|
||||
// 交易统计折线图数据赋值
|
||||
const payStatisticsGetData = (res) => {
|
||||
Object.keys(res).length === 0 ? payStatisticsEmpty.value = true : payStatisticsEmpty.value = false
|
||||
statisticsEcharts.xAxis.data = res.resDateArr // x轴日期
|
||||
let payAmountArr = []
|
||||
res.resPayAmountArr.forEach(item => payAmountArr.push((item / 100).toFixed(2) as never)) // 成交金额分转元
|
||||
statisticsEcharts.series[0].data = payAmountArr // 成交金额
|
||||
statisticsEcharts.series[1].data = res.resPayCountArr // 订单笔数
|
||||
let refAmountArr = []
|
||||
res.resRefAmountArr.forEach(item => refAmountArr.push((item / 100).toFixed(2) as never)) // 退款金额分转元
|
||||
statisticsEcharts.series[2].data = refAmountArr // 退款金额
|
||||
nextTick(() => {
|
||||
payStatistics = echarts.init(document.getElementById('pay-statistics') as HTMLElement)
|
||||
payStatistics.setOption(statisticsEcharts) // 数据填充
|
||||
})
|
||||
}
|
||||
// 交易统计折线图请求数据
|
||||
const payStatisticsHandle = (data) => {
|
||||
$getPayCount(data).then(res => {
|
||||
payStatisticsGetData(res)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
// 今日金额折线图日期选择
|
||||
const amountSelectHandle = (value: string) => {
|
||||
payAmountHandle(value)
|
||||
}
|
||||
let payAmount // 金额板块折线图
|
||||
let payAmountEmpty = ref(false) // 金额折线图缺省图是否展示
|
||||
let amountSelectDate = ref('近30天') // 交易统计折线图日期查询
|
||||
// 成交金额 数据赋值
|
||||
const payAmountGetData = (res) => {
|
||||
amountEcharts.xAxis.data = res.dateList
|
||||
res.dateList.length === 0 ? payAmountEmpty.value = true : payAmountEmpty.value = false
|
||||
let payAmountList = []
|
||||
res.payAmountList.forEach(item => {payAmountList.push((item / 100).toFixed(2) as never)})
|
||||
amountEcharts.series[0].data = payAmountList // 数据赋值
|
||||
nextTick(() => {
|
||||
payAmount = echarts.init(document.getElementById('pay-amount') as HTMLElement)
|
||||
payAmount.setOption(amountEcharts)
|
||||
})
|
||||
}
|
||||
// 金额板块折线图请求数据
|
||||
const payAmountHandle = (date) => {
|
||||
$getPayTrendCount(date).then(res => {
|
||||
payAmountGetData(res)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
// 缺省图片的样式
|
||||
const emptyImg = Empty.PRESENTED_IMAGE_SIMPLE
|
||||
|
||||
// 骨架屏是否展示
|
||||
let skeletonIsShow = ref(true)
|
||||
|
||||
// 首页骨架屏隐藏采用 promise all,只有本页面5个请求全部获得数据才会隐藏, 请求顺序依次为:成交金额, 趋势折线图, 商户数量, 支付方式, 交易统计
|
||||
Promise.all([$getNumCount({queryDateRange: amountDate.value}), $getPayTrendCount(30), $getIsvAndMchCount(), $getPayType(payMethodDate.value), $getPayCount(payStatisticsDate.value)]).then((res) => {
|
||||
skeletonIsShow.value = false // 骨架屏取消
|
||||
payAmountGetDateData(res[0]) // 成交金额
|
||||
payAmountGetData(res[1]) // 趋势折线图
|
||||
isvAndMchGetData(res[2]) // 商户数量
|
||||
payMethodGetData(res[3]) // 饼图
|
||||
payStatisticsGetData(res[4]) // 交易统计
|
||||
}).catch((error) => {
|
||||
skeletonIsShow.value = false // 骨架屏取消
|
||||
console.log(error)
|
||||
})
|
||||
|
||||
// 所有图表根据屏幕大小 图表自适应
|
||||
window.addEventListener('resize', () => {
|
||||
payMethod.resize()
|
||||
payStatistics.resize()
|
||||
payAmount.resize()
|
||||
})
|
||||
|
||||
// 问候语句
|
||||
const nextAge = computed(() => {
|
||||
const time = new Date()
|
||||
const hour = time.getHours()
|
||||
return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好'
|
||||
})
|
||||
// 快速菜单集合
|
||||
const quickMenuList: any = computed(() => {
|
||||
const result = []
|
||||
|
||||
const putResult = function (item) {
|
||||
for (let i = 0; i < item.length; i++) {
|
||||
if (item[i].menuUri && item[i].quickJump === 1) {
|
||||
result.push(item[i] as never)
|
||||
}
|
||||
if (item[i].children) {
|
||||
putResult(item[i].children)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
putResult(userStore.userInfo['allMenuRouteTree'])
|
||||
return result
|
||||
})
|
||||
// 金额处理 超过1000万时拼接万 超过亿时 拼接亿
|
||||
const amountHandle = (amount) => {
|
||||
if (amount >= 100000000) {
|
||||
return parseFloat( (amount / 100000000).toFixed(2) )
|
||||
} else if (amount >= 10000000) {
|
||||
return parseFloat( (amount / 10000).toFixed(2) )
|
||||
} else {
|
||||
return amount
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@import './index.less'; // 响应式布局
|
||||
// 个人信息页标题
|
||||
.personal-title {
|
||||
display: flex;
|
||||
img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
}
|
||||
&>div {
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
p {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
margin:0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 个人信息 快速开始
|
||||
.quick-start {
|
||||
p {
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-right: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
// 通用图表标题
|
||||
.echart-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
b {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.date {
|
||||
width: 215px
|
||||
}
|
||||
}
|
||||
|
||||
// 成交金额折线图 日期选择器样式
|
||||
// #selet-date .ant-select {
|
||||
// background: rgba(255, 255, 255, 0.05) !important;
|
||||
// color: rgba(255, 255, 255, 0.7) !important;
|
||||
|
||||
// }
|
||||
// /deep/ #selet-date .ant-select-arrow {
|
||||
// color: rgba(255, 255, 255, 0.7) !important;
|
||||
// }
|
||||
|
||||
// 交易统计图表标题
|
||||
.pay-statistics {
|
||||
&>div{
|
||||
position: relative;
|
||||
&>b, &>.date{
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
z-index: 9
|
||||
}
|
||||
&>b {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-right: 10px;
|
||||
top: 36px;
|
||||
}
|
||||
&>.date {
|
||||
width: 215px;
|
||||
right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
// 缺省图的样式
|
||||
/deep/ .ant-empty-normal {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
.h_opt_p_r {
|
||||
padding: 20px;
|
||||
margin-bottom: 15px;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.h_title_box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.h_title_box{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
}
|
||||
.h_title_box .h_tit_name {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #1f2d3d;
|
||||
}
|
||||
.h_title_box .h_tit_timer {
|
||||
padding-top: 6px;
|
||||
margin-left: 10px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
.h_opt_p_r .h_opt_p_r_l {
|
||||
padding: 10px;
|
||||
margin: 5px 0 10px;
|
||||
color: #fff;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.h_opt_p_r_l_2 {
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
background: linear-gradient(90deg, #734bff, #b190f6);
|
||||
}
|
||||
.h_opt_p_r_l_3 {
|
||||
margin-bottom: 15px;
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
background: linear-gradient(90deg, #ff9b00, #face67);
|
||||
}
|
||||
.ant-btn-primary {
|
||||
color: #fff;
|
||||
border-color: #165dff;
|
||||
background: #165dff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .12);
|
||||
box-shadow: 0 2px #0000000b;
|
||||
}
|
||||
.ant-btn-lg {
|
||||
height: 40px;
|
||||
padding: 6.4px 15px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.h_opt_p_r_l_1 {
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
background: linear-gradient(90deg, #165dff, #5f8cf6);
|
||||
}
|
||||
</style>
|
||||
495
jeepay-ui-merchant/src/views/dashboard/OrderZnFzLargeScreen.vue
Normal file
495
jeepay-ui-merchant/src/views/dashboard/OrderZnFzLargeScreen.vue
Normal file
@@ -0,0 +1,495 @@
|
||||
<template>
|
||||
<!-- 交易路由概况-->
|
||||
<div id="chart-card">
|
||||
<div class="amount">
|
||||
<div style="background-color: rgb(85, 85, 85);">
|
||||
<a-skeleton :loading="skeletonIsShow" active :paragraph="{ rows: 6 }" />
|
||||
<div v-show="!skeletonIsShow" v-if="$access('ENT_C_MAIN_PAY_DAY_COUNT')" class="amount-top">
|
||||
<div class="amount-date">
|
||||
<div :class="{'amount-date-active': amountDate === 'today'}" @click="amountDateHandle('today')">今日交易</div>
|
||||
<div :class="{'amount-date-active': amountDate === 'yesterday'}" @click="amountDateHandle('yesterday')">昨日交易</div>
|
||||
</div>
|
||||
<p>成交金额(元)</p>
|
||||
<a-tooltip placement="top" color="#fff">
|
||||
<template #title>
|
||||
<p style="font-size: 20px; margin-bottom: 0;color:#000">{{ payAmountDataAll.payAmount }}</p>
|
||||
</template>
|
||||
<p style="font-size: 40px;margin-bottom: 35px;color:#fff;width: max-content;">
|
||||
{{ amountHandle(payAmountDataAll.payAmount) }}<span v-if="payAmountDataAll.payAmount >=100000000" style="font-size: 20px;font-weight: 600;margin-left: 5px;vertical-align: middle;">亿</span><span v-else-if="payAmountDataAll.payAmount >=10000000" style="font-size: 20px;font-weight: 600;margin-left: 5px;vertical-align: middle;">万</span>
|
||||
</p>
|
||||
</a-tooltip>
|
||||
<div class="amount-list">
|
||||
<div><p>成交笔数</p><span>{{ payAmountDataAll.payCount }}</span></div>
|
||||
<div><p>手续费金额(元)</p><span>{{ payAmountDataAll.refundAmount }}</span></div>
|
||||
<!-- <div><p>退款笔数</p><span>{{ payAmountDataAll.refundCount }}</span></div>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="amount-line" />
|
||||
<a-skeleton v-show="skeletonIsShow" active :paragraph="{ rows: 6 }" />
|
||||
<div v-show="!skeletonIsShow" v-if="$access('ENT_C_MAIN_PAY_TREND_COUNT')" class="amount-bottom" style="width: 100%">
|
||||
<div class="echart-title">
|
||||
<div style="display: flex;">
|
||||
<b style="color: #fff">趋势</b>
|
||||
<a-tooltip class="tooltip">
|
||||
<template #title>近期成交金额</template>
|
||||
<i class="bi bi-info-circle" style="color:rgba(255, 255, 255, 0.6)" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- -->
|
||||
<a-select id="selet-date" v-model:value="amountSelectDate" class="date amount-date" placeholder="近30天" @change="amountSelectHandle">
|
||||
<a-select-option value="30">近30天</a-select-option>
|
||||
<a-select-option value="7">近7天</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div v-show="!payAmountEmpty" id="pay-amount" style="width: 100%;" />
|
||||
<a-empty v-show="payAmountEmpty" :image="emptyImg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="personal">
|
||||
<div class="h_opt_p_r">
|
||||
<div class="h_title_box" style="cursor: pointer;"><span class="h_tit_name">账户概况</span></div>
|
||||
<div class="h_opt_p_r_l h_opt_p_r_l_1">
|
||||
<div>总交易金额(元)</div>
|
||||
<div class="ant-statistic">
|
||||
<div class="ant-statistic-content" style="color: rgb(255, 255, 255); font-size: 20px;"><span
|
||||
class="ant-statistic-content-value"><span
|
||||
class="ant-statistic-content-value-int">6,261</span><span
|
||||
class="ant-statistic-content-value-decimal">.67</span></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h_opt_p_r_l h_opt_p_r_l_2">
|
||||
<div>手续费余额(元)</div>
|
||||
<div class="ant-statistic">
|
||||
<div class="ant-statistic-content" style="color: rgb(255, 255, 255); font-size: 20px;"><span
|
||||
class="ant-statistic-content-value"><span
|
||||
class="ant-statistic-content-value-int">6,261</span><span
|
||||
class="ant-statistic-content-value-decimal">.67</span></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h_opt_p_r_l h_opt_p_r_l_3">
|
||||
<div>支付宝费率(%):0.2</div>
|
||||
<div>银行卡费率(%):0.3</div>
|
||||
<!-- <div class="ant-statistic">-->
|
||||
<!-- <div class="ant-statistic-content" style="color: rgb(255, 255, 255); font-size: 20px;"><span-->
|
||||
<!-- class="ant-statistic-content-value"><span class="ant-statistic-content-value-int">0</span><span-->
|
||||
<!-- class="ant-statistic-content-value-decimal">.00</span></span></div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" class="ant-btn ant-btn-primary ant-btn-lg" style="margin-right: 3%;">
|
||||
<span>充 值</span></button>
|
||||
<button type="button" class="ant-btn ant-btn-default ant-btn-lg" style="margin-right: 3%;">
|
||||
<span>结 算</span></button>
|
||||
<!-- <button type="button" class="ant-btn ant-btn-primary ant-btn-lg"><span>计算器</span></button>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="method">
|
||||
<a-skeleton :loading="skeletonIsShow" active :paragraph="{ rows: 6 }" />
|
||||
<div v-show="!skeletonIsShow" v-if="$access('ENT_C_MAIN_PAY_TYPE_COUNT')">
|
||||
<div class="echart-title">
|
||||
<b>支付方式</b>
|
||||
<JeepayDateRangePicker v-model:value="payMethodDate" class="date" customDateRangeType="date" :allTimeIsShow="false" @update:value="payMethodDateHandle" />
|
||||
</div>
|
||||
<div v-show="!payMethodEmpty" id="pay-method" style="width: 100%;height: 100%" />
|
||||
<a-empty v-show="payMethodEmpty" :image="emptyImg" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="pay-statistics">
|
||||
<a-skeleton :loading="skeletonIsShow" active :paragraph="{ rows: 6 }" />
|
||||
<div v-show="!skeletonIsShow" v-if="$access('ENT_C_MAIN_PAY_COUNT')">
|
||||
<b>交易统计</b>
|
||||
<!-- <JeepayDateRangePicker v-model:value="payStatisticsDate" class="date" customDateRangeType="date" :statisticalTimeIsShow="true" @update:value="statisticsHandle" />-->
|
||||
<div v-show="!payStatisticsEmpty" id="pay-statistics" style="width: 100%;height: 100%" />
|
||||
<a-empty v-show="payStatisticsEmpty" :image="emptyImg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, ref, computed, onMounted,getCurrentInstance } from 'vue'
|
||||
import * as echarts from 'echarts' // 引入图标组件
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { $getPayTrendCount, $getIsvAndMchCount, $getNumCount, $getPayCount, $getPayType,$getUserInfo } from '@/api/manage'
|
||||
import {pieEcharts, statisticsEcharts, amountEcharts} from './echartsConfig.js' // 图标配置项组件
|
||||
import { Empty } from 'ant-design-vue' // 缺省图
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const { $infoBox, $access, $hasAgentEnt } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const userStore = useUserStore()
|
||||
// 获取到路由对象
|
||||
const router = useRouter() //这是全部路由
|
||||
// 特约商户 普通商户文字显示与隐藏
|
||||
let normalMchIsShow = ref(false) // 普通商户
|
||||
let subMchIsShow = ref(false) // 特约商户
|
||||
const safeWord = ref('')
|
||||
onMounted(() =>{
|
||||
$getUserInfo().then(res =>{
|
||||
safeWord.value = res.safeWord
|
||||
})
|
||||
})
|
||||
// 切换今日昨日金额数据
|
||||
let amountDate = ref('today') // 默认为今日
|
||||
const amountDateHandle = (param) => {
|
||||
amountDate.value = param
|
||||
numCountHandle() // 切换后调用请求
|
||||
}
|
||||
|
||||
let payAmountDataAll: any = ref({}) // 成交金额总数据(今天和昨天)
|
||||
const payAmountGetDateData = ( res ) => { //数据赋值
|
||||
// 分转元显示
|
||||
Object.keys(res.dayCount).forEach(item => {
|
||||
if ((item == 'payCount') || (item == 'refundCount')) {
|
||||
return
|
||||
} else {
|
||||
res.dayCount[item] = (res.dayCount[item] / 100).toFixed(2)
|
||||
}
|
||||
|
||||
})
|
||||
payAmountDataAll.value = res.dayCount
|
||||
}
|
||||
// 成交金额请求数据
|
||||
const numCountHandle = () => {
|
||||
$getNumCount({queryDateRange: amountDate.value}).then(res => {
|
||||
payAmountGetDateData(res)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
//设置信息
|
||||
const setSafeWord = () =>{
|
||||
router.push({
|
||||
path:'/currentUserinfo',
|
||||
query:{type:'msg'}
|
||||
})
|
||||
}
|
||||
// 商户数量
|
||||
let isvAndMchCount: any = ref({})
|
||||
const isvAndMchGetData = (res) => {
|
||||
isvAndMchCount.value = res
|
||||
}
|
||||
|
||||
let payMethod // 支付方式饼图
|
||||
let payMethodEmpty = ref(false) // 支付方式饼图缺省图
|
||||
let payMethodDate = ref('near2now_30') // 饼图日期查询
|
||||
// 当支付方式自定义日期格式中不包含N ,则代表选择了正确的日期格式
|
||||
const payMethodDateHandle = () => {
|
||||
let flag = payMethodDate.value.indexOf('N') === -1
|
||||
if (payMethodDate.value && flag) {
|
||||
payMethodHandle(payMethodDate.value)
|
||||
}
|
||||
}
|
||||
// 饼图数据赋值
|
||||
const payMethodGetData = (res) => {
|
||||
let payTypeData = []
|
||||
res[0].length === 0 ? payMethodEmpty.value = true : payMethodEmpty.value = false
|
||||
res[0].forEach(item => {
|
||||
payTypeData.push({
|
||||
value: (item.typeAmount / 100).toFixed(2), // 分转元
|
||||
name: item.typeName,
|
||||
} as never)
|
||||
})
|
||||
|
||||
pieEcharts.series[0].data = payTypeData // 饼图数据赋值
|
||||
nextTick(() => {
|
||||
payMethod = echarts.init(document.getElementById('pay-method') as HTMLElement)
|
||||
payMethod.setOption(pieEcharts) // 数据填充
|
||||
})
|
||||
}
|
||||
// 饼图请求数据
|
||||
const payMethodHandle = (data) => {
|
||||
$getPayType(data).then(res => {
|
||||
payMethodGetData(res)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
let payStatistics // 交易统计折线图
|
||||
let payStatisticsDate = ref('near2now_30') // 交易统计折线图日期查询
|
||||
let payStatisticsEmpty = ref(false) // 交易统计折线图缺省图
|
||||
const statisticsHandle = () => {
|
||||
let flag = payStatisticsDate.value.indexOf('N') === -1
|
||||
if (payStatisticsDate.value && flag) {
|
||||
payStatisticsHandle(payStatisticsDate.value)
|
||||
}
|
||||
}
|
||||
// 交易统计折线图数据赋值
|
||||
const payStatisticsGetData = (res) => {
|
||||
Object.keys(res).length === 0 ? payStatisticsEmpty.value = true : payStatisticsEmpty.value = false
|
||||
statisticsEcharts.xAxis.data = res.resDateArr // x轴日期
|
||||
let payAmountArr = []
|
||||
res.resPayAmountArr.forEach(item => payAmountArr.push((item / 100).toFixed(2) as never)) // 成交金额分转元
|
||||
statisticsEcharts.series[0].data = payAmountArr // 成交金额
|
||||
statisticsEcharts.series[1].data = res.resPayCountArr // 订单笔数
|
||||
let refAmountArr = []
|
||||
res.resRefAmountArr.forEach(item => refAmountArr.push((item / 100).toFixed(2) as never)) // 退款金额分转元
|
||||
statisticsEcharts.series[2].data = refAmountArr // 退款金额
|
||||
nextTick(() => {
|
||||
payStatistics = echarts.init(document.getElementById('pay-statistics') as HTMLElement)
|
||||
payStatistics.setOption(statisticsEcharts) // 数据填充
|
||||
})
|
||||
}
|
||||
// 交易统计折线图请求数据
|
||||
const payStatisticsHandle = (data) => {
|
||||
$getPayCount(data).then(res => {
|
||||
payStatisticsGetData(res)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
// 今日金额折线图日期选择
|
||||
const amountSelectHandle = (value: string) => {
|
||||
payAmountHandle(value)
|
||||
}
|
||||
let payAmount // 金额板块折线图
|
||||
let payAmountEmpty = ref(false) // 金额折线图缺省图是否展示
|
||||
let amountSelectDate = ref('近30天') // 交易统计折线图日期查询
|
||||
// 成交金额 数据赋值
|
||||
const payAmountGetData = (res) => {
|
||||
amountEcharts.xAxis.data = res.dateList
|
||||
res.dateList.length === 0 ? payAmountEmpty.value = true : payAmountEmpty.value = false
|
||||
let payAmountList = []
|
||||
res.payAmountList.forEach(item => {payAmountList.push((item / 100).toFixed(2) as never)})
|
||||
amountEcharts.series[0].data = payAmountList // 数据赋值
|
||||
nextTick(() => {
|
||||
payAmount = echarts.init(document.getElementById('pay-amount') as HTMLElement)
|
||||
payAmount.setOption(amountEcharts)
|
||||
})
|
||||
}
|
||||
// 金额板块折线图请求数据
|
||||
const payAmountHandle = (date) => {
|
||||
$getPayTrendCount(date).then(res => {
|
||||
payAmountGetData(res)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
// 缺省图片的样式
|
||||
const emptyImg = Empty.PRESENTED_IMAGE_SIMPLE
|
||||
|
||||
// 骨架屏是否展示
|
||||
let skeletonIsShow = ref(true)
|
||||
|
||||
// 首页骨架屏隐藏采用 promise all,只有本页面5个请求全部获得数据才会隐藏, 请求顺序依次为:成交金额, 趋势折线图, 商户数量, 支付方式, 交易统计
|
||||
Promise.all([$getNumCount({queryDateRange: amountDate.value}), $getPayTrendCount(30), $getIsvAndMchCount(), $getPayType(payMethodDate.value), $getPayCount(payStatisticsDate.value)]).then((res) => {
|
||||
skeletonIsShow.value = false // 骨架屏取消
|
||||
payAmountGetDateData(res[0]) // 成交金额
|
||||
payAmountGetData(res[1]) // 趋势折线图
|
||||
isvAndMchGetData(res[2]) // 商户数量
|
||||
payMethodGetData(res[3]) // 饼图
|
||||
payStatisticsGetData(res[4]) // 交易统计
|
||||
}).catch((error) => {
|
||||
skeletonIsShow.value = false // 骨架屏取消
|
||||
console.log(error)
|
||||
})
|
||||
|
||||
// 所有图表根据屏幕大小 图表自适应
|
||||
window.addEventListener('resize', () => {
|
||||
payMethod.resize()
|
||||
payStatistics.resize()
|
||||
payAmount.resize()
|
||||
})
|
||||
|
||||
// 问候语句
|
||||
const nextAge = computed(() => {
|
||||
const time = new Date()
|
||||
const hour = time.getHours()
|
||||
return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好'
|
||||
})
|
||||
// 快速菜单集合
|
||||
const quickMenuList: any = computed(() => {
|
||||
const result = []
|
||||
|
||||
const putResult = function (item) {
|
||||
for (let i = 0; i < item.length; i++) {
|
||||
if (item[i].menuUri && item[i].quickJump === 1) {
|
||||
result.push(item[i] as never)
|
||||
}
|
||||
if (item[i].children) {
|
||||
putResult(item[i].children)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
putResult(userStore.userInfo['allMenuRouteTree'])
|
||||
return result
|
||||
})
|
||||
// 金额处理 超过1000万时拼接万 超过亿时 拼接亿
|
||||
const amountHandle = (amount) => {
|
||||
if (amount >= 100000000) {
|
||||
return parseFloat( (amount / 100000000).toFixed(2) )
|
||||
} else if (amount >= 10000000) {
|
||||
return parseFloat( (amount / 10000).toFixed(2) )
|
||||
} else {
|
||||
return amount
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@import './index.less'; // 响应式布局
|
||||
// 个人信息页标题
|
||||
.personal-title {
|
||||
display: flex;
|
||||
img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
}
|
||||
&>div {
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
p {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
margin:0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 个人信息 快速开始
|
||||
.quick-start {
|
||||
p {
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-right: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
// 通用图表标题
|
||||
.echart-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
b {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.date {
|
||||
width: 215px
|
||||
}
|
||||
}
|
||||
|
||||
// 成交金额折线图 日期选择器样式
|
||||
// #selet-date .ant-select {
|
||||
// background: rgba(255, 255, 255, 0.05) !important;
|
||||
// color: rgba(255, 255, 255, 0.7) !important;
|
||||
|
||||
// }
|
||||
// /deep/ #selet-date .ant-select-arrow {
|
||||
// color: rgba(255, 255, 255, 0.7) !important;
|
||||
// }
|
||||
|
||||
// 交易统计图表标题
|
||||
.pay-statistics {
|
||||
&>div{
|
||||
position: relative;
|
||||
&>b, &>.date{
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
z-index: 9
|
||||
}
|
||||
&>b {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-right: 10px;
|
||||
top: 36px;
|
||||
}
|
||||
&>.date {
|
||||
width: 215px;
|
||||
right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
// 缺省图的样式
|
||||
/deep/ .ant-empty-normal {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
.h_opt_p_r {
|
||||
padding: 20px;
|
||||
margin-bottom: 15px;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.h_title_box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.h_title_box{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
}
|
||||
.h_title_box .h_tit_name {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #1f2d3d;
|
||||
}
|
||||
.h_title_box .h_tit_timer {
|
||||
padding-top: 6px;
|
||||
margin-left: 10px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
.h_opt_p_r .h_opt_p_r_l {
|
||||
padding: 10px;
|
||||
margin: 5px 0 10px;
|
||||
color: #fff;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.h_opt_p_r_l_2 {
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
background: linear-gradient(90deg, #734bff, #b190f6);
|
||||
}
|
||||
.h_opt_p_r_l_3 {
|
||||
margin-bottom: 15px;
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
background: linear-gradient(90deg, #ff9b00, #face67);
|
||||
}
|
||||
.ant-btn-primary {
|
||||
color: #fff;
|
||||
border-color: #165dff;
|
||||
background: #165dff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .12);
|
||||
box-shadow: 0 2px #0000000b;
|
||||
}
|
||||
.ant-btn-lg {
|
||||
height: 40px;
|
||||
padding: 6.4px 15px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.h_opt_p_r_l_1 {
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
background: linear-gradient(90deg, #165dff, #5f8cf6);
|
||||
}
|
||||
</style>
|
||||
206
jeepay-ui-merchant/src/views/dashboard/echartsConfig.js
Normal file
206
jeepay-ui-merchant/src/views/dashboard/echartsConfig.js
Normal file
@@ -0,0 +1,206 @@
|
||||
export const pieEcharts = {
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
itemHeight: 12,
|
||||
itemWidth: 12,
|
||||
top: '85%',
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
fontSize: 11
|
||||
},
|
||||
},
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
color: ['#5470C6', '#91CC75', '#FAC858', '#EE6666', '#73C0DE'],
|
||||
series: [
|
||||
{
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
radius: ['40%', '65%'],
|
||||
center: ['50%', '40%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: '20',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 1048, name: '支付宝支付' },
|
||||
{ value: 735, name: '微信支付' },
|
||||
{ value: 580, name: '微信扫码' },
|
||||
{ value: 484, name: '云闪付支付' },
|
||||
{ value: 300, name: '支付宝二维码' }
|
||||
]
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
export const statisticsEcharts = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '13%',
|
||||
containLabel: true
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
start: 0,
|
||||
end: 100
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
icon: 'rect',
|
||||
itemHeight: 12,
|
||||
itemWidth: 12,
|
||||
top: '2%',
|
||||
data: ['成交金额', '支付(成功)笔数','退款金额'],
|
||||
selected: { // 默认把后两项置灰
|
||||
'成交金额': true,
|
||||
'支付(成功)笔数': false,
|
||||
'退款金额': false
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '成交金额',
|
||||
type: 'line',
|
||||
areaStyle: {},
|
||||
symbol: 'none',
|
||||
smooth: true,
|
||||
data: [120, 132, 101, 134, 90, 230, 210]
|
||||
},
|
||||
{
|
||||
name: '支付(成功)笔数',
|
||||
type: 'line',
|
||||
areaStyle: {},
|
||||
symbol: 'none',
|
||||
smooth: true,
|
||||
data: [220, 182, 191, 234, 290, 330, 310]
|
||||
},
|
||||
{
|
||||
name: '退款金额',
|
||||
type: 'line',
|
||||
areaStyle: {},
|
||||
symbol: 'none',
|
||||
smooth: true,
|
||||
data: []
|
||||
}
|
||||
|
||||
],
|
||||
media: [ // 这里定义了 media query 的逐条规则。
|
||||
{
|
||||
query: { maxWidth: 700 }, // 这里写规则。
|
||||
option: { // 这里写此规则满足下的option。
|
||||
legend: {
|
||||
top: '12%',
|
||||
},
|
||||
grid: {
|
||||
top: '20%',
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
query: {minWidth:701, maxWidth: 1024 }, // 这里写规则。
|
||||
option: { // 这里写此规则满足下的option。
|
||||
legend: {
|
||||
top: '2%',
|
||||
left: '15%'
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
query: {minWidth:1025 }, // 这里写规则。
|
||||
option: { // 这里写此规则满足下的option。
|
||||
legend: {
|
||||
left: '25%'
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
export const amountEcharts = {
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisLine: true,
|
||||
onZero: true,
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: 'rgba(255, 255, 255, 0.5)',
|
||||
},
|
||||
},
|
||||
|
||||
offset: 15
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
grid: {
|
||||
left: '2%',
|
||||
bottom: '15%',
|
||||
right: '2%',
|
||||
containLabel: false
|
||||
},
|
||||
yAxis: {
|
||||
show: false
|
||||
},
|
||||
series: [
|
||||
{
|
||||
lineStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 1,
|
||||
y2: 0,
|
||||
colorStops: [{
|
||||
offset: 0, color: '#FFCC74' // 0% 处的颜色
|
||||
}, {
|
||||
offset: 1, color: '#FFFFFF' // 100% 处的颜色
|
||||
}],
|
||||
global: false // 缺省为 false
|
||||
},
|
||||
width: 7
|
||||
},
|
||||
data: [820, 932, 901, 934, 1290, 1330, 1320],
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
}
|
||||
],
|
||||
|
||||
}
|
||||
194
jeepay-ui-merchant/src/views/dashboard/index.css
Normal file
194
jeepay-ui-merchant/src/views/dashboard/index.css
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
1. amount 金额
|
||||
2.
|
||||
3. personal 个人信息
|
||||
4. payMethod 支付方式
|
||||
5. pay-statistics 交易统计
|
||||
*/
|
||||
#chart-card {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
#chart-card > div {
|
||||
padding: 0 15px 30px;
|
||||
width: 100%;
|
||||
}
|
||||
#chart-card > div > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 30px;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#chart-card .amount {
|
||||
order: 1;
|
||||
}
|
||||
#chart-card .amount > div {
|
||||
background: linear-gradient(103.57deg, #0c2640 0%, #12375e 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#chart-card .amount > div .amount-top {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
min-width: 250px;
|
||||
}
|
||||
#chart-card .amount > div .amount-top .amount-date {
|
||||
width: auto;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
#chart-card .amount > div .amount-top .amount-date div {
|
||||
display: inline-block;
|
||||
background: #000;
|
||||
padding: 9px 20px;
|
||||
}
|
||||
#chart-card .amount > div .amount-top .amount-date div:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
#chart-card .amount > div .amount-top .amount-date .amount-date-active {
|
||||
background: #2691FF;
|
||||
color: #fff;
|
||||
}
|
||||
#chart-card .amount > div .amount-top .amount-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
#chart-card .amount > div .amount-top .amount-list p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
#chart-card .amount > div .amount-top .amount-list span {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
#chart-card .amount > div .amount-line {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.15);
|
||||
margin: 30px 0;
|
||||
}
|
||||
#chart-card .amount > div #pay-amount {
|
||||
height: 200px;
|
||||
}
|
||||
#chart-card .personal {
|
||||
order: 3;
|
||||
}
|
||||
#chart-card .personal > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
}
|
||||
#chart-card .personal > div .personal-line {
|
||||
width: 100%;
|
||||
border-top: 1px solid #ebeff2;
|
||||
margin: 25px 0;
|
||||
}
|
||||
#chart-card .method {
|
||||
order: 4;
|
||||
height: 530px;
|
||||
}
|
||||
#chart-card .method > div {
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#chart-card .pay-statistics {
|
||||
order: 5;
|
||||
height: 530px;
|
||||
}
|
||||
#chart-card .pay-statistics > div {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
}
|
||||
#chart-card .personal {
|
||||
order: 0;
|
||||
}
|
||||
@media screen and (min-width: 1024px) {
|
||||
#chart-card .personal {
|
||||
order: 0;
|
||||
width: 100%;
|
||||
}
|
||||
#chart-card .personal > div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
#chart-card .personal > div .personal-line {
|
||||
width: 0;
|
||||
height: 100%;
|
||||
border-left: 1px solid #ebeff2;
|
||||
margin: 0 25px;
|
||||
}
|
||||
#chart-card .amount {
|
||||
width: 100%;
|
||||
}
|
||||
#chart-card .amount > div {
|
||||
flex-direction: row;
|
||||
}
|
||||
#chart-card .amount > div .amount-line {
|
||||
width: 0;
|
||||
height: 100%;
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.15);
|
||||
margin: 0 30px;
|
||||
}
|
||||
#chart-card .amount > div #pay-amount {
|
||||
height: 100%;
|
||||
}
|
||||
#chart-card .method {
|
||||
width: calc(100% - 285px);
|
||||
flex-grow: 1;
|
||||
}
|
||||
#chart-card .pay-statistics {
|
||||
width: 100% ;
|
||||
height: 530px;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 1366px) {
|
||||
#chart-card .personal {
|
||||
order: 0;
|
||||
width: 100%;
|
||||
}
|
||||
#chart-card .amount {
|
||||
width: calc(100% - 265px);
|
||||
flex-grow: 1;
|
||||
}
|
||||
#chart-card .method {
|
||||
width: 460px;
|
||||
}
|
||||
#chart-card .pay-statistics {
|
||||
width: calc(100% - 460px);
|
||||
flex-grow: 1;
|
||||
height: 530px;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 1600px) {
|
||||
#chart-card .amount {
|
||||
order: 1;
|
||||
width: calc(100% - 270px - 330px);
|
||||
flex-grow: 1;
|
||||
}
|
||||
#chart-card .personal {
|
||||
order: 3;
|
||||
width: 330px;
|
||||
}
|
||||
#chart-card .personal > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#chart-card .personal > div .personal-line {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border-top: 1px solid #ebeff2;
|
||||
margin: 25px 0;
|
||||
}
|
||||
#chart-card .method {
|
||||
width: 544px;
|
||||
}
|
||||
#chart-card .pay-statistics {
|
||||
width: calc(100% - 544px);
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
261
jeepay-ui-merchant/src/views/dashboard/index.less
Normal file
261
jeepay-ui-merchant/src/views/dashboard/index.less
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
1. amount 金额
|
||||
2.
|
||||
3. personal 个人信息
|
||||
4. payMethod 支付方式
|
||||
5. pay-statistics 交易统计
|
||||
*/
|
||||
@import '../node_modules/ant-design-vue/es/style/themes/default.less';
|
||||
#chart-card {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
& > div {
|
||||
padding: 0 15px 30px;
|
||||
// flex-grow: 1;
|
||||
width: 100%;
|
||||
}
|
||||
& > div > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 30px;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
// order 排列顺序 越小越靠前
|
||||
.amount {
|
||||
order: 1;
|
||||
& > div {
|
||||
background: linear-gradient(103.57deg, #0c2640 0%, #12375e 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.amount-top {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
min-width: 450px;
|
||||
.amount-date {
|
||||
width: auto;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-bottom: 30px;
|
||||
div {
|
||||
display: inline-block;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
padding: 9px 20px;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.amount-date-active {
|
||||
background: var(--ant-primary-color);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.amount-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
div{
|
||||
margin-top: 30px;
|
||||
width: 150px;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
span {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.amount-line {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.15);
|
||||
margin: 30px 0;
|
||||
}
|
||||
#pay-amount {
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.personal {
|
||||
order: 3;
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
.before-msg {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
color: #8f8f8f;
|
||||
p {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
.personal-line {
|
||||
width: 100%;
|
||||
border-top: 1px solid #ebeff2;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.latest-post {
|
||||
min-width: 250px;
|
||||
.title {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
span {
|
||||
&:nth-child(1) {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.post-list {
|
||||
width: 100%;
|
||||
padding-top: 10px;
|
||||
|
||||
// background-color: rgb(204, 191, 191);
|
||||
.post-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 15px;
|
||||
cursor: pointer;
|
||||
.title {
|
||||
display: block;
|
||||
width: 60%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis; //溢出用省略号显示
|
||||
white-space: nowrap;
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
color: #575757;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.method {
|
||||
order: 4;
|
||||
height: 530px;
|
||||
& > div {
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
.pay-statistics {
|
||||
order: 5;
|
||||
height: 530px;
|
||||
& > div {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
.personal {
|
||||
order: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1024px) {
|
||||
#chart-card {
|
||||
.personal {
|
||||
order: 0;
|
||||
width: 100%;
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.personal-line {
|
||||
width: 0;
|
||||
height: 100%;
|
||||
border-left: 1px solid #ebeff2;
|
||||
margin: 0 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.amount {
|
||||
width: 100%;
|
||||
& > div {
|
||||
flex-direction: row;
|
||||
.amount-line {
|
||||
width: 0;
|
||||
height: 100%;
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.15);
|
||||
margin: 0 10px 0 20px;
|
||||
}
|
||||
#pay-amount {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.method {
|
||||
width: calc(100% - 285px);
|
||||
flex-grow: 1;
|
||||
}
|
||||
.pay-statistics {
|
||||
width: 100%;
|
||||
height: 530px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 1366px) {
|
||||
#chart-card {
|
||||
.personal {
|
||||
order: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.amount {
|
||||
width: calc(100% - 265px);
|
||||
flex-grow: 1;
|
||||
}
|
||||
.method {
|
||||
width: 460px;
|
||||
}
|
||||
.pay-statistics {
|
||||
width: calc(100% - 460px);
|
||||
flex-grow: 1;
|
||||
height: 530px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 1600px) {
|
||||
#chart-card {
|
||||
.amount {
|
||||
order: 1;
|
||||
width: calc(100% - 270px - 330px);
|
||||
flex-grow: 1;
|
||||
} // order 排列顺序 越小越靠前
|
||||
.personal {
|
||||
order: 3;
|
||||
width: 330px;
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.personal-line {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border-top: 1px solid #ebeff2;
|
||||
margin: 20px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.method {
|
||||
width: 544px;
|
||||
}
|
||||
.pay-statistics {
|
||||
width: calc(100% - 544px);
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
79
jeepay-ui-merchant/src/views/device/BizConfig.vue
Normal file
79
jeepay-ui-merchant/src/views/device/BizConfig.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<a-form ref="formRef" :model="vdata.bizConfig" layout="vertical" :rules="vdata.formRules">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">其他配置</a-tag>
|
||||
</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col v-if="vdata.provider != 'fe'" :span="11">
|
||||
<a-form-item label="打印机模式" name="printMode">
|
||||
<a-radio-group v-model:value="vdata.bizConfig.printMode">
|
||||
<a-radio :value="1">仅打印</a-radio>
|
||||
<a-radio :value="2">仅播报</a-radio>
|
||||
<a-radio :value="3">打印并播报</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<a-form-item label="打印联数" name="printNum">
|
||||
<a-radio-group v-model:value="vdata.bizConfig.printNum">
|
||||
<a-input v-model:value="vdata.bizConfig.printNum" placeholder="请输入打印联数" />
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {reactive, ref, defineExpose} from 'vue'
|
||||
|
||||
// 当前的form
|
||||
const formRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
isShow: false,
|
||||
deviceType: 0, // 1-云喇叭 2-云打印 3-扫码POS
|
||||
provider: '', // 厂商,飞鹅打印机无播报,特殊处理
|
||||
// 配置对象
|
||||
bizConfig: {} as any,
|
||||
// 表单规则
|
||||
formRules: {
|
||||
printMode: [{ required: true, type: 'number', message: '请选择打印机模式', trigger: 'blur' }],
|
||||
printNum: [{ required: true, message: '请输入打印联数', trigger: 'blur' }],
|
||||
}
|
||||
})
|
||||
|
||||
// 对外提供的页面的渲染函数 ( ifDefineArray = 接口的配置定义项数组, bizConfig = 当前配置项 )
|
||||
function pageRender(bizConfig: any, deviceType: number, provider: string){
|
||||
// 赋值
|
||||
if (bizConfig) {
|
||||
vdata.bizConfig = bizConfig
|
||||
}
|
||||
vdata.deviceType = deviceType
|
||||
vdata.provider = provider
|
||||
|
||||
// 重置form验证
|
||||
if (formRef.value !== undefined && formRef.value !== null) {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
vdata.isShow = true
|
||||
}
|
||||
|
||||
// 对外提供的获取配置参数函数 (返回JSON类型)
|
||||
function getConfigParams(){
|
||||
|
||||
// 云喇叭 扫码POS 暂无业务配置,直接返回
|
||||
if (vdata.deviceType == 1 || vdata.deviceType == 3) {
|
||||
vdata.isShow = false
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return formRef.value.validate().then( () => {
|
||||
vdata.isShow = false
|
||||
return vdata.bizConfig
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ getConfigParams, pageRender })
|
||||
|
||||
</script>
|
||||
250
jeepay-ui-merchant/src/views/device/CommonAddOrEdit.vue
Normal file
250
jeepay-ui-merchant/src/views/device/CommonAddOrEdit.vue
Normal file
@@ -0,0 +1,250 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.drawerVisible"
|
||||
:mask-closable="false"
|
||||
:title=" vdata.isAdd ? '新增设备' : '修改设备' "
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="40%"
|
||||
class="drawer-width"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form v-if="vdata.drawerVisible" ref="infoFormModel" :model="vdata.saveObject" layout="vertical" :rules="vdata.rules">
|
||||
<a-row v-if="vdata.isAdd" justify="space-between" type="flex">
|
||||
<a-col :span="11">
|
||||
<a-form-item label="设备号" name="deviceNo">
|
||||
<a-input v-model:value="vdata.saveObject.deviceNo" placeholder="请输入设备号" />
|
||||
<div v-if="vdata.checkMsg" :style="vdata.checkCode == 1 ? {'color' : 'green'} : {'color' : 'red'}">{{ vdata.checkMsg }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label=" ">
|
||||
<a-button type="primary" @click="checkFunc">查询设备是否允许绑定</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="vdata.providerConfigList.length > 0 && vdata.checkCode == 2" justify="space-between" type="flex">
|
||||
<a-col :span="11">
|
||||
<a-form-item label="选择厂商" name="provider">
|
||||
<a-select v-model:value="vdata.saveObject.provider" :disabled="!vdata.isAdd" placeholder="请选择厂商">
|
||||
<a-select-option v-for="d in vdata.providerConfigList" :key="d.provider" v-model:value="d.provider">
|
||||
【{{ (allList.find(item => item.value == d.provider) as any).text || '其他' }}】{{ d.configDesc }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="11">
|
||||
<a-form-item label="设备名称" name="deviceName">
|
||||
<a-input v-model:value="vdata.saveObject.deviceName" placeholder="请输入设备名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="11">
|
||||
<a-form-item label="选择门店" name="storeId">
|
||||
<a-select v-model:value="vdata.saveObject.storeId" placeholder="请选择门店" show-search @search="handleBankChange" >
|
||||
<a-select-option v-for="d in vdata.filteredStoreInfoList" :key="d.storeId" v-model:value="d.storeId">
|
||||
{{ d.storeName }} [{{ d.storeId }}]
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col v-if="vdata.deviceType != 1 && vdata.deviceType != 2 && vdata.deviceType != 3" :span="11">
|
||||
<a-form-item label="选择应用" name="appId">
|
||||
<a-select v-model:value="vdata.saveObject.appId" placeholder="请选择应用" show-search @search="handleAppidChange">
|
||||
<a-select-option v-for="d in vdata.filteredAppInfoList" :key="d.appId" v-model:value="d.appId">
|
||||
{{ d.appName }} [{{ d.appId }}]
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col v-if="vdata.deviceType != 5" :span="11">
|
||||
<a-form-item label="状态" name="state">
|
||||
<a-radio-group v-model:value="vdata.saveObject['state']">
|
||||
<a-radio :value="1">启用</a-radio>
|
||||
<a-radio :value="0">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" style="margin-right:8px" @click="onClose"><close-outlined />取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="handleOkFunc"><check-outlined />保存</a-button>
|
||||
</div>
|
||||
|
||||
<!-- 业务参数配置组件 -->
|
||||
<BizConfig v-if="vdata.deviceType == 2 && !vdata.isAdd" ref="bizConfigRef" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_STORE_DEVICE, API_URL_MCH_STORE_LIST, API_URL_MCH_APP, req, $checkDevice } from '@/api/manage'
|
||||
import { defineProps, reactive, ref, getCurrentInstance } from 'vue'
|
||||
import BizConfig from '@/views/device/BizConfig.vue'
|
||||
import provider from './provider.json'
|
||||
|
||||
const allList = provider.all
|
||||
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const bizConfigRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
providerConfigList: [] as any, // 厂商列表
|
||||
storeList: [] as any, // 门店列表
|
||||
filteredStoreInfoList: [] as any, // 门店列表
|
||||
appList: [] as any, // 应用列表
|
||||
filteredAppInfoList: [] as any, // 应用列表
|
||||
btnLoading: false,
|
||||
isAdd: true, // 新增 or 修改页面标志
|
||||
deviceType: 1, // 1-云喇叭 2-云打印 3-扫码POS
|
||||
saveObject: {} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
drawerVisible: false, // 是否显示弹层/抽屉
|
||||
rules: {
|
||||
provider: [{ required: true, message: '请选择厂商', trigger: 'blur' }],
|
||||
storeId: [{ required: true,message: '请选择门店', trigger: 'blur' }],
|
||||
deviceName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
|
||||
deviceNo: [{ required: true, message: '请输入设备号', trigger: 'blur' }],
|
||||
appId: [{
|
||||
required: false,
|
||||
trigger: 'blur'
|
||||
}, {
|
||||
validator: async (rule, value) => {
|
||||
if ((vdata.deviceType != 1 && vdata.deviceType != 2) && !value) {
|
||||
return Promise.reject('请选择应用')
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}) as any
|
||||
|
||||
function show (record: any) { // 弹层打开事件
|
||||
|
||||
vdata.isAdd = !record.deviceId
|
||||
vdata.deviceType = record.deviceType // 设备类型deviceType: 1-云喇叭, 2-云打印,3-扫码POS,4-智能POS
|
||||
vdata.provider = record.provider
|
||||
|
||||
vdata.saveObject = { 'state': 1, 'deviceType': record.deviceType }
|
||||
|
||||
vdata.providerConfigList = []
|
||||
vdata.checkMsg = ''
|
||||
|
||||
if (infoFormModel.value != undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
req.list(API_URL_MCH_STORE_LIST, { 'pageSize': -1 }).then(res => { // 门店下拉选择列表
|
||||
vdata.storeList = res.records
|
||||
vdata.filteredStoreInfoList = res.records
|
||||
})
|
||||
req.list(API_URL_MCH_APP, { 'pageSize': -1 }).then(res => { // 应用下拉选择列表
|
||||
vdata.appList = res.records
|
||||
vdata.filteredAppInfoList = res.records
|
||||
|
||||
})
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.recordId = record.deviceId
|
||||
|
||||
req.getById(API_URL_STORE_DEVICE, vdata.recordId).then((res: any) => {
|
||||
if(res){
|
||||
vdata.saveObject = res
|
||||
|
||||
// 业务参数配置组件
|
||||
if(vdata.deviceType == 2) {
|
||||
let bizConfig = JSON.parse(vdata.saveObject.bizConfigParams || '{}' )
|
||||
bizConfigRef.value.pageRender(bizConfig, vdata.deviceType, vdata.provider)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
vdata.drawerVisible = true // 立马展示弹层信息
|
||||
}
|
||||
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then((valid: any) =>{
|
||||
if(vdata.deviceType == 2 && !vdata.isAdd) {
|
||||
bizConfigRef.value.getConfigParams().then((bizConfigParams: any) => {
|
||||
// 赋值
|
||||
vdata.saveObject.bizConfigParams = bizConfigParams || ''
|
||||
addOrEdit()
|
||||
})
|
||||
} else {
|
||||
addOrEdit()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function addOrEdit() {
|
||||
vdata.btnLoading = true
|
||||
// 请求接口
|
||||
if (vdata.isAdd) {
|
||||
req.add(API_URL_STORE_DEVICE, vdata.saveObject).then((res: any) => {
|
||||
successFunc('保存成功')
|
||||
}).catch((err: any) => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
} else {
|
||||
req.updateById(API_URL_STORE_DEVICE, vdata.recordId, vdata.saveObject).then((res: any) => {
|
||||
successFunc('修改成功')
|
||||
}).catch((err: any) => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function successFunc(e: string) { // 新增/更新成功
|
||||
vdata.btnLoading = false
|
||||
$infoBox.message.success(e)
|
||||
props.callbackFunc()
|
||||
vdata.drawerVisible = false
|
||||
}
|
||||
|
||||
function checkFunc() {
|
||||
vdata.checkMsg = ''
|
||||
|
||||
$checkDevice(vdata.saveObject.deviceNo, vdata.saveObject.deviceType).then(res => {
|
||||
vdata.checkCode = res.checkCode
|
||||
vdata.checkMsg = res.checkMsg
|
||||
|
||||
if (vdata.checkCode == 2) {
|
||||
vdata.providerConfigList = res.deviceList
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onClose () { // 关闭抽屉
|
||||
vdata.drawerVisible = false
|
||||
}
|
||||
|
||||
const handleBankChange = (value) => {
|
||||
vdata.filteredStoreInfoList = [];
|
||||
vdata.storeList.forEach((item: { storeName: string | any[], storeId: any[] },index) => {
|
||||
if (item.storeName.includes(value) || item.storeId.toString().includes(value) ) {
|
||||
vdata.filteredStoreInfoList.push(vdata.storeList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleAppidChange = (value) => {
|
||||
vdata.filteredAppInfoList = [];
|
||||
vdata.appList.forEach((item: { appName: string | any[], appId: string | any[] },index) => {
|
||||
if (item.appName.includes(value) || item.appId.includes(value) ) {
|
||||
vdata.filteredAppInfoList.push(vdata.appList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
53
jeepay-ui-merchant/src/views/device/CommonConfig.vue
Normal file
53
jeepay-ui-merchant/src/views/device/CommonConfig.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<a-form v-if="vdata.currentConfig" ref="formRef" :model="vdata.currentConfig" layout="vertical" :rules="vdata.formRules">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">设备编号配置</a-tag>
|
||||
</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="11">
|
||||
<a-form-item label="设备编号" name="deviceNo">
|
||||
<a-input v-model:value="vdata.currentConfig.deviceNo" placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {reactive, ref, defineExpose} from 'vue'
|
||||
|
||||
// 当前的form
|
||||
const formRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
// 配置对象
|
||||
currentConfig: {} as any,
|
||||
// 表单规则
|
||||
formRules: {
|
||||
deviceNo: [{ required: true, message: '请输入设备编号', trigger: 'blur' }]
|
||||
}
|
||||
})
|
||||
|
||||
// 对外提供的页面的渲染函数 ( ifDefineArray = 接口的配置定义项数组, currentConfig = 当前配置项 )
|
||||
function pageRender(currentConfig: any){
|
||||
// 赋值
|
||||
if (currentConfig) {
|
||||
vdata.currentConfig = currentConfig
|
||||
}
|
||||
|
||||
// 重置form验证
|
||||
if (formRef.value !== undefined && formRef.value !== null) {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
}
|
||||
|
||||
// 对外提供的获取配置参数函数 (返回JSON类型)
|
||||
function getConfigParams(){
|
||||
return formRef.value.validate().then( () => {
|
||||
return vdata.currentConfig
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ getConfigParams, pageRender })
|
||||
|
||||
</script>
|
||||
58
jeepay-ui-merchant/src/views/device/TestDevice.vue
Normal file
58
jeepay-ui-merchant/src/views/device/TestDevice.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<a-modal v-model:visible="vdata.isShow" title="测试" @ok="handleOkFunc">
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" :label-col="{span: 6}" :wrapper-col="{span: 15}" :rules="rules">
|
||||
<a-form-item label="金额:" name="amount">
|
||||
<a-input v-model:value="vdata.saveObject.amount" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { $speakTest, $printTest }from '@/api/manage'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
const infoFormModel = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
loading: false, // 按钮上的loading
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: {} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
deviceType: 1 // 设备类型,1-云喇叭 2-云打印
|
||||
})
|
||||
|
||||
const rules = {
|
||||
amount: [{ required: true, pattern: /^(([1-9]{1}\d{0,6})|(0{1}))(\.\d{1,2})?$/, message: '请输入正确的金额', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
defineExpose({show})
|
||||
|
||||
function show (recordId, deviceType) { // 弹层打开事件
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
vdata.isShow = true
|
||||
vdata.saveObject.amount = ''
|
||||
vdata.recordId = recordId
|
||||
vdata.deviceType = deviceType
|
||||
}
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
|
||||
if(vdata.deviceType == 1) {
|
||||
infoFormModel.value.validate().then(valid =>{
|
||||
$speakTest(vdata.recordId, vdata.saveObject.amount)
|
||||
})
|
||||
} else if(vdata.deviceType == 2) {
|
||||
infoFormModel.value.validate().then(valid =>{
|
||||
$printTest(vdata.recordId, vdata.saveObject.amount)
|
||||
})
|
||||
}
|
||||
}
|
||||
// 点击遮罩层关闭抽屉
|
||||
function onClose () {
|
||||
vdata.isShow = false
|
||||
}
|
||||
|
||||
</script>
|
||||
218
jeepay-ui-merchant/src/views/device/autopos/AutoPosList.vue
Normal file
218
jeepay-ui-merchant/src/views/device/autopos/AutoPosList.vue
Normal file
@@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="date" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.storeId" :placeholder="'门店名称/编号'" />
|
||||
<!-- <jeepay-text-up v-model:value="vdata.searchData.deviceNo" :placeholder="'设备号'" />-->
|
||||
<jeepay-text-up v-model:value="vdata.searchData['deviceName']" :placeholder="'设备名称/编号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchApplyName']" :placeholder="'商户名称/商户号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['ifName']" :placeholder="'支付通道'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['isvNo']" :placeholder="'渠道名称/渠道号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['appId']" :placeholder="'应用名称'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.provider" placeholder="所属支付接口">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option v-for="item in vdata.ifCodeList" :key="item.ifCode" :value="item.ifCode">{{ item.ifName }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">禁用</a-select-option>
|
||||
<a-select-option value="1">启用</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData['bindState']" placeholder="绑定状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">未绑定</a-select-option>
|
||||
<a-select-option value="1">已绑定</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button v-if="$access('ENT_DEVICE_POS_ADD')" type="primary" @click="addFunc"><plus-outlined />绑定设备</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_QR_CODE_ADD')" type="primary" @click="showShop()"> <PlusOutlined /> 设备商城</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'state'">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="$access('ENT_DEVICE_AUTO_POS_EDIT')" :onChange="(state) => { return updateState(record.deviceId, state)}" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'provider'">
|
||||
<a-tag :key="record.provider" color="processing">
|
||||
{{ (vdata.ifCodeList.find(item => item.ifCode == record.provider) as any)?.ifName || '其他' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'bindAppIdName'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>应用名称:{{record.bindAppIdName}}</span><br>
|
||||
<span>应用ID:{{record.appId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.bindAppIdName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchApplyName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>商户名称:{{record.mchApplyName}}</span><br>
|
||||
<span>商户号:{{record.mchApplyId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchApplyName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'isvNo'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>渠道名称:{{record.isvName}}</span><br>
|
||||
<span>渠道号:{{record.isvNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.isvName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'storeId'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>门店名称:{{record.storeName}}</span><br>
|
||||
<span>门店编号:{{record.storeId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.storeName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_DEVICE_AUTO_POS_EDIT')" type="link" @click="editFunc(record)">修改</a-button>
|
||||
<a-button
|
||||
v-if="$access('ENT_DEVICE_AUTO_POS_EDIT') && (userStore.userInfo['userType'] != '11' && userStore.userInfo['userType'] != '12')"
|
||||
type="link"
|
||||
style="color: red"
|
||||
@click="deBindFunc(record.deviceId)"
|
||||
>
|
||||
解绑
|
||||
</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, API_URL_IFDEFINES_LIST, req, reqLoad, $unbindDevice } from '@/api/manage'
|
||||
import InfoAddOrEdit from '../CommonAddOrEdit.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoAddOrEdit = ref()
|
||||
const bind = ref()
|
||||
const infoTable = ref()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const deviceType = 4
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ title: '设备号', fixed: 'left', dataIndex: 'deviceNo' },
|
||||
{ key: 'provider', title: '所属支付接口', dataIndex: 'provider', },
|
||||
{ title: "商户名称", key: "mchApplyName", dataIndex: "mchApplyName" },
|
||||
{ key: 'storeId',title: '门店名称', dataIndex: 'storeId',},
|
||||
{ key: "ifName", title: "支付通道", dataIndex: "ifName" },
|
||||
{ key: "isvNo", title: "所属渠道", dataIndex: "isvNo" },
|
||||
{ key: 'bindAppIdName', dataIndex: 'bindAppIdName', title: '所属应用', },
|
||||
// { key: 'bindState', title: '绑定状态',},
|
||||
{ key: 'state', title: '使用状态',},
|
||||
{ dataIndex: 'createdAt', title: '创建日期',},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
const vdata = reactive({
|
||||
ifCodeList: [], // 通道列表
|
||||
searchData: {} as any
|
||||
}) as any
|
||||
|
||||
onMounted(() => {
|
||||
vdata.searchData.mchNo = useRoute().query.mchNo
|
||||
searchFunc()
|
||||
|
||||
req.list(API_URL_IFDEFINES_LIST, { 'state': 1 }).then(res => { // 通道下拉选择列表
|
||||
vdata.ifCodeList = res.filter(r => r.wayCodes.some(s => s.wayCode == 'AUTO_POS' || s.wayCode == 'OUT_TRADE'))
|
||||
})
|
||||
})
|
||||
|
||||
function reqTableDataFunc(params: any) { // 请求table接口数据
|
||||
return req.list(API_URL_STORE_DEVICE, Object.assign({ deviceType: deviceType }, params))
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
btnLoading.value = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show({ deviceType: deviceType })
|
||||
}
|
||||
function editFunc (record: any) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(record)
|
||||
}
|
||||
function bindFunc (record: any) { // 绑定设备函数
|
||||
bind.value.show(record)
|
||||
}
|
||||
function onReset(){ //重置搜索内容
|
||||
vdata.searchData = {}
|
||||
}
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
const title = state ? '确认启用?' : '确认禁用?'
|
||||
const content = state ? '' : '禁用后该设备将无法使用!'
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return reqLoad.updateById(API_URL_STORE_DEVICE, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 解绑设备
|
||||
function deBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后商户将无法使用该设备!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindDevice(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
|
||||
function showShop(){
|
||||
$infoBox.message.error('暂未开通')
|
||||
}
|
||||
</script>
|
||||
209
jeepay-ui-merchant/src/views/device/faceapp/AddOrEdit.vue
Normal file
209
jeepay-ui-merchant/src/views/device/faceapp/AddOrEdit.vue
Normal file
@@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.drawerVisible"
|
||||
:mask-closable="false"
|
||||
:title=" vdata.isAdd ? '新增设备' : '修改设备' "
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="40%"
|
||||
class="drawer-width"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form v-if="vdata.drawerVisible" ref="infoFormModel" :model="vdata.saveObject" layout="horizontal" :rules="vdata.rules">
|
||||
<a-row v-if="vdata.isAdd" justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="选择设备厂商" name="provider">
|
||||
<a-select v-model:value="vdata.saveObject.provider" :disabled="!vdata.isAdd" placeholder="请选择设备厂商">
|
||||
<a-select-option value="wxpayQWPro">微信青蛙pro</a-select-option>
|
||||
<a-select-option value="alipayQT">支付宝蜻蜓</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="批次号" name="batchId">
|
||||
<a-input v-model:value="vdata.saveObject.batchId" placeholder="请输入批次号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row v-else justify="space-between" type="flex">
|
||||
<a-col :span="16">
|
||||
<a-form-item label="设备名称" name="deviceName">
|
||||
<a-input v-model:value="vdata.saveObject.deviceName" placeholder="请输入设备名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="16" justify="space-between" type="flex">
|
||||
<a-form-item label="设备号" name="deviceNo">
|
||||
<a-input v-model:value="vdata.saveObject.deviceNo" placeholder="请输入设备号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<template v-if="vdata.isAdd">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="">
|
||||
<a-radio-group v-model:value="vdata.deviceInputMode">
|
||||
<a-radio :value="1">逐条添加</a-radio>
|
||||
<a-radio :value="2">批量添加</a-radio>
|
||||
<!-- <a-radio :value="3">导入Excel</a-radio> -->
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<!-- 逐条输入 -->
|
||||
<template v-if="vdata.deviceInputMode == 1">
|
||||
<a-row v-for="(item, index) in vdata.saveObject.deviceList" :key="index" justify="start" type="flex" :gutter="8">
|
||||
<a-col :span="10" style="margin-right: 15px;">
|
||||
<a-form-item
|
||||
layout="vertical"
|
||||
label="设备号"
|
||||
:name="['deviceList', index, 'deviceNo']"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: '设备号不能为空',
|
||||
trigger: 'blur',
|
||||
}"
|
||||
>
|
||||
<a-input v-model:value="item.deviceNo" placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-button v-if="index >= 1" danger type="link" @click="removeDomain(item)"><MinusCircleOutlined class="delete-button" /></a-button>
|
||||
</a-row>
|
||||
<a-col :span="24">
|
||||
<a-form-item>
|
||||
<a-button type="dashed" @click="addDomain"><PlusOutlined />新增</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
|
||||
<!-- 批量输入 -->
|
||||
<a-row v-if="vdata.deviceInputMode == 2" justify="start" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="设备号">
|
||||
<a-textarea v-model:value="vdata.deviceTextarea" :rows="8" placeholder="请输入" />
|
||||
<div class="jeepay-tip-text" style="display: flex;flex-direction: column">
|
||||
<span>多设备号之间以英文逗号隔开,例如:111,222,333</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</a-form>
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" style="margin-right:8px" @click="onClose"><close-outlined />取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="handleOkFunc"><check-outlined />保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_STORE_DEVICE, req } from '@/api/manage'
|
||||
import { defineProps, getCurrentInstance, reactive, ref } from 'vue'
|
||||
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
storeList: [] as any, // 门店列表
|
||||
btnLoading: false,
|
||||
isAdd: true, // 新增 or 修改页面标志
|
||||
|
||||
deviceInputMode: 1, // 设备号输入方式:1-逐条 2-批量
|
||||
deviceTextarea: '', // 批量输入设备号model
|
||||
|
||||
saveObject: {} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
drawerVisible: false, // 是否显示弹层/抽屉
|
||||
rules: {
|
||||
deviceName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
|
||||
deviceNo: [{ required: true, message: '请输入设备号', trigger: 'blur' }]
|
||||
}
|
||||
}) as any
|
||||
|
||||
|
||||
function show (record: any) { // 弹层打开事件
|
||||
|
||||
vdata.isAdd = !record.deviceId
|
||||
|
||||
vdata.saveObject = { 'state': 1, deviceType: record.deviceType, deviceList: [{ deviceNo: '' }] }
|
||||
|
||||
if (infoFormModel.value != undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.recordId = record.deviceId
|
||||
|
||||
req.getById(API_URL_STORE_DEVICE, vdata.recordId).then((res: any) => {
|
||||
vdata.saveObject = res
|
||||
})
|
||||
}
|
||||
|
||||
vdata.drawerVisible = true // 立马展示弹层信息
|
||||
}
|
||||
|
||||
// 保存
|
||||
function handleOkFunc () {
|
||||
infoFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.btnLoading = true
|
||||
|
||||
// 请求接口
|
||||
if (vdata.isAdd) {
|
||||
|
||||
// 设备号赋值,以 , 隔开的字符串
|
||||
vdata.saveObject.deviceNoParams = vdata.deviceTextarea
|
||||
if (vdata.deviceInputMode == 1) {
|
||||
vdata.saveObject.deviceNoParams = vdata.saveObject.deviceList.map((item) => {
|
||||
return item.deviceNo
|
||||
}).join(',')
|
||||
}
|
||||
|
||||
req.add(API_URL_STORE_DEVICE, vdata.saveObject).then((res: any) => {
|
||||
successFunc('保存成功')
|
||||
}).catch((err: any) => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
|
||||
} else {
|
||||
const { deviceNo, deviceName } = vdata.saveObject
|
||||
req.updateById(API_URL_STORE_DEVICE, vdata.recordId, { deviceNo, deviceName }).then((res: any) => {
|
||||
successFunc('修改成功')
|
||||
}).catch((err: any) => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function successFunc(e: string) { // 新增/更新成功
|
||||
vdata.btnLoading = false
|
||||
$infoBox.message.success(e)
|
||||
props.callbackFunc()
|
||||
vdata.drawerVisible = false
|
||||
}
|
||||
|
||||
function onClose () { // 关闭抽屉
|
||||
vdata.drawerVisible = false
|
||||
}
|
||||
|
||||
function addDomain() {
|
||||
vdata.saveObject.deviceList.push({
|
||||
deviceNo: ''
|
||||
})
|
||||
}
|
||||
|
||||
function removeDomain(item) {
|
||||
const index = vdata.saveObject.deviceList.indexOf(item)
|
||||
if (index != -1) {
|
||||
vdata.saveObject.deviceList.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
184
jeepay-ui-merchant/src/views/device/faceapp/FaceAppList.vue
Normal file
184
jeepay-ui-merchant/src/views/device/faceapp/FaceAppList.vue
Normal file
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="vdata.searchData.storeId" :placeholder="'门店ID'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.deviceNo" :placeholder="'设备号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.deviceName" :placeholder="'设备名称'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.provider" placeholder="设备厂商">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="wxpayQWPro">微信青蛙pro</a-select-option>
|
||||
<a-select-option value="alipayQT">支付宝蜻蜓</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">禁用</a-select-option>
|
||||
<a-select-option value="1">启用</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button v-if="$access('ENT_DEVICE_FACE_APP_ADD')" type="primary" @click="addFunc"><plus-outlined />新建</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'bindState'">
|
||||
<template v-if="record.bindState == 0"><exclamation-circle-outlined />未绑定</template>
|
||||
<template v-else>已绑定商户: {{ record.mchNo }} ({{ record.mchName }})<br>应用: {{ record.appId }}<br>门店: {{ record.storeId }} ({{ record.storeName }})</template>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'appName'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
应用ID:{{record.appId}}
|
||||
</template>
|
||||
{{record.appName}}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'storeId'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
门店ID:{{record.storeId}}
|
||||
</template>
|
||||
{{record.storeName}}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'state'">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="$access('ENT_DEVICE_AUTO_POS_EDIT')" :onChange="(state) => { return updateState(record.deviceId, state)}" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'provider'">
|
||||
<a-tag :color="record.provider == 'wxpayQWPro' ? 'green' : 'blue'">
|
||||
{{ record.provider == 'wxpayQWPro' ? '微信青蛙pro':'支付宝蜻蜓' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_DEVICE_FACE_APP_EDIT')" type="link" @click="editFunc(record)">修改</a-button>
|
||||
<a-button
|
||||
v-if="$access('ENT_DEVICE_FACE_APP_EDIT') && (userStore.userInfo['userType'] != '11' && userStore.userInfo['userType'] != '12')"
|
||||
type="link"
|
||||
style="color: red"
|
||||
@click="deBindFunc(record.deviceId)"
|
||||
>
|
||||
解绑
|
||||
</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, req, reqLoad, $unbindDevice } from '@/api/manage'
|
||||
import InfoAddOrEdit from '../CommonAddOrEdit.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
const { $infoBox, $access, $hasAgentEnt } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const userStore = useUserStore()
|
||||
const infoAddOrEdit = ref()
|
||||
const infoTable = ref()
|
||||
|
||||
const deviceType = 6
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ title: '设备号', fixed: 'left', dataIndex: 'deviceNo', },
|
||||
{ key: 'provider', title: '设备厂商', dataIndex: 'provider', },
|
||||
{ title: '设备名称', dataIndex: 'deviceName', },
|
||||
{ key: 'storeId',title: '门店名称', dataIndex: 'storeId',},
|
||||
{ key: 'appId', dataIndex: 'appId', title: '应用名称', },
|
||||
{ key: 'state', title: '状态', },
|
||||
{ dataIndex: 'createdAt', title: '创建日期',},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
const vdata = reactive({
|
||||
allotByBatchIdVisible: false, // 批次划拨设备弹窗
|
||||
searchData: {} as any,
|
||||
allotObject: {
|
||||
agentNo: null, // 划拨代理商号
|
||||
allotType: null, // 划拨类型:select-勾选划拨 batch-批次划拨
|
||||
batchId: null, // 批次号,划拨类型为 batch-批次划拨 时必填
|
||||
allotDeviceIds: [] as any, // 要划拨的设备ID,划拨类型为 select-勾选划拨 时必填
|
||||
} as any, // 划拨设备对象
|
||||
allotDeviceIdList: [] as any, // 要划拨的设备ID,划拨类型为 select-勾选划拨 时必填
|
||||
allotRules: {
|
||||
batchId: [{ required: true, message: '请输入批次号', trigger: 'blur' }]
|
||||
}
|
||||
}) as any
|
||||
|
||||
onMounted(() => {
|
||||
vdata.searchData.mchNo = useRoute().query.mchNo
|
||||
searchFunc()
|
||||
})
|
||||
|
||||
function reqTableDataFunc(params: any) { // 请求table接口数据
|
||||
return req.list(API_URL_STORE_DEVICE, Object.assign({ deviceType: deviceType }, params))
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
btnLoading.value = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show({ deviceType: deviceType })
|
||||
}
|
||||
function editFunc (record: any) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(record)
|
||||
}
|
||||
function onReset(){ //重置搜索内容
|
||||
vdata.searchData = {}
|
||||
}
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
const title = state ? '确认启用?' : '确认禁用?'
|
||||
const content = state ? '' : '禁用后该设备将无法使用!'
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return reqLoad.updateById(API_URL_STORE_DEVICE, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 解绑设备
|
||||
function deBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后商户将无法使用该设备!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindDevice(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
172
jeepay-ui-merchant/src/views/device/plugin/CdKeyList.vue
Normal file
172
jeepay-ui-merchant/src/views/device/plugin/CdKeyList.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchConditionNum="6" :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="vdata.searchData.storeId" :placeholder="'门店ID'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.deviceNo" :placeholder="'激活码'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.deviceName" :placeholder="'激活码名称'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.provider" placeholder="所属厂商">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option v-for="item in pluginList" :key="item.value" :value="item.value">{{ item.text }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="激活状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">待激活</a-select-option>
|
||||
<a-select-option value="1">已激活</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.bindState" placeholder="绑定状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">未绑定</a-select-option>
|
||||
<a-select-option value="1">已绑定</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="addFunc"><plus-outlined />申请新激活码</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'provider'">
|
||||
<a-tag :key="record.provider" color="processing">
|
||||
{{ (pluginList.find(item => item.value == record.provider) as any).text || '其他' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'state'">
|
||||
<a-tag v-if="record.state == 0" color="orange">待激活</a-tag>
|
||||
<a-switch v-else :checked="record.state == 1 ? true : false" @change="(state) => { return updateState(record.deviceId, state)}" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'expiredTime'">
|
||||
{{ JSON.parse(record.deviceParams).expiredTime == 0 ? '长期有效' : dateUtil.formatDate(JSON.parse(record.deviceParams).expiredTime) }}
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'activeTime'">
|
||||
<template v-if="record.deviceParams && JSON.parse(record.deviceParams).activeTime">
|
||||
{{ JSON.parse(record.deviceParams).activeTime }}
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="column.key === 'appName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
应用ID:{{record.appId}}
|
||||
</template>
|
||||
{{record.appName}}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'storeId'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
门店ID:{{record.storeId}}
|
||||
</template>
|
||||
{{record.storeName}}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_DEVICE_PLUGIN_CDKEY_EDIT')" type="link" @click="editFunc(record)">修改</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_DEVICE_PLUGIN_CDKEY_EDIT') && record.bindState == 1" type="link" @click="deBindFunc(record.deviceId)">解绑</a-button> -->
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {$unbindDevice, API_URL_STORE_DEVICE, req, reqLoad} from '@/api/manage'
|
||||
import InfoAddOrEdit from '../CommonAddOrEdit.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import dateUtil from '@/utils/dateUtil.js'
|
||||
import provider from '../provider.json'
|
||||
|
||||
const pluginList = provider.plugin
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoAddOrEdit = ref()
|
||||
const infoTable = ref()
|
||||
const deviceType = 5
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ title: '激活码', fixed: 'left', dataIndex: 'deviceNo', },
|
||||
{ key: 'provider', title: '厂商', dataIndex: 'provider',},
|
||||
{ title: '激活码名称', dataIndex: 'deviceName', },
|
||||
{ key: 'storeId',title: '门店', dataIndex: 'storeId',},
|
||||
{ key: 'appName', dataIndex: 'appName', title: '所属应用', },
|
||||
{ key: 'state', title: '激活状态',},
|
||||
{ key: 'activeTime', title: '激活时间',},
|
||||
{ key: 'expiredTime', title: '有效期止',},
|
||||
{ dataIndex: 'createdAt', title: '创建日期',},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center', }
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
const vdata = reactive({
|
||||
searchData: {} as any
|
||||
}) as any
|
||||
|
||||
function reqTableDataFunc(params: any) { // 请求table接口数据
|
||||
return req.list(API_URL_STORE_DEVICE, Object.assign({ deviceType: deviceType }, params))
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
btnLoading.value = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
$infoBox.message.success('请联系运营平台申请')
|
||||
}
|
||||
function editFunc (record: any) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(record)
|
||||
}
|
||||
function onReset(){ //重置搜索内容
|
||||
vdata.searchData = {}
|
||||
}
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger('确认解除激活?', '解除激活后,该激活码将不可用!', () => {
|
||||
return reqLoad.updateById(API_URL_STORE_DEVICE, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 解绑激活码
|
||||
function deBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后商户将无法使用该激活码!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindDevice(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
205
jeepay-ui-merchant/src/views/device/pos/List.vue
Normal file
205
jeepay-ui-merchant/src/views/device/pos/List.vue
Normal file
@@ -0,0 +1,205 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="searchData['queryDateRange']" customDateRangeType="date" />
|
||||
</a-form-item>
|
||||
<!-- <jeepay-text-up v-model:value="searchData['deviceName']" :placeholder="'应用名称'" />-->
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="searchData['provider']" placeholder="设备厂商">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option v-for="item in posList" :key="item.value" :value="item.value">{{ item.text }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="searchData['deviceName']" :placeholder="'设备名称/编号'" />
|
||||
<jeepay-text-up v-model:value="searchData['storeId']" :placeholder="'门店名称/编号'" />
|
||||
<jeepay-text-up v-model:value="searchData['mchApplyName']" :placeholder="'商户名称/商户号'" />
|
||||
<jeepay-text-up v-model:value="searchData['ifName']" :placeholder="'支付通道'" />
|
||||
<jeepay-text-up v-model:value="searchData['isvNo']" :placeholder="'渠道名称/渠道号'" />
|
||||
<!-- <jeepay-text-up v-model:value="searchData['deviceNo']" :placeholder="'设备号'" />-->
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="searchData['state']" placeholder="使用状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">禁用</a-select-option>
|
||||
<a-select-option value="1">启用</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="" class="table-search-item">-->
|
||||
<!-- <a-select v-model:value="searchData['bindState']" placeholder="绑定状态">-->
|
||||
<!-- <a-select-option value="">全部</a-select-option>-->
|
||||
<!-- <a-select-option value="0">未绑定</a-select-option>-->
|
||||
<!-- <a-select-option value="1">已绑定</a-select-option>-->
|
||||
<!-- </a-select>-->
|
||||
<!-- </a-form-item>-->
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="searchData"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button v-if="$access('ENT_DEVICE_POS_ADD')" type="primary" @click="addFunc"><plus-outlined />绑定设备</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_POS_SHOP')" type="primary" @click="showShop()"> <PlusOutlined /> 设备商城</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'bindState'">
|
||||
<a-badge v-if="record.bindState == 0" status="default" text="未绑定" />
|
||||
<a-badge v-if="record.bindState == 1" status="success" text="已绑定" />
|
||||
</template>
|
||||
<template v-if="column.key === 'bindAppIdName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>应用名称:{{record.bindAppIdName}}</span><br>
|
||||
<span>应用ID:{{record.appId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.bindAppIdName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchApplyName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>商户名称:{{record.mchApplyName}}</span><br>
|
||||
<span>商户号:{{record.mchApplyId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchApplyName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'isvNo'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>渠道名称:{{record.isvName}}</span><br>
|
||||
<span>渠道号:{{record.isvNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.isvName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'storeId'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>门店名称:{{record.storeName}}</span><br>
|
||||
<span>门店编号:{{record.storeId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.storeName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'state'">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="$access('ENT_DEVICE_POS_EDIT')" :onChange="(state) => { return updateState(record.deviceId, state)}" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'provider'">
|
||||
<a-tag :key="record.provider" color="processing">
|
||||
{{ (posList.find(item => item.value == record.provider) as any).text || '其他' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_DEVICE_POS_EDIT')" type="link" @click="editFunc(record)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_POS_DEL') && (userStore.userInfo['userType'] != '11' && userStore.userInfo['userType'] != '12')" type="link" style="color: red" @click="deBindFunc(record.deviceId)">解绑</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<!-- 测试设备组件 -->
|
||||
<TestDevice ref="testDevice" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, req, reqLoad, $unbindDevice } from '@/api/manage'
|
||||
import InfoAddOrEdit from '../CommonAddOrEdit.vue'
|
||||
import TestDevice from '../TestDevice.vue'
|
||||
import { ref, reactive, getCurrentInstance } from 'vue'
|
||||
import provider from '../provider.json'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
const posList = provider.pos
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const userStore = useUserStore()
|
||||
const infoAddOrEdit = ref()
|
||||
const testDevice = ref()
|
||||
const infoTable = ref()
|
||||
const deviceType = ref(3)
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ key: 'provider', title: '设备厂家', },
|
||||
{ title: '设备号', dataIndex: 'deviceNo' },
|
||||
{ title: '设备名称', dataIndex: 'deviceName', },
|
||||
{ title: "商户名称", key: "mchApplyName", dataIndex: "mchApplyName" },
|
||||
{ key: 'storeId',title: '门店名称', dataIndex: 'storeId',},
|
||||
{ key: "ifName", title: "支付通道", dataIndex: "ifName" },
|
||||
{ key: "isvNo", title: "所属渠道", dataIndex: "isvNo" },
|
||||
// { key: 'bindAppIdName', dataIndex: 'bindAppIdName', title: '所属应用', },
|
||||
// { key: 'appName', dataIndex: 'appName', title: '所属应用', },
|
||||
// { key: 'bindState', title: '绑定状态',},
|
||||
{ key: 'state', title: '使用状态',},
|
||||
{ dataIndex: 'createdAt', title: '创建日期',},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let searchData = ref({})
|
||||
|
||||
function reqTableDataFunc(params: any) { // 请求table接口数据
|
||||
return req.list(API_URL_STORE_DEVICE, Object.assign({ deviceType: deviceType.value }, params))
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
btnLoading.value = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show({ deviceType: deviceType.value })
|
||||
}
|
||||
function editFunc (record: any) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(record)
|
||||
}
|
||||
function onReset(){ //重置搜索内容
|
||||
searchData.value = {}
|
||||
}
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
const title = state ? '确认启用?' : '确认禁用?'
|
||||
const content = state ? '' : '禁用后该设备将无法使用!'
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return reqLoad.updateById(API_URL_STORE_DEVICE, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 解绑设备
|
||||
function deBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后将无法使用该设备!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindDevice(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
function showShop(){
|
||||
$infoBox.message.error('暂未开通')
|
||||
}
|
||||
</script>
|
||||
239
jeepay-ui-merchant/src/views/device/printer/List.vue
Normal file
239
jeepay-ui-merchant/src/views/device/printer/List.vue
Normal file
@@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="searchData['queryDateRange']" customDateRangeType="date" />
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="searchData['provider']" placeholder="设备厂商">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option v-for="item in printerList" :key="item.value" :value="item.value">{{ item.text }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="searchData['deviceName']" :placeholder="'设备名称/编号'" />
|
||||
<jeepay-text-up v-model:value="searchData['storeId']" :placeholder="'门店名称/编号'" />
|
||||
<jeepay-text-up v-model:value="searchData['mchApplyName']" :placeholder="'商户名称/商户号'" />
|
||||
<jeepay-text-up v-model:value="searchData['ifName']" :placeholder="'支付通道'" />
|
||||
<jeepay-text-up v-model:value="searchData['isvNo']" :placeholder="'渠道名称/渠道号'" />
|
||||
<!-- <jeepay-text-up v-model:value="vdata.searchData.deviceNo" :placeholder="'设备号'" />-->
|
||||
<!-- <jeepay-text-up v-model:value="searchData['deviceName']" :placeholder="'应用名称'" />-->
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="searchData['state']" placeholder="使用状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">禁用</a-select-option>
|
||||
<a-select-option value="1">启用</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="searchData['printMode']" placeholder="打印机模式">
|
||||
<a-select-option value="1">仅打印</a-select-option>
|
||||
<a-select-option value="2">仅播报</a-select-option>
|
||||
<a-select-option value="3">打印并播报</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="" class="table-search-item">-->
|
||||
<!-- <a-select v-model:value="searchData['bindState']" placeholder="绑定状态">-->
|
||||
<!-- <a-select-option value="">全部</a-select-option>-->
|
||||
<!-- <a-select-option value="0">未绑定</a-select-option>-->
|
||||
<!-- <a-select-option value="1">已绑定</a-select-option>-->
|
||||
<!-- </a-select>-->
|
||||
<!-- </a-form-item>-->
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="searchData"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button v-if="$access('ENT_DEVICE_PRINTER_ADD')" type="primary" @click="addFunc"><plus-outlined />绑定设备</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_PRINTER_ADD')" type="primary" @click="showShop()"> <PlusOutlined /> 设备商城</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'bindState'">
|
||||
<a-badge v-if="record.bindState == 0" status="default" text="未绑定" />
|
||||
<a-badge v-if="record.bindState == 1" status="success" text="已绑定" />
|
||||
</template>
|
||||
<template v-if="column.key === 'jsonBizConfigParams'">
|
||||
<a-tag v-if="record.jsonBizConfigParams.printMode == 1" color="blue">仅打印</a-tag>
|
||||
<a-tag v-else-if="record.jsonBizConfigParams.printMode == 2" color="orange">仅播报</a-tag>
|
||||
<a-tag v-else-if="record.jsonBizConfigParams.printMode == 3" color="green">打印并播报</a-tag>
|
||||
<a-tag v-else>未知</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'bizConfigParams'">
|
||||
{{record.jsonBizConfigParams.printNum}}
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'state'">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="$access('ENT_DEVICE_PRINTER_EDIT')" :onChange="(state) => { return updateState(record.deviceId, state)}" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'provider'">
|
||||
<a-tag :key="record.provider" color="processing">
|
||||
{{ (printerList.find(item => item.value == record.provider) as any).text || '其他' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'isvNo'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>渠道名称:{{record.isvName}}</span><br>
|
||||
<span>渠道号:{{record.isvNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.isvName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'bindAppIdName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>应用名称:{{record.bindAppIdName}}</span><br>
|
||||
<span>应用ID:{{record.appId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.bindAppIdName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchApplyName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>商户名称:{{record.mchApplyName}}</span><br>
|
||||
<span>商户号:{{record.mchApplyId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchApplyName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'storeId'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>门店名称:{{record.storeName}}</span><br>
|
||||
<span>门店编号:{{record.storeId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.storeName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_DEVICE_PRINTER_EDIT')" type="link" @click="editFunc(record)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_PRINTER_TEST')" type="link" @click="print(record.deviceId)">打印测试</a-button>
|
||||
<a-button v-if="record.provider === 'fe' && $access('ENT_DEVICE_PRINTER_CLEAR')" type="link" @click="clear(record.deviceId)">清空打印队列</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_PRINTER_EDIT') && (userStore.userInfo['userType'] != '11' && userStore.userInfo['userType'] != '12')" type="link" style="color: red" @click="deBindFunc(record.deviceId)">解绑</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<!-- 测试设备组件 -->
|
||||
<TestDevice ref="testDevice" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {API_URL_STORE_DEVICE, req, reqLoad, $clearPrint, $unbindDevice} from '@/api/manage'
|
||||
import InfoAddOrEdit from '../CommonAddOrEdit.vue'
|
||||
import TestDevice from '../TestDevice.vue'
|
||||
import { ref, reactive, getCurrentInstance } from 'vue'
|
||||
import provider from '../provider.json'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
const printerList = provider.printer
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const userStore = useUserStore()
|
||||
const infoAddOrEdit = ref()
|
||||
const testDevice = ref()
|
||||
const infoTable = ref()
|
||||
const deviceType = ref(2)
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ key: 'provider', title: '设备厂商', },
|
||||
{ title: '设备号', fixed: 'left', dataIndex: 'deviceNo' },
|
||||
{ title: '设备名称', dataIndex: 'deviceName', },
|
||||
{ key: "ifName", title: "支付通道", dataIndex: "ifName" },
|
||||
{ key: "isvNo", title: "所属渠道", dataIndex: "isvNo" },
|
||||
{ title: "商户名称", key: "mchApplyName", dataIndex: "mchApplyName" },
|
||||
{ key: 'storeId',title: '门店名称', dataIndex: 'storeId',},
|
||||
// { key: 'bindAppIdName', dataIndex: 'bindAppIdName', title: '所属应用', },
|
||||
// { key: 'bindState', title: '绑定状态', },
|
||||
{ key: 'state', title: '使用状态',},
|
||||
{ key: 'jsonBizConfigParams', title: '打印机模式',},
|
||||
{ key: 'bizConfigParams', title: '打印联数',},
|
||||
{ dataIndex: 'createdAt', title: '创建日期',},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let searchData = ref({})
|
||||
|
||||
function reqTableDataFunc(params: any) { // 请求table接口数据
|
||||
return req.list(API_URL_STORE_DEVICE, Object.assign({ deviceType: deviceType.value }, params))
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
btnLoading.value = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show({ deviceType: deviceType.value })
|
||||
}
|
||||
function editFunc (record: any) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(record)
|
||||
}
|
||||
function showShop(){
|
||||
$infoBox.message.error('暂未开通')
|
||||
}
|
||||
function onReset(){ //重置搜索内容
|
||||
searchData.value = {}
|
||||
}
|
||||
function print(recordId){ //重置搜索内容
|
||||
testDevice.value.show(recordId, 2)
|
||||
}
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
const title = state ? '确认启用?' : '确认禁用?'
|
||||
const content = state ? '' : '禁用后该设备将无法使用!'
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return reqLoad.updateById(API_URL_STORE_DEVICE, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
function clear (recordId) { // 【更新状态】
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger('', '', () => {
|
||||
return $clearPrint(recordId).then(res => {
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 解绑设备
|
||||
function deBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后将无法使用该设备!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindDevice(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
1
jeepay-ui-merchant/src/views/device/provider.json
Normal file
1
jeepay-ui-merchant/src/views/device/provider.json
Normal file
@@ -0,0 +1 @@
|
||||
{"all":[{"text":"智谷联","value":"zgwl"},{"text":"品生","value":"ps"},{"text":"博实结","value":"bsj"},{"text":"飞鹅","value":"fe"},{"text":"财来聚","value":"clj"},{"text":"微收银","value":"wsy"},{"text":"小精灵","value":"xjl"},{"text":"智网","value":"zw"},{"text":"零零智能","value":"llzn"}],"speaker":[{"text":"智谷联","value":"zgwl"},{"text":"品生","value":"ps"},{"text":"博实结","value":"bsj"},{"text":"智网","value":"zw"},{"text":"拉卡拉","value":"lkls"}],"printer":[{"text":"智谷联","value":"zgwl"},{"text":"飞鹅","value":"fe"},{"text":"博实结","value":"bsj"},{"text":"智网","value":"zw"}],"pos":[{"text":"智谷联","value":"zgwl"},{"text":"品生","value":"ps"},{"text":"博实结","value":"bsj"},{"text":"零零智能","value":"llzn"}],"plugin":[{"text":"财来聚","value":"clj"},{"text":"微收银","value":"wsy"},{"text":"小精灵","value":"xjl"}]}
|
||||
53
jeepay-ui-merchant/src/views/device/provider/BsjConfig.vue
Normal file
53
jeepay-ui-merchant/src/views/device/provider/BsjConfig.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<a-form v-if="vdata.currentConfig" ref="formRef" :model="vdata.currentConfig" layout="vertical" :rules="vdata.formRules">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">设备参数配置</a-tag>
|
||||
</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="11">
|
||||
<a-form-item label="设备编号" name="deviceNo">
|
||||
<a-input v-model:value="vdata.currentConfig.deviceNo" placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {reactive, ref, defineExpose} from 'vue'
|
||||
|
||||
// 当前的form
|
||||
const formRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
// 配置对象
|
||||
currentConfig: {} as any,
|
||||
// 表单规则
|
||||
formRules: {
|
||||
deviceNo: [{ required: true, message: '请输入设备编号', trigger: 'blur' }]
|
||||
}
|
||||
})
|
||||
|
||||
// 对外提供的页面的渲染函数 ( ifDefineArray = 接口的配置定义项数组, currentConfig = 当前配置项 )
|
||||
function pageRender(currentConfig: any){
|
||||
|
||||
if (currentConfig) {
|
||||
vdata.currentConfig = currentConfig
|
||||
}
|
||||
|
||||
// 重置form验证
|
||||
if (formRef.value !== undefined && formRef.value !== null) {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
}
|
||||
|
||||
// 对外提供的获取配置参数函数 (返回JSON类型)
|
||||
function getConfigParams(){
|
||||
return formRef.value.validate().then( () => {
|
||||
return vdata.currentConfig
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ getConfigParams, pageRender })
|
||||
|
||||
</script>
|
||||
60
jeepay-ui-merchant/src/views/device/provider/FeConfig.vue
Normal file
60
jeepay-ui-merchant/src/views/device/provider/FeConfig.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<a-form v-if="vdata.currentConfig" ref="formRef" :model="vdata.currentConfig" layout="vertical" :rules="vdata.formRules">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">设备参数配置</a-tag>
|
||||
</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="11">
|
||||
<a-form-item label="设备号" name="deviceNo">
|
||||
<a-input v-model:value="vdata.currentConfig.deviceNo" placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<a-form-item label="设备Key" name="deviceKey">
|
||||
<a-input v-model:value="vdata.currentConfig.deviceKey" placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {reactive, ref, defineExpose} from 'vue'
|
||||
|
||||
// 当前的form
|
||||
const formRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
// 配置对象
|
||||
currentConfig: {} as any,
|
||||
// 表单规则
|
||||
formRules: {
|
||||
deviceNo: [{ required: true, message: '请输入设备号', trigger: 'blur' }],
|
||||
deviceKey: [{ required: true, message: '请输入设备Key', trigger: 'blur' }]
|
||||
}
|
||||
})
|
||||
|
||||
// 对外提供的页面的渲染函数 ( currentConfig = 当前配置项 )
|
||||
function pageRender(currentConfig: any){
|
||||
|
||||
// 赋值
|
||||
if (currentConfig) {
|
||||
vdata.currentConfig = currentConfig
|
||||
}
|
||||
|
||||
// 重置form验证
|
||||
if (formRef.value !== undefined && formRef.value !== null) {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
}
|
||||
|
||||
// 对外提供的获取配置参数函数 (返回JSON类型)
|
||||
function getConfigParams(){
|
||||
return formRef.value.validate().then( () => {
|
||||
return vdata.currentConfig
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ getConfigParams, pageRender })
|
||||
|
||||
</script>
|
||||
65
jeepay-ui-merchant/src/views/device/provider/ZgwlConfig.vue
Normal file
65
jeepay-ui-merchant/src/views/device/provider/ZgwlConfig.vue
Normal file
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<a-form v-if="vdata.currentConfig" ref="formRef" :model="vdata.currentConfig" layout="vertical" :rules="vdata.formRules">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">设备参数配置</a-tag>
|
||||
</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="11">
|
||||
<a-form-item label="设备编号" name="deviceNo">
|
||||
<a-input v-model:value="vdata.currentConfig.deviceNo" placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.deviceType == 2" :span="11">
|
||||
<a-form-item label="打印机模式" name="printMode">
|
||||
<a-radio-group v-model:value="vdata.currentConfig.printMode">
|
||||
<a-radio :value="1">仅打印</a-radio>
|
||||
<a-radio :value="2">仅播报</a-radio>
|
||||
<a-radio :value="3">打印并播报</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {reactive, ref, defineExpose} from 'vue'
|
||||
|
||||
// 当前的form
|
||||
const formRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
// 配置对象
|
||||
currentConfig: {} as any,
|
||||
deviceType: null, // 设备类型: 1-云喇叭, 2-云打印
|
||||
// 表单规则
|
||||
formRules: {
|
||||
deviceNo: [{ required: true, message: '请输入设备编号', trigger: 'blur' }],
|
||||
printMode: [{ required: true, type: 'number', message: '请选择打印机模式', trigger: 'blur' }]
|
||||
}
|
||||
})
|
||||
|
||||
// 对外提供的页面的渲染函数 ( ifDefineArray = 接口的配置定义项数组, currentConfig = 当前配置项 )
|
||||
function pageRender(currentConfig: any, deviceType: any){
|
||||
|
||||
vdata.deviceType = deviceType
|
||||
if (currentConfig) {
|
||||
vdata.currentConfig = currentConfig
|
||||
}
|
||||
|
||||
// 重置form验证
|
||||
if (formRef.value !== undefined && formRef.value !== null) {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
}
|
||||
|
||||
// 对外提供的获取配置参数函数 (返回JSON类型)
|
||||
function getConfigParams(){
|
||||
return formRef.value.validate().then( () => {
|
||||
return vdata.currentConfig
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ getConfigParams, pageRender })
|
||||
|
||||
</script>
|
||||
182
jeepay-ui-merchant/src/views/device/ruyi/RuyiList.vue
Normal file
182
jeepay-ui-merchant/src/views/device/ruyi/RuyiList.vue
Normal file
@@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="vdata.searchData.storeId" :placeholder="'门店ID'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.deviceNo" :placeholder="'设备号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.alipayShopId" :placeholder="'蚂蚁店铺ID'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">禁用</a-select-option>
|
||||
<a-select-option value="1">启用</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button v-if="$access('ENT_DEVICE_RUYI_ADD')" type="primary" @click="addFunc"><plus-outlined />新建</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'state'">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="$access('ENT_DEVICE_RUYI_EDIT')" :onChange="(state) => { return updateState(record.deviceId, state)}" />
|
||||
</template>
|
||||
<template v-if="column.key === 'alipayBindState'">
|
||||
<a-tag v-if="record.alipayBindState==1" color="green">已绑定</a-tag>
|
||||
<a-span v-if="record.alipayBindState==1 && record.alipayShopId">蚂蚁店铺ID:{{ record.alipayShopId }}</a-span>
|
||||
<a-tag v-else-if="record.alipayBindState==0" color="red">未绑定</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_DEVICE_RUYI_EDIT')" type="link" @click="editFunc(record)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_RUYI_BIND')" type="link" @click="alipayIotBindShowFunc(record)">绑定蚂蚁店铺</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_RUYI_BIND') && record.alipayBindState == 1" type="link" style="color: red" @click="alipayIotUnBindFunc(record.deviceId)">解绑蚂蚁店铺</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_RUYI_EDIT') && (userStore.userInfo['userType'] != '11' && userStore.userInfo['userType'] != '12')" type="link" style="color: red" @click="deBindFunc(record.deviceId)">删除</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
|
||||
<!-- 绑定蚂蚁店铺弹窗 -->
|
||||
<a-modal :visible="vdata.alipayIotBindShow" title="绑定/解绑蚂蚁店铺" @ok="alipayIotBindFunc(vdata.alipayIotBindObject.deviceId, 1)" @cancel="() => vdata.alipayIotBindShow = false">
|
||||
<a-form ref="alipayIotBindModel" :model="vdata.alipayIotBindObject" layout="vertical">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="选择门店" name="storeId">
|
||||
<a-select v-model:value="vdata.alipayIotBindObject.storeId" placeholder="请选择门店">
|
||||
<a-select-option v-for="(d, index) in vdata.storeList" :key="index" v-model:value="d.storeId">
|
||||
{{ d.storeName }} 【蚂蚁店铺ID:{{ d.alipayShopId }} 】
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, API_URL_MCH_STORE_LIST, API_ALIPAY_IOT, req, reqLoad, $unbindDevice } from '@/api/manage'
|
||||
import InfoAddOrEdit from '../CommonAddOrEdit.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoAddOrEdit = ref()
|
||||
const infoTable = ref()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const deviceType = 7
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ title: '设备号', fixed: 'left', dataIndex: 'deviceNo' },
|
||||
{ title: '门店编号', dataIndex: 'storeId' },
|
||||
{ key: 'appId', dataIndex: 'appId', title: '应用ID' },
|
||||
{ key: 'state', title: '状态' },
|
||||
{ key: 'alipayBindState', title: '蚂蚁店铺绑定状态' },
|
||||
{ dataIndex: 'createdAt', title: '创建日期'},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
const vdata = reactive({
|
||||
searchData: {} as any,
|
||||
|
||||
alipayIotBindShow: false,
|
||||
alipayIotBindObject: {} as any,
|
||||
storeList: {} as any,
|
||||
}) as any
|
||||
|
||||
onMounted(() => {
|
||||
vdata.searchData.mchNo = useRoute().query.mchNo
|
||||
searchFunc()
|
||||
})
|
||||
|
||||
function reqTableDataFunc(params: any) { // 请求table接口数据
|
||||
return req.list(API_URL_STORE_DEVICE, Object.assign({ deviceType: deviceType }, params))
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
btnLoading.value = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show({ deviceType: deviceType })
|
||||
}
|
||||
function editFunc (record: any) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(record)
|
||||
}
|
||||
function alipayIotBindShowFunc (record: any) { // 蚂蚁店铺绑定管理
|
||||
req.list(API_URL_MCH_STORE_LIST, { 'pageSize': -1, 'alipayShopStatus': '99' }).then(res => { // 门店下拉选择列表
|
||||
vdata.storeList = res.records || []
|
||||
if (vdata.storeList.length > 0 && vdata.storeList.some(i => i.storeId == record.storeId)) {
|
||||
vdata.alipayIotBindObject.storeId = record.storeId
|
||||
}
|
||||
})
|
||||
vdata.alipayIotBindObject.deviceId = record.deviceId
|
||||
vdata.alipayIotBindObject.alipayBindState = record.alipayBindState
|
||||
|
||||
vdata.alipayIotBindShow = true
|
||||
}
|
||||
function alipayIotBindFunc(recordId, alipayBindState) { // 绑定蚂蚁店铺设备
|
||||
vdata.alipayIotBindObject.alipayBindState = alipayBindState
|
||||
reqLoad.add(API_ALIPAY_IOT + '/bind/' + recordId, vdata.alipayIotBindObject).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('操作成功')
|
||||
vdata.alipayIotBindShow = false
|
||||
}).catch(err =>console.log(err))
|
||||
}
|
||||
function alipayIotUnBindFunc(recordId) { // 解绑蚂蚁店铺设备
|
||||
$infoBox.confirmDanger('解绑蚂蚁店铺', '确定解绑蚂蚁店铺吗?', () => {
|
||||
return alipayIotBindFunc(recordId, 0)
|
||||
})
|
||||
}
|
||||
function onReset(){ //重置搜索内容
|
||||
vdata.searchData = {}
|
||||
}
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
const title = state ? '确认启用?' : '确认禁用?'
|
||||
const content = state ? '' : '禁用后该设备将无法使用!'
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return reqLoad.updateById(API_URL_STORE_DEVICE, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 解绑设备
|
||||
function deBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后商户将无法使用该设备!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindDevice(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
276
jeepay-ui-merchant/src/views/device/speaker/AddOrEdit.vue
Normal file
276
jeepay-ui-merchant/src/views/device/speaker/AddOrEdit.vue
Normal file
@@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.drawerVisible"
|
||||
:mask-closable="false"
|
||||
:title=" vdata.isAdd ? '新增设备' : '修改设备' "
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="50%"
|
||||
class="drawer-width"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form v-if="vdata.drawerVisible" ref="infoFormModel" :model="vdata.saveObject" :rules="vdata.rules" layout="vertical">
|
||||
<a-row v-if="vdata.isAdd" justify="space-between" type="flex">
|
||||
<a-col :span="11">
|
||||
<a-form-item label="设备号" name="deviceNo">
|
||||
<a-input v-model:value="vdata.saveObject.deviceNo" placeholder="请输入设备号" />
|
||||
<div v-if="vdata.checkMsg" :style="vdata.checkCode == 1 ? {'color' : 'green'} : {'color' : 'red'}">{{ vdata.checkMsg }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<a-form-item label="查看绑定状态">
|
||||
<a-button type="primary" @click="checkFunc">查询设备是否允许绑定</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col v-if="vdata.providerConfigList.length > 0 && vdata.checkCode == 2" :span="11">
|
||||
<a-form-item label="选择厂商" name="provider">
|
||||
<a-select v-model:value="vdata.saveObject.provider" :disabled="!vdata.isAdd" placeholder="请选择厂商">
|
||||
<a-select-option v-for="d in vdata.providerConfigList" :key="d.provider" v-model:value="d.provider">
|
||||
【{{ (allList.find(item => item.value == d.provider) as any).text || '其他' }}】{{ d.configDesc }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="24">
|
||||
<a-form-item label="设备名称" name="deviceName">
|
||||
<a-input v-model:value="vdata.saveObject.deviceName" placeholder="请输入设备名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="24">
|
||||
<a-form-item label="选择门店" name="storeId">
|
||||
<a-select v-model:value="vdata.saveObject.storeId" placeholder="请选择门店" @change="onChangeStoreId" show-search @search="handleBankChange">
|
||||
<a-select-option v-for="d in vdata.filteredStoreInfoList" :key="d.storeId" v-model:value="d.storeId">
|
||||
{{ d.storeName }} - {{ d.storeId }} - {{ d.ifName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<a-form-item label="固定金额" name="fixedFlag">
|
||||
<a-radio-group v-model:value="vdata.saveObject.fixedFlag">
|
||||
<a-radio :value="0">任意金额</a-radio>
|
||||
<a-radio :value="1">固定金额</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="vdata.saveObject.fixedFlag" label="" name="fixedPayAmount">
|
||||
<a-input-number v-model:value="vdata.saveObject.fixedPayAmount" :precision="2" style="width: 130px" placeholder="请输入金额"/> 元
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<a-form-item label="状态" name="qrcState">
|
||||
<a-radio-group v-model:value="vdata.saveObject.state">
|
||||
<a-radio :value="1">启用</a-radio>
|
||||
<a-radio :value="0">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="11">
|
||||
<a-form-item label="关联播报" name="bindType">
|
||||
<a-radio-group v-model:value="vdata.saveObject.bindType">
|
||||
<a-radio :value="0">门店所有码牌</a-radio>
|
||||
<a-radio :value="1">指定码牌</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row v-if="vdata.saveObject.bindType == 1" justify="space-between" type="flex">
|
||||
<a-col v-if="vdata.saveObject.qrcIdList && vdata.saveObject.qrcIdList.length > 0" :span="24">
|
||||
<a-form-item label="播报码牌ID">
|
||||
<a-textarea v-model:value="vdata.saveObject.qrcIdList" disabled />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-item>
|
||||
<a-button type="primary" @click="showQrcSelectModel">{{ vdata.isAdd ? '选择绑定码牌' : '重新绑定码牌' }}</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" style="margin-right:8px" @click="onClose"><close-outlined />取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="handleOkFunc"><check-outlined />保存</a-button>
|
||||
</div>
|
||||
|
||||
<!-- 选择码牌组件 -->
|
||||
<JeepayModelQrcList ref="jeepayModelQrcListRef" @selectFinishFunc="selectQrcFinishFunc" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_STORE_DEVICE, API_URL_MCH_STORE_LIST, req, $checkDevice } from '@/api/manage'
|
||||
import { defineProps, reactive, ref, getCurrentInstance } from 'vue'
|
||||
import provider from '../provider.json'
|
||||
|
||||
const allList = provider.all
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const jeepayModelQrcListRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
providerConfigList: [] as any, // 厂商列表
|
||||
storeList: [] as any, // 门店列表
|
||||
filteredStoreInfoList:[] as any,
|
||||
btnLoading: false,
|
||||
isAdd: true, // 新增 or 修改页面标志
|
||||
deviceType: 1, // 1-云喇叭 2-云打印 3-扫码POS
|
||||
saveObject: {} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
drawerVisible: false, // 是否显示弹层/抽屉
|
||||
rules: {
|
||||
provider: [{ required: true, message: '请选择厂商', trigger: 'blur' }],
|
||||
storeId: [{ required: true, message: '请选择门店', trigger: 'string' }],
|
||||
deviceName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
|
||||
deviceNo: [{ required: true, message: '请输入设备号', trigger: 'blur' }],
|
||||
bindType: [{ required: true, message: '请选择关联播报', trigger: 'blur' }],
|
||||
appId: [{
|
||||
required: false,
|
||||
trigger: 'blur'
|
||||
}, {
|
||||
validator: async (rule, value) => {
|
||||
if (vdata.deviceType == 3 && !value) {
|
||||
return Promise.reject('请选择应用')
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}) as any
|
||||
|
||||
|
||||
function show (record: any) { // 弹层打开事件
|
||||
|
||||
vdata.isAdd = !record.deviceId
|
||||
vdata.deviceType = record.deviceType // 设备类型deviceType: 1-云喇叭, 2-云打印
|
||||
vdata.provider = record.provider
|
||||
|
||||
vdata.saveObject = { 'state': 1, 'deviceType': record.deviceType }
|
||||
|
||||
vdata.providerConfigList = []
|
||||
vdata.checkMsg = ''
|
||||
|
||||
if (infoFormModel.value != undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
req.list(API_URL_MCH_STORE_LIST, { 'pageSize': -1 }).then(res => { // 门店下拉选择列表
|
||||
vdata.storeList = res.records
|
||||
vdata.filteredStoreInfoList = res.records
|
||||
})
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.recordId = record.deviceId
|
||||
|
||||
req.getById(API_URL_STORE_DEVICE, vdata.recordId).then((res: any) => {
|
||||
if(res){
|
||||
res.fixedPayAmount = ( res.fixedPayAmount / 100).toFixed(2)
|
||||
vdata.saveObject = res
|
||||
vdata.drawerVisible = true
|
||||
}
|
||||
})
|
||||
} else {
|
||||
vdata.drawerVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then((valid: any) =>{
|
||||
addOrEdit()
|
||||
})
|
||||
}
|
||||
|
||||
function addOrEdit() {
|
||||
vdata.btnLoading = true
|
||||
// 请求接口
|
||||
vdata.saveObject.fixedPayAmount = vdata.saveObject.fixedPayAmount*100
|
||||
if (vdata.isAdd) {
|
||||
req.add(API_URL_STORE_DEVICE, vdata.saveObject).then((res: any) => {
|
||||
successFunc('保存成功')
|
||||
}).catch((err: any) => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
} else {
|
||||
req.updateById(API_URL_STORE_DEVICE, vdata.recordId, vdata.saveObject).then((res: any) => {
|
||||
successFunc('修改成功')
|
||||
}).catch((err: any) => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function successFunc(e: string) { // 新增/更新成功
|
||||
vdata.btnLoading = false
|
||||
$infoBox.message.success(e)
|
||||
props.callbackFunc()
|
||||
vdata.drawerVisible = false
|
||||
}
|
||||
|
||||
function checkFunc() {
|
||||
vdata.checkMsg = ''
|
||||
|
||||
$checkDevice(vdata.saveObject.deviceNo, vdata.saveObject.deviceType).then(res => {
|
||||
vdata.checkCode = res.checkCode
|
||||
vdata.checkMsg = res.checkMsg
|
||||
|
||||
if (vdata.checkCode == 2) {
|
||||
vdata.providerConfigList = res.deviceList
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function showQrcSelectModel() {
|
||||
if (vdata.saveObject.storeId && vdata.saveObject.bindType == 1) {
|
||||
jeepayModelQrcListRef.value.show(vdata.saveObject.storeId, vdata.saveObject.qrcIdList)
|
||||
}else{
|
||||
message.error("请先选择门店")
|
||||
}
|
||||
}
|
||||
|
||||
function onChangeStoreId(e) {
|
||||
console.log(e,'onChangeStoreId')
|
||||
vdata.saveObject.storeId = e
|
||||
console.log(vdata.saveObject.storeId,'vdata.saveObject.storeId')
|
||||
vdata.saveObject.qrcIdList = []
|
||||
}
|
||||
|
||||
function selectQrcFinishFunc (e) { // 码牌选择完成事件
|
||||
|
||||
if (!e || e.length <= 0) {
|
||||
return $infoBox.message.error('请开启要绑定的码牌!')
|
||||
}
|
||||
|
||||
vdata.saveObject.qrcIdList = e
|
||||
jeepayModelQrcListRef.value.close()
|
||||
}
|
||||
|
||||
function onClose () { // 关闭抽屉
|
||||
vdata.drawerVisible = false
|
||||
}
|
||||
|
||||
|
||||
//门店搜索
|
||||
const handleBankChange = (value) => {
|
||||
vdata.filteredStoreInfoList = [];
|
||||
console.log(value,'valuevaluevalue')
|
||||
vdata.storeList.forEach((item: { storeName: string | any[], storeId: any[] },index) => {
|
||||
if (item.storeName.includes(value) || item.storeId.toString().includes(value) ) {
|
||||
vdata.filteredStoreInfoList.push(vdata.storeList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
278
jeepay-ui-merchant/src/views/device/speaker/List.vue
Normal file
278
jeepay-ui-merchant/src/views/device/speaker/List.vue
Normal file
@@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="searchData['queryDateRange']" customDateRangeType="date" />
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="searchData['provider']" placeholder="设备厂商">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option v-for="item in speakerList" :key="item.value" :value="item.value">{{ item.text }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="searchData['state']" placeholder="页面类型">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">H5</a-select-option>
|
||||
<a-select-option value="1">小程序</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="searchData['deviceName']" :placeholder="'设备名称/设备号'" />
|
||||
<jeepay-text-up v-model:value="searchData['bindQrcName']" placeholder="二维码名称/编号" />
|
||||
<jeepay-text-up v-model:value="searchData['mchApplyName']" :placeholder="'商户名称/商户号'" />
|
||||
<jeepay-text-up v-model:value="searchData['storeId']" :placeholder="'门店名称/编号'" />
|
||||
<jeepay-text-up v-model:value="searchData['ifName']" :placeholder="'支付通道'" />
|
||||
<jeepay-text-up v-model:value="searchData['isvNo']" :placeholder="'渠道名称/渠道号'" />
|
||||
<!-- <a-form-item label="" class="table-search-item">-->
|
||||
<!-- <a-select v-model:value="searchData['state']" placeholder="绑定状态">-->
|
||||
<!-- <a-select-option value="">全部</a-select-option>-->
|
||||
<!-- <a-select-option value="0">未绑定</a-select-option>-->
|
||||
<!-- <a-select-option value="1">已绑定</a-select-option>-->
|
||||
<!-- </a-select>-->
|
||||
<!-- </a-form-item>-->
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="searchData['state']" placeholder="使用状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">禁用</a-select-option>
|
||||
<a-select-option value="1">启用</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<!-- <jeepay-text-up v-model:value="searchData['deviceId']" :placeholder="'设备ID'" />-->
|
||||
<!-- <jeepay-text-up v-model:value="searchData['deviceNo']" :placeholder="'设备号'" />-->
|
||||
<!-- <jeepay-text-up v-model:value="searchData['deviceName']" :placeholder="'应用名称'" />-->
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="searchData"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_ADD')" type="primary" @click="addFunc"><plus-outlined />绑定设备</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_SHOP')" type="primary" @click="showShop()"> <PlusOutlined /> 设备商城</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'bindType'">
|
||||
<a-tag v-if="record.bindType == 0" color="green">门店</a-tag>
|
||||
<a-tag v-if="record.bindType == 1" color="purple">码牌</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'bindQrcId'">
|
||||
<!-- <a-tooltip class="my-tooltip">-->
|
||||
<!-- <template #title>-->
|
||||
<!-- 码牌ID:{{record.bindQrcId}}-->
|
||||
<!-- </template>-->
|
||||
<!-- </a-tooltip>-->
|
||||
{{record.bindQrcId}}
|
||||
<QrcodeOutlined v-if="record.bindQrcId" style="font-size: 16px" @click="showQrImgFunc(record.bindQrcId)" />
|
||||
</template>
|
||||
<template v-if="column.key === 'deviceNo'">
|
||||
{{ record.deviceNo }}
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'bindAppIdName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>应用名称:{{record.bindAppIdName}}</span><br>
|
||||
<span>应用ID:{{record.appId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.bindAppIdName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'isvNo'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>渠道名称:{{record.isvName}}</span><br>
|
||||
<span>渠道号:{{record.isvNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.isvName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'state'">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="$access('ENT_DEVICE_SPEAKER_EDIT')" :onChange="(state) => { return updateState(record.deviceId, state)}" />
|
||||
</template>
|
||||
<template v-if="column.key === 'bindState'">
|
||||
<JeepayTableColState :state="record.bindState" :showSwitchType="$access('ENT_DEVICE_SPEAKER_EDIT')" :onChange="(bindState) => { return updateBindState(record.deviceId, bindState)}" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'provider'">
|
||||
<a-tag :key="record.provider" color="processing">
|
||||
{{ (speakerList.find(item => item.value == record.provider) as any).text || '其他' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
|
||||
<template v-if="column.key === 'mchApplyName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>商户名称:{{record.mchApplyName}}</span><br>
|
||||
<span>商户号:{{record.mchApplyId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchApplyName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'storeId'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>门店名称:{{record.storeName}}</span><br>
|
||||
<span>门店编号:{{record.storeId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.storeName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'fixedFlag'">
|
||||
<span v-if="record.fixedFlag === 0">任意金额</span>
|
||||
<span v-else>¥{{ (record.fixedPayAmount / 100).toFixed(2)}}</span>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_EDIT')" type="link" @click="editFunc(record)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_TEST')" type="link" @click="speak(record.deviceId)">播报测试</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_UNBIND') && (userStore.userInfo['userType'] != '11' && userStore.userInfo['userType'] != '12')" type="link" style="color: red" @click="unBindFunc(record.deviceId)">解绑</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<!-- 测试设备组件 -->
|
||||
<TestDevice ref="testDevice" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import { API_URL_STORE_DEVICE, req, reqLoad, $unbindDevice ,$qrcShellViewByQrc} from '@/api/manage'
|
||||
import InfoAddOrEdit from './AddOrEdit.vue'
|
||||
import TestDevice from '../TestDevice.vue'
|
||||
import {ref, reactive, getCurrentInstance, onMounted} from 'vue'
|
||||
import provider from '../provider.json'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
const speakerList = provider.speaker
|
||||
|
||||
const { $infoBox, $access ,$viewerApi} = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const userStore = useUserStore()
|
||||
const infoAddOrEdit = ref()
|
||||
const testDevice = ref()
|
||||
const infoTable = ref()
|
||||
const deviceType = ref(1)
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ key: 'provider', title: '设备厂商', },
|
||||
// { key: 'entryPage', title: '页面类型', customRender: ({ record }) => {return record.entryPage == 'default' ? '默认' : record.entryPage == 'h5' ? 'H5' : '小程序'} ,},
|
||||
// { title: '设备ID', fixed: 'left', dataIndex: 'deviceId' },
|
||||
{ key: 'deviceNo',title: '设备号', dataIndex: 'deviceNo' },
|
||||
{ title: '设备名称', dataIndex: 'deviceName', },
|
||||
{ key: 'bindQrcId', title: '二维码编号', },
|
||||
{ title: "商户名称", key: "mchApplyName", dataIndex: "mchApplyName" },
|
||||
{ key: 'storeId', title: '门店名称', dataIndex: 'storeId', },
|
||||
{ key: "ifName", title: "支付通道", dataIndex: "ifName" },
|
||||
{ key: "isvNo", title: "所属渠道", dataIndex: "isvNo" },
|
||||
// { key: 'bindAppIdName', dataIndex: 'bindAppIdName', title: '所属应用', },
|
||||
// { title: '门店编号', dataIndex: 'storeId',},
|
||||
{ key: 'bindType', title: '绑定类型',},
|
||||
{ key: 'state', title: '使用状态', },
|
||||
// { key: 'bindState', title: '绑定状态', },
|
||||
{ key: 'fixedFlag', title: '固定金额', },
|
||||
{ dataIndex: 'createdAt', title: '创建日期',},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let searchData = ref({})
|
||||
|
||||
|
||||
|
||||
function reqTableDataFunc(params: any) { // 请求table接口数据
|
||||
return req.list(API_URL_STORE_DEVICE, Object.assign({ deviceType: deviceType.value }, params))
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
btnLoading.value = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show({ deviceType: deviceType.value })
|
||||
}
|
||||
function editFunc (record: any) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(record)
|
||||
}
|
||||
function onReset(){ //重置搜索内容
|
||||
searchData.value = {}
|
||||
}
|
||||
function speak(recordId){ //重置搜索内容
|
||||
testDevice.value.show(recordId, 1)
|
||||
}
|
||||
function showShop(){
|
||||
$infoBox.message.error('暂未开通')
|
||||
}
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
const title = state ? '确认启用?' : '确认禁用?'
|
||||
const content = state ? '' : '禁用后该设备将无法使用!'
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return reqLoad.updateById(API_URL_STORE_DEVICE, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function updateBindState (recordId, bindState) { // 【更新状态】
|
||||
const title = bindState ? '确认启用?' : '确认禁用?'
|
||||
const content = bindState ? '' : '禁用后该设备将无法使用!'
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return reqLoad.updateById(API_URL_STORE_DEVICE, recordId, { bindState: bindState }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 解绑设备
|
||||
function unBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后商户将无法使用该设备!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindDevice(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
// 显示二维码图片
|
||||
function showQrImgFunc(recordId){
|
||||
$qrcShellViewByQrc(recordId).then((res) => {
|
||||
$viewerApi({images: [res]})
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
searchData.value['deviceName'] = useRoute().query.deviceName
|
||||
|
||||
setTimeout(function (){
|
||||
searchFunc()
|
||||
},1000)
|
||||
})
|
||||
</script>
|
||||
657
jeepay-ui-merchant/src/views/divide/AddOrEdit.vue
Normal file
657
jeepay-ui-merchant/src/views/divide/AddOrEdit.vue
Normal file
@@ -0,0 +1,657 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.isShow"
|
||||
:title=" vdata.isAdd ? '新增交易路由策略' : '修改交易路由策略' "
|
||||
:confirmLoading="vdata.confirmLoading"
|
||||
@ok="handleOkFunc"
|
||||
@close="onClose"
|
||||
width="100%"
|
||||
>
|
||||
<a-form ref="infoFormModel" layout="vertical" :model="vdata.saveObject" :rules="vdata.rules">
|
||||
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="11">
|
||||
<a-form-item label="选择应用" name="appid">
|
||||
<a-select v-model:value="vdata.saveObject.appid" placeholder="请选择应用" show-search @change="getSaveObjectAppid" @search="handleAppidChange" :filter-option="false">
|
||||
<a-select-option v-for="d in vdata.filteredAppidInfoList" :key="d.storeId" v-model:value="d.appId">
|
||||
{{ d.appName }} - {{ d.appId }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :sm="11">
|
||||
<a-form-item label="策略名称:" name="name">
|
||||
<a-input v-model:value="vdata.saveObject.name" placeholder="请输入交易路由策略名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :sm="11">
|
||||
<a-form-item label="策略规则:" name="ruleStrategy">
|
||||
<div style="display: grid">
|
||||
<a-select v-model:value="vdata.saveObject.ruleStrategy" placeholder="策略规则" :disabled="!vdata.isAdd">
|
||||
<a-select-option value="TRADE_NUM">按收款笔数</a-select-option>
|
||||
<a-select-option value="TRADE_AMOUNT">按累计收款金额</a-select-option>
|
||||
<a-select-option value="TRADE_TIME">按收款时间</a-select-option>
|
||||
<a-select-option value="TRADE_AMOUNT_INTERVAL">按交易金额区间</a-select-option>
|
||||
<!-- <a-select-option value="5">按交易类型</a-select-option>-->
|
||||
</a-select>
|
||||
<span class="jeepay-tip-text" v-if="vdata.saveObject.ruleStrategy == 'TRADE_NUM'">设置允许用户在一定时间内(如每日、每周、每月)的最大收款笔数。</span>
|
||||
<span class="jeepay-tip-text" v-if="vdata.saveObject.ruleStrategy == 'TRADE_AMOUNT'">设置用户在一定时间内的累计收款金额上限。</span>
|
||||
<span class="jeepay-tip-text" v-if="vdata.saveObject.ruleStrategy == 'TRADE_TIME'">设置允许用户收款的有效时间段。</span>
|
||||
<span class="jeepay-tip-text" v-if="vdata.saveObject.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'">设置不同交易金额区间对应的路由策略。</span>
|
||||
<!-- <span class="jeepay-tip-text" v-if="vdata.saveObject.rule == 5">选择适用的交易类型(如微信、支付宝等)。</span>-->
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="11">
|
||||
<a-form-item label="交易顺序策略:" name="sortStrategy">
|
||||
<a-select v-model:value="vdata.saveObject.sortStrategy" placeholder="交易顺序策略">
|
||||
<a-select-option value="ORDER">商户排列顺序</a-select-option>
|
||||
<a-select-option value="RANDOM">随机排序</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">高级策略规则</a-divider>
|
||||
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" :rules="vdata.rules">
|
||||
<a-row>
|
||||
<a-col :sm="24">
|
||||
<a-form-item label="新用户策略开关:" name="isNewUser" >
|
||||
<div style="display: flex">
|
||||
<JeepayTableColState :state="vdata.saveObject.seniorStrategy.isNewUser" :showSwitchType="true" :onChange="getUserChange" />
|
||||
<div class="jeepay-tip-text" style="margin: 0 5px 0 5px !important;">开启后可设置新用户前X笔付款不路由,以及同一用户累计支付未满X元不路由的阈值</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
<!-- <div v-if="vdata.saveObject.user == 1">-->
|
||||
<!-- <a-checkbox-group v-model:value="vdata.saveObject.userType" >-->
|
||||
<!-- <div style="display: inline-grid;">-->
|
||||
<!-- <a-checkbox :value="0" style="margin-bottom: 10px;margin-left: 10px;">-->
|
||||
<!-- <div style="display: flex">-->
|
||||
<!-- <div class="user-ploy-span span-color">同一用户前</div>-->
|
||||
<!-- <a-input-number addon-after="笔" :min="0" :precision="0" v-model:value="vdata.saveObject.price" />-->
|
||||
<!-- <div class="user-ploy-span span-color">付款前不分流</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </a-checkbox>-->
|
||||
<!-- <a-checkbox :value="1" style="margin-bottom: 10px">-->
|
||||
<!-- <div style="display: flex">-->
|
||||
<!-- <div class="user-ploy-span span-color">同一用户累计消费未满</div>-->
|
||||
<!-- <a-input-number addon-after="元" :min="0" :precision="2" v-model:value="vdata.saveObject.price" />-->
|
||||
<!-- <div class="user-ploy-span span-color">付款前不分流</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </a-checkbox>-->
|
||||
<!-- </div>-->
|
||||
<!-- </a-checkbox-group>-->
|
||||
<!-- </div>-->
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="24">
|
||||
<a-form-item label="分笔支付策略开关" name="isSplit" >
|
||||
<div style="display: flex">
|
||||
<JeepayTableColState :state="vdata.saveObject.seniorStrategy.isSplit" :showSwitchType="true" :onChange="getUserChangeNumState" />
|
||||
<div class="jeepay-tip-text" style="margin: 0 5px 0 5px !important;">选择用户上一笔支付失败时或支付页提示拦截后的分笔支付模式</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-form-item label="分笔支付策略:" class="span-color" name="splitStrategy" placeholder="分笔支付策略" v-if="vdata.saveObject.seniorStrategy.isSplit == 1">
|
||||
<div style="display: grid">
|
||||
<a-select class="span-color" v-model:value="vdata.saveObject.seniorStrategy.splitStrategy" placeholder="分笔支付策略">
|
||||
<a-select-option value="0">多支付通道多商户分笔</a-select-option>
|
||||
<a-select-option value="1">单支付通道多商户分笔</a-select-option>
|
||||
<a-select-option value="2">单支付通道单商户分笔</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-form-item label="通道展示策略" name="isChannel" >
|
||||
<div style="display: flex">
|
||||
<JeepayTableColState :state="vdata.saveObject.seniorStrategy.isChannel" :onChange="getIsChannel" :showSwitchType="true" />
|
||||
<div class="jeepay-tip-text" style="margin: 0 5px 0 5px !important;">开启后允许商户在支付时自主选择支付通道,若选择的通道内无商户,则提示报错。</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
||||
|
||||
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">策略门店规则设置</a-divider>
|
||||
|
||||
<a-form
|
||||
ref="infoFormModel"
|
||||
:model="vdata.receiveList"
|
||||
:label-col="{ span: 6 }"
|
||||
:wrapper-col="{ span: 15 }">
|
||||
<a-table bordered :data-source="vdata.receiveList" :columns="tableColumns"
|
||||
:pagination="false" style="margin-left: -1px;">
|
||||
<template #headerCell="{ column }">
|
||||
<span v-if="column.tooltipTitle">
|
||||
{{ column.title }}
|
||||
<a-tooltip :title="column.tooltipTitle"><info-circle-outlined /></a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #storeId="{ record }">
|
||||
<a-select class="tb_width_80" v-model:value="record.storeId" placeholder="请选择商户" show-search @change="handleStoreChange" @search="handleDivisionNameChange" :filter-option="false">
|
||||
<a-select-option v-for="d in vdata.filteredMchNameInfoList" :key="d.storeId" v-model:value="d.storeId">
|
||||
{{ d.storeName }} - {{ d.storeId }}- {{ d.ifName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #value="{ record }" >
|
||||
<a-input-number class="tb_width_80" addon-after="笔" :min="1" :precision="0" v-model:value="record.value" v-if="vdata.saveObject.ruleStrategy == 'TRADE_NUM'" placeholder="请输入交易笔数"/>
|
||||
<a-input-number class="tb_width_80" addon-after="元" :min="1" :precision="2" v-model:value="record.value" v-if="vdata.saveObject.ruleStrategy == 'TRADE_AMOUNT'" placeholder="请按照门店收款情况预估,输入收款金额"/>
|
||||
<!-- <a-input-number addon-after="笔" :min="1" v-model:value="record.content" v-if="vdata.saveObject.rule == 1" placeholder="请输入交易笔数"/>-->
|
||||
<div v-if="vdata.saveObject.ruleStrategy == 'TRADE_TIME'" class="con-flex-div" >
|
||||
<a-time-picker class="con-flex-span" v-model:value="record.value" format="HH:mm" />
|
||||
<span class="rule-span">至</span>
|
||||
<a-time-picker class="con-flex-span" v-model:value="record.value1" format="HH:mm" />
|
||||
</div>
|
||||
<div v-if="vdata.saveObject.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'" class="con-flex-div" >
|
||||
<a-input-number class="con-flex-span" addon-after="元" :min="1" :precision="2" v-model:value="record.value" placeholder="请输入最小金额"/>
|
||||
<span class="rule-span">至</span>
|
||||
<a-input-number class="con-flex-span" addon-after="元" :min="1" :precision="2" v-model:value="record.value1" placeholder="请输入最大金额"/>
|
||||
</div>
|
||||
<!-- <div v-if="vdata.saveObject.rule == 5" >-->
|
||||
<!-- <a-select class="con-flex-span tb_width_80" v-model:value="record.content" mode="multiple" style="width: 100%" placeholder="请选择配置" :options="vdata.payWay" />-->
|
||||
<!-- </div>-->
|
||||
<!-- <a-input-number addon-after="笔" :min="1" v-model:value="record.content" v-if="vdata.saveObject.rule == 1" placeholder="请输入交易笔数"/>-->
|
||||
</template>
|
||||
|
||||
<template #scope="{ record }">
|
||||
<div v-if="vdata.saveObject.ruleStrategy == 'TRADE_TIME'">
|
||||
|
||||
</div>
|
||||
<div v-else>
|
||||
<a-select class="con-flex-span tb_width_80" v-model:value="record.scope" style="width: 100%" placeholder="请选择时限" >
|
||||
<a-select-option :value="-1">不限</a-select-option>
|
||||
<a-select-option :value="1">日</a-select-option>
|
||||
<a-select-option :value="2">周</a-select-option>
|
||||
<a-select-option :value="3">月</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<template #typeStrategy="{ record }">
|
||||
<a-select class="con-flex-span tb_width_80" v-model:value="record.typeStrategy" mode="multiple" style="width: 100%" placeholder="请选择支付类型" :options="vdata.payWay" />
|
||||
</template>
|
||||
|
||||
<template #rate="{ record }">
|
||||
<a-input-number class="tb_width_80" addon-after="%" :min="1" :max="100" :precision="0" v-model:value="record.rate" placeholder="请输入付款率"/>
|
||||
</template>
|
||||
<template #state="{ record }">
|
||||
<div style="display: flex">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="true" :onChange="(state) => { return getState(record, state)}" />
|
||||
|
||||
|
||||
<a-tooltip>
|
||||
<template #title>
|
||||
{{record.remark}}
|
||||
</template>
|
||||
<question-circle-outlined v-if="record.remark" style="padding-left: 10px;color: #ff4c5b"/>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<template #operation="{ record }">
|
||||
<a @click="onAdd(0)" class="operation-a" >添加</a>
|
||||
<a-popconfirm title="确认删除吗?" @confirm="onDelete(record.key)">
|
||||
<a class="operation-a" style="color: #ff4c5b" v-if="record.key != 1">删除</a>
|
||||
</a-popconfirm>
|
||||
<a @click="onMove(record,1)" v-if="record.key != 1" class="operation-a" >上移</a>
|
||||
<a @click="onMove(record,0)" v-if="record.key != vdata.receiveList[vdata.receiveList.length-1].key && record.key != 1" class="operation-a" >下移</a>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-form>
|
||||
|
||||
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="vdata.isShow = false"><close-outlined /> 取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.confirmLoading" @click="handleOkFunc"><check-outlined /> 保存</a-button>
|
||||
</div>
|
||||
<!-- 选择码牌组件 -->
|
||||
<!-- <JeepayModelQrcList ref="jeepayModelQrcListRef" @selectFinishFunc="selectQrcFinishFunc" />-->
|
||||
<JeepayModelAccountsQrcList ref="jeepayModelQrcListRef" @selectFinishFunc="selectQrcFinishFunc" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
$getMchRouteDetail,
|
||||
API_MCH_PAY_DEFINES,
|
||||
API_URL_DIVISION_RECEIVER_GROUP,
|
||||
API_URL_DIVISION_TEMPLATE_ADD,
|
||||
API_URL_DIVISION_TEMPLATE_EDIT,
|
||||
API_URL_ENT_MCH_ROUTE_ADD,
|
||||
API_URL_ENT_MCH_ROUTE_EDIT,
|
||||
API_URL_MCH_APPS,
|
||||
API_URL_MCH_STORE_LIST,
|
||||
req
|
||||
} from '@/api/manage'
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
import { message } from 'ant-design-vue'
|
||||
import {getCurrentInstance, reactive, ref} from 'vue'
|
||||
import ReceiverGroupAdd from './ReceiverGroupAdd.vue'
|
||||
import moment from "moment/moment";
|
||||
|
||||
const jeepayModelQrcListRef = ref()
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const vdata = reactive ({
|
||||
filteredMchNameInfoList:[] as any,
|
||||
filteredMchNoInfoList:[] as any,
|
||||
storeList:[] as any,
|
||||
detailData:[] as any,
|
||||
receiveList:[{ key: 1, storeId: '',rate:1,scope:1,state:0,value: '' as any, typeStrategy: [] as any, value1:'',operation: ''}],
|
||||
modeList:[
|
||||
{name:"按比例分账",value:0},
|
||||
{name:"按金额分账",value:1},
|
||||
],
|
||||
typeList:[
|
||||
{name:"实时分账",value:0},
|
||||
{name:"延时分账",value:1},
|
||||
{name:"秒到分账",value:2},
|
||||
],
|
||||
payDefines: [] as any,
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isAdd: true, // 新增 or 修改页面标识
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: { } as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
rules: {
|
||||
appid: [{ required: true, message: '请输入选择应用', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '请输入策略名称', trigger: 'blur' }],
|
||||
ruleStrategy: [{ required: true, message: '请选择策略规则', trigger: 'blur' }],
|
||||
sortStrategy: [{ required: true, message: '请选择交易顺序策略', trigger: 'blur' }],
|
||||
divisionType: [{ required: true, message: '请输入分账类型', trigger: 'blur' }],
|
||||
divisionAmount: [{ required: true, message: '请输入分账金额', trigger: 'blur' }],
|
||||
minAmount: [{ required: true, message: '请输入最小支付金额', trigger: 'blur' }],
|
||||
isSpecify: [{ required: true, message: '请指定指定设备', trigger: 'blur' }],
|
||||
deviceInfo: [{ required: true, message: '请选择设备信息', trigger: 'blur' }]
|
||||
},
|
||||
filteredAppidInfoList:[] as any,
|
||||
appidList:[] as any,
|
||||
payWay:[
|
||||
{
|
||||
value: 'WECHAT',
|
||||
label: '微信',
|
||||
},
|
||||
{
|
||||
value: 'ALIPAY',
|
||||
label: '支付宝',
|
||||
}
|
||||
]
|
||||
})
|
||||
function onClose(){
|
||||
vdata.isShow = false
|
||||
}
|
||||
defineExpose({show})
|
||||
function show (record) { // 弹层打开事件
|
||||
vdata.isAdd = !record
|
||||
vdata.saveObject = {}
|
||||
vdata.receiveList = [{ key: 1, storeId: '',rate:1,scope:1 as any,state:0,value: '' as any, typeStrategy: [] as any, value1:'',operation: ''}]
|
||||
vdata.saveObject.seniorStrategy = {isNewUser:false,isSplit:false,isChannel:false} as any // 数据清空
|
||||
vdata.confirmLoading = false // 关闭loading
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
req.list(API_URL_MCH_APPS, { 'pageSize': -1,state:1 }).then(res => {
|
||||
vdata.appidList = res.records
|
||||
vdata.filteredAppidInfoList = res.records
|
||||
})
|
||||
|
||||
// payFefines()
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.recordId = record.routeId
|
||||
$getMchRouteDetail(record.routeId).then(res => {
|
||||
vdata.saveObject = res
|
||||
|
||||
storeList()
|
||||
vdata.saveObject.seniorStrategy.isNewUser = vdata.saveObject.seniorStrategy.isNewUser?1:0
|
||||
vdata.saveObject.seniorStrategy.isSplit = vdata.saveObject.seniorStrategy.isSplit?1:0
|
||||
vdata.saveObject.seniorStrategy.isChannel = vdata.saveObject.seniorStrategy.isChannel?1:0
|
||||
vdata.isShow = true
|
||||
if(res.configList.length == 0){
|
||||
vdata.receiveList = [{ key: 1, storeId: '',rate:1,scope:1,state:0,value: '' as any, typeStrategy: [] as any, value1:'',operation: ''}]
|
||||
return false;
|
||||
}
|
||||
const receiveList = [] as any;
|
||||
for (let i = 0;i<res.configList.length;i++) {
|
||||
// moment('12:08', 'HH:mm')
|
||||
if (vdata.saveObject.ruleStrategy == 'TRADE_TIME') {
|
||||
receiveList.push({
|
||||
key: i + 1,
|
||||
storeId: res.configList[i].storeId,
|
||||
value: moment(res.configList[i].value[0], 'HH:mm'),
|
||||
value1: moment(res.configList[i].value[1], 'HH:mm'),
|
||||
typeStrategy: res.configList[i].typeStrategy,
|
||||
state: res.configList[i].state,
|
||||
rate: res.configList[i].rate,
|
||||
scope: -1,
|
||||
operation: ''
|
||||
})
|
||||
} else {
|
||||
receiveList.push({
|
||||
key: i + 1,
|
||||
storeId: res.configList[i].storeId,
|
||||
value: res.configList[i].value[0],
|
||||
value1: res.configList[i].value[1],
|
||||
state: res.configList[i].state,
|
||||
rate: res.configList[i].rate,
|
||||
scope: res.configList[i].scope,
|
||||
typeStrategy: res.configList[i].typeStrategy,
|
||||
operation: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
vdata.receiveList = receiveList;
|
||||
})
|
||||
} else {
|
||||
vdata.isShow = true // 立马展示弹层信息
|
||||
}
|
||||
}
|
||||
function getType(e){
|
||||
console.log(vdata.saveObject.type,'vdata.saveObject.type')
|
||||
}
|
||||
function payFefines() {
|
||||
req.list(API_MCH_PAY_DEFINES,{ 'pageSize': -1 }).then(res => {
|
||||
vdata.payDefines = res
|
||||
})
|
||||
}
|
||||
|
||||
function getIfCode(){
|
||||
console.log(vdata.saveObject.ifCode,'saveObjectsaveObjectsaveObject')
|
||||
}
|
||||
function handleOkFunc() { // 点击【确认】按钮事件
|
||||
|
||||
const configList = vdata.receiveList
|
||||
console.log(configList,'configListconfigListconfigList')
|
||||
const list = [] as any;
|
||||
for (var i=0;i<configList.length;i++){
|
||||
if(!configList[i].storeId){
|
||||
message.error("请选择门店")
|
||||
return false;
|
||||
}
|
||||
if(!configList[i].value){
|
||||
message.error("请输入配置")
|
||||
return false;
|
||||
}
|
||||
if(configList[i].typeStrategy.length == 0){
|
||||
message.error("请选择支付配置")
|
||||
return false;
|
||||
}
|
||||
|
||||
let value = [configList[i].value] as any;
|
||||
|
||||
if(!configList[i].value1){
|
||||
if(vdata.saveObject.ruleStrategy == 'TRADE_TIME' || vdata.saveObject.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'){
|
||||
message.error("请输入配置")
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
value.push(configList[i].value1)
|
||||
}
|
||||
if(vdata.saveObject.ruleStrategy == 'TRADE_TIME' || vdata.saveObject.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'){
|
||||
// const value = [] as any;
|
||||
const value1 = dateFormat(configList[i].value);
|
||||
const value2 = dateFormat(configList[i].value1);
|
||||
value = [value1,value2] as any;
|
||||
}
|
||||
list.push({
|
||||
storeId: configList[i].storeId,
|
||||
value: value,
|
||||
scope: configList[i].scope as any,
|
||||
typeStrategy: configList[i].typeStrategy,
|
||||
rate: configList[i].rate,
|
||||
state: configList[i].state,
|
||||
sortNum: i,
|
||||
})
|
||||
}
|
||||
console.log(list,'listlistlist')
|
||||
const data = vdata.saveObject
|
||||
data.configList = list
|
||||
|
||||
infoFormModel.value.validate().then(valid=>{
|
||||
vdata.confirmLoading = true // 显示loading
|
||||
|
||||
// vdata.saveObject.isNewUser = vdata.saveObject.seniorStrategy.isNewUser==1?true:false
|
||||
// vdata.saveObject.isSplit = vdata.saveObject.seniorStrategy.isSplit==1?true:false
|
||||
if (vdata.isAdd) {
|
||||
req.add(API_URL_ENT_MCH_ROUTE_ADD, data).then(res => {
|
||||
message.success('添加成功')
|
||||
vdata.isShow = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(res => { vdata.confirmLoading = false })
|
||||
} else {
|
||||
req.updateById(API_URL_ENT_MCH_ROUTE_EDIT, vdata.recordId, data).then(res => {
|
||||
message.success('修改成功')
|
||||
vdata.isShow = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(res => { vdata.confirmLoading = false })
|
||||
}
|
||||
})
|
||||
}
|
||||
function selectQrcFinishFunc (e) { // 码牌选择完成事件
|
||||
|
||||
if (!e || e.length <= 0) {
|
||||
return $infoBox.message.error('请开启要绑定的码牌!')
|
||||
}
|
||||
|
||||
vdata.saveObject.deviceInfo = e
|
||||
jeepayModelQrcListRef.value.close()
|
||||
}
|
||||
|
||||
function showQrcSelectModel() {
|
||||
if(!vdata.saveObject.ifCode){
|
||||
return $infoBox.message.error('请选择支付通道!')
|
||||
}
|
||||
jeepayModelQrcListRef.value.show(vdata.saveObject.storeId, vdata.saveObject.deviceInfo, vdata.saveObject.ifCode)
|
||||
}
|
||||
|
||||
function getUserChange(e){
|
||||
vdata.saveObject.seniorStrategy.isNewUser = e
|
||||
}
|
||||
function getUserChangeNumState(e){
|
||||
|
||||
vdata.saveObject.seniorStrategy.isSplit = e
|
||||
}
|
||||
|
||||
function getIsChannel(e){
|
||||
vdata.saveObject.seniorStrategy.isChannel = e
|
||||
}
|
||||
|
||||
//门店搜索
|
||||
const handleAppidChange = (value) => {
|
||||
vdata.filteredAppidInfoList = [];
|
||||
vdata.appidList.forEach((item: { appName: string | any[], appId: any[] },index) => {
|
||||
if (item.appName.includes(value) || item.appId.toString().includes(value) ) {
|
||||
vdata.filteredAppidInfoList.push(vdata.appidList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
function getSaveObjectAppid(e){
|
||||
storeList()
|
||||
}
|
||||
|
||||
//接收方
|
||||
const tableColumns = reactive([
|
||||
// { key: 'key', title: '序号', dataIndex: 'key', align: 'center',width:'5%'},
|
||||
{ key: 'storeId',title: '门店名称', dataIndex: 'storeId', align: 'center',slots: { customRender: 'storeId' },width:'25%' },
|
||||
{ key: 'value',title: '配置', dataIndex: 'value', align: 'center',slots: { customRender: 'value' } ,width:'15%'},
|
||||
{ key: 'scope',title: '时效', dataIndex: 'scope', align: 'center',slots: { customRender: 'scope' } ,width:'10%'},
|
||||
{ key: 'typeStrategy',title: '支付类型', dataIndex: 'typeStrategy', align: 'center',slots: { customRender: 'typeStrategy' } ,width:'15%'},
|
||||
{ key: 'rate',title: '付款率', dataIndex: 'rate', tooltipTitle: '付款率低于设置的,自动下架', align: 'center',slots: { customRender: 'rate' } ,width:'10%'},
|
||||
{ key: 'state',title: '状态', dataIndex: 'state', align: 'center',slots: { customRender: 'state' } ,width:'10%'},
|
||||
{ key: 'operation',title: '操作', dataIndex: 'operation', align: 'center',slots: { customRender: 'operation' },width:'10%' },
|
||||
])
|
||||
|
||||
const onAdd = (type = 0) => {
|
||||
if (!vdata.receiveList) {
|
||||
vdata.receiveList = [] as any
|
||||
}
|
||||
if(vdata.receiveList.length >=9){
|
||||
return $infoBox.message.error('分账接收方最多设置 9 个!')
|
||||
}
|
||||
vdata.receiveList.push({
|
||||
key: vdata.receiveList[vdata.receiveList.length - 1].key + 1,
|
||||
storeId: '',
|
||||
value: '',
|
||||
value1:'',
|
||||
scope:1,
|
||||
rate:1,
|
||||
state:0,
|
||||
typeStrategy: [] as any,
|
||||
})
|
||||
console.log(vdata.receiveList,'vdata.receiveList')
|
||||
|
||||
}
|
||||
function storeList(){
|
||||
vdata.storeList = []
|
||||
vdata.filteredMchNameInfoList = []
|
||||
vdata.filteredMchNoInfoList = []
|
||||
if(!vdata.saveObject.appid){
|
||||
return $infoBox.message.error("请先选择应用")
|
||||
}
|
||||
|
||||
vdata.receiveList = [{ key: 1, storeId: '',rate:1,scope:1,state:0,value: '' as any, typeStrategy: [] as any, value1:'',operation: ''}]
|
||||
req.list(API_URL_MCH_STORE_LIST, { 'pageSize': -1,bindAppIdName:vdata.saveObject.appid }).then(res => {
|
||||
vdata.storeList = res.records
|
||||
vdata.filteredMchNameInfoList = res.records
|
||||
vdata.filteredMchNoInfoList = res.records
|
||||
})
|
||||
}
|
||||
function onMove(record,type){
|
||||
console.log(record.key,record.userType,'key')
|
||||
const key = record.key
|
||||
let receiveList = vdata.receiveList
|
||||
vdata.receiveList = [];
|
||||
let list = [];
|
||||
for (let i=0;i<receiveList.length;i++){
|
||||
if(receiveList[i].key == key){
|
||||
if(parseInt(type) === 1){
|
||||
receiveList[i].key = parseInt(receiveList[i-1].key) - 1
|
||||
}else{
|
||||
receiveList[i].key = parseInt(receiveList[i+1].key) + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
receiveList.sort((a, b) => {
|
||||
return a.key - b.key;
|
||||
});
|
||||
receiveList.forEach((item,index) => {
|
||||
item.key = index+1
|
||||
vdata.receiveList.push(item)
|
||||
});
|
||||
}
|
||||
|
||||
function dateFormat(time) {
|
||||
let date = new Date(time);
|
||||
let year = date.getFullYear();
|
||||
let wk = date.getDay()
|
||||
/* 在日期格式中,月份是从0开始的,因此要加0
|
||||
* 使用三元表达式在小于10的前面加0,以达到格式统一 如 09:11:05
|
||||
* */
|
||||
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
|
||||
let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
|
||||
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
|
||||
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
|
||||
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
|
||||
let weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
|
||||
let week = weeks[wk]
|
||||
// 拼接
|
||||
return hours + ":" + minutes;
|
||||
// return year + "年" + month + "月" + day + "日" + " " + hours + ":" + minutes + ":" + seconds + ' ' + week;
|
||||
}
|
||||
const handleStoreChange=(value)=>{
|
||||
const key = [];
|
||||
vdata.receiveList.forEach((vv,kk) => {
|
||||
console.log(vv,'v1')
|
||||
const index = kk as any;
|
||||
if(vv.storeId == value){
|
||||
key.push(index as any)
|
||||
// message.error("已存在门店规格")
|
||||
return false;
|
||||
}
|
||||
})
|
||||
if(key.length > 1){
|
||||
message.error("已存在门店配置")
|
||||
vdata.receiveList[key.length-1].storeId = ''
|
||||
}
|
||||
console.log(vdata.receiveList,'vdatareceiveListvdatareceiveListvdatareceiveList')
|
||||
}
|
||||
//门店搜索
|
||||
const handleDivisionNameChange = (value) => {
|
||||
vdata.filteredMchNameInfoList = [];
|
||||
vdata.storeList.forEach((item: { mchShortName: string | any[], storeId: any[] },index) => {
|
||||
if (item.mchShortName.includes(value) || item.storeId.toString().includes(value) ) {
|
||||
|
||||
vdata.filteredMchNameInfoList.push(vdata.storeList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
const handleDivisionNoChange = (value) => {
|
||||
vdata.filteredMchNoInfoList = [];
|
||||
vdata.storeList.forEach((item: { mchShortName: string | any[], storeId: any[] },index) => {
|
||||
if (item.mchShortName.includes(value) || item.storeId.toString().includes(value) ) {
|
||||
vdata.filteredMchNoInfoList.push(vdata.storeList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
const onDelete = (key,type=0) => {
|
||||
if (vdata.receiveList.length <= 1) {
|
||||
$infoBox.message.error('最少保留一项')
|
||||
return false
|
||||
}
|
||||
vdata.receiveList = vdata.receiveList.filter(item => item.key !== key)
|
||||
}
|
||||
function getState(record,e){
|
||||
vdata.receiveList[record.key - 1].state = e
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.jeepay-tip-text::before{
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.user-ploy-span{
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.span-color{
|
||||
color: #595959 !important;
|
||||
}
|
||||
:deep(.span-color .ant-form-item-label>label){
|
||||
color: #595959 !important;
|
||||
}
|
||||
|
||||
:deep(.jeepay-table-top-row){
|
||||
display: none;
|
||||
}
|
||||
.rule-span{
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.con-flex-span{
|
||||
flex: 1 !important;
|
||||
}
|
||||
.tb_width_80{
|
||||
width: 80% !important;
|
||||
}
|
||||
.con-flex-div{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
}
|
||||
.operation-a{
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
547
jeepay-ui-merchant/src/views/divide/GroupAdd.vue
Normal file
547
jeepay-ui-merchant/src/views/divide/GroupAdd.vue
Normal file
@@ -0,0 +1,547 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.isShow"
|
||||
:title="vdata.isAdd ? '新增路由配置' : '编辑路由配置'"
|
||||
width="80%"
|
||||
:mask-closable="false"
|
||||
@close="vdata.isShow = false"
|
||||
>
|
||||
|
||||
<a-row >
|
||||
|
||||
|
||||
<a-col :span="24">
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">编辑路由门店</a-divider>
|
||||
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="策略规则" >-->
|
||||
<!-- <div style="display: block">-->
|
||||
<!-- <div>-->
|
||||
<!-- <span v-if="vdata.detailData.ruleStrategy == 'TRADE_NUM'">按收款笔数</span>-->
|
||||
<!-- <span v-if="vdata.detailData.ruleStrategy == 'TRADE_AMOUNT'">按累计收款金额</span>-->
|
||||
<!-- <span v-if="vdata.detailData.ruleStrategy == 'TRADE_TIME'">按收款时间</span>-->
|
||||
<!-- <span v-if="vdata.detailData.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'">按交易金额区间</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div>-->
|
||||
<!-- <span class="jeepay-tip-text" v-if="vdata.detailData.ruleStrategy == 'TRADE_NUM'">设置允许用户在一定时间内(如每日、每周、每月)的最大收款笔数。</span>-->
|
||||
<!-- <span class="jeepay-tip-text" v-if="vdata.detailData.ruleStrategy == 'TRADE_AMOUNT'">设置用户在一定时间内的累计收款金额上限。</span>-->
|
||||
<!-- <span class="jeepay-tip-text" v-if="vdata.detailData.ruleStrategy == 'TRADE_TIME'">设置允许用户收款的有效时间段。</span>-->
|
||||
<!-- <span class="jeepay-tip-text" v-if="vdata.detailData.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'">设置不同交易金额区间对应的路由策略。</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!--<!– <span class="jeepay-tip-text" v-if="vdata.detailData.ruleStrategy == 5">选择适用的交易类型(如微信、支付宝等)。</span>–>-->
|
||||
<!-- </a-col>-->
|
||||
<a-col :sm="24">
|
||||
|
||||
<a-form-item label="策略规则:" name="ruleStrategy" >
|
||||
<div style="display: grid">
|
||||
|
||||
<a-select v-model:value="vdata.detailData.ruleStrategy" :disabled="vdata.ruleStrategy" placeholder="策略规则" @change="getRuleStrategy">
|
||||
<a-select-option value="TRADE_NUM">按收款笔数</a-select-option>
|
||||
<a-select-option value="TRADE_AMOUNT">按累计收款金额</a-select-option>
|
||||
<a-select-option value="TRADE_TIME">按收款时间</a-select-option>
|
||||
<a-select-option value="TRADE_AMOUNT_INTERVAL">按交易金额区间</a-select-option>
|
||||
</a-select>
|
||||
<span class="jeepay-tip-text" v-if="vdata.detailData.ruleStrategy == 'TRADE_NUM'">设置允许用户在一定时间内(如每日、每周、每月)的最大收款笔数。</span>
|
||||
<span class="jeepay-tip-text" v-if="vdata.detailData.ruleStrategy == 'TRADE_AMOUNT'">设置用户在一定时间内的累计收款金额上限。</span>
|
||||
<span class="jeepay-tip-text" v-if="vdata.detailData.ruleStrategy == 'TRADE_TIME'">设置允许用户收款的有效时间段。</span>
|
||||
<span class="jeepay-tip-text" v-if="vdata.detailData.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'">设置不同交易金额区间对应的路由策略。</span>
|
||||
<span class="jeepay-tip-text" v-if="vdata.saveObject.rule == 5">选择适用的交易类型(如微信、支付宝等)。</span>
|
||||
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">策略门店规则设置</a-divider>
|
||||
|
||||
<a-form
|
||||
ref="infoFormModel"
|
||||
:model="vdata.receiveList"
|
||||
:label-col="{ span: 6 }"
|
||||
:wrapper-col="{ span: 15 }">
|
||||
<a-table bordered :data-source="vdata.receiveList" :columns="tableColumns"
|
||||
:pagination="false" style="margin-left: -1px;">
|
||||
<template #headerCell="{ column }">
|
||||
<span v-if="column.tooltipTitle">
|
||||
{{ column.title }}
|
||||
<a-tooltip :title="column.tooltipTitle"><info-circle-outlined /></a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #storeId="{ record }">
|
||||
<a-select class="tb_width_80" v-model:value="record.storeId" placeholder="请选择商户" show-search @change="handleStoreChange" @search="handleDivisionNameChange" :filter-option="false">
|
||||
<a-select-option v-for="d in vdata.filteredMchNameInfoList" :key="d.mchShortName" v-model:value="d.storeId">
|
||||
{{ d.storeName }} - {{ d.storeId }}- {{ d.ifName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #value="{ record }" >
|
||||
<a-input-number class="tb_width_80" addon-after="笔" :min="1" :precision="0" v-model:value="record.value" v-if="vdata.detailData.ruleStrategy == 'TRADE_NUM'" placeholder="请输入交易笔数"/>
|
||||
<a-input-number class="tb_width_80" addon-after="元" :min="1" :precision="2" v-model:value="record.value" v-if="vdata.detailData.ruleStrategy == 'TRADE_AMOUNT'" placeholder="请按照门店收款情况预估,输入收款金额"/>
|
||||
<!-- <a-input-number addon-after="笔" :min="1" v-model:value="record.content" v-if="vdata.saveObject.rule == 1" placeholder="请输入交易笔数"/>-->
|
||||
<div v-if="vdata.detailData.ruleStrategy == 'TRADE_TIME'" class="con-flex-div" >
|
||||
<a-time-picker class="con-flex-span" v-model:value="record.value" format="HH:mm" />
|
||||
<span class="rule-span">至</span>
|
||||
<a-time-picker class="con-flex-span" v-model:value="record.value1" format="HH:mm" />
|
||||
</div>
|
||||
<div v-if="vdata.detailData.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'" class="con-flex-div" >
|
||||
<a-input-number class="con-flex-span" addon-after="元" :min="1" :precision="2" v-model:value="record.value" placeholder="请输入最小金额"/>
|
||||
<span class="rule-span">至</span>
|
||||
<a-input-number class="con-flex-span" addon-after="元" :min="1" :precision="2" v-model:value="record.value1" placeholder="请输入最大金额"/>
|
||||
</div>
|
||||
<!-- <div v-if="vdata.saveObject.rule == 5" >-->
|
||||
<!-- <a-select class="con-flex-span tb_width_80" v-model:value="record.content" mode="multiple" style="width: 100%" placeholder="请选择配置" :options="vdata.payWay" />-->
|
||||
<!-- </div>-->
|
||||
<!-- <a-input-number addon-after="笔" :min="1" v-model:value="record.content" v-if="vdata.saveObject.rule == 1" placeholder="请输入交易笔数"/>-->
|
||||
</template>
|
||||
|
||||
<template #timeLimit="{ record }">
|
||||
<a-select class="con-flex-span tb_width_80" v-model:value="record.timeLimit" style="width: 100%" placeholder="请选择时限" >
|
||||
<option value="不限">不限</option>
|
||||
<option value="日">日</option>
|
||||
<option value="周">周</option>
|
||||
<option value="月">月</option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<template #typeStrategy="{ record }">
|
||||
<a-select class="con-flex-span tb_width_80" v-model:value="record.typeStrategy" mode="multiple" style="width: 100%" placeholder="请选择支付类型" :options="vdata.payWay" />
|
||||
</template>
|
||||
|
||||
<template #rate="{ record }">
|
||||
<a-input-number class="tb_width_80" addon-after="%" :min="0" :max="1" :precision="2" v-model:value="record.record" placeholder="请输入付款率"/>
|
||||
</template>
|
||||
<template #state="{ record }">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="true" />
|
||||
<!-- <a-select class="con-flex-span tb_width_80" v-model:value="record.state" mode="multiple" style="width: 100%" placeholder="请选择支付类型" :options="vdata.payWay" />-->
|
||||
</template>
|
||||
|
||||
|
||||
<template #operation="{ record }">
|
||||
<a @click="onAdd(0)" class="operation-a" >添加</a>
|
||||
<a-popconfirm title="确认删除吗?" @confirm="onDelete(record.key)">
|
||||
<a class="operation-a" style="color: #ff4c5b" v-if="record.key != 1">删除</a>
|
||||
</a-popconfirm>
|
||||
<a @click="onMove(record,1)" v-if="record.key != 1" class="operation-a" >上移</a>
|
||||
<a @click="onMove(record,0)" v-if="record.key != vdata.receiveList[vdata.receiveList.length-1].key && record.key != 1" class="operation-a" >下移</a>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-form>
|
||||
|
||||
</a-col>
|
||||
|
||||
</a-row>
|
||||
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="vdata.isShow = false"><close-outlined /> 取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.confirmLoading" @click="handleOkFunc"><check-outlined /> 保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
API_MCH_PAY_DEFINES,
|
||||
API_URL_DIVISION_TEMPLATE_SAVE_CONFIG,
|
||||
API_URL_DIVISION_TEMPLATE_EDIT,
|
||||
API_URL_MCH_QR_CODE_LIST,
|
||||
req,
|
||||
reqLoad,
|
||||
$getMchDivisionTemplateConfig,
|
||||
API_URL_MCH_STORE_LIST,
|
||||
API_URL_MCH_APPLYMENT_LIST,
|
||||
$getMchRouteConfig,
|
||||
$getMchRouteSetConfigSave
|
||||
} from '@/api/manage'
|
||||
|
||||
import { reactive, ref, getCurrentInstance, computed ,watch} from 'vue'
|
||||
import {message} from "ant-design-vue";
|
||||
import moment from 'moment';
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoFormModel = ref()
|
||||
const infoForm2Model = ref()
|
||||
const ifCode = ref('')
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => { } },
|
||||
columnsType: { type: Number, default: 0 }
|
||||
})
|
||||
|
||||
//接收方
|
||||
const tableColumns = reactive([
|
||||
// { key: 'key', title: '序号', dataIndex: 'key', align: 'center',width:'5%'},
|
||||
{ key: 'storeId',title: '门店名称', dataIndex: 'storeId', align: 'center',slots: { customRender: 'storeId' },width:'30%' },
|
||||
{ key: 'value',title: '配置', dataIndex: 'value', align: 'center',slots: { customRender: 'value' } ,width:'20%'},
|
||||
{ key: 'timeLimit',title: '时效', dataIndex: 'timeLimit', align: 'center',slots: { customRender: 'timeLimit' } ,width:'20%'},
|
||||
{ key: 'typeStrategy',title: '支付类型', dataIndex: 'typeStrategy', align: 'center',slots: { customRender: 'typeStrategy' } ,width:'15%'},
|
||||
{ key: 'rate',title: '付款率', dataIndex: 'rate', tooltipTitle: '付款率低于设置的,自动下架', align: 'center',slots: { customRender: 'rate' } ,width:'10%'},
|
||||
{ key: 'state',title: '状态', dataIndex: 'state', align: 'center',slots: { customRender: 'state' } ,width:'10%'},
|
||||
{ key: 'operation',title: '操作', dataIndex: 'operation', align: 'center',slots: { customRender: 'operation' },width:'15%' },
|
||||
])
|
||||
|
||||
const onAdd = (type = 0) => {
|
||||
if (!vdata.receiveList) {
|
||||
vdata.receiveList = [] as any
|
||||
}
|
||||
if(vdata.receiveList.length >=9){
|
||||
return $infoBox.message.error('分账接收方最多设置 9 个!')
|
||||
}
|
||||
vdata.receiveList.push({
|
||||
key: vdata.receiveList[vdata.receiveList.length - 1].key + 1,
|
||||
storeId: '',
|
||||
value: '',
|
||||
value1:"",
|
||||
rate:"",
|
||||
state:"",
|
||||
typeStrategy: [] as any,
|
||||
})
|
||||
console.log(vdata.receiveList,'vdata.receiveList')
|
||||
|
||||
}
|
||||
// const tableColumnsReceive=()=>{
|
||||
//
|
||||
// console.log(tableColumnsReceiveRatio,'tableColumnsReceivetableColumnsReceivetableColumnsReceive')
|
||||
// return tableColumnsReceiveRatio.pay as any
|
||||
// }
|
||||
// function tableColumnsCede(){
|
||||
// return tableColumnsCedePrice.pay
|
||||
// }
|
||||
|
||||
//
|
||||
const infoTable = ref();
|
||||
|
||||
const handleAdd = () => {
|
||||
// if (vdata.saveObject.appPlaceType == '1' && vdata.saveObject.receiveList.length > 1) {
|
||||
// return $infoBox.message.error('卡片模版最多添加两条记录!')
|
||||
// }
|
||||
|
||||
const newData = { key: 1, storeId: '',rate:"",state:"",value: '' as any, typeStrategy: [] as any,value1:'', operation: '' }
|
||||
vdata.receiveList.push(newData)
|
||||
infoTable.value.refTable(true);
|
||||
}
|
||||
|
||||
const vdata: any = reactive({
|
||||
ruleStrategy:true,
|
||||
filteredMchNameInfoList:[] as any,
|
||||
filteredMchNoInfoList:[] as any,
|
||||
storeList:[] as any,
|
||||
detailData:{} as any,
|
||||
payDefines: [] as any,
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isAdd: true, // 新增 or 修改页面标识
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
receiveList:[{ key: 1, storeId: '',rate:"",state:"",value: '' as any, typeStrategy: [] as any, value1:'',operation: ''}],
|
||||
expendList:[{ key: 1, storeId: '',rate:"",state:"",value: '' as any, typeStrategy: [] as any, value1:'',operation: ''}],
|
||||
saveObject: {
|
||||
receiveList: [{ key: 1, storeId: '',rate:"",state:"",value: '' as any, typeStrategy: [] as any, value1:'',operation: ''}],
|
||||
expendList: [{ key: 1, storeId: '',rate:"",state:"",value: '' as any, typeStrategy: [] as any, value1:'',operation: ''}]
|
||||
} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
groupKey: '',
|
||||
payWay:[
|
||||
{
|
||||
value: 'WECHAT',
|
||||
label: '微信',
|
||||
},
|
||||
{
|
||||
value: 'ALIPAY',
|
||||
label: '支付宝',
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
async function reqTableDataFunc(){
|
||||
return {
|
||||
hasNext:true,
|
||||
records:vdata.receiveList,
|
||||
}
|
||||
}
|
||||
const onDelete = (key,type=0) => {
|
||||
|
||||
if(type == 0){
|
||||
if (vdata.receiveList.length <= 1) {
|
||||
$infoBox.message.error('最少保留一项')
|
||||
return false
|
||||
}
|
||||
vdata.receiveList = vdata.receiveList.filter(item => item.key !== key)
|
||||
}else{
|
||||
if (vdata.expendList.length <= 1) {
|
||||
$infoBox.message.error('最少保留一项')
|
||||
return false
|
||||
}
|
||||
vdata.expendList = vdata.expendList.filter(item => item.key !== key)
|
||||
}
|
||||
}
|
||||
const rules = {
|
||||
}
|
||||
|
||||
function storeList(){
|
||||
req.list(API_URL_MCH_STORE_LIST, { 'pageSize': -1,autoConfigMchAppId:vdata.detailData.appid }).then(res => {
|
||||
vdata.storeList = res.records
|
||||
vdata.filteredMchNameInfoList = res.records
|
||||
vdata.filteredMchNoInfoList = res.records
|
||||
})
|
||||
}
|
||||
|
||||
function show( record) { // 弹层打开事件
|
||||
vdata.ruleStrategy = true
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
vdata.groupKey = 'faceAdvert'
|
||||
vdata.isAdd = !record
|
||||
|
||||
vdata.recordId = record.id
|
||||
vdata.detailData = record
|
||||
storeList()
|
||||
// 数据恢复为默认数据
|
||||
vdata.saveObject = record
|
||||
|
||||
vdata.confirmLoading = false // 关闭loading
|
||||
|
||||
vdata.receiveList = [{ key: 1, storeId: '',rate:"",state:"",value: '' as any, typeStrategy: [] as any, value1:'',operation: ''}]
|
||||
getMchRouteeConfig()
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
if (vdata.saveObject.params) {
|
||||
// vdata.saveObject.receiveList = vdata.saveObject.params
|
||||
}
|
||||
}
|
||||
vdata.isShow = true // 立马展示弹层信息
|
||||
}
|
||||
function getMchRouteeConfig(){
|
||||
$getMchRouteConfig(vdata.detailData.id).then(config => {
|
||||
|
||||
if(config.configList.length == 0){
|
||||
vdata.ruleStrategy = false;
|
||||
vdata.receiveList = [{ key: 1, storeId: '',rate:"",state:"",value: '' as any, typeStrategy: [] as any,value1:'', operation: ''}]
|
||||
return false;
|
||||
}
|
||||
const receiveList = [] as any;
|
||||
for (let i = 0;i<config.configList.length;i++){
|
||||
// moment('12:08', 'HH:mm')
|
||||
if(vdata.detailData.ruleStrategy == 'TRADE_TIME'){
|
||||
receiveList.push({
|
||||
key: i+1,
|
||||
storeId: config.configList[i].storeId,
|
||||
value: moment(config.configList[i].value[0], 'HH:mm'),
|
||||
value1: moment(config.configList[i].value[1], 'HH:mm'),
|
||||
typeStrategy: config.configList[i].typeStrategy,
|
||||
operation: ''
|
||||
})
|
||||
}else{
|
||||
receiveList.push({
|
||||
key: i+1,
|
||||
storeId: config.configList[i].storeId,
|
||||
value: config.configList[i].value[0],
|
||||
value1: config.configList[i].value[1],
|
||||
typeStrategy: config.configList[i].typeStrategy,
|
||||
operation: ''
|
||||
})
|
||||
}
|
||||
// receiveList.push({
|
||||
// key: i+1,
|
||||
// storeId: config.configList[i].storeId,
|
||||
// value: value,
|
||||
// value1: value1,
|
||||
// typeStrategy: config.configList[i].typeStrategy,
|
||||
// operation: ''
|
||||
// })
|
||||
}
|
||||
vdata.receiveList = receiveList;
|
||||
})
|
||||
}
|
||||
function handleOkFunc() { // 点击【确认】按钮事件
|
||||
vdata.confirmLoading = false // 显示loading
|
||||
|
||||
const configList = vdata.receiveList
|
||||
const list = [] as any;
|
||||
for (var i=0;i<configList.length;i++){
|
||||
console.log(configList[i].value,'configList[i].value')
|
||||
if(!configList[i].storeId){
|
||||
message.error("请选择门店")
|
||||
return false;
|
||||
}
|
||||
if(!configList[i].value){
|
||||
message.error("请输入配置")
|
||||
return false;
|
||||
}
|
||||
if(configList[i].typeStrategy.length == 0){
|
||||
message.error("请选择支付配置")
|
||||
return false;
|
||||
}
|
||||
|
||||
let value = [configList[i].value] as any;
|
||||
|
||||
if(!configList[i].value1){
|
||||
if(vdata.detailData.ruleStrategy == 'TRADE_TIME' || vdata.detailData.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'){
|
||||
message.error("请输入配置")
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
value.push(configList[i].value1)
|
||||
}
|
||||
if(vdata.detailData.ruleStrategy == 'TRADE_TIME' || vdata.detailData.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'){
|
||||
// const value = [] as any;
|
||||
const value1 = dateFormat(configList[i].value);
|
||||
const value2 = dateFormat(configList[i].value1);
|
||||
value = [value1,value2] as any;
|
||||
}
|
||||
console.log(value,'value')
|
||||
list.push({
|
||||
storeId: configList[i].storeId,
|
||||
value: value,
|
||||
typeStrategy: configList[i].typeStrategy,
|
||||
rate: configList[i].storeId,
|
||||
state: configList[i].state,
|
||||
sortNum: i,
|
||||
})
|
||||
}
|
||||
console.log(list,'listlistlist')
|
||||
const data = {
|
||||
ruleStrategy:vdata.detailData.ruleStrategy,
|
||||
configList:list,
|
||||
}
|
||||
|
||||
$getMchRouteSetConfigSave(vdata.detailData.id, data).then(res => {
|
||||
message.success('添加成功')
|
||||
props.callbackFunc() // 刷新列表
|
||||
})
|
||||
// req.add(API_URL_DIVISION_TEMPLATE_SAVE_CONFIG, vdata.saveObject).then(res => {
|
||||
// message.success('添加成功')
|
||||
// vdata.isShow = false
|
||||
// props.callbackFunc() // 刷新列表
|
||||
// }).catch(res => { vdata.confirmLoading = false })
|
||||
}
|
||||
function dateFormat(time) {
|
||||
let date = new Date(time);
|
||||
let year = date.getFullYear();
|
||||
let wk = date.getDay()
|
||||
/* 在日期格式中,月份是从0开始的,因此要加0
|
||||
* 使用三元表达式在小于10的前面加0,以达到格式统一 如 09:11:05
|
||||
* */
|
||||
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
|
||||
let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
|
||||
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
|
||||
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
|
||||
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
|
||||
let weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
|
||||
let week = weeks[wk]
|
||||
// 拼接
|
||||
return hours + ":" + minutes;
|
||||
// return year + "年" + month + "月" + day + "日" + " " + hours + ":" + minutes + ":" + seconds + ' ' + week;
|
||||
}
|
||||
const handleStoreChange=(value)=>{
|
||||
const key = [];
|
||||
vdata.receiveList.forEach((vv,kk) => {
|
||||
console.log(vv,'v1')
|
||||
const index = kk as any;
|
||||
if(vv.storeId == value){
|
||||
key.push(index as any)
|
||||
// message.error("已存在门店规格")
|
||||
return false;
|
||||
}
|
||||
})
|
||||
if(key.length > 1){
|
||||
message.error("已存在门店配置")
|
||||
vdata.receiveList[key.length-1].storeId = ''
|
||||
}
|
||||
console.log(key,'key')
|
||||
}
|
||||
//门店搜索
|
||||
const handleDivisionNameChange = (value) => {
|
||||
vdata.filteredMchNameInfoList = [];
|
||||
vdata.storeList.forEach((item: { mchShortName: string | any[], storeId: any[] },index) => {
|
||||
if (item.mchShortName.includes(value) || item.storeId.toString().includes(value) ) {
|
||||
|
||||
vdata.filteredMchNameInfoList.push(vdata.storeList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
const handleDivisionNoChange = (value) => {
|
||||
vdata.filteredMchNoInfoList = [];
|
||||
vdata.storeList.forEach((item: { mchShortName: string | any[], storeId: any[] },index) => {
|
||||
if (item.mchShortName.includes(value) || item.storeId.toString().includes(value) ) {
|
||||
vdata.filteredMchNoInfoList.push(vdata.storeList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//排序
|
||||
function onMove(record,type){
|
||||
console.log(record.key,record.userType,'key')
|
||||
const key = record.key
|
||||
let receiveList = vdata.receiveList
|
||||
vdata.receiveList = [];
|
||||
let list = [];
|
||||
for (let i=0;i<receiveList.length;i++){
|
||||
if(receiveList[i].key == key){
|
||||
if(parseInt(type) === 1){
|
||||
receiveList[i].key = parseInt(receiveList[i-1].key) - 1
|
||||
}else{
|
||||
receiveList[i].key = parseInt(receiveList[i+1].key) + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
receiveList.sort((a, b) => {
|
||||
return a.key - b.key;
|
||||
});
|
||||
receiveList.forEach((item,index) => {
|
||||
item.key = index+1
|
||||
vdata.receiveList.push(item)
|
||||
});
|
||||
}
|
||||
function updateState (fee) { // 【更新状态】
|
||||
|
||||
}
|
||||
function getRuleStrategy(e){
|
||||
console.log(e,'getRuleStrategy')
|
||||
const receiveList = [] as any
|
||||
for (var i=0;i<vdata.receiveList.length;i++){
|
||||
receiveList.push({
|
||||
storeId: vdata.receiveList[i].storeId,
|
||||
value: '',
|
||||
value1: '',
|
||||
rate: '',
|
||||
state: '',
|
||||
typeStrategy: vdata.receiveList[i].typeStrategy,
|
||||
})
|
||||
}
|
||||
vdata.receiveList = receiveList
|
||||
}
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.ant-btn-dangerous {
|
||||
position: absolute;
|
||||
right: 50px;
|
||||
}
|
||||
|
||||
.ant-row-space-between {
|
||||
position: relative;
|
||||
}
|
||||
:deep(.jeepay-table-top-row){
|
||||
display: none;
|
||||
}
|
||||
.rule-span{
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.con-flex-span{
|
||||
flex: 1 !important;
|
||||
}
|
||||
.tb_width_80{
|
||||
width: 80% !important;
|
||||
}
|
||||
.con-flex-div{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
}
|
||||
.operation-a{
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
253
jeepay-ui-merchant/src/views/divide/List.vue
Normal file
253
jeepay-ui-merchant/src/views/divide/List.vue
Normal file
@@ -0,0 +1,253 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchConditionNum="3" :searchFunc="searchFunc" :resetFunc="() => { vdata.searchData= {} }">
|
||||
<jeepay-text-up v-model:value="vdata.searchData.name" :placeholder="'交易路由策略名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appId" placeholder="应用名称/应用ID" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="是否启用">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option :value="0">否</a-select-option>
|
||||
<a-select-option :value="1">是</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.ruleStrategy" placeholder="策略规则">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="TRADE_NUM">收款笔数</a-select-option>
|
||||
<a-select-option value="TRADE_AMOUNT">累计收款金额</a-select-option>
|
||||
<a-select-option value="TRADE_TIME">收款时间段</a-select-option>
|
||||
<a-select-option value="TRADE_AMOUNT_INTERVAL">交易金额区间</a-select-option>
|
||||
<!-- <a-select-option value="4">交易类型</a-select-option>-->
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.sortStrategy" placeholder="交易顺序策略">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="ORDER">商户排列顺序</a-select-option>
|
||||
<a-select-option value="RANDOM">随机排序</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="receiverGroupId"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<div>
|
||||
<a-button v-if="$access('ENT_MCH_ROUTE_ADD')" type="primary" class="mg-b-30" @click="addFunc"><plus-outlined />新增交易路由策略</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
|
||||
<template v-if="column.key == 'name'">
|
||||
{{record.name}}
|
||||
<!-- <QrcodeOutlined style="font-size: 16px" @click="showQrImgFunc(record.routeId)" />-->
|
||||
</template>
|
||||
<template v-if="column.key == 'ruleStrategy'">
|
||||
|
||||
<a-tag v-if="record.ruleStrategy == 'TRADE_NUM'" color="orange">按收款笔数</a-tag>
|
||||
<a-tag v-if="record.ruleStrategy == 'TRADE_AMOUNT'" color="green">按累计收款金额</a-tag>
|
||||
<a-tag v-if="record.ruleStrategy == 'TRADE_TIME'" color="processing">按收款时间</a-tag>
|
||||
<a-tag v-if="record.ruleStrategy == 'TRADE_AMOUNT_INTERVAL'" color="warning">按交易金额区间</a-tag>
|
||||
|
||||
</template>
|
||||
<template v-if="column.key == 'sortStrategy'">
|
||||
<a-tag
|
||||
:key="record.sortStrategy"
|
||||
:color="record.sortStrategy === 'ORDER' ?'orange':record.sortStrategy === 'RANDOM'?'blue':''"
|
||||
>
|
||||
{{ record.sortStrategy === 'ORDER'?'商户排列顺序':record.sortStrategy === 'RANDOM'?'随机排序':'未知' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key == 'receiver'">
|
||||
--
|
||||
</template>
|
||||
<template v-if="column.key == 'divider'">
|
||||
--
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'appName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>应用名称:{{record.appName}}</span><br>
|
||||
<span>应用ID:{{record.appid}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.appName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'state'">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="true" :onChange="(state) => { return updateState(record.routeId, state)}" />
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<!-- <a-button v-if="$access('ENT_MCH_ROUTE_CONFIG')" type="link" style="padding-left: 10px;padding-right: 10px;" @click="groupAddFunc(record)">路由配置</a-button>-->
|
||||
<a-button v-if="$access('ENT_MCH_ROUTE_EDIT')" type="link" style="padding-left: 10px;padding-right: 10px;" @click="editFunc(record)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_ROUTE_DEL')" type="link" style="color: red" @click="delFunc(record.routeId)">删除</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 新增 / 修改 页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<ReceiverGroupAdd ref="ledgerGroupAdd" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
<a-modal
|
||||
v-model:visible="vdata.visibleAdd"
|
||||
:footer="null"
|
||||
@cancel="handleCancel"
|
||||
style="top: 35% !important;"
|
||||
wrap-class-name="full-modal"
|
||||
width="330px"
|
||||
:maskClosable="false"
|
||||
>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- 扫条码与刷脸 -->
|
||||
|
||||
<div >
|
||||
<img
|
||||
v-if="vdata.qrCodeUrl"
|
||||
:src="vdata.qrCodeUrl"
|
||||
alt=""
|
||||
style="width: 200px; height: 200px"
|
||||
>
|
||||
<div class="zfb-wx" style="margin: 10px 0">
|
||||
<img src="/src/assets/svg/alipay.svg" alt="">
|
||||
<img
|
||||
src="/src/assets/svg/wechatpay.svg"
|
||||
alt=""
|
||||
style="margin: 0 5px"
|
||||
>
|
||||
<span style="color: grey">支持支付宝与微信支付</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 提示文字 来自函数-->
|
||||
<p style="font-size: 20px; font-weight: 500; color: grey">
|
||||
请扫描二维码付款
|
||||
</p>
|
||||
<a-button
|
||||
type="primary"
|
||||
class="cancel"
|
||||
size="large"
|
||||
block
|
||||
@click="vdata.visibleAdd = false"
|
||||
>
|
||||
取消
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
</a-modal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
$getMchRouteQrcode,
|
||||
$qrcShellViewByQrc,
|
||||
API_URL_DIVISION_RECEIVER_GROUP,
|
||||
API_URL_DIVISION_TEMPLATE_DEL,
|
||||
API_URL_DIVISION_TEMPLATE_EDIT,
|
||||
API_URL_DIVISION_TEMPLATE_LIST,
|
||||
API_URL_ENT_MCH_ROUTE_DEL,
|
||||
API_URL_ENT_MCH_ROUTE_EDIT,
|
||||
API_URL_ENT_MCH_ROUTE_LIST, API_URL_ENT_MCH_ROUTE_SAVE,
|
||||
API_URL_MCH_QR_CODE_LIST,
|
||||
req,
|
||||
reqLoad
|
||||
} from '@/api/manage'
|
||||
import InfoAddOrEdit from './AddOrEdit.vue'
|
||||
import ReceiverGroupAdd from "./GroupAdd.vue";
|
||||
import { reactive, ref,getCurrentInstance } from 'vue'
|
||||
import {message} from "ant-design-vue";
|
||||
const { $access,$infoBox,$viewerApi } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const tableColumns = reactive([
|
||||
{ key: 'name', dataIndex: 'name', title: '交易路由策略名称' },
|
||||
{ key: 'ruleStrategy', dataIndex: 'ruleStrategy', title: '策略规则' },
|
||||
{ key: 'appName', dataIndex: 'appName', title: '应用名称' },
|
||||
{ key: 'sortStrategy', dataIndex: 'sortStrategy', title: '交易顺序策略' },
|
||||
{ key: 'state', title: '是否启用', },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建时间' },
|
||||
{ key: 'op', title: '操作', width: '200px', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
|
||||
const infoAddOrEdit =ref()
|
||||
const ledgerGroupAdd =ref()
|
||||
const infoTable = ref()
|
||||
const vdata = reactive ({
|
||||
visibleAdd:false,
|
||||
qrCodeUrl:"" as any,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {} as any,
|
||||
btnLoading: false
|
||||
})
|
||||
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_ENT_MCH_ROUTE_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
vdata.btnLoading = true // 打开查询按钮上的loading
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function addFunc() { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show()
|
||||
}
|
||||
|
||||
function editFunc(record) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(record)
|
||||
}
|
||||
|
||||
function handleCancel(e) {
|
||||
vdata.visibleAdd = false;
|
||||
}
|
||||
function delFunc (recordId) { // 业务通用【删除】 函数
|
||||
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
// 需要【按钮】loading 请返回 promise对象, 不需要请直接返回null
|
||||
return req.delById(API_URL_ENT_MCH_ROUTE_DEL, recordId).then(res => {
|
||||
$infoBox. message.success('删除成功!')
|
||||
infoTable.value.refTable(false)
|
||||
})
|
||||
},() => {
|
||||
})
|
||||
}
|
||||
function groupAddFunc(record) { // 业务通用【新增】 函数
|
||||
ledgerGroupAdd.value.show(record)
|
||||
}
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
|
||||
const title = state === 1 ? '确认[启用]?' : '确认[停用]?'
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, '', () => {
|
||||
return reqLoad.updateById(API_URL_ENT_MCH_ROUTE_SAVE, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function showQrImgFunc(recordId){
|
||||
$getMchRouteQrcode(recordId).then((res) => {
|
||||
// $viewerApi({images: [res]})
|
||||
vdata.qrCodeUrl = res
|
||||
vdata.visibleAdd = true
|
||||
})
|
||||
}
|
||||
</script>
|
||||
212
jeepay-ui-merchant/src/views/division/group/AddOrEdit.vue
Normal file
212
jeepay-ui-merchant/src/views/division/group/AddOrEdit.vue
Normal file
@@ -0,0 +1,212 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.isShow"
|
||||
:title=" vdata.isAdd ? '新增分账模版' : '修改分账模版' "
|
||||
:confirmLoading="vdata.confirmLoading"
|
||||
@ok="handleOkFunc"
|
||||
@close="onClose"
|
||||
width="50%"
|
||||
>
|
||||
<a-form ref="infoFormModel" layout="vertical" :model="vdata.saveObject" :label-col="{span: 6}" :wrapper-col="{span: 15}" :rules="vdata.rules">
|
||||
<a-form-item label="分账模版名称:" name="name">
|
||||
<a-input v-model:value="vdata.saveObject.name" placeholder="请输入分账模版名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="支付通道:" name="ifCode">
|
||||
<a-select v-model:value="vdata.saveObject.ifCode" placeholder="支付通道" @change="getIfCode">
|
||||
<a-select-option v-for="item in vdata.payDefines" :key="item.ifCode" :value="item.ifCode" :disabled="item.ifCode != 'yspay' && item.ifCode != 'dgpay'">{{ item.ifName }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="分账模式:" name="divisionMode" >
|
||||
<div style="display: grid;">
|
||||
<a-radio-group v-model:value="vdata.saveObject.divisionMode">
|
||||
<a-radio v-for="item in vdata.modeList" :key="item.value" :value="item.value" >
|
||||
{{ item.name }}
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
<span class="jeepay-tip-text" v-if="vdata.saveObject.divisionMode == 0">({{ vdata.saveObject.ifCode === 'yspay'?'默认分账比例为30%,最高可申请至100%':vdata.saveObject.ifCode === 'dgpay'?'分账比例最高为30%':'' }})</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="最小支付金额:" name="minAmount" v-if="vdata.saveObject.divisionMode == 1">
|
||||
<a-input v-model:value="vdata.saveObject.minAmount" placeholder="请输入最小支付金额" :precision="2" :min="0"/>
|
||||
</a-form-item>
|
||||
<a-form-item label="分账金额:" name="divisionAmount" v-if="vdata.saveObject.divisionMode == 1">
|
||||
<a-input v-model:value="vdata.saveObject.divisionAmount" placeholder="请输入分账金额" :precision="2" :min="0"/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="分账类型:" name="divisionType">
|
||||
<div style="display: grid;">
|
||||
<a-radio-group v-model:value="vdata.saveObject.divisionType">
|
||||
<a-radio v-for="item in vdata.typeList" :key="item.value" :value="item.value" :disabled="item.value ==3 && vdata.saveObject.ifCode == 'dgpay'" >
|
||||
{{ item.name }}
|
||||
<!-- <a-tooltip v-if="item.value == 1" title="订单产生后立马发起分账指令,资金D1结算">-->
|
||||
<!-- <question-circle-outlined style="font-size: 16px;"/>-->
|
||||
<!-- </a-tooltip>-->
|
||||
<!-- <a-tooltip v-if="item.value == 2" :title="vdata.saveObject.ifCode === 'yspay'?'订单产生后90天内都可以发起分账指令,资金D1结算,如90天内未发起分账指令,资金于第二个工作日自动结算至收款商户的结算银行卡':vdata.saveObject.ifCode === 'dgpay'?'订单产生后180天内都可以发起分账指令,资金D1结算,如180天内未发起分账指令,资金于第二个工作日自动结算至收款商户的结算银行卡':''">-->
|
||||
<!-- <question-circle-outlined style="font-size: 16px; "/>-->
|
||||
<!-- </a-tooltip>-->
|
||||
<!-- <a-tooltip v-if="item.value == 3 && vdata.saveObject.ifCode === 'yspay'" :title="vdata.saveObject.ifCode === 'yspay'?'订单产生后立马发起分账指令,资金D0结算':''">-->
|
||||
<!-- <question-circle-outlined style="font-size: 16px; "/>-->
|
||||
<!-- </a-tooltip>-->
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
<span class="jeepay-tip-text" v-if="vdata.saveObject.divisionType == 0">(订单产生后立马发起分账指令,资金D1结算)</span>
|
||||
<span class="jeepay-tip-text" v-if="vdata.saveObject.divisionType == 1">({{ vdata.saveObject.ifCode === 'yspay'?'订单产生后90天内都可以发起分账指令,资金D1结算,如90天内未发起分账指令,资金于第二个工作日自动结算至收款商户的结算银行卡':vdata.saveObject.ifCode === 'dgpay'?'订单产生后180天内都可以发起分账指令,资金D1结算,如180天内未发起分账指令,资金于第二个工作日自动结算至收款商户的结算银行卡':'' }})</span>
|
||||
<span class="jeepay-tip-text" v-if="vdata.saveObject.divisionType == 2 && vdata.saveObject.ifCode === 'yspay'">({{ vdata.saveObject.ifCode === 'yspay'?'订单产生后立马发起分账指令,资金D0结算':'' }})</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item label="指定设备" name="isSpecify">
|
||||
<a-radio-group v-model:value="vdata.saveObject.isSpecify">
|
||||
<a-radio :value="0">全部设备</a-radio>
|
||||
<a-radio :value="1">指定设备</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-row v-if="vdata.saveObject.isSpecify == 1" justify="space-between" type="flex">
|
||||
<a-col v-if="vdata.saveObject.deviceInfo && vdata.saveObject.deviceInfo.length > 0" :span="24">
|
||||
<a-form-item label="设备码牌ID">
|
||||
<a-textarea v-model:value="vdata.saveObject.deviceInfo" disabled />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24" >
|
||||
<a-form-item>
|
||||
<a-button type="primary" @click="showQrcSelectModel">{{ vdata.isAdd ? '选择绑定设备' : '重新绑定设备' }}</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="vdata.isShow = false"><close-outlined /> 取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.confirmLoading" @click="handleOkFunc"><check-outlined /> 保存</a-button>
|
||||
</div>
|
||||
<!-- 选择码牌组件 -->
|
||||
<!-- <JeepayModelQrcList ref="jeepayModelQrcListRef" @selectFinishFunc="selectQrcFinishFunc" />-->
|
||||
<JeepayModelAccountsQrcList ref="jeepayModelQrcListRef" @selectFinishFunc="selectQrcFinishFunc" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
API_MCH_PAY_DEFINES,
|
||||
API_URL_DIVISION_RECEIVER_GROUP,
|
||||
API_URL_DIVISION_TEMPLATE_ADD,
|
||||
API_URL_DIVISION_TEMPLATE_EDIT,
|
||||
req
|
||||
} from '@/api/manage'
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
import { message } from 'ant-design-vue'
|
||||
import {getCurrentInstance, reactive, ref} from 'vue'
|
||||
import ReceiverGroupAdd from './ReceiverGroupAdd.vue'
|
||||
|
||||
const jeepayModelQrcListRef = ref()
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const vdata = reactive ({
|
||||
modeList:[
|
||||
{name:"按比例分账",value:0},
|
||||
{name:"按金额分账",value:1},
|
||||
],
|
||||
typeList:[
|
||||
{name:"实时分账",value:0},
|
||||
{name:"延时分账",value:1},
|
||||
{name:"秒到分账",value:2},
|
||||
],
|
||||
payDefines: [] as any,
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isAdd: true, // 新增 or 修改页面标识
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: { autoDivisionFlag: 0,ifCode:"" } as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
rules: {
|
||||
name: [{ required: true, message: '请输入组名称', trigger: 'blur' }],
|
||||
ifCode: [{ required: true, message: '请选择所属渠道', trigger: 'blur' }],
|
||||
divisionMode: [{ required: true, message: '请输入分账模式', trigger: 'blur' }],
|
||||
divisionType: [{ required: true, message: '请输入分账类型', trigger: 'blur' }],
|
||||
divisionAmount: [{ required: true, message: '请输入分账金额', trigger: 'blur' }],
|
||||
minAmount: [{ required: true, message: '请输入最小支付金额', trigger: 'blur' }],
|
||||
isSpecify: [{ required: true, message: '请指定指定设备', trigger: 'blur' }],
|
||||
deviceInfo: [{ required: true, message: '请选择设备信息', trigger: 'blur' }]
|
||||
}
|
||||
})
|
||||
function onClose(){
|
||||
vdata.isShow = false
|
||||
}
|
||||
defineExpose({show})
|
||||
function show (record) { // 弹层打开事件
|
||||
vdata.isAdd = !record
|
||||
vdata.saveObject = { autoDivisionFlag: 0 } // 数据清空
|
||||
vdata.confirmLoading = false // 关闭loading
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
payFefines()
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.recordId = record.id
|
||||
vdata.saveObject = record
|
||||
if(record.divisionMode == 1){
|
||||
vdata.saveObject.divisionAmount = (record.divisionAmount/ 100).toFixed(2)
|
||||
vdata.saveObject.minAmount = (record.minAmount/ 100).toFixed(2)
|
||||
}
|
||||
console.log(vdata.saveObject,'saveObjectsaveObjectsaveObjectsaveObjectsaveObject')
|
||||
vdata.isShow = true
|
||||
} else {
|
||||
vdata.isShow = true // 立马展示弹层信息
|
||||
}
|
||||
}
|
||||
function getType(e){
|
||||
console.log(vdata.saveObject.type,'vdata.saveObject.type')
|
||||
}
|
||||
function payFefines() {
|
||||
req.list(API_MCH_PAY_DEFINES,{ 'pageSize': -1 }).then(res => {
|
||||
vdata.payDefines = res
|
||||
})
|
||||
}
|
||||
|
||||
function getIfCode(){
|
||||
console.log(vdata.saveObject.ifCode,'saveObjectsaveObjectsaveObject')
|
||||
}
|
||||
function handleOkFunc() { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then(valid=>{
|
||||
vdata.confirmLoading = true // 显示loading
|
||||
|
||||
if (vdata.isAdd) {
|
||||
req.add(API_URL_DIVISION_TEMPLATE_ADD, vdata.saveObject).then(res => {
|
||||
message.success('添加成功')
|
||||
vdata.isShow = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(res => { vdata.confirmLoading = false })
|
||||
} else {
|
||||
req.updateById(API_URL_DIVISION_TEMPLATE_EDIT, vdata.recordId, vdata.saveObject).then(res => {
|
||||
message.success('修改成功')
|
||||
vdata.isShow = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(res => { vdata.confirmLoading = false })
|
||||
}
|
||||
})
|
||||
}
|
||||
function selectQrcFinishFunc (e) { // 码牌选择完成事件
|
||||
|
||||
if (!e || e.length <= 0) {
|
||||
return $infoBox.message.error('请开启要绑定的码牌!')
|
||||
}
|
||||
|
||||
vdata.saveObject.deviceInfo = e
|
||||
jeepayModelQrcListRef.value.close()
|
||||
}
|
||||
|
||||
function showQrcSelectModel() {
|
||||
if(!vdata.saveObject.ifCode){
|
||||
return $infoBox.message.error('请选择支付通道!')
|
||||
}
|
||||
jeepayModelQrcListRef.value.show(vdata.saveObject.storeId, vdata.saveObject.deviceInfo, vdata.saveObject.ifCode)
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.jeepay-tip-text::before{
|
||||
border: none !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchConditionNum="3" :searchFunc="searchFunc" :resetFunc="() => { vdata.searchData= {} }">
|
||||
<jeepay-text-up v-model:value="vdata.searchData.name" :placeholder="'分账模版名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.ifCode" :placeholder="'支付通道'" />
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="receiverGroupId"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<div>
|
||||
<a-button v-if="$access('ENT_DIVISION_TEMPLATE_ADD')" type="primary" class="mg-b-30" @click="addFunc"><plus-outlined />新增分账模版</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'ifCode'">
|
||||
--
|
||||
</template>
|
||||
<template v-if="column.key == 'divisionMode'">
|
||||
<a-tag
|
||||
:key="record.divisionMode"
|
||||
:color="record.divisionMode === 0 ?'orange':record.divisionMode === 1?'blue':''"
|
||||
>
|
||||
{{ record.divisionMode === 0?'按比例分账':record.divisionMode === 1?'按金额分账':'未知' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key == 'divisionType'">
|
||||
|
||||
|
||||
<a-tag
|
||||
:key="record.divisionType"
|
||||
:color="record.divisionType === 0 ?'orange':record.divisionType === 1?'orange':record.divisionType === 2?'blue':''"
|
||||
>
|
||||
{{ record.divisionType === 0?'实时分账':record.divisionType === 1?'延时分账':record.divisionType === 2?'延时分账':'未知' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key == 'receiver'">
|
||||
--
|
||||
</template>
|
||||
<template v-if="column.key == 'divider'">
|
||||
--
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'state'">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="true" :onChange="(state) => { return updateState(record.id, state)}" />
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<a-button v-if="$access('ENT_DIVISION_TEMPLATE_EDIT')" type="link" style="padding-left: 10px;padding-right: 10px;" @click="groupAddFunc(record)">分账设置</a-button>
|
||||
<a-button v-if="$access('ENT_DIVISION_TEMPLATE_EDIT')" type="link" style="padding-left: 10px;padding-right: 10px;" @click="editFunc(record)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_DIVISION_TEMPLATE_DELETE')" type="link" style="color: red" @click="delFunc(record.id)">删除</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 新增 / 修改 页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<ReceiverGroupAdd ref="ledgerGroupAdd" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
API_URL_DIVISION_RECEIVER_GROUP,
|
||||
API_URL_DIVISION_TEMPLATE_DEL, API_URL_DIVISION_TEMPLATE_EDIT,
|
||||
API_URL_DIVISION_TEMPLATE_LIST, API_URL_MCH_QR_CODE_LIST,
|
||||
req, reqLoad
|
||||
} from '@/api/manage'
|
||||
import InfoAddOrEdit from './AddOrEdit.vue'
|
||||
import ReceiverGroupAdd from "./ReceiverGroupAdd.vue";
|
||||
import { reactive, ref,getCurrentInstance } from 'vue'
|
||||
import {message} from "ant-design-vue";
|
||||
const { $access,$infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const tableColumns = reactive([
|
||||
{ key: 'name', dataIndex: 'name', title: '分账模版名称' },
|
||||
{ key: 'ifName', dataIndex: 'ifName', title: '支付通道' },
|
||||
{ key: 'divisionMode', dataIndex: 'divisionMode', title: '分账模式' },
|
||||
{ key: 'divisionType', dataIndex: 'divisionType', title: '分账类型' },
|
||||
// { key: 'receiver', dataIndex: 'receiver', title: '分账接收方' },
|
||||
// { key: 'divider', dataIndex: 'divider', title: '分账分出方' },
|
||||
{ key: 'state', title: '使用状态', },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建时间' },
|
||||
{ key: 'op', title: '操作', width: '200px', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
|
||||
const infoAddOrEdit =ref()
|
||||
const ledgerGroupAdd =ref()
|
||||
const infoTable = ref()
|
||||
const vdata = reactive ({
|
||||
tableColumns: tableColumns,
|
||||
searchData: {} as any,
|
||||
btnLoading: false
|
||||
})
|
||||
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_DIVISION_TEMPLATE_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
vdata.btnLoading = true // 打开查询按钮上的loading
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function addFunc() { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show()
|
||||
}
|
||||
|
||||
function editFunc(record) { // 业务通用【修改】 函数
|
||||
console.log(record,'recordrecordrecordrecordrecord')
|
||||
infoAddOrEdit.value.show(record)
|
||||
}
|
||||
|
||||
function delFunc (recordId) { // 业务通用【删除】 函数
|
||||
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
// 需要【按钮】loading 请返回 promise对象, 不需要请直接返回null
|
||||
return req.delById(API_URL_DIVISION_TEMPLATE_DEL, recordId).then(res => {
|
||||
$infoBox. message.success('删除成功!')
|
||||
infoTable.value.refTable(false)
|
||||
})
|
||||
},() => {
|
||||
})
|
||||
}
|
||||
function groupAddFunc(record) { // 业务通用【新增】 函数
|
||||
ledgerGroupAdd.value.show(record)
|
||||
}
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
|
||||
const title = state === 1 ? '确认[启用]?' : '确认[停用]?'
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, '', () => {
|
||||
return reqLoad.updateById(API_URL_DIVISION_TEMPLATE_EDIT, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
459
jeepay-ui-merchant/src/views/division/group/ReceiverGroupAdd.vue
Normal file
459
jeepay-ui-merchant/src/views/division/group/ReceiverGroupAdd.vue
Normal file
@@ -0,0 +1,459 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.isShow"
|
||||
:title="vdata.isAdd ? '新增分账组' : '编辑分账组'"
|
||||
width="80%"
|
||||
:mask-closable="false"
|
||||
@close="vdata.isShow = false"
|
||||
>
|
||||
|
||||
<a-row >
|
||||
|
||||
|
||||
<a-col :span="24">
|
||||
<div style="margin: 10px 30px;">
|
||||
分账接收方
|
||||
</div>
|
||||
<!-- :columns="tableColumnsReceiveRatio.pay"-->
|
||||
<a-form
|
||||
ref="infoFormModel"
|
||||
:model="vdata.receiveList"
|
||||
:label-col="{ span: 6 }"
|
||||
:wrapper-col="{ span: 15 }">
|
||||
<a-table bordered :data-source="vdata.receiveList" :columns="ifCode == 'dgpay'?tableColumnsReceiveRatio.pay:tableColumnsReceiveRatio.dgpay"
|
||||
:pagination="false" style="margin-left: -1px;">
|
||||
<template #name="{ record }">
|
||||
<a-input v-model:value="record.name" placeholder="请输入个人名称/商户名称" v-if="record.userType == 0" />
|
||||
<a-select style="min-width: 300px" v-model:value="record.name" v-if="record.userType == 1" placeholder="请选择商户" show-search @search="handleDivisionNameChange" :filter-option="false">
|
||||
<a-select-option v-for="d in vdata.filteredMchNameInfoList" :key="d.mchShortName" v-model:value="d.mchShortName">
|
||||
{{ d.mchShortName }} - {{ d.applyId }}- {{ d.ifName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #userType="{ record }">
|
||||
<a-radio-group v-model:value="record.userType">
|
||||
<a-radio :value="0" > 个人 </a-radio>
|
||||
<a-radio :value="1" > 商户 </a-radio>
|
||||
</a-radio-group>
|
||||
</template>
|
||||
|
||||
<template #divisionNo="{ record }">
|
||||
<a-input v-model:value="record.divisionNo" v-if="record.userType == 0" placeholder="请输入手机号/商户号" />
|
||||
<a-select style="min-width: 300px" v-model:value="record.divisionNo" v-if="record.userType == 1" placeholder="请选择商户" show-search @search="handleDivisionNameChange" :filter-option="false">
|
||||
<a-select-option v-for="d in vdata.filteredMchNameInfoList" :key="d.applyId" v-model:value="d.applyId">
|
||||
{{ d.mchShortName }} - {{ d.applyId }}- {{ d.ifName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #divisionValue="{ record }">
|
||||
|
||||
<a-input-number v-if="vdata.detailData.divisionMode == 1" addon-after="元" v-model:value="record.divisionValue" :precision="2" :min="0"
|
||||
:step="0.01" placeholder="请输入分账金额" />
|
||||
<a-input-number v-if="vdata.detailData.divisionMode == 0" addon-after="%" v-model:value="record.divisionValue" :precision="2" :min="0"
|
||||
:step="0.01" placeholder="请输入分账比例" />
|
||||
</template>
|
||||
|
||||
<template #isCharge="{ record }">
|
||||
<a-radio-group v-model:value="record.isCharge" >
|
||||
<a-radio :value="0" > 否 </a-radio>
|
||||
<a-radio :value="1" > 是 </a-radio>
|
||||
</a-radio-group>
|
||||
</template>
|
||||
|
||||
<template #operation="{ record }">
|
||||
<a-popconfirm title="确认删除吗?" @confirm="onDelete(record.key)">
|
||||
<a style="margin-right: 20px;color: #ff4c5b">删除</a>
|
||||
</a-popconfirm>
|
||||
<a @click="onAdd(0)">添加</a>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-form>
|
||||
|
||||
</a-col>
|
||||
|
||||
<a-form
|
||||
ref="infoForm2Model"
|
||||
:model="vdata.expendList"
|
||||
:label-col="{ span: 6 }"
|
||||
:wrapper-col="{ span: 15 }">
|
||||
<a-col :span="24">
|
||||
<div style="margin: 10px 30px;">
|
||||
分账分出方
|
||||
</div>
|
||||
<!-- :table-columns="tableColumnsCede as any"-->
|
||||
|
||||
<a-table bordered :data-source="vdata.expendList" :columns="ifCode == 'dgpay'?tableColumnsCedeRatio.pay:tableColumnsCedePrice.dgpay"
|
||||
:pagination="false" style="margin-left: -1px;">
|
||||
<template #name="{ record }">
|
||||
<a-input v-model:value="record.name" v-if="record.userType == 0" placeholder="请输入个人名称/商户名称" />
|
||||
<a-select style="min-width: 300px" v-model:value="record.name" v-if="record.userType == 1" placeholder="请选择商户" show-search @search="handleDivisionNoChange" :filter-option="false">
|
||||
<a-select-option v-for="d in vdata.filteredMchNoInfoList" :key="d.mchShortName" v-model:value="d.mchShortName">
|
||||
{{ d.mchShortName }} - {{ d.applyId }}- {{ d.ifName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #userType="{ record }">
|
||||
<a-radio-group v-model:value="record.userType">
|
||||
<a-radio :value="0" > 个人 </a-radio>
|
||||
<a-radio :value="1" > 商户 </a-radio>
|
||||
</a-radio-group>
|
||||
</template>
|
||||
|
||||
<template #divisionNo="{ record }">
|
||||
<a-input v-model:value="record.divisionNo" v-if="record.userType == 0" placeholder="请输入手机号/商户号" />
|
||||
<a-select style="min-width: 300px" v-model:value="record.divisionNo" v-if="record.userType == 1" placeholder="请选择商户" show-search @search="handleDivisionNoChange" :filter-option="false">
|
||||
<a-select-option v-for="d in vdata.filteredMchNoInfoList" :key="d.applyId" v-model:value="d.applyId">
|
||||
{{ d.mchShortName }} - {{ d.applyId }}- {{ d.ifName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #divisionValue="{ record }">
|
||||
<a-input v-model:value="record.divisionValue" />
|
||||
</template>
|
||||
|
||||
<template #isCharge="{ record }">
|
||||
<a-radio-group v-model:value="record.isCharge">
|
||||
<a-radio :value="0" > 否 </a-radio>
|
||||
<a-radio :value="1" > 是 </a-radio>
|
||||
</a-radio-group>
|
||||
</template>
|
||||
|
||||
<template #operation="{ record }">
|
||||
<a-popconfirm title="确认删除吗?" @confirm="onDelete(record.key,1)">
|
||||
<a style="margin-right: 20px;color: #ff4c5b">删除</a>
|
||||
</a-popconfirm>
|
||||
<a @click="onAdd(1)">添加</a>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-col>
|
||||
</a-form>
|
||||
</a-row>
|
||||
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="vdata.isShow = false"><close-outlined /> 取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.confirmLoading" @click="handleOkFunc"><check-outlined /> 保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
API_MCH_PAY_DEFINES,
|
||||
API_URL_DIVISION_TEMPLATE_SAVE_CONFIG,
|
||||
API_URL_DIVISION_TEMPLATE_EDIT,
|
||||
API_URL_MCH_QR_CODE_LIST,
|
||||
req,
|
||||
reqLoad, $getMchDivisionTemplateConfig, API_URL_MCH_STORE_LIST, API_URL_MCH_APPLYMENT_LIST
|
||||
} from '@/api/manage'
|
||||
|
||||
import { reactive, ref, getCurrentInstance, computed ,watch} from 'vue'
|
||||
import {message} from "ant-design-vue";
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoFormModel = ref()
|
||||
const infoForm2Model = ref()
|
||||
const ifCode = ref('')
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => { } },
|
||||
columnsType: { type: Number, default: 0 }
|
||||
})
|
||||
|
||||
//接收方
|
||||
const tableColumnsReceiveRatio = reactive({
|
||||
"pay":[
|
||||
{ key: 'key', title: '序号', dataIndex: 'key', align: 'center'},
|
||||
{ key: 'userType',title: '用户类型', dataIndex: 'userType', align: 'center',slots: { customRender: 'userType' } },
|
||||
{ key: 'name',title: '个人名称/商户名称', dataIndex: 'name', align: 'center',slots: { customRender: 'name' } },
|
||||
{ key: 'divisionNo',title: ' 手机号/商户号', dataIndex: 'divisionNo', align: 'center',slots: { customRender: 'divisionNo' } },
|
||||
{ key: 'divisionValue ',title: '分账接收', dataIndex: 'divisionValue ', align: 'center',slots: { customRender: 'divisionValue' }},
|
||||
{ key: 'isCharge',title: '是否承担手续费 ', dataIndex: 'isCharge', align: 'center',slots: { customRender: 'isCharge' }},
|
||||
{ key: 'operation',title: '操作', dataIndex: 'operation', align: 'center',slots: { customRender: 'operation' } },
|
||||
],
|
||||
"dgpay":[
|
||||
{ key: 'key', title: '序号', dataIndex: 'key', align: 'center' },
|
||||
{ key: 'userType',title: '用户类型', dataIndex: 'userType', align: 'center',slots: { customRender: 'userType' } },
|
||||
{ key: 'name',title: '个人名称/商户名称', dataIndex: 'name', align: 'center',slots: { customRender: 'name' } },
|
||||
{ key: 'divisionNo',title: ' 手机号/商户号', dataIndex: 'divisionNo', align: 'center',slots: { customRender: 'divisionNo' } },
|
||||
{ key: 'divisionValue ',title: '分账接收', dataIndex: 'divisionValue ', align: 'center',slots: { customRender: 'divisionValue' }},
|
||||
{ key: 'isCharge',title: '是否承担手续费 ', dataIndex: 'isCharge', align: 'center',slots: { customRender: 'isCharge' }},
|
||||
{ key: 'operation',title: '操作', dataIndex: 'operation', align: 'center',slots: { customRender: 'operation' } },
|
||||
],
|
||||
})
|
||||
//分出方
|
||||
const tableColumnsCedeRatio = reactive({
|
||||
"pay":[
|
||||
{ title: '序号', dataIndex: 'key', align: 'center' },
|
||||
{ key: 'userType',title: '用户类型', dataIndex: 'userType', align: 'center',slots: { customRender: 'userType' } },
|
||||
{ key: 'name',title: '个人名称/商户名称', dataIndex: 'name', align: 'center',slots: { customRender: 'name' } },
|
||||
{ key: 'divisionNo',title: ' 手机号/商户号', dataIndex: 'divisionNo', align: 'center',slots: { customRender: 'divisionNo' } },
|
||||
{ key: 'operation',title: '操作', dataIndex: 'operation', align: 'center',slots: { customRender: 'operation' } },
|
||||
],
|
||||
"dgpay":[
|
||||
{ title: '序号', dataIndex: 'key', align: 'center' },
|
||||
{ key: 'userType',title: '用户类型', dataIndex: 'userType', align: 'center',slots: { customRender: 'userType' } },
|
||||
{ key: 'name',title: '个人名称/商户名称', dataIndex: 'name', align: 'center',slots: { customRender: 'name' } },
|
||||
{ key: 'divisionNo',title: ' 手机号/商户号', dataIndex: 'divisionNo', align: 'center',slots: { customRender: 'divisionNo' } },
|
||||
{ key: 'operation',title: '操作', dataIndex: 'operation', align: 'center',slots: { customRender: 'operation' } },
|
||||
],
|
||||
})
|
||||
|
||||
//接收方
|
||||
const tableColumnsReceivePrice = reactive({
|
||||
"pay":[
|
||||
{ key: 'key', title: '序号', dataIndex: 'key', align: 'center' },
|
||||
{ key: 'userType',title: '用户类型', dataIndex: 'userType', align: 'center',slots: { customRender: 'userType' } },
|
||||
{ key: 'name',title: '个人名称/商户名称', dataIndex: 'name', align: 'center',slots: { customRender: 'name' } },
|
||||
{ key: 'divisionNo',title: ' 手机号/商户号', dataIndex: 'divisionNo', align: 'center',slots: { customRender: 'divisionNo' } },
|
||||
{ key: 'divisionValue ',title: '分账接收', dataIndex: 'divisionValue ', align: 'center',slots: { customRender: 'divisionValue' }},
|
||||
{ key: 'isCharge',title: '是否承担手续费 ', dataIndex: 'isCharge', align: 'center',slots: { customRender: 'isCharge' }},
|
||||
{ key: 'operation',title: '操作', dataIndex: 'operation', align: 'center',slots: { customRender: 'operation' } },
|
||||
],
|
||||
"dgpay":[
|
||||
{ title: '序号', dataIndex: 'key', align: 'center' },
|
||||
{ key: 'userType',title: '用户类型', dataIndex: 'userType', align: 'center',slots: { customRender: 'userType' } },
|
||||
{ key: 'name',title: '个人名称/商户名称', dataIndex: 'name', align: 'center',slots: { customRender: 'name' } },
|
||||
{ key: 'divisionNo',title: ' 手机号/商户号', dataIndex: 'divisionNo', align: 'center',slots: { customRender: 'divisionNo' } },
|
||||
{ key: 'divisionValue ',title: '分账接收', dataIndex: 'divisionValue ', align: 'center',slots: { customRender: 'divisionValue' }},
|
||||
{ key: 'isCharge',title: '是否承担手续费 ', dataIndex: 'isCharge', align: 'center',slots: { customRender: 'isCharge' }},
|
||||
{ key: 'operation',title: '操作', dataIndex: 'operation', align: 'center',slots: { customRender: 'operation' } },
|
||||
],
|
||||
})
|
||||
//分出方
|
||||
const tableColumnsCedePrice = reactive({
|
||||
"pay":[
|
||||
{ title: '序号', dataIndex: 'key', align: 'center' },
|
||||
{ key: 'userType',title: '用户类型', dataIndex: 'userType', align: 'center',slots: { customRender: 'userType' } },
|
||||
{ key: 'name',title: '个人名称/商户名称', dataIndex: 'name', align: 'center',slots: { customRender: 'name' } },
|
||||
{ key: 'divisionNo',title: ' 手机号/商户号', dataIndex: 'divisionNo', align: 'center',slots: { customRender: 'divisionNo' } },
|
||||
{ key: 'operation',title: '操作', dataIndex: 'operation', align: 'center',slots: { customRender: 'operation' } },
|
||||
],
|
||||
"dgpay":[
|
||||
{ title: '序号', dataIndex: 'key', align: 'center' },
|
||||
{ key: 'userType',title: '用户类型', dataIndex: 'userType', align: 'center',slots: { customRender: 'userType' } },
|
||||
{ key: 'name',title: '个人名称/商户名称', dataIndex: 'name', align: 'center',slots: { customRender: 'name' } },
|
||||
{ key: 'divisionNo',title: ' 手机号/商户号', dataIndex: 'divisionNo', align: 'center',slots: { customRender: 'divisionNo' } },
|
||||
{ key: 'operation',title: '操作', dataIndex: 'operation', align: 'center',slots: { customRender: 'operation' } },
|
||||
],
|
||||
})
|
||||
const onAdd = (type = 0) => {
|
||||
if(type == 0){
|
||||
if (!vdata.receiveList) {
|
||||
vdata.receiveList = [] as any
|
||||
}
|
||||
if(vdata.receiveList.length >=9){
|
||||
return $infoBox.message.error('分账接收方最多设置 9 个!')
|
||||
}
|
||||
vdata.receiveList.push({
|
||||
name: '',
|
||||
userType: 0,
|
||||
divisionNo: '',
|
||||
divisionValue: '',
|
||||
isCharge: 0,
|
||||
key: vdata.receiveList[vdata.receiveList.length - 1].key + 1,
|
||||
})
|
||||
}
|
||||
|
||||
if(type == 1){
|
||||
if (!vdata.expendList) {
|
||||
vdata.expendList = [] as any
|
||||
}
|
||||
vdata.expendList.push({
|
||||
name: '',
|
||||
userType: 0,
|
||||
divisionNo: '',
|
||||
divisionValue: '',
|
||||
isCharge: 0,
|
||||
key: vdata.expendList[vdata.expendList.length - 1].key + 1,
|
||||
})
|
||||
}
|
||||
}
|
||||
// const tableColumnsReceive=()=>{
|
||||
//
|
||||
// console.log(tableColumnsReceiveRatio,'tableColumnsReceivetableColumnsReceivetableColumnsReceive')
|
||||
// return tableColumnsReceiveRatio.pay as any
|
||||
// }
|
||||
// function tableColumnsCede(){
|
||||
// return tableColumnsCedePrice.pay
|
||||
// }
|
||||
|
||||
//
|
||||
const infoTable = ref();
|
||||
|
||||
const handleAdd = () => {
|
||||
// if (vdata.saveObject.appPlaceType == '1' && vdata.saveObject.receiveList.length > 1) {
|
||||
// return $infoBox.message.error('卡片模版最多添加两条记录!')
|
||||
// }
|
||||
|
||||
const newData = { key: 1, userType: 0,name: '', divisionNo: '',divisionValue: '',isCharge: 0, operation: '' }
|
||||
vdata.receiveList.push(newData)
|
||||
infoTable.value.refTable(true);
|
||||
}
|
||||
|
||||
const vdata: any = reactive({
|
||||
filteredMchNameInfoList:[] as any,
|
||||
filteredMchNoInfoList:[] as any,
|
||||
mchList:[] as any,
|
||||
detailData:{} as any,
|
||||
payDefines: [] as any,
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isAdd: true, // 新增 or 修改页面标识
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
receiveList:[{ key: 1, userType: 0,name: '', divisionNo: '',divisionValue: '',isCharge: 0, operation: '' }],
|
||||
expendList:[{ key: 1, userType: 0,name: '', divisionNo: '',divisionValue: '',isCharge: 0, operation: '' }],
|
||||
saveObject: {
|
||||
receiveList: [{ key: 1, userType: 0,name: '', divisionNo: '',divisionValue: '',isCharge: 0, operation: '' }],
|
||||
expendList: [{ key: 1,userType: 0,name: '', divisionNo: '',divisionValue: '',isCharge: 0, operation: '' }]
|
||||
} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
groupKey: '',
|
||||
})
|
||||
|
||||
|
||||
async function reqTableDataFunc(){
|
||||
return {
|
||||
hasNext:true,
|
||||
records:vdata.receiveList,
|
||||
}
|
||||
}
|
||||
const onDelete = (key,type=0) => {
|
||||
|
||||
if(type == 0){
|
||||
if (vdata.receiveList.length <= 1) {
|
||||
$infoBox.message.error('最少保留一项')
|
||||
return false
|
||||
}
|
||||
vdata.receiveList = vdata.receiveList.filter(item => item.key !== key)
|
||||
}else{
|
||||
if (vdata.expendList.length <= 1) {
|
||||
$infoBox.message.error('最少保留一项')
|
||||
return false
|
||||
}
|
||||
vdata.expendList = vdata.expendList.filter(item => item.key !== key)
|
||||
}
|
||||
}
|
||||
const rules = {
|
||||
}
|
||||
function payFefines() {
|
||||
req.list(API_MCH_PAY_DEFINES,{ 'pageSize': -1 }).then(res => {
|
||||
vdata.payDefines = res
|
||||
})
|
||||
}
|
||||
|
||||
function mchList(){
|
||||
req.list(API_URL_MCH_APPLYMENT_LIST, { 'pageSize': -1 ,state:99,ifCode: vdata.detailData.ifCode}).then(res => {
|
||||
vdata.mchList = res.records
|
||||
vdata.filteredMchNameInfoList = res.records
|
||||
vdata.filteredMchNoInfoList = res.records
|
||||
})
|
||||
}
|
||||
|
||||
function show( record) { // 弹层打开事件
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
vdata.groupKey = 'faceAdvert'
|
||||
vdata.isAdd = !record
|
||||
|
||||
vdata.recordId = record.id
|
||||
vdata.detailData = record
|
||||
payFefines()
|
||||
mchList()
|
||||
// 数据恢复为默认数据
|
||||
vdata.saveObject = { id: record.id }
|
||||
|
||||
getMchDivisionTemplateConfig()
|
||||
vdata.confirmLoading = false // 关闭loading
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
if (vdata.saveObject.params) {
|
||||
// vdata.saveObject.receiveList = vdata.saveObject.params
|
||||
}
|
||||
}
|
||||
vdata.isShow = true // 立马展示弹层信息
|
||||
}
|
||||
function getMchDivisionTemplateConfig(){
|
||||
$getMchDivisionTemplateConfig(vdata.recordId).then(config => {
|
||||
|
||||
if(config.expendList == 0 || config.receiveList == 0){
|
||||
vdata.expendList = [{ key: 1,userType: 0,name: '', divisionNo: '',divisionValue: '',isCharge: 0, operation: ''}]
|
||||
vdata.receiveList = [{ key: 1, userType: 0,name: '', divisionNo: '',divisionValue: '',isCharge: 0, operation: ''}]
|
||||
return false;
|
||||
}
|
||||
const expendList = [] as any;
|
||||
for (let i = 0;i<config.expendList.length;i++){
|
||||
expendList.push({
|
||||
key: i+1 ,
|
||||
userType: config.expendList[i].userType,
|
||||
name: config.expendList[i].name,
|
||||
divisionNo: config.expendList[i].divisionNo,
|
||||
divisionValue: config.expendList[i].divisionValue,
|
||||
isCharge: config.expendList[i].isCharge,
|
||||
operation: ''
|
||||
})
|
||||
}
|
||||
vdata.expendList = expendList;
|
||||
const receiveList = [] as any;
|
||||
for (let i = 0;i<config.receiveList.length;i++){
|
||||
receiveList.push({
|
||||
key: i+1,
|
||||
userType: config.receiveList[i].userType,
|
||||
name: config.receiveList[i].name,
|
||||
divisionNo: config.receiveList[i].divisionNo,
|
||||
divisionValue: config.receiveList[i].divisionValue,
|
||||
isCharge: config.receiveList[i].isCharge,
|
||||
operation: ''
|
||||
})
|
||||
}
|
||||
vdata.receiveList = receiveList;
|
||||
})
|
||||
}
|
||||
function handleOkFunc() { // 点击【确认】按钮事件
|
||||
vdata.confirmLoading = true // 显示loading
|
||||
|
||||
vdata.saveObject.id = vdata.recordId
|
||||
vdata.saveObject.receiveList = vdata.receiveList
|
||||
vdata.saveObject.expendList = vdata.expendList
|
||||
req.add(API_URL_DIVISION_TEMPLATE_SAVE_CONFIG, vdata.saveObject).then(res => {
|
||||
message.success('添加成功')
|
||||
vdata.isShow = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(res => { vdata.confirmLoading = false })
|
||||
}
|
||||
//门店搜索
|
||||
const handleDivisionNameChange = (value) => {
|
||||
vdata.filteredMchNameInfoList = [];
|
||||
vdata.mchList.forEach((item: { mchShortName: string | any[], applyId: any[] },index) => {
|
||||
if (item.mchShortName.includes(value) || item.applyId.toString().includes(value) ) {
|
||||
vdata.filteredMchNameInfoList.push(vdata.mchList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
const handleDivisionNoChange = (value) => {
|
||||
vdata.filteredMchNoInfoList = [];
|
||||
vdata.mchList.forEach((item: { mchShortName: string | any[], applyId: any[] },index) => {
|
||||
if (item.mchShortName.includes(value) || item.applyId.toString().includes(value) ) {
|
||||
vdata.filteredMchNoInfoList.push(vdata.mchList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
function updateState (fee) { // 【更新状态】
|
||||
|
||||
}
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.ant-btn-dangerous {
|
||||
position: absolute;
|
||||
right: 50px;
|
||||
}
|
||||
|
||||
.ant-row-space-between {
|
||||
position: relative;
|
||||
}
|
||||
:deep(.jeepay-table-top-row){
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
92
jeepay-ui-merchant/src/views/division/receiver/AccountOp.vue
Normal file
92
jeepay-ui-merchant/src/views/division/receiver/AccountOp.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<a-drawer v-model:visible="vdata.isShow" title="账户操作" width="30%" :maskClosable="false" @close="vdata.isShow = false">
|
||||
<a-form ref="infoFormModel" :label-col="{span: 6}" :wrapper-col="{span: 15}">
|
||||
<a-form-item label="账号余额 :" name="balanceAmount">
|
||||
<a-input v-model:value="vdata.balanceAmount" class="form-item-content" :disabled="true">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
<a-button :loading="vdata.confirmLoading1" size="small" style="margin-left: 20px;" type="primary" @click="queryBalanceFunc"><save-outlined />查询</a-button>
|
||||
</a-form-item>
|
||||
|
||||
|
||||
<a-form-item label="提现 :" name="cashoutAmount">
|
||||
<a-input v-model:value="vdata.cashoutAmount" class="form-item-content">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
<a-button :loading="vdata.confirmLoading2" size="small" style="margin-left: 20px;" type="primary" @click="cashoutFunc"><send-outlined />提现</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { $divisionReceiverBalance, $divisionReceiverCashout, req } from '@/api/manage'
|
||||
import { reactive, ref, getCurrentInstance } from 'vue'
|
||||
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
const vdata : any = reactive({
|
||||
|
||||
confirmLoading1: false, // 显示确定按钮loading图标
|
||||
confirmLoading2: false, // 显示确定按钮loading图标
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
recordId: null, // 更新对象ID
|
||||
|
||||
balanceAmount: null, // 账户余额
|
||||
cashoutAmount: null, // 提现余额
|
||||
|
||||
})
|
||||
|
||||
function queryBalanceFunc(){
|
||||
|
||||
vdata.confirmLoading1 = true
|
||||
$divisionReceiverBalance(vdata.recordId).then(res => {
|
||||
vdata.balanceAmount = ( ( res.balanceAmount || 0 ) / 100).toFixed(2)
|
||||
}).finally(() => {
|
||||
vdata.confirmLoading1 = false
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function cashoutFunc(){
|
||||
|
||||
if(!vdata.cashoutAmount || vdata.cashoutAmount <= 0){
|
||||
return $infoBox.message.error('请填入金额')
|
||||
}
|
||||
|
||||
$infoBox.confirmDangerPromise('确认提现?').then(() => {
|
||||
vdata.confirmLoading2 = true
|
||||
$divisionReceiverCashout(vdata.recordId, vdata.cashoutAmount).then(res => {
|
||||
if(res.state == 1){
|
||||
return $infoBox.message.success('申请成功')
|
||||
}
|
||||
|
||||
return $infoBox.message.error('错误信息: ' + res.errMsg)
|
||||
|
||||
}).finally(() => {
|
||||
vdata.confirmLoading2 = false
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function show(recordId){
|
||||
vdata.balanceAmount = null
|
||||
vdata.cashoutAmount = null
|
||||
vdata.recordId = recordId
|
||||
vdata.isShow = true
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
<style>
|
||||
|
||||
|
||||
.form-item-content{
|
||||
width: 60%
|
||||
}
|
||||
|
||||
</style>
|
||||
165
jeepay-ui-merchant/src/views/division/receiver/Detail.vue
Normal file
165
jeepay-ui-merchant/src/views/division/receiver/Detail.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="详情"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="40%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">基本信息</a-divider>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="用户号">
|
||||
{{ vdata.detailData['mchNo'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="接收方绑定ID">
|
||||
{{ vdata.detailData['receiverId'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="应用APPID">
|
||||
{{ vdata.detailData['appId'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="分账状态">
|
||||
{{ vdata.detailData['state'] == 1?'正常分账':'暂停分账' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付接口">
|
||||
{{ vdata.detailData['ifCode'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="分账比例">
|
||||
{{ vdata.detailData['divisionProfit'] * 100 }}%
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="绑定成功时间">
|
||||
{{ vdata.detailData['bindSuccessTime'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">账户信息</a-divider>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="接收方账号别名">
|
||||
{{ vdata.detailData['receiverAlias'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="账户类型">
|
||||
{{ vdata.detailData['accType'] == 0?'个人(对私)':'商户(对公)' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="分账组ID">
|
||||
{{ vdata.detailData['receiverGroupId'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="分账组名称">
|
||||
{{ vdata.detailData['receiverGroupName'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="分账接收账号名称">
|
||||
{{ vdata.detailData['accName'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="分账接收账号">
|
||||
{{ vdata.detailData['accNo'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">账户参数信息</a-divider>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道账号参数">
|
||||
{{ vdata.detailData['channelAccNo'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="绑定响应参数">
|
||||
{{ vdata.detailData['channelBindResult'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<!-- <a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道特殊信息">
|
||||
{{ vdata.detailData['channelExtInfo'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col> -->
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="创建时间">
|
||||
{{ vdata.detailData['createdAt'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_DIVISION_RECEIVER, req } from '@/api/manage'
|
||||
import {defineProps,reactive} from 'vue'
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata:any = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_DIVISION_RECEIVER, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appId" placeholder="应用APPID" />
|
||||
|
||||
<jeepay-text-up v-model:value="vdata.searchData.receiverId" placeholder="分账接收者ID[精准]" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.receiverAlias" placeholder="接收者账号别名[模糊]" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.receiverGroupId" placeholder="组ID[精准]" />
|
||||
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="账号状态(本系统)">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="1">正常分账</a-select-option>
|
||||
<a-select-option value="0">暂停分账</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<JeepaySelect ref="ifCodeRef" placeholder="支付接口" :reset="isReset">
|
||||
<a-select v-model:value="vdata.searchData.ifCode" @change="ifCodeRef.textupHandle()">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<template v-for="(item) in vdata.ifCodeList" :key="item.ifCode">
|
||||
<a-select-option :value="item.ifCode">{{ item.ifName }}[{{ item.ifCode }}]</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
</JeepaySelect>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="false"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="receiverId"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<div>
|
||||
<a-button v-if="$access('ENT_DIVISION_RECEIVER_ADD')" type="primary" class="mg-b-30" @click="addFunc"><plus-outlined />新建</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key === 'receiverId'">
|
||||
<a @click="detailFunc(record.receiverId)"><b>{{ record.receiverId }}</b></a>
|
||||
</template>
|
||||
<template v-if="column.key == 'divisionProfit'">{{ (record.divisionProfit * 100).toFixed(2) + '%' }}</template>
|
||||
<template v-if="column.key == 'ifCode'">
|
||||
<!-- <template v-if="record.ifCode === 'wxpay'"><span style="color: green"> <wechat-outlined />微信</span></template>
|
||||
<template v-else-if="record.ifCode == 'alipay'"><span style="color: dodgerblue"><alipay-circle-outlined /> 支付宝</span></template> -->
|
||||
<!-- <template v-else>{{ record.ifCode }}</template> -->
|
||||
<template v-for="(item) in vdata.ifCodeList" :key="item.ifCode">
|
||||
<div v-if="record.ifCode == item.ifCode">
|
||||
<span class="icon-style" :style="{backgroundColor: item.bgColor}">
|
||||
<img class="icon" :src="item.icon">
|
||||
</span>
|
||||
{{ item.ifName }}
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 状态(本系统) -->
|
||||
<template v-if="column.key == 'state'">
|
||||
<div v-if="record.state == 0"><a-badge status="error" text="暂停分账" /></div>
|
||||
<div v-else-if="record.state == 1"><a-badge status="processing" text="正常分账" /></div>
|
||||
<div v-else><a-badge status="warning" text="未知" /></div>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_DIVISION_RECEIVER_EDIT')" type="link" @click="editFunc(record.receiverId)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_DIVISION_RECEIVER_EDIT') && record.ifCode =='shengpay' " type="link" @click="ifCOdeOpFunc(record.receiverId, record.ifCode)">账户操作</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
|
||||
<!-- 新增收款账号页面 -->
|
||||
<ReceiverAdd ref="receiverAdd" :callbackFunc="searchFunc" />
|
||||
|
||||
<!-- 修改 页面组件 -->
|
||||
<ReceiverEdit ref="receiverEdit" :callbackFunc="searchFunc" />
|
||||
|
||||
<!-- 引入具体的接口组件 -->
|
||||
<AccountOp ref="currentIfCodeOpComponentRef" />
|
||||
|
||||
<!-- 详情页面组件 -->
|
||||
<InfoDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
</a-card>
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_DIVISION_RECEIVER, API_URL_IFDEFINES_LIST, req } from '@/api/manage'
|
||||
import ReceiverAdd from './ReceiverAdd.vue'
|
||||
import ReceiverEdit from './ReceiverEdit.vue'
|
||||
import AccountOp from './AccountOp.vue'
|
||||
import InfoDetail from './Detail.vue'
|
||||
import { onMounted, reactive,ref,getCurrentInstance } from 'vue'
|
||||
const { $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const tableColumns = reactive([
|
||||
{ key: 'receiverId', title: '接收方绑定ID' },
|
||||
{ key: 'appId', dataIndex: 'appId', title: '应用ID' },
|
||||
{ key: 'receiverGroupId', dataIndex: 'receiverGroupId', title: '组ID' },
|
||||
{ key: 'ifCode', title: '支付接口' },
|
||||
{ key: 'receiverAlias', dataIndex: 'receiverAlias', title: '账号别名' },
|
||||
{ key: 'receiverGroupName', dataIndex: 'receiverGroupName', title: '组名称' },
|
||||
{ key: 'accNo', dataIndex: 'accNo', title: '分账接收账号' },
|
||||
{ key: 'accName', dataIndex: 'accName', title: '分账接收账号名称' },
|
||||
{ key: 'channelAccNo', dataIndex: 'channelAccNo', title: '渠道账号', },
|
||||
{ key: 'relationTypeName', dataIndex: 'relationTypeName', title: '分账关系类型' },
|
||||
{ key: 'state', title: '状态', align: 'center' },
|
||||
{ key: 'bindSuccessTime', dataIndex: 'bindSuccessTime', title: '绑定成功时间' },
|
||||
{ key: 'divisionProfit', dataIndex: 'divisionProfit', title: '默认分账比例' },
|
||||
{ key: 'createdAt', title: '创建时间', dataIndex: 'createdAt' },
|
||||
{ key: 'op', title: '操作', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
const receiverEdit =ref()
|
||||
const receiverAdd =ref()
|
||||
const ledgerGroupAdd =ref()
|
||||
const infoTable = ref()
|
||||
const ifCodeRef = ref()
|
||||
const infoDetail = ref()
|
||||
const currentIfCodeOpComponentRef = ref()
|
||||
|
||||
const vdata : any = reactive({
|
||||
tableColumns: tableColumns,
|
||||
searchData: {} as any,
|
||||
btnLoading: false,
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
searchFunc()
|
||||
req.list(API_URL_IFDEFINES_LIST, {}).then((res) => {
|
||||
vdata.ifCodeList = res
|
||||
})
|
||||
})
|
||||
|
||||
let isReset = ref(0) // 下拉搜索框是否重置
|
||||
|
||||
function onReset(){
|
||||
isReset.value++ // 下拉搜索框重置
|
||||
vdata.searchData = {}
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params) {
|
||||
return req.list(API_URL_DIVISION_RECEIVER, params)
|
||||
}
|
||||
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
vdata.btnLoading = true // 打开查询按钮上的loading
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function addFunc() { // 业务通用【新增】 函数
|
||||
// 打开弹层
|
||||
receiverAdd.value.show()
|
||||
}
|
||||
function groupAddFunc() { // 业务通用【新增】 函数
|
||||
// 打开弹层
|
||||
ledgerGroupAdd.value.show()
|
||||
}
|
||||
|
||||
function editFunc(recordId) { // 业务通用【修改】 函数
|
||||
receiverEdit.value.show(recordId)
|
||||
}
|
||||
|
||||
// 账户操作
|
||||
function ifCOdeOpFunc(recordId, selectIfCode){
|
||||
currentIfCodeOpComponentRef.value.show(recordId)
|
||||
}
|
||||
|
||||
function detailFunc (recordId: any) { // 商户详情页
|
||||
infoDetail.value.show(recordId)
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<style>
|
||||
.icon-style{
|
||||
|
||||
/* background-color: black; */
|
||||
border-radius: 5px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
.icon{
|
||||
width: 15px;
|
||||
height: 14px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
</style>
|
||||
299
jeepay-ui-merchant/src/views/division/receiver/ReceiverAdd.vue
Normal file
299
jeepay-ui-merchant/src/views/division/receiver/ReceiverAdd.vue
Normal file
@@ -0,0 +1,299 @@
|
||||
<!--
|
||||
新建分账用户
|
||||
|
||||
@author terrfly
|
||||
@site https://www.jeequan.com
|
||||
@date 2022/05/09 14:20
|
||||
copy自 运营平台, 删除了 商户号的 formitem ; 删除了selectFinishFunc函数, 新增了init 并在 show函数中调用
|
||||
删除: JeepayModelMchList 组件
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:closable="true"
|
||||
:maskClosable="false"
|
||||
width="80%"
|
||||
title="绑定分账接收者账号"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form layout="vertical">
|
||||
<a-row :gutter="40">
|
||||
<a-col :span="6">
|
||||
<a-form-item label="选择商户应用">
|
||||
<a-select v-model:value="vdata.selectedMchAndIfcodeInfo.appId" placeholder="应用AppId" @change="mchAppChangeFunc($event)">
|
||||
<a-select-option v-for="(item) in vdata.allMchAppList" :key="item.appId" :value="item.appId">{{ item.appName }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item label="选择要加入到的账号分组">
|
||||
<div style="display: flex;">
|
||||
<a-select v-model:value="vdata.selectedMchAndIfcodeInfo.receiverGroupId" placeholder="分账账号组">
|
||||
<a-select-option v-for="(item) in vdata.allReceiverGroup" :key="item.receiverGroupId" :value="item.receiverGroupId">{{ item.receiverGroupName }}</a-select-option>
|
||||
</a-select>
|
||||
<a-button type="primary" style="margin-left:20px;" @click="groupInfoAddOrEditRef.show(vdata.selectedMchAndIfcodeInfo.mchNo)"><plus-outlined />新建</a-button>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<a-divider style="margin-top: 0;margin-bottom:20px" />
|
||||
<div v-if="vdata.selectedMchAndIfcodeInfo.appId">
|
||||
<a-form layout="vertical">
|
||||
<a-form-item label="选择接口">
|
||||
<a-select v-model:value="vdata.selectedMchAndIfcodeInfo.ifCode" style="width: 210px" placeholder="账号所属接口" @change="ifCodeChangeFunc">
|
||||
<a-select-option v-for="(item) in vdata.appSupportIfCodes" :key="item.ifCode" :value="item.ifCode">
|
||||
<div>
|
||||
<span class="icon-style" :style="{backgroundColor: item.bgColor}">
|
||||
<img class="icon" :src="item.icon">
|
||||
</span>
|
||||
{{ item.ifName }}
|
||||
</div>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 引入具体的接口组件 -->
|
||||
<JeepayDivisionReceiver ref="ifCodeComponentRef" />
|
||||
|
||||
<div v-if="vdata.selectedMchAndIfcodeInfo.ifCode" class="btn">
|
||||
<a-button :loading="vdata.confirmBtnLoading" type="primary" style="margin-right: 10px" @click="reqBatchBindReceiver(0)"><check-outlined />确认绑定</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
|
||||
<!-- 新增 / 修改 页面组件 -->
|
||||
<GroupInfoAddOrEdit ref="groupInfoAddOrEditRef" :callbackFunc="reloadGroup" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import GroupInfoAddOrEdit from '../group/AddOrEdit.vue'
|
||||
import { reactive, ref,getCurrentInstance, provide, computed, nextTick, onMounted } from 'vue'
|
||||
import { API_URL_DIVISION_RECEIVER, API_URL_DIVISION_RECEIVER_GROUP, API_URL_MCH_APP, req, $getIfCodeByAppId } from '@/api/manage'
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const jeepayModelMchListRef = ref()
|
||||
const ifCodeComponentRef = ref()
|
||||
const groupInfoAddOrEditRef = ref()
|
||||
|
||||
// 响应式数据
|
||||
const vdata : any = reactive({
|
||||
visible: false, // 是否显示抽屉
|
||||
|
||||
allMchAppList: [], // 所有的应用
|
||||
allReceiverGroup: [], // 所有的分账组
|
||||
appSupportIfCodes: [], // 商户应用支持的所有的支付接口
|
||||
|
||||
selectedMchAndIfcodeInfo: {}, //选择的商户or渠道信息
|
||||
|
||||
|
||||
confirmBtnLoading: false,
|
||||
|
||||
})
|
||||
|
||||
// 向子组件注入: 当前选择的数据对象信息(包含 ifCode, mchNo, appId 等参数 )
|
||||
provide('selectedMchAndIfcodeInfo', computed( ()=> vdata.selectedMchAndIfcodeInfo) )
|
||||
|
||||
|
||||
// 弹层打开事件
|
||||
function show () {
|
||||
|
||||
// 数据重置
|
||||
vdata.allMchAppList = []
|
||||
vdata.allReceiverGroup = []
|
||||
vdata.appSupportIfCodes = []
|
||||
vdata.selectedMchAndIfcodeInfo = { }
|
||||
|
||||
// 清空组件
|
||||
if(ifCodeComponentRef.value){
|
||||
ifCodeComponentRef.value.ifCodeChangeFunc()
|
||||
}
|
||||
|
||||
vdata.visible = true // 显示弹层
|
||||
|
||||
init()
|
||||
}
|
||||
// 抽屉关闭
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
// 当选择的 app发生变化时
|
||||
function mchAppChangeFunc(appId){
|
||||
|
||||
vdata.selectedMchAndIfcodeInfo.ifCode = null //选择的接口置空
|
||||
|
||||
// 清空组件
|
||||
if(ifCodeComponentRef.value){
|
||||
ifCodeComponentRef.value.ifCodeChangeFunc()
|
||||
}
|
||||
|
||||
// 请求商户应用 支持的所有的支付接口
|
||||
$getIfCodeByAppId(appId).then((res) => {
|
||||
vdata.appSupportIfCodes = res
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function init(){
|
||||
|
||||
reloadGroup()
|
||||
|
||||
req.list(API_URL_MCH_APP, { pageSize: -1}).then(res => {
|
||||
vdata.allMchAppList = res.records
|
||||
if (vdata.allMchAppList && vdata.allMchAppList.length > 0) { // 默认选中第一个 & 更新列表
|
||||
vdata.selectedMchAndIfcodeInfo.appId = vdata.allMchAppList[0].appId
|
||||
}
|
||||
|
||||
// 存在appId 请求接口列表
|
||||
if(vdata.selectedMchAndIfcodeInfo.appId){
|
||||
mchAppChangeFunc(vdata.selectedMchAndIfcodeInfo.appId)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 重新加载账号分组
|
||||
function reloadGroup(){
|
||||
|
||||
// 当商户选择完成后: 请求接口,获取所有分组信息,只有此处进行pageSize=-1传参
|
||||
vdata.selectedMchAndIfcodeInfo.receiverGroupId = null
|
||||
req.list(API_URL_DIVISION_RECEIVER_GROUP, { pageSize: -1, mchNo: vdata.selectedMchAndIfcodeInfo.mchNo }).then(res => {
|
||||
vdata.allReceiverGroup = res.records
|
||||
if (vdata.allReceiverGroup && vdata.allReceiverGroup.length > 0) { // 默认选中第一个 & 更新列表
|
||||
vdata.selectedMchAndIfcodeInfo.receiverGroupId = vdata.allReceiverGroup[0].receiverGroupId
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 选择支付接口 切换事件
|
||||
function ifCodeChangeFunc(selectIfCode){
|
||||
|
||||
ifCodeComponentRef.value.ifCodeChangeFunc(selectIfCode)
|
||||
}
|
||||
|
||||
// 单条绑定 返回是否成功
|
||||
function reqBatchBindReceiver (i) {
|
||||
|
||||
// 获取参数( 返回 Promise )
|
||||
ifCodeComponentRef.value.getReqDataList().then(reqListRef => {
|
||||
|
||||
if (reqListRef.length <= 0) {
|
||||
return $infoBox.message.error('请先添加账号')
|
||||
}
|
||||
|
||||
// 完成了所有的绑定操作
|
||||
if (i >= reqListRef.length) {
|
||||
return $infoBox.message.success('已完成所有账号的绑定操作')
|
||||
}
|
||||
|
||||
// 深度拷贝, 避免更改组件内的值
|
||||
let reqList = JSON.parse(JSON.stringify(reqListRef))
|
||||
|
||||
// 当前的账号
|
||||
const currentReceiver = reqList[i]
|
||||
|
||||
// 设置分组ID 和 其他信息
|
||||
currentReceiver.receiverGroupId = vdata.selectedMchAndIfcodeInfo.receiverGroupId
|
||||
currentReceiver.mchNo = vdata.selectedMchAndIfcodeInfo.mchNo
|
||||
currentReceiver.appId = vdata.selectedMchAndIfcodeInfo.appId
|
||||
currentReceiver.ifCode = vdata.selectedMchAndIfcodeInfo.ifCode
|
||||
|
||||
if (currentReceiver.reqBindState === 1) { // 已经绑定成功, 不在重复发起
|
||||
return reqBatchBindReceiver(++i) // 递归继续绑定
|
||||
}
|
||||
|
||||
if (!currentReceiver.accNo) {
|
||||
return $infoBox.message.error(`第${i + 1 }条: 接收方账号不能为空`)
|
||||
}
|
||||
|
||||
if (currentReceiver.relationType === 'CUSTOM' && !currentReceiver.relationTypeName) {
|
||||
return $infoBox.message.error(`第${i + 1 }条: 自定义类型时接收方账号名称不能为空`)
|
||||
}
|
||||
|
||||
if (!currentReceiver.divisionProfit || currentReceiver.divisionProfit <= 0 || currentReceiver.divisionProfit > 100) {
|
||||
return $infoBox.message.error(`第${i + 1 }条: 默认分账比例请设置在[0.01% ~ 100% ] 之间`)
|
||||
}
|
||||
|
||||
vdata.confirmBtnLoading = true
|
||||
req.add(API_URL_DIVISION_RECEIVER, currentReceiver).then(apiRes => {
|
||||
// 绑定成功
|
||||
if (apiRes.bindState === 1) {
|
||||
|
||||
ifCodeComponentRef.value.changeState(i, 1) // 状态变更
|
||||
reqBatchBindReceiver(++i) // 递归继续绑定
|
||||
|
||||
} else {
|
||||
ifCodeComponentRef.value.changeState(i, 2) // 状态变更
|
||||
$infoBox.modalError(`第${i + 1 }条: 绑定异常`, `错误码:${apiRes.errCode || '未知'} , 错误信息:${apiRes.errMsg}`)
|
||||
}
|
||||
}).catch(() => {
|
||||
ifCodeComponentRef.value.changeState(i, 2) // 状态变更
|
||||
}).finally(() => {
|
||||
vdata.confirmBtnLoading = false
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({show})
|
||||
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.btn{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 70px;
|
||||
}
|
||||
.icon-style{
|
||||
|
||||
/* background-color: black; */
|
||||
border-radius: 5px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
.icon{
|
||||
width: 15px;
|
||||
height: 14px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
.text{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.mch{
|
||||
box-sizing: border-box;
|
||||
height: 34px;
|
||||
padding: 0 11px 0 11px;
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
font-size: 14px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.cont{
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
//background-color: aqua;
|
||||
display: flex;
|
||||
//justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.search{
|
||||
width: 10%;
|
||||
height: 100%;
|
||||
// background-color: antiquewhite;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
104
jeepay-ui-merchant/src/views/division/receiver/ReceiverEdit.vue
Normal file
104
jeepay-ui-merchant/src/views/division/receiver/ReceiverEdit.vue
Normal file
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<a-drawer v-model:visible="vdata.isShow" title="修改分账用户信息" width="30%" :maskClosable="false" @close="vdata.isShow = false">
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" :label-col="{span: 6}" :wrapper-col="{span: 15}" :rules="rules">
|
||||
<a-form-item label="账号别名:" name="receiverAlias">
|
||||
<a-input v-model:value="vdata.saveObject.receiverAlias" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="默认分账比例:" name="divisionProfit">
|
||||
<a-input-number
|
||||
v-model:value="vdata.saveObject.divisionProfit"
|
||||
style="width: 120px"
|
||||
:precision="2"
|
||||
:min="0.01"
|
||||
:max="100"
|
||||
>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input-number>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="状态" name="state">
|
||||
<a-radio-group v-model:value="vdata.saveObject.state">
|
||||
<a-radio :value="1">正常分账</a-radio>
|
||||
<a-radio :value="0">暂停分账</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="分组变更:" name="receiverGroupId">
|
||||
<a-select v-model:value="vdata.saveObject.receiverGroupId" style="width: 210px" placeholder="账号分组">
|
||||
<a-select-option v-for="(item) in vdata.allReceiverGroup" :key="item.receiverGroupId" :value="item.receiverGroupId">{{ item.receiverGroupName }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="vdata.isShow = false"><close-outlined />取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.confirmLoading" @click="handleOkFunc"><check-outlined />保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_DIVISION_RECEIVER, API_URL_DIVISION_RECEIVER_GROUP, req } from '@/api/manage'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
const props= defineProps ({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const vdata = reactive({
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: {state:'',receiverGroupId:''} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
allReceiverGroup: [] as any, // 当前商户所有的接收账号的分组情况
|
||||
|
||||
})
|
||||
const rules= {
|
||||
receiverAlias: [{ required: true, message: '请输入别名', trigger: 'blur' }],
|
||||
// receiverGroupId: [{ required: true, message: '请选择分组', trigger: 'change', type: 'array' }],
|
||||
divisionProfit: [{ required: true, message: '请录入默认分账比例', trigger: 'blur' }],
|
||||
// state: [{ required: true, message: '请选择状态', trigger: 'change' }]
|
||||
}
|
||||
|
||||
|
||||
defineExpose({show})
|
||||
function show(recordId) { // 弹层打开事件
|
||||
vdata.saveObject = {state:'',receiverGroupId:''} // 数据清空
|
||||
vdata.confirmLoading = false // 关闭loading
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
vdata.recordId = recordId
|
||||
|
||||
// 查询账号信息
|
||||
req.getById(API_URL_DIVISION_RECEIVER, recordId).then(res => {
|
||||
res.divisionProfit = (res.divisionProfit * 100).toFixed(2)
|
||||
vdata.saveObject = res
|
||||
console.log(res)
|
||||
|
||||
})
|
||||
// 请求接口,获取所有分组信息,只有此处进行pageSize=-1传参
|
||||
req.list(API_URL_DIVISION_RECEIVER_GROUP, { pageSize: -1 }).then(res => { vdata.allReceiverGroup = res.records })
|
||||
vdata.isShow = true
|
||||
}
|
||||
function handleOkFunc() { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then(valid => {
|
||||
vdata.confirmLoading = true // 显示loading
|
||||
var reqObject = {
|
||||
receiverAlias: vdata.saveObject.receiverAlias,
|
||||
receiverGroupId: vdata.saveObject.receiverGroupId,
|
||||
divisionProfit: vdata.saveObject.divisionProfit,
|
||||
state: vdata.saveObject.state
|
||||
}
|
||||
req.updateById(API_URL_DIVISION_RECEIVER, vdata.recordId, reqObject).then(res => {
|
||||
message.success('修改成功')
|
||||
vdata.isShow = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(res => { vdata.confirmLoading = false })
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
82
jeepay-ui-merchant/src/views/division/record/Detail.vue
Normal file
82
jeepay-ui-merchant/src/views/division/record/Detail.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<!-- 详情抽屉 -->
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
width="50%"
|
||||
:closable="true"
|
||||
title="记录详情"
|
||||
@close="vdata.visible = false"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账记录ID">{{ vdata.detailData.recordId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="用户号">{{ vdata.detailData.mchNo }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="应用ID">{{ vdata.detailData.appId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="支付接口">{{ vdata.detailData.ifCode }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="系统支付订单号">{{ vdata.detailData.payOrderId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="支付订单渠道支付订单号">{{ vdata.detailData.payOrderChannelOrderNo }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="订单金额">{{ vdata. detailData.payOrderAmount / 100 }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="分账基数">
|
||||
{{ vdata.detailData.payOrderDivisionAmount / 100 }}
|
||||
{{ vdata.detailData.calBaseAmountType == 'ORDER_AMOUNT' ? '(订单金额-退款金额)' : '(订单金额-手续费-退款金额)' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="系统分账批次号">{{ vdata.detailData.batchOrderId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="上游分账批次号">{{ vdata.detailData.channelBatchOrderId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="状态">
|
||||
<a-tag v-if="vdata.detailData.state == 0" color="blue">待分账</a-tag>
|
||||
<a-tag v-if="vdata.detailData.state == 1" color="green">分账成功</a-tag>
|
||||
<a-tag v-if="vdata.detailData.state == 2" color="volcano">分账失败</a-tag>
|
||||
<a-tag v-if="vdata.detailData.state == 3" color="orange">分账处理中</a-tag>
|
||||
<a-tag v-if="vdata.detailData.state == 4" color="orange">分账已受理</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收者ID">{{ vdata.detailData.receiverId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="收款账号组ID">{{ vdata. detailData.receiverGroupId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="收款账号别名">{{ vdata.detailData.receiverAlias }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号类型">{{ vdata.detailData.accType == 0 ? '个人' : '商户' }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号">{{ vdata.detailData.accNo }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号名称">{{ vdata.detailData.accName }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账关系类型">{{ vdata.detailData.relationType }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账关系类型名称">{{ vdata.detailData.relationTypeName }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="实际分账比例">{{ (vdata.detailData.divisionProfit * 100).toFixed(2) }}%</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账金额">{{ vdata.detailData.calDivisionAmount / 100 }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="创建时间">{{ vdata.detailData.createdAt }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="更新时间">{{ vdata.detailData.updatedAt }}</a-descriptions-item></a-descriptions></a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<a-row justify="start" type="flex">
|
||||
<a-col :sm="24">
|
||||
<span style="color: black;">上游返回数据包:</span>
|
||||
<a-form-item>
|
||||
<a-textarea v-model:value="vdata.detailData.channelRespResult" type="textarea" disabled="disabled" :rows="4" style="color: black;margin-top: 10px" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_PAY_ORDER_DIVISION_RECORD_LIST, req } from '@/api/manage'
|
||||
import { reactive } from 'vue'
|
||||
|
||||
|
||||
const vdata = reactive({
|
||||
visible: false,
|
||||
detailData: {} as any
|
||||
})
|
||||
|
||||
defineExpose({show})
|
||||
function show (recordId) {
|
||||
|
||||
req.getById(API_URL_PAY_ORDER_DIVISION_RECORD_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="resetFunc">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker
|
||||
ref="dateRangePicker"
|
||||
v-model:value="vdata.searchData['queryDateRange']"
|
||||
customDateRangeType="dateTime"
|
||||
/>
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.receiverId" placeholder="分账接受者ID" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.receiverGroupId" placeholder="分账账号组ID" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appId" placeholder="应用AppId" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.payOrderId" placeholder="支付订单号" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.accNo" placeholder="分账接收账号" />
|
||||
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="分账状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">待分账</a-select-option>
|
||||
<a-select-option value="1">分账成功</a-select-option>
|
||||
<a-select-option value="2">分账失败</a-select-option>
|
||||
<a-select-option value="3">分账处理中</a-select-option>
|
||||
<a-select-option value="4">分账已受理</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
:rowSelection="{ type: 'checkbox', selectedRowKeys: vdata.recordIdList, onChange: infoTableSelectChangeFunc }"
|
||||
rowKey="recordId"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button v-if="$access('ENT_DIVISION_RECORD_RESEND')" type="primary" @click="resendBatchFunc"><redo-outlined />批量重新发起分账</a-button>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'calDivisionAmount'"><b>¥{{ record.calDivisionAmount/100 }}</b></template>
|
||||
<template v-if="column.key == 'divisionRefundAmount'"><b>¥{{ record.refundAmount/100 }}</b></template>
|
||||
<template v-if="column.key == 'calRealAmount'"><b>¥{{ (record.calDivisionAmount - record.refundAmount)/100 }}</b></template>
|
||||
<template v-if="column.key == 'payOrderAmount'">¥{{ record.payOrderAmount/100 }}</template>
|
||||
<template v-if="column.key == 'state'">
|
||||
<a-tag v-if="record.state == 0" color="blue">待分账</a-tag>
|
||||
<a-tag v-if="record.state == 1" color="green">分账成功</a-tag>
|
||||
<a-tag v-if="record.state == 2" color="volcano">分账失败</a-tag>
|
||||
<a-tag v-if="record.state == 3" color="orange">分账处理中</a-tag>
|
||||
<a-tag v-if="record.state == 4" color="orange">分账已受理</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'ifCode'">
|
||||
<template v-for="(item) in vdata.ifCodeList" :key="item.ifCode">
|
||||
<label v-if="record.ifCode == item.ifCode">{{ item.ifName }}({{ item.ifCode }})</label>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<a-button v-if="record.state == 2 && $access('ENT_DIVISION_RECORD_RESEND')" type="link" @click="redivFunc(record.recordId)">重试</a-button>
|
||||
<a-button v-if="$access('ENT_DIVISION_RECORD_VIEW')" type="link" @click="detailFunc(record.recordId)">详情</a-button>
|
||||
</template>
|
||||
<template v-if="column.key == 'payOrderDivisionAmount'">{{ (record.payOrderDivisionAmount / 100).toFixed(2) }}</template>
|
||||
<template v-if="column.key == 'divisionProfit'">{{ (record.divisionProfit * 100).toFixed(2) }}%</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<Detail ref="recordDetail" />
|
||||
|
||||
<ResendModal ref="resendModalRef" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_PAY_ORDER_DIVISION_RECORD_LIST, API_URL_IFDEFINES_LIST, req } from '@/api/manage'
|
||||
import moment from 'moment'
|
||||
import Detail from './Detail.vue'
|
||||
import ResendModal from './ResendModal.vue'
|
||||
import { reactive, ref,getCurrentInstance, provide, onMounted } from 'vue'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
||||
const tableColumns = reactive([
|
||||
{ key: 'calDivisionAmount', title: '分账金额(首次)' },
|
||||
{ key: 'divisionRefundAmount', title: '回退金额' },
|
||||
{ key: 'calRealAmount', title: '实际入账金额' },
|
||||
{ key: 'batchOrderId', title: '分账批次号', dataIndex: 'batchOrderId' },
|
||||
{ key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
{ key: 'ifCode', title: '支付接口' },
|
||||
{ key: 'payOrderAmount', title: '订单金额' },
|
||||
{ key: 'payOrderDivisionAmount', dataIndex: 'payOrderDivisionAmount', title: '分账基数' },
|
||||
{ key: 'receiverAlias', title: '账号别名', dataIndex: 'receiverAlias' },
|
||||
{ key: 'accNo', title: '接收账号', dataIndex: 'accNo' },
|
||||
{ key: 'accName', title: '账号姓名', dataIndex: 'accName' },
|
||||
{ key: 'relationTypeName', title: '分账关系类型', dataIndex: 'relationTypeName' },
|
||||
{ key: 'divisionProfit', dataIndex: 'divisionProfit', title: '分账比例'},
|
||||
{ key: 'state', title: '分账状态', scopedSlots: { customRender: 'stateSlot' } },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
|
||||
{ key: 'op', title: '操作', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
const recordDetail = ref()
|
||||
const resendModalRef = ref()
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
const vdata : any = reactive({
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: { queryDateRange: 'today' } as any,
|
||||
createdStart: '', // 选择开始时间
|
||||
createdEnd: '', // 选择结束时间
|
||||
visible:false,
|
||||
recordIdList: [] as any, // 多选ID集合
|
||||
ifCodeList: [],
|
||||
})
|
||||
|
||||
// 注入搜索函数
|
||||
provide('searchFunc', searchFunc)
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
req.list(API_URL_IFDEFINES_LIST, {state:1}).then((res) => {
|
||||
vdata.ifCodeList = res
|
||||
})
|
||||
})
|
||||
|
||||
function resetFunc() {
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: 'today' }
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_PAY_ORDER_DIVISION_RECORD_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc() { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function detailFunc (recordId) {
|
||||
recordDetail.value.show(recordId)
|
||||
}
|
||||
|
||||
function onChange (date, dateString) {
|
||||
vdata.searchData.createdStart = dateString[0] // 开始时间
|
||||
vdata.searchData.createdEnd = dateString[1] // 结束时间
|
||||
}
|
||||
|
||||
function disabledDate (current) { // 今日之后日期不可选
|
||||
return current && current > moment().endOf('day')
|
||||
}
|
||||
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
// 表格多选
|
||||
function infoTableSelectChangeFunc(selectedRowKeys, selectedRows) {
|
||||
vdata.recordIdList = selectedRowKeys
|
||||
if (selectedRows && selectedRows.length > 0) {
|
||||
selectedRows.forEach(e => {
|
||||
if (e.state != 2) {
|
||||
$infoBox.message.warn('重新发起分账只针对分账失败的订单有效,建议通过筛选条件缩小范围,再批量重试分账')
|
||||
throw new Error('包含非分账失败状态的')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 重新发起分账
|
||||
function redivFunc(recordId) {
|
||||
resendModalRef.value.show([recordId])
|
||||
}
|
||||
|
||||
// 批量重试分账
|
||||
function resendBatchFunc() {
|
||||
if (vdata.recordIdList.length <= 0) {
|
||||
$infoBox.message.error('请选择分账记录')
|
||||
return
|
||||
}
|
||||
|
||||
resendModalRef.value.show(vdata.recordIdList)
|
||||
}
|
||||
|
||||
</script>
|
||||
74
jeepay-ui-merchant/src/views/division/record/ResendModal.vue
Normal file
74
jeepay-ui-merchant/src/views/division/record/ResendModal.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="vdata.showModal"
|
||||
title="确认重新分账?"
|
||||
:confirm-loading="vdata.btnLoading"
|
||||
:closable="false"
|
||||
@ok="handleOkFunc"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<br>
|
||||
<p style="color:red">提示:重新分账将按照订单维度重新发起(仅限分账失败订单)。</p>
|
||||
<br>
|
||||
<a-form-item label="是否重新订单金额" name="recalAmount">
|
||||
<a-radio-group v-model:value="vdata.isResendAndRecalAmount">
|
||||
<a-radio :value="0">不重新计算</a-radio>
|
||||
<a-radio :value="1">重新计算</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { $resendDivision } from '@/api/manage'
|
||||
import { reactive, ref, getCurrentInstance, inject } from 'vue'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
||||
|
||||
const vdata : any = reactive({
|
||||
showModal: false,
|
||||
recordIds: null,
|
||||
isResendAndRecalAmount: 0,
|
||||
btnLoading: false,
|
||||
})
|
||||
|
||||
// 预览函数
|
||||
let searchFunc : any = inject('searchFunc')
|
||||
|
||||
|
||||
// 确认请求: 重新发起分账
|
||||
function handleOkFunc() {
|
||||
vdata.btnLoading = true
|
||||
$resendDivision(vdata.recordIds.join(","), vdata.isResendAndRecalAmount).then(res => {
|
||||
|
||||
$infoBox.message.warning('请等待接口最新状态')
|
||||
if(searchFunc){
|
||||
searchFunc()
|
||||
}
|
||||
|
||||
vdata.showModal = false
|
||||
|
||||
}).finally(() => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 弹层取消
|
||||
function handleCancel (e) {
|
||||
vdata.showModal = false
|
||||
}
|
||||
|
||||
//
|
||||
function show(recordIds) {
|
||||
|
||||
vdata.btnLoading = false
|
||||
vdata.isResendAndRecalAmount = 0
|
||||
vdata.recordIds = recordIds
|
||||
vdata.showModal = true
|
||||
|
||||
}
|
||||
|
||||
defineExpose({show})
|
||||
</script>
|
||||
85
jeepay-ui-merchant/src/views/division/refund/Detail.vue
Normal file
85
jeepay-ui-merchant/src/views/division/refund/Detail.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<!-- 详情抽屉 -->
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
width="50%"
|
||||
:closable="true"
|
||||
title="记录详情"
|
||||
@close="vdata.visible = false"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账退款订单号">{{ vdata.detailData.divisionRefundId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账记录ID">{{ vdata.detailData.divisionRecordId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="用户号">{{ vdata.detailData.mchNo }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="应用ID">{{ vdata.detailData.appId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="支付接口">{{ vdata.detailData.ifCode }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="系统支付订单号">{{ vdata.detailData.payOrderId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="支付订单退款单号">{{ vdata.detailData.payOrderRefundOrderId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="支付订单渠道支付订单号">{{ vdata.detailData.payOrderChannelOrderNo }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="订单金额">{{ vdata. detailData.payOrderAmount / 100 }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="支付订单退款金额">{{ vdata. detailData.payOrderRefundAmount / 100 }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="系统分账批次号">{{ vdata.detailData.divisionBatchOrderId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="状态">
|
||||
<a-tag v-if="vdata.detailData.state == 0" color="orange">回退中</a-tag>
|
||||
<a-tag v-if="vdata.detailData.state == 1" color="blue">回退成功</a-tag>
|
||||
<a-tag v-if="vdata.detailData.state == 2" color="volcano">回退失败</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收者ID">{{ vdata.detailData.receiverId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="收款账号组ID">{{ vdata. detailData.receiverGroupId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="收款账号别名">{{ vdata.detailData.receiverAlias }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号类型">{{ vdata.detailData.accType == 0 ? '个人' : '商户' }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号">{{ vdata.detailData.accNo }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号名称">{{ vdata.detailData.accName }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账关系类型">{{ vdata.detailData.relationType }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账关系类型名称">{{ vdata.detailData.relationTypeName }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="实际分账比例">{{ (vdata.detailData.divisionProfit * 100).toFixed(2) }}%</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账金额">{{ vdata.detailData.divisionAmount / 100 }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="回退金额">{{ vdata.detailData.divisionRefundAmount / 100 }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="创建时间">{{ vdata.detailData.createdAt }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="更新时间">{{ vdata.detailData.updatedAt }}</a-descriptions-item></a-descriptions></a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<a-row justify="start" type="flex">
|
||||
<a-col :sm="24">
|
||||
<span style="color: black;">上游返回错误码:</span>
|
||||
<a-form-item>
|
||||
<a-textarea v-model:value="vdata.detailData.errCode" type="textarea" disabled="disabled" :rows="4" style="color: black;margin-top: 10px" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="start" type="flex">
|
||||
<a-col :sm="24">
|
||||
<span style="color: black;">上游返回错误数据包:</span>
|
||||
<a-form-item>
|
||||
<a-textarea v-model:value="vdata.detailData.errMsg" type="textarea" disabled="disabled" :rows="4" style="color: black;margin-top: 10px" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_PAY_ORDER_DIVISION_REFUND_RECORD_LIST, req } from '@/api/manage'
|
||||
import { reactive } from 'vue'
|
||||
|
||||
|
||||
const vdata = reactive({
|
||||
visible: false,
|
||||
detailData: {} as any
|
||||
})
|
||||
|
||||
defineExpose({show})
|
||||
function show (recordId) {
|
||||
|
||||
req.getById(API_URL_PAY_ORDER_DIVISION_REFUND_RECORD_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="() => { vdata.searchData= {} }">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<!-- <a-icon slot="suffixIcon" type="sync" /> -->
|
||||
<JeepayDateRangePicker v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="dateTime" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.divisionRecordId" placeholder="分账记录ID" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.receiverId" placeholder="分账接受者ID" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.receiverGroupId" placeholder="分账账号组ID" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appId" placeholder="应用AppId" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.payOrderId" placeholder="支付订单号" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.payOrderRefundOrderId" placeholder="退款订单号" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.accNo" placeholder="分账接收账号" />
|
||||
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="退款状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">待退款</a-select-option>
|
||||
<a-select-option value="1">分账成功</a-select-option>
|
||||
<a-select-option value="2">分账失败</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="recordId"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'divisionAmount'"><b>¥{{ record.divisionAmount/100 }}</b></template>
|
||||
<template v-if="column.key == 'divisionRefundAmount'"><b>¥{{ record.divisionRefundAmount/100 }}</b></template>
|
||||
<template v-if="column.key == 'payOrderAmount'">¥{{ record.payOrderAmount/100 }}</template>
|
||||
<template v-if="column.key == 'state'">
|
||||
<a-tag v-if="record.state == 0" color="orange">回退中</a-tag>
|
||||
<a-tag v-if="record.state == 1" color="blue">回退成功</a-tag>
|
||||
<a-tag v-if="record.state == 2" color="volcano">回退失败</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key == 'ifCode'">
|
||||
<template v-for="(item) in vdata.ifCodeList" :key="item.ifCode">
|
||||
<label v-if="record.ifCode == item.ifCode">{{ item.ifName }}({{ item.ifCode }})</label>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<a-button v-if="$access('ENT_DIVISION_REFUND_RECORD_VIEW')" type="link" @click="detailFunc(record.divisionRefundId)">详情</a-button>
|
||||
</template>
|
||||
<template v-if="column.key == 'payOrderDivisionAmount'">{{ (record.payOrderDivisionAmount / 100).toFixed(2) }}</template>
|
||||
<template v-if="column.key == 'divisionProfit'">{{ (record.divisionProfit * 100).toFixed(2) }}%</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<Detail ref="recordDetail" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_PAY_ORDER_DIVISION_REFUND_RECORD_LIST, API_URL_IFDEFINES_LIST, req } from '@/api/manage'
|
||||
import Detail from './Detail.vue'
|
||||
import { reactive, ref,getCurrentInstance, onMounted } from 'vue'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
||||
const tableColumns = reactive([
|
||||
|
||||
{ key: 'divisionRefundId', title: '分账退款订单号', dataIndex: 'divisionRefundId' },
|
||||
{ key: 'divisionRefundAmount', title: '回退金额' },
|
||||
{ key: 'divisionAmount', title: '分账金额(首次)' },
|
||||
{ key: 'divisionRecordId', title: '分账记录ID', dataIndex: 'divisionRecordId' },
|
||||
{ key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
{ key: 'payOrderRefundOrderId', title: '支付订单退款单号', dataIndex: 'payOrderRefundOrderId' },
|
||||
{ key: 'ifCode', title: '支付接口' },
|
||||
{ key: 'payOrderAmount', title: '支付订单金额' },
|
||||
{ key: 'receiverAlias', title: '账号别名', dataIndex: 'receiverAlias' },
|
||||
{ key: 'accNo', title: '接收账号', dataIndex: 'accNo' },
|
||||
{ key: 'accName', title: '账号姓名', dataIndex: 'accName' },
|
||||
{ key: 'relationTypeName', title: '分账关系类型', dataIndex: 'relationTypeName' },
|
||||
{ key: 'divisionProfit', dataIndex: 'divisionProfit', title: '分账比例'},
|
||||
{ key: 'state', title: '状态', scopedSlots: { customRender: 'stateSlot' } },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
|
||||
{ key: 'op', title: '操作', width: '180px', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
const recordDetail = ref()
|
||||
const infoTable = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
searchData: {} as any,
|
||||
ifCodeList: [] as any,
|
||||
visible:false,
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
req.list(API_URL_IFDEFINES_LIST, {state:1}).then((res) => {
|
||||
vdata.ifCodeList = res
|
||||
})
|
||||
})
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_PAY_ORDER_DIVISION_REFUND_RECORD_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc() { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function detailFunc (recordId) {
|
||||
recordDetail.value.show(recordId)
|
||||
}
|
||||
|
||||
</script>
|
||||
21
jeepay-ui-merchant/src/views/exception/403.vue
Normal file
21
jeepay-ui-merchant/src/views/exception/403.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class="result-err">
|
||||
<img src="~@/assets/svg/403.svg" alt="">
|
||||
<div>
|
||||
抱歉,您无权访问此页。
|
||||
</div>
|
||||
<a-button type="primary" style="margin-top:30px" @click="toHome">
|
||||
返回首页
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {useRoute} from 'vue-router'
|
||||
import router from '@/router'
|
||||
|
||||
function toHome () {
|
||||
router.push({ path: '/' })
|
||||
}
|
||||
|
||||
</script>
|
||||
21
jeepay-ui-merchant/src/views/exception/404.vue
Normal file
21
jeepay-ui-merchant/src/views/exception/404.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class="result-err">
|
||||
<img src="~@/assets/svg/404.svg" alt="">
|
||||
<div>
|
||||
抱歉,您访问的页面不存在。
|
||||
</div>
|
||||
<a-button type="primary" style="margin-top:30px" @click="toHome">
|
||||
返回首页
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {useRoute} from 'vue-router'
|
||||
import router from '@/router'
|
||||
|
||||
function toHome () {
|
||||
router.push({ path: '/' })
|
||||
}
|
||||
|
||||
</script>
|
||||
21
jeepay-ui-merchant/src/views/exception/500.vue
Normal file
21
jeepay-ui-merchant/src/views/exception/500.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class="result-err">
|
||||
<img src="~@/assets/svg/500.svg" alt="">
|
||||
<div>
|
||||
对不起,服务器错误。
|
||||
</div>
|
||||
<a-button type="primary" style="margin-top:30px" @click="toHome">
|
||||
返回首页
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {useRoute} from 'vue-router'
|
||||
import router from '@/router'
|
||||
|
||||
function toHome () {
|
||||
router.push({ path: '/' })
|
||||
}
|
||||
|
||||
</script>
|
||||
605
jeepay-ui-merchant/src/views/info/MchInfoPage.vue
Normal file
605
jeepay-ui-merchant/src/views/info/MchInfoPage.vue
Normal file
@@ -0,0 +1,605 @@
|
||||
<template>
|
||||
<div class="c-wrapper">
|
||||
<!-- 左侧布局 -->
|
||||
<div class="c-content-left">
|
||||
<a-card style=" padding:30px">
|
||||
|
||||
<div class="div-top">
|
||||
<div class="div-top-title">
|
||||
<div>
|
||||
用户信息
|
||||
</div>
|
||||
<div>
|
||||
<a-button type="link" @click="copyMchInfo">
|
||||
<template #icon><copy-outlined /></template>
|
||||
复制用户信息
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-top-line"></div>
|
||||
</div>
|
||||
<!-- <div class="c-header h-flex">
|
||||
<p class="header-title">用户信息</p>
|
||||
<a-button type="link" @click="copyMchInfo">
|
||||
<template #icon><copy-outlined /></template>
|
||||
复制用户信息
|
||||
</a-button>
|
||||
</div> -->
|
||||
<div class="ite-wrapper">
|
||||
<!-- <div class="item">
|
||||
<span class="label">商家名称:</span>
|
||||
<span class="desc">{{ vdata.mchInfo.mchName }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">商家简称:</span>
|
||||
<span class="desc">{{ vdata.mchInfo.mchShortName }}</span>
|
||||
</div> -->
|
||||
<div class="item">
|
||||
<span class="label">登录名:</span>
|
||||
<span class="desc">{{ vdata.mchInfo.loginUsername }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">用户名称:</span>
|
||||
<span class="desc">{{ vdata.mchInfo.mchNo }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">手机号</span>
|
||||
<span class="desc">{{ vdata.mchInfo.contactTel }}</span>
|
||||
</div>
|
||||
<!-- <div class="item">
|
||||
<span class="label">商户类型:</span>
|
||||
<span class="desc">{{ vdata.mchInfo.type==1?'普通商户':'特约商户' }}</span>
|
||||
</div> -->
|
||||
<!-- <div v-if="vdata.mchInfo.type == 2" class="item">-->
|
||||
<!-- <span class="label">服务商号:</span>-->
|
||||
<!-- <span class="desc">{{ vdata.mchInfo.isvNo }}</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="item">
|
||||
<span class="label">代理商号</span>
|
||||
<span class="desc">{{ vdata.mchInfo.agentNo }}</span>
|
||||
</div> -->
|
||||
<div class="item">
|
||||
<span class="label">注册时间:</span>
|
||||
<span class="desc">{{ vdata.mchInfo.createdAt }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="item">
|
||||
<span class="label">签约状态</span>
|
||||
<span class="desc"><a-tag color="cyan">已签约</a-tag></span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">签约到期时间</span>
|
||||
<span class="desc">{{ vdata.mchInfo.createdAt }}</span>
|
||||
</div> -->
|
||||
</a-card>
|
||||
<a-card v-if="$access('AGREEMENT_PAGE_SIGN') && vdata.isvConfigIsOpen" style="min-height: 473px;padding:30px;margin-top: 30px;">
|
||||
<div class="c-header">
|
||||
<p class="header-title">支付宝安全发管理</p>
|
||||
</div>
|
||||
<div class="s-wrapper">
|
||||
<div class="s-label">
|
||||
选择应用:
|
||||
</div>
|
||||
<div class="s-input">
|
||||
<a-select v-model:value="vdata.configAppId" class="form-item-content" placeholder="选择应用" style="width: 100%;" @change="changeAppId">
|
||||
<a-select-option v-for="(item) in vdata.mchAppList" :key="item.appId">{{ item.appName }} [{{ item.appId }}]</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="!vdata.isAuthorize">
|
||||
<div class="zfb-null">
|
||||
<img src="@/assets/svg/zfb-pay-null.svg" alt="">
|
||||
<div class="zfb-tips">当前应用暂未开通支付宝安全发</div>
|
||||
</div>
|
||||
<div v-if="vdata.isShowButton" class="zfb-subimit-but">
|
||||
<a-button type="primary" @click="pageSign()">1>签约开通</a-button>
|
||||
<a-button type="primary" style="margin-left: 30px;" @click="queryPageSign()">2>签约查询</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="vdata.isAuthorize">
|
||||
<div class="zfb-header">
|
||||
<div class="z-h-left">
|
||||
<div class="z-h-l-title">记账本余额(元):</div>
|
||||
<div class="z-h-l-text">{{ vdata.aliAccountBookInfo.available_amount }}</div>
|
||||
</div>
|
||||
<div class="z-h-right">
|
||||
<a-button style="margin-right: 15px;" @click="toRecharge()">前往充值</a-button>
|
||||
<a-button type="primary" @click="toTransferPage()">发起转账</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ite-wrapper" style="margin-top: 30px;">
|
||||
<div class="item">
|
||||
<span class="label l-120">记账本ID:</span>
|
||||
<span class="desc">{{ vdata.aliAccountBookInfo.account_book_id }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label l-120">记账外卡卡号:</span>
|
||||
<span class="desc">{{ vdata.aliAccountBookInfo.ext_card_info.card_no }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label l-120">记账外卡户名:</span>
|
||||
<span class="desc">{{ vdata.aliAccountBookInfo.ext_card_info.bank_acc_name }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label l-120">记账外卡支行:</span>
|
||||
<span class="desc">{{ vdata.aliAccountBookInfo.ext_card_info.card_branch }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label l-120">记账外卡开户行:</span>
|
||||
<span class="desc">{{ vdata.aliAccountBookInfo.ext_card_info.card_bank }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label l-120">记账外卡开户地址:</span>
|
||||
<span class="desc">{{ vdata.aliAccountBookInfo.ext_card_info.card_location }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label l-120">记账外卡联行号:</span>
|
||||
<span class="desc">{{ vdata.aliAccountBookInfo.ext_card_info.card_deposit }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label l-120">记账外卡状态:</span>
|
||||
<span class="desc">{{ vdata.aliAccountBookInfo.ext_card_info.status == 'A'?'正常':'异常' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-card>
|
||||
</div>
|
||||
<!-- 右侧布局 -->
|
||||
<!-- <div v-if="vdata.mchInfo.type == 2" class="c-content-right">
|
||||
<a-card style="padding:30px">
|
||||
<div class="c-header h-flex" style="margin-bottom: 40px;">
|
||||
<p class="header-title">
|
||||
支付宝代运营授权请求
|
||||
</p>
|
||||
<a-tag v-if="vdata.showAuthStatus" :color="calcZfbStatus(vdata.alipayAuthData.handleStatus,'color')" style="padding:5px 18px;">{{ calcZfbStatus(vdata.alipayAuthData.handleStatus,'text') }}</a-tag>
|
||||
</div>
|
||||
<a-alert message="注意!!!仅当使用支付宝如意lite产品时使用" type="info" style="margin-bottom: 20px;" />
|
||||
<a-form
|
||||
ref="configFormModelRef"
|
||||
:label-col="labelCol"
|
||||
labelAlign="right"
|
||||
labelWidth="120"
|
||||
:model="vdata.alipayAuthData"
|
||||
layout="horizontal"
|
||||
>
|
||||
<a-form-item label="授权方式" name="authType" :rules="[{ required: true, message: '请选择授权方式' }]">
|
||||
<a-radio-group v-model:value="vdata.alipayAuthData.authType">
|
||||
<a-radio value="qrcode">使用支付宝扫授权码</a-radio>
|
||||
<a-radio value="apply">发送支付宝授权消息</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="支付宝账号" name="alipayAccount" :rules="[{ required: true, message: '请输入支付宝账号' }]">
|
||||
<a-input v-model:value="vdata.alipayAuthData.alipayAccount" style="width: 70%;" placeholder="请输入支付宝账号(一般为手机或邮箱)" />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<div class="sub-but">
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="alipayAuthFunc"><check-circle-outlined />发起授权</a-button>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-card>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- 扫码授权弹窗 -->
|
||||
<a-modal v-model:visible="vdata.showAuthQrCodeUrl" title="二维码" :footer="null" :width="350" @ok="() => vdata.showAuthQrCodeUrl = false">
|
||||
<span>请使用支付宝账号【{{ vdata.alipayAuthData.alipayAccount }}】绑定的支付宝扫码,根据页面指引完成授权</span>
|
||||
<img :src="vdata.authQrCodeUrl" style="width: 300px;height: 300px;text-align: center;">
|
||||
</a-modal>
|
||||
|
||||
<!-- 充值订单弹出页 -->
|
||||
<RechargeModalInfo ref="rechargeModalInfo" :callback-func="refTable" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import RechargeModalInfo from './RechargeModal.vue' // 充值订单弹出页
|
||||
import { API_ALIPAY_SP_OPERATION, reqLoad, req, $getMainUserInfo, API_URL_MCH_APP, $queryUserAgreementPageSign, $fundAccountbookQuery, $alipayAgreementPageSign } from '@/api/manage' // 接口
|
||||
import { reactive, ref, getCurrentInstance, createVNode } from 'vue'
|
||||
import router from '@/router'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import { Modal } from 'ant-design-vue'
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
|
||||
|
||||
const configFormModelRef = ref()
|
||||
const rechargeModalInfo = ref()
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const vdata : any = reactive ({
|
||||
mchInfo: {},
|
||||
mchAppList:[],
|
||||
alipayAuthData: {}, // 支付宝代运营授权
|
||||
authQrCodeUrl: '',
|
||||
showAuthQrCodeUrl: false,
|
||||
showAuthStatus: false,
|
||||
btnLoading: false,
|
||||
aliaqfIsShow: false, // 支付宝安全发显示开关
|
||||
configAppId: '', // 支付宝安全发选择的appid
|
||||
isAuthorize: false, // 应用授权显示
|
||||
isvConfigIsOpen: false, // 服务商安全发是否配置
|
||||
isShowButton: false, // 商户应用安全发是否配置
|
||||
aliAccountBookInfo: {
|
||||
ext_card_info: {} as any // 记账外卡信息
|
||||
} as any, // 支付宝记账本详情
|
||||
})
|
||||
const labelCol = {
|
||||
style: { width: '150px' }
|
||||
}
|
||||
$getMainUserInfo().then(res => {
|
||||
vdata.mchInfo = res
|
||||
})
|
||||
|
||||
// 回显当前代运营授权信息
|
||||
// queryAuthInfo().then(res => {
|
||||
// if(res) {
|
||||
// vdata.alipayAuthData = res
|
||||
// vdata.showAuthStatus = true
|
||||
// }
|
||||
// })
|
||||
|
||||
// 查询当前授权信息
|
||||
function queryAuthInfo() {
|
||||
return false;
|
||||
return req.getById(API_ALIPAY_SP_OPERATION, 'authInfo')
|
||||
}
|
||||
|
||||
// 发起支付宝代运营授权
|
||||
function alipayAuthFunc() {
|
||||
queryAuthInfo().then(res => {
|
||||
if (res && res.handleStatus == 'SUCCESS') {
|
||||
/* if (res.alipayAccount == vdata.alipayAuthData.alipayAccount) {
|
||||
$infoBox.message.success('当前支付宝账号已授权通过,无需再次授权')
|
||||
return
|
||||
} */
|
||||
// 支付宝账号【' + res.alipayAccount + '】已授权成功。重新授权的同时,需要重新同步店铺,否则可能会导致无法绑定如意设备
|
||||
$infoBox.confirmDanger('授权', '确认授权?', () => {
|
||||
sendAuth()
|
||||
}, undefined, { okText: '确认授权' })
|
||||
}else {
|
||||
sendAuth()
|
||||
}
|
||||
})
|
||||
}
|
||||
// 支付宝代运营授权请求
|
||||
function sendAuth() {
|
||||
configFormModelRef.value.validate().then(valid =>{
|
||||
if (vdata.alipayAuthData.authType == 'qrcode') {
|
||||
reqLoad.getById(API_ALIPAY_SP_OPERATION, 'queryQrcode', { alipayAccount: vdata.alipayAuthData.alipayAccount }).then(res => {
|
||||
vdata.authQrCodeUrl = decodeURIComponent(res.qrCodeUrl)
|
||||
vdata.showAuthQrCodeUrl = true
|
||||
vdata.showAuthStatus = true
|
||||
})
|
||||
}else if (vdata.alipayAuthData.authType == 'apply') {
|
||||
reqLoad.add(API_ALIPAY_SP_OPERATION + '/apply', { alipayAccount: vdata.alipayAuthData.alipayAccount }).then(res => {
|
||||
vdata.showAuthStatus = true
|
||||
$infoBox.modalSuccess('发送成功', '授权消息已发送至支付宝:' + vdata.alipayAuthData.alipayAccount + ',请前往支付宝App处理')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查询支付宝代运营授权结果
|
||||
function queryAlipayAuthResultFunc() {
|
||||
return reqLoad.getById(API_ALIPAY_SP_OPERATION, 'queryResult', undefined).then(res => {
|
||||
if (res ) {
|
||||
vdata.alipayAuthData.handleStatus =res.handleStatus
|
||||
}
|
||||
})
|
||||
}
|
||||
// 赋值商户信息
|
||||
function copyMchInfo(){
|
||||
var textarea= document.createElement("textarea"); // 创建textarea对象
|
||||
textarea.value = `登录名:${vdata.mchInfo.loginUsername}\r\n用户名称:${vdata.mchInfo.mchNo}\r\n手机号:${vdata.mchInfo.contactTel}\r\n注册时间:${vdata.mchInfo.createdAt}`; // 设置复制内容
|
||||
document.body.appendChild(textarea); // 添加临时实例
|
||||
textarea.select(); // 选择实例内容
|
||||
document.execCommand("Copy"); // 执行复制
|
||||
document.body.removeChild(textarea); // 删除临时实例
|
||||
$infoBox.message.success('复制成功!')
|
||||
// const copyList = [
|
||||
// { title:'用户名称',value:'mchName'},
|
||||
// { title:'商户简称',value:'mchShortName'},
|
||||
// { title:'登录名',value:'loginUsername'},
|
||||
// { title:'用户号',value:'mchNo'},
|
||||
// { title:'商户类型',value:'type'},
|
||||
// // { title:'服务商号',value:'isvNo'},
|
||||
// { title:'注册时间',value:'createdAt'},
|
||||
// ]
|
||||
// const copyData = copyList.map((v:any)=>{
|
||||
// if(v.value =='type') return v.title +':'+ (vdata.mchInfo[v.value] == '1'?'普通商户':'特约商户')
|
||||
// return v.title +':'+ vdata.mchInfo[v.value]
|
||||
// }).join('\n')
|
||||
// navigator && navigator.clipboard && navigator.clipboard.writeText(copyData).then(res => {
|
||||
// console.log(res)
|
||||
// $infoBox.message.success('复制成功!')
|
||||
// }).catch(err=> {
|
||||
// console.log('copy err'+err)
|
||||
// })
|
||||
}
|
||||
|
||||
// 计算授权状态
|
||||
function calcZfbStatus(sta: String, key:any) {
|
||||
const staObj: any = {}
|
||||
switch (sta) {
|
||||
case 'SUCCESS':
|
||||
staObj.text = '授权成功'
|
||||
staObj.color = 'success'
|
||||
break
|
||||
case 'PROCESS':
|
||||
staObj.text = '待确认授权'
|
||||
staObj.color = 'warning'
|
||||
break
|
||||
default:
|
||||
staObj.text = '暂未授权'
|
||||
staObj.color = 'default'
|
||||
break
|
||||
}
|
||||
return staObj[key]
|
||||
}
|
||||
|
||||
function refTable () {}
|
||||
|
||||
// 支付宝安全发权限
|
||||
if (useUserStore().userInfo.mchType == '2' && $access('AGREEMENT_PAGE_SIGN')) {
|
||||
aliAqfConfig()
|
||||
}
|
||||
|
||||
// 变更 appId的事件
|
||||
function changeAppId (value) {
|
||||
vdata.configAppId = value
|
||||
queryUserAgreementPageSign(value)
|
||||
}
|
||||
|
||||
// 点击充值,打开充值金额弹窗
|
||||
function toRecharge () {
|
||||
|
||||
if (!vdata.configAppId) {
|
||||
return $infoBox.message.console.error('请先选择应用')
|
||||
}
|
||||
rechargeModalInfo.value.show(vdata.configAppId)
|
||||
}
|
||||
|
||||
// 跳转至转账页面
|
||||
function toTransferPage () {
|
||||
router.push({
|
||||
path: '/doTransfer',
|
||||
query: { appId: vdata.configAppId, ifCode: 'aliaqfpay' }
|
||||
})
|
||||
}
|
||||
|
||||
function aliAqfConfig() {
|
||||
// 1.查询应用
|
||||
req.list(API_URL_MCH_APP, { pageSize: -1, mchNo: vdata.mchInfo.mchNo, state: 1}).then(res2 => {
|
||||
vdata.mchAppList = res2.records
|
||||
if (vdata.mchAppList.length > 0) {
|
||||
vdata.configAppId = vdata.mchAppList[0].appId
|
||||
// 查询签约信息
|
||||
queryUserAgreementPageSign(vdata.configAppId)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function queryUserAgreementPageSign(appId) {
|
||||
vdata.isAuthorize = true
|
||||
return false
|
||||
// 2.查询当前应用签约详情
|
||||
$queryUserAgreementPageSign(appId).then(res => {
|
||||
// 开启显示支付宝安全发
|
||||
vdata.isvConfigIsOpen = true
|
||||
vdata.isShowButton = true
|
||||
// 如果服务商配置未配置,关闭安全发显示
|
||||
if (res.isvConfigIsOpen && res.isvConfigIsOpen == 'hide') {
|
||||
vdata.isvConfigIsOpen = false
|
||||
}
|
||||
// 如果商户应用安全发未配置,关闭安全发操作显示
|
||||
if (res.isShowButton && res.isShowButton == 'hide') {
|
||||
vdata.isShowButton = false
|
||||
}
|
||||
if (res.agreementNo && res.accountBookId) {
|
||||
// 显示当前应用已授权
|
||||
vdata.isAuthorize = true
|
||||
// 查询当前记账本信息
|
||||
$fundAccountbookQuery(appId).then(res => {
|
||||
vdata.isAuthorize = res.isAuthorize
|
||||
vdata.aliAccountBookInfo = res
|
||||
})
|
||||
}else {
|
||||
// 显示当前应用未授权开通
|
||||
vdata.isAuthorize = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 跳转签约页面
|
||||
function pageSign() {
|
||||
$alipayAgreementPageSign(vdata.configAppId).then(res => {
|
||||
const winOpen = window.open('', '_blank')
|
||||
winOpen?.document.write(res)
|
||||
winOpen?.focus()
|
||||
})
|
||||
|
||||
Modal.warning({
|
||||
title: '注意:',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
content: '请确认已完成签约',
|
||||
okText: '已签约',
|
||||
onOk() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 查询结果
|
||||
queryPageSign()
|
||||
// 关闭弹窗
|
||||
resolve(true)
|
||||
})
|
||||
},
|
||||
onCancel() {},
|
||||
})
|
||||
}
|
||||
|
||||
// 查询签约结果
|
||||
function queryPageSign() {
|
||||
$queryUserAgreementPageSign(vdata.configAppId).then(res => {
|
||||
if (!res.agreementNo || !res.accountBookId) {
|
||||
return $infoBox.message.error('请先扫码签约,再查询结果')
|
||||
}
|
||||
$infoBox.message.success('查询成功')
|
||||
// 重新查询签约信息及记账本信息
|
||||
queryUserAgreementPageSign(vdata.configAppId)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
// 布局 css
|
||||
.c-wrapper{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 50px;
|
||||
.c-content-left,.c-content-right{
|
||||
flex: 1%;
|
||||
}
|
||||
.c-content-left{
|
||||
margin-right: 15px;
|
||||
}
|
||||
.c-content-right{
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
.ite-wrapper{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0 15px;
|
||||
.item{
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
p {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin:0 5px;
|
||||
}
|
||||
.desc {
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.05em;
|
||||
color: #262626;
|
||||
}
|
||||
.label {
|
||||
min-width: 100px;
|
||||
color: #262626ff;
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
.l-120{
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.header-title{
|
||||
color: #000000ff;
|
||||
font-weight: 600;
|
||||
}
|
||||
.c-header{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.h-flex{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.s-wrapper{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.s-label{
|
||||
margin-left: 5px;
|
||||
|
||||
color: #262626ff;
|
||||
}
|
||||
.s-input{
|
||||
flex: 1;
|
||||
margin-left: 150px;
|
||||
}
|
||||
}
|
||||
.zfb-null{
|
||||
margin: 60px auto 30px;
|
||||
width: 218px;
|
||||
img{
|
||||
width: 218px;
|
||||
height: 97px;
|
||||
}
|
||||
.zfb-tips{
|
||||
margin-top: 24px;
|
||||
text-align: center;
|
||||
color: #b3b3b3ff;
|
||||
}
|
||||
}
|
||||
.zfb-subimit-but{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.sub-but{
|
||||
margin: 30px 150px;
|
||||
}
|
||||
:deep .ant-form-item-required{
|
||||
margin-right: 15px;
|
||||
}
|
||||
.zfb-header{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
margin-top: 30px;
|
||||
padding: 30px;
|
||||
border-top: 1px solid #F2F2F2;
|
||||
border-bottom: 1px solid #F2F2F2;
|
||||
.z-h-l-title{
|
||||
color: #262626ff;
|
||||
}
|
||||
.z-h-l-text{
|
||||
margin-top: 20px;
|
||||
color: #262626ff;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.div-top{
|
||||
background: #ffffff;
|
||||
padding: 10px 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.div-top-title{
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.div-top-des{
|
||||
color: #2C6EF6;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.div-top-line{
|
||||
border-bottom: 1px solid #EDEDED;
|
||||
}
|
||||
.div-top-status{
|
||||
display: flex;
|
||||
margin: 18px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.div-top-status-title{
|
||||
padding-right:10px;
|
||||
color:#767676;
|
||||
}
|
||||
.div-top-status-title-span{
|
||||
padding: 0 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.div-top-active{
|
||||
color: #2C6EF6;
|
||||
}
|
||||
</style>
|
||||
86
jeepay-ui-merchant/src/views/info/RechargeModal.vue
Normal file
86
jeepay-ui-merchant/src/views/info/RechargeModal.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
title="充值信息"
|
||||
:confirm-loading="confirmLoading"
|
||||
:closable="false"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form ref="rechargeInfo" :rules="rules" :model="data.rechargeInfo">
|
||||
<a-form-item label="充值金额" name="transAmount">
|
||||
<a-input-number v-model:value="data.rechargeInfo.transAmount" :min="0.01" :precision="2" style="width:100%" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="tsx" >
|
||||
import { req, $fundTransPage } from '@/api/manage'
|
||||
import { ref, reactive, getCurrentInstance, defineProps, defineExpose, computed } from 'vue'
|
||||
|
||||
// 定义函数
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
|
||||
// 导入全局函数
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
// refundInfo组件
|
||||
const rechargeInfo = ref()
|
||||
|
||||
|
||||
let visible= ref(false)
|
||||
let confirmLoading= false
|
||||
|
||||
let data : any = reactive({
|
||||
recordId: '', // 应用ID
|
||||
refundErrorModal: null, // 退款错误信息的modal对象
|
||||
detailData: {} as any,
|
||||
rechargeInfo: {
|
||||
// title: '', // 标题
|
||||
// remark: '', // 备注
|
||||
transAmount: '' // 充值金额
|
||||
} as any,
|
||||
})
|
||||
|
||||
const rules = {
|
||||
transAmount: [{ required: true, message: '请输入金额', type:'number' }]
|
||||
}
|
||||
|
||||
function show (recordId) {
|
||||
|
||||
data.rechargeInfo = {}
|
||||
data.recordId = recordId
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
function handleOk (e) {
|
||||
rechargeInfo.value.validate().then( (valid) => {
|
||||
confirmLoading = true
|
||||
// 去支付宝充值
|
||||
$fundTransPage(data.recordId, data.rechargeInfo.transAmount).then(res =>{
|
||||
const winOpen = window.open('', '_blank')
|
||||
winOpen?.document.write(res)
|
||||
winOpen?.focus()
|
||||
|
||||
visible.value = false
|
||||
}).catch(() => {
|
||||
confirmLoading = false // 取消按钮转圈
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function handleCancel (e) {
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
232
jeepay-ui-merchant/src/views/mchApp/AddOrEdit.vue
Normal file
232
jeepay-ui-merchant/src/views/mchApp/AddOrEdit.vue
Normal file
@@ -0,0 +1,232 @@
|
||||
<!-- 复制自: 运营平台
|
||||
差异: 删除商户号mchNo 的input即可。
|
||||
|
||||
-->
|
||||
<template>
|
||||
<a-drawer
|
||||
:visible="vdata.visible"
|
||||
:title=" vdata.isAdd ? '新增应用' : '修改应用'"
|
||||
width="40%"
|
||||
:maskClosable="false"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" layout="vertical" :rules="vdata.rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="应用名称" name="appName">
|
||||
<a-input v-model:value="vdata.saveObject['appName']" placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="应用状态" name="state">
|
||||
<a-radio-group v-model:value="vdata.saveObject['state']">
|
||||
<a-radio :value="1">启用</a-radio>
|
||||
<a-radio :value="0">停用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="!vdata.isAdd" :span="12">
|
||||
<a-form-item label="应用ID" name="appId">
|
||||
<a-input v-model:value="vdata.saveObject['appId']" placeholder="请输入" :disabled="!vdata.isAdd" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- <a-col :span="12" v-if="!vdata.isAdd && vdata.saveObject.range == 0">-->
|
||||
<!-- <a-form-item label="是否设置为默认应用" name="defaultFlag">-->
|
||||
<!-- <a-radio-group v-model:value="vdata.saveObject['defaultFlag']">-->
|
||||
<!-- <a-radio :value="1">是</a-radio>-->
|
||||
<!-- <a-radio :value="0">否</a-radio>-->
|
||||
<!-- </a-radio-group>-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<a-col :span="12">
|
||||
<a-form-item label="备注" name="remark" class="m-b-50 ">
|
||||
<a-input v-model:value="vdata.saveObject['remark']" placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col v-if="vdata.isAdd" :span="24">
|
||||
<a-divider orientation="left" style="color: #1A66FF;">签名配置</a-divider>
|
||||
|
||||
<a-form-item name="appSignType">
|
||||
<template #label>
|
||||
<span>支持的签名方式</span>
|
||||
<a-popover placement="top">
|
||||
<template #title><span>签名方式</span></template>
|
||||
<template #content>
|
||||
<p>若需要使用系统测试或者{{ $SYS_NAME_MAP.MCH_APP }}APP则必须支持MD5, 若仅通过API调用则根据需求进行选择。 </p>
|
||||
</template>
|
||||
<question-circle-outlined />
|
||||
</a-popover>
|
||||
</template>
|
||||
|
||||
<a-checkbox-group v-model:value="vdata.saveObject.appSignTypeObject">
|
||||
<a-checkbox value="MD5">MD5</a-checkbox>
|
||||
<a-checkbox value="RSA2">RSA2</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-show="vdata.saveObject.appSignTypeObject && vdata.saveObject.appSignTypeObject.indexOf('MD5') >= 0" label="设置MD5秘钥" name="appSecret">
|
||||
<a-textarea v-model:value="vdata.saveObject['appSecret']" :placeholder="vdata.saveObject['appSecret_ph']" type="textarea" />
|
||||
<a-button type="primary" style="margin-top: 5px;" ghost @click="randomKey(false, 128, 0)"><file-sync-outlined />随机生成私钥</a-button>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-show="vdata.saveObject.appSignTypeObject && vdata.saveObject.appSignTypeObject.indexOf('RSA2') >= 0" label="设置RSA2应用公钥" name="appRsa2PublicKey">
|
||||
<a-textarea v-model:value="vdata.saveObject['appRsa2PublicKey']" type="textarea" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-show="vdata.saveObject.appSignTypeObject && vdata.saveObject.appSignTypeObject.indexOf('RSA2') >= 0" label="支付网关系统公钥(回调验签使用)">
|
||||
<a-textarea :rows="6" :value="vdata.sysRSA2PublicKey" :disabled="true" type="textarea" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose"><close-outlined />取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="onSubmit"><check-outlined />保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_APP, req, $getSysRSA2PublicKey } from '@/api/manage'
|
||||
import {ref, reactive, getCurrentInstance} from 'vue'
|
||||
|
||||
const { $SYS_NAME_MAP } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
|
||||
const vdata : any = reactive({
|
||||
isAdd: true, // 新增 or 修改
|
||||
visible: false, // 抽屉开关
|
||||
appId: '', // 应用AppId
|
||||
saveObject: {}, // 数据对象
|
||||
btnLoading:false,
|
||||
sysRSA2PublicKey: '',
|
||||
rules: {
|
||||
mchNo: [{ required: true, message: '请输入商户号', trigger: 'blur' }],
|
||||
appName: [{ required: true, message: '请输入应用名称', trigger: 'blur' }],
|
||||
appSecret: [{
|
||||
validator: (rule, value) => {
|
||||
|
||||
// 新增 & 选择了MD5 : 必须输入MD5私钥
|
||||
if(vdata.isAdd && vdata.saveObject.appSignTypeObject.indexOf('MD5') >= 0 && !value){
|
||||
return Promise.reject('请输入MD5秘钥')
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
}],
|
||||
appRsa2PublicKey: [{
|
||||
validator: (rule, value) => {
|
||||
|
||||
// 新增 & 选择了MD5 : 必须输入MD5私钥
|
||||
if(vdata.saveObject.appSignTypeObject.indexOf('RSA2') >= 0 && !value){
|
||||
return Promise.reject('请输入RSA2应用公钥')
|
||||
}
|
||||
return Promise.resolve()
|
||||
|
||||
}
|
||||
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
// 表单组件
|
||||
const infoFormModel = ref()
|
||||
|
||||
// 抽屉显示
|
||||
const show = (mchNo, appId) => {
|
||||
vdata.isAdd = !appId
|
||||
// 数据清空
|
||||
vdata.saveObject = {
|
||||
'state': 1,
|
||||
'appSecret': '',
|
||||
'mchNo': mchNo,
|
||||
'defaultFlag': 1,
|
||||
'appSecret_ph': '请输入',
|
||||
appSignTypeObject: ['MD5']
|
||||
}
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.appId = appId
|
||||
// 拉取详情
|
||||
req.getById(API_URL_MCH_APP, appId).then(res => {
|
||||
vdata.saveObject = res
|
||||
vdata.saveObject['appSecret_ph'] = res.appSecret
|
||||
vdata.saveObject['range'] = res.range
|
||||
vdata.saveObject['appSecret'] = ''
|
||||
|
||||
vdata.saveObject.appSignTypeObject = []
|
||||
if(res.appSignType){
|
||||
vdata.saveObject.appSignTypeObject = JSON.parse(res.appSignType)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
vdata.visible = true
|
||||
} else {
|
||||
|
||||
vdata.visible = true // 展示弹层信息
|
||||
}
|
||||
|
||||
// 查询系统公钥
|
||||
$getSysRSA2PublicKey().then((res) => {
|
||||
vdata.sysRSA2PublicKey = res
|
||||
})
|
||||
|
||||
}
|
||||
// 表单提交
|
||||
const onSubmit = () => {
|
||||
|
||||
// 处理签名方式
|
||||
vdata.saveObject.appSignType = JSON.stringify(vdata.saveObject.appSignTypeObject)
|
||||
|
||||
infoFormModel.value.validate().then(() => {
|
||||
|
||||
vdata.btnLoading = true
|
||||
let reqObject = Object.assign({}, vdata.saveObject) // 请求数据
|
||||
|
||||
delete reqObject['appSecret_ph']
|
||||
if (!vdata.isAdd && reqObject['appSecret'] === '') {
|
||||
delete reqObject['appSecret']
|
||||
}
|
||||
console.log(reqObject,'reqObjectreqObjectreqObject')
|
||||
// return false;
|
||||
|
||||
req.addOrUpdate(vdata.isAdd ? null : vdata.appId, API_URL_MCH_APP, reqObject).then(res => {
|
||||
vdata.visible = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).finally(() => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function randomKey(randomFlag, min, max) { // 生成随机128位私钥
|
||||
let str = ''
|
||||
let range = min
|
||||
const arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
|
||||
// 随机产生
|
||||
if (randomFlag) {
|
||||
range = Math.round(Math.random() * (max - min)) + min
|
||||
}
|
||||
for (var i = 0; i < range; i++) {
|
||||
var pos = Math.round(Math.random() * (arr.length - 1))
|
||||
str += arr[ pos ]
|
||||
}
|
||||
vdata.saveObject['appSecret'] = str
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
|
||||
75
jeepay-ui-merchant/src/views/mchApp/AlipayAuth.vue
Normal file
75
jeepay-ui-merchant/src/views/mchApp/AlipayAuth.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<a-modal v-model:visible="vdata.isShow" title="支付宝子商户扫码授权" @ok="handleOkFunc" @cancel="handleOkFunc">
|
||||
<div style="text-align: center">
|
||||
<p>方式1: <br> 使用商家账号登录【支付宝】APP, 扫描如下二维码, 按提示授权: </p>
|
||||
<img style="margin-bottom: 10px" :src="vdata.apiResData.authQrImgUrl">
|
||||
<hr>
|
||||
|
||||
<p style="margin-top: 10px">
|
||||
<!-- 方式2: <br> <a-button v-clipboard:copy="vdata.apiResData.authUrl" v-clipboard:success="onCopySuccess" size="small" class="copy-btn">点击复制</a-button> -->
|
||||
<br> <a-button size="small" class="copy-btn" @click="onCopy">点击复制</a-button>
|
||||
或点击以下链接,按照页面提示自主授权:
|
||||
</p>
|
||||
<a target="_blank" :href="vdata.apiResData.authUrl">{{ vdata.apiResData.authUrl }}</a>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { $queryAlipayIsvsubMchAuthUrl } from '@/api/manage'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { reactive } from 'vue'
|
||||
import useClipboard from 'vue-clipboard3'
|
||||
|
||||
const { toClipboard } = useClipboard()
|
||||
const props = defineProps ({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata = reactive({
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
appId: '',
|
||||
apiResData: {} as any
|
||||
})
|
||||
|
||||
function onCopy () {
|
||||
// $infoBox.message.success('复制成功')
|
||||
const Msg = vdata.apiResData.authUrl
|
||||
copy(Msg)
|
||||
}
|
||||
const copy = async (Msg) => {
|
||||
try {
|
||||
//复制
|
||||
await toClipboard(Msg)
|
||||
console.log(Msg,123)
|
||||
//下面可以设置复制成功的提示框等操作
|
||||
message.success('复制成功')
|
||||
} catch (e) {
|
||||
//复制失败
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({show})
|
||||
function show(appId) { // 弹层打开事件
|
||||
vdata.apiResData = {}
|
||||
vdata.appId = appId
|
||||
|
||||
$queryAlipayIsvsubMchAuthUrl(appId).then(res => {
|
||||
vdata.apiResData = res
|
||||
vdata.isShow = true
|
||||
})
|
||||
}
|
||||
|
||||
function handleOkFunc() { // 点击【确认】按钮事件
|
||||
vdata.isShow = false
|
||||
if (props.callbackFunc) {
|
||||
props.callbackFunc()
|
||||
}
|
||||
}
|
||||
|
||||
function onCopySuccess () {
|
||||
message.success('复制成功')
|
||||
}
|
||||
|
||||
</script>
|
||||
238
jeepay-ui-merchant/src/views/mchApp/List.vue
Normal file
238
jeepay-ui-merchant/src/views/mchApp/List.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card v-show="vdata.tableType == 'table'">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="() => { vdata.searchData= {} }">
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appName" :placeholder="'应用名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appId" :placeholder="'应用ID'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="应用状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">禁用</a-select-option>
|
||||
<a-select-option value="1">启用</a-select-option>
|
||||
<a-select-option value="2">审核中</a-select-option>
|
||||
<a-select-option value="-1">审核驳回</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.range" placeholder="应用类型">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">线下场景</a-select-option>
|
||||
<a-select-option value="1">线上场景</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="appId"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<div>
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APP_ADD')" type="primary" class="mg-b-30" @click="addFunc"><plus-outlined />新建</a-button>-->
|
||||
<a-button v-if="$access('ENT_MCH_APP_ADD')" type="primary" class="mg-b-30" @click="getAddFunc('appSaveEdit')"><plus-outlined />新建</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'appId'">
|
||||
<b>{{ record.appId }}</b>
|
||||
</template> <!-- 自定义插槽 -->
|
||||
|
||||
<template v-if="column.key == 'range'">
|
||||
<a-tag v-if="record.range == 0" color="orange">线下场景</a-tag>
|
||||
<a-tag v-if="record.range == 1" color="green">线上场景</a-tag>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<template v-if="column.key === 'state'">
|
||||
<a-badge status="error" text="禁用" v-if="record.state === 0"/>
|
||||
<a-badge status="processing" text="启用" v-if="record.state === 1"/>
|
||||
<a-badge status="warning" text="审核中" v-if="record.state === 2"/>
|
||||
<a-badge status="error" text="驳回" v-if="record.state === -1"/>
|
||||
<a-tooltip v-if="record.state == -1" :title="record.stateDesc" >
|
||||
<info-circle-outlined style="color: #F00;margin-left: 10px"/>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'defaultFlag'">
|
||||
<a-badge :status="record.defaultFlag === 0?'error':'processing'" :text="record.defaultFlag === 0?'否':'是'" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" @click="showLookModal(record)" v-if="record.state != -1 && record.range == 1" >查看</a-button>
|
||||
<a-button type="link" @click="showLookModal(record,2)" v-if="record.state == -1" >修改</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_APP_EDIT') && record.state !== 2 && record.state !== -1" type="link" @click="editFunc(record.appId)">修改</a-button>
|
||||
<!-- <a-button type="link" @click="ShopFunc(record.appId)" v-if="record.turnsPay == 'Y'">关联商户</a-button>-->
|
||||
<!-- <a-button v-if="userStore.userInfo.mchType == '2' && $access('ENT_MCH_APP_PAY_CONFIG')" type="link" @click="jeepayOauth2ConfigDrawer.show(record.appId, true)">小程序支付配置</a-button> -->
|
||||
<!-- <a-button v-if="userStore.userInfo.mchType == '1' && $access('ENT_MCH_APP_PAY_CONFIG') && record.state !== 2 && record.state !== -1" type="link" @click="jeepayOauth2ConfigDrawer.show(record.appId, false)">oauth2</a-button>-->
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APP_PAY_CONFIG') && record.state !== 2 && record.state !== -1" type="link" @click="showPayIfConfigList(record.appId)">支付配置</a-button>-->
|
||||
<a-button v-if="$access('ENT_MCH_APP_PAY_CONFIG') && record.state !== 2 && record.state !== -1" type="link" @click="productFunc(record.appId)">产品绑定</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_APP_PAY_CONFIG') && record.state !== 2 && record.state !== -1" type="link" @click="caseFunc(record.appId)">方案绑定</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_APP_SIGN') && record.state !== 2 && record.state !== -1 && record.range == 1" type="link" @click="signFunc(record.appId)">签名配置</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_PAY_TEST') && record.state !== 2 && record.state !== -1" type="link">
|
||||
<router-link :to="{name:'ENT_MCH_PAY_TEST', params:{appId:record.appId}}">
|
||||
支付测试
|
||||
</router-link>
|
||||
</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_MCH_TRANSFER') && record.state !== 2 && record.state !== -1" type="link">-->
|
||||
<!-- <router-link :to="{name:'ENT_MCH_TRANSFER', params:{appId:record.appId}}">-->
|
||||
<!-- 发起转账-->
|
||||
<!-- </router-link>-->
|
||||
<!-- </a-button>-->
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APP_DEL') && record.state !== 2 && record.state !== -1" type="link" style="color: red" @click="delFunc(record.appId)">删除</a-button>-->
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增应用 -->
|
||||
<MchAppAddOrEdit ref="mchAppAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<!-- 签名配置 -->
|
||||
<MchAppSignConfig ref="mchAppSignConfig" :callbackFunc="searchFunc" />
|
||||
<!-- 产品绑定 -->
|
||||
<MchAppProduct ref="mchAppProduct" :callbackFunc="searchFunc" />
|
||||
<!-- 关联商户 -->
|
||||
<MchAppShop ref="mchAppShop" :callbackFunc="searchFunc" />
|
||||
|
||||
|
||||
<!-- 费率配置页面 -->
|
||||
<JeepayPayConfigDrawer ref="jeepayPayWayFeeConfigDrawer" :configMode=" userStore.userInfo.mchType == '1' ? 'mchSelfApp1' : 'mchSelfApp2' " />
|
||||
|
||||
<!-- oauth2配置 -->
|
||||
<JeepayOauth2ConfigDrawer ref="jeepayOauth2ConfigDrawer" configMode="mchSelfApp1" />
|
||||
|
||||
<a-card v-show="vdata.tableType == 'appSaveEdit'" style="background: #f0f2f5; ">
|
||||
<JeepayApplicationSave ref="jeepayApplicationSave" :configMode="'mch'" @itemRender="getMchAppSave" style="background: #f0f2f5; "/>
|
||||
</a-card>
|
||||
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MCH_APP, req } from '@/api/manage'
|
||||
import MchAppAddOrEdit from './AddOrEdit.vue'
|
||||
import MchAppSignConfig from './SignConfig.vue'
|
||||
import MchAppProduct from './Product.vue'
|
||||
import MchAppShop from './Shop.vue'
|
||||
import {ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import JeepayApplicationSave from "@/components/link/JeepayUIComponents/JeepayMchApplyment/JeepayApplicationSave.vue";
|
||||
import {useRouter} from "vue-router";
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
// store对象
|
||||
const userStore = useUserStore()
|
||||
const router = useRouter() //这是全部路由
|
||||
|
||||
const jeepayOauth2ConfigDrawer = ref()
|
||||
const jeepayApplicationSave = ref()
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = reactive([
|
||||
{ key: 'appName',fixed: 'left', title: '应用名称', dataIndex: 'appName' },
|
||||
{ key: 'appId', title: '应用ID', },
|
||||
{ key: 'range', title: '应用类型',},
|
||||
{ key: 'state', title: '应用状态',},
|
||||
// { key: 'defaultFlag', title: '默认',},
|
||||
{ key: 'createdAt', title: '创建日期', dataIndex: 'createdAt',},
|
||||
{ key: 'op', title: '操作', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
const jeepayPayWayFeeConfigDrawer = ref()
|
||||
const mchAppAddOrEdit = ref()
|
||||
const mchAppSignConfig = ref()
|
||||
const mchAppProduct = ref()
|
||||
const mchAppShop = ref()
|
||||
const infoTable = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
tableType:'table',
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {} as any
|
||||
})
|
||||
|
||||
function queryFunc () {
|
||||
vdata.btnLoading = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_MCH_APP, params)
|
||||
}
|
||||
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function addFunc() { // 业务通用【新增】 函数
|
||||
mchAppAddOrEdit.value.show()
|
||||
}
|
||||
|
||||
function editFunc (recordId) { // 业务通用【修改】 函数
|
||||
mchAppAddOrEdit.value.show(null, recordId)
|
||||
}
|
||||
|
||||
function signFunc (recordId) { // 业务通用【修改】 函数
|
||||
mchAppSignConfig.value.show(recordId)
|
||||
}
|
||||
function productFunc (recordId) { // 产品绑定
|
||||
// mchAppProduct.value.show(recordId)
|
||||
|
||||
router.push({
|
||||
path:'/productCenter',
|
||||
})
|
||||
}
|
||||
function caseFunc (recordId) { // 方案绑定
|
||||
router.push({
|
||||
path:'/markets',
|
||||
})
|
||||
}
|
||||
function ShopFunc (recordId) { // 产品绑定
|
||||
mchAppShop.value.show(recordId)
|
||||
}
|
||||
|
||||
|
||||
function delFunc (appId) {
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
req.delById(API_URL_MCH_APP, appId).then(res => {
|
||||
$infoBox.message.success('删除成功!')
|
||||
searchFunc()
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
|
||||
function showPayIfConfigList(recordId) { // 支付参数配置
|
||||
jeepayPayWayFeeConfigDrawer.value.show(recordId)
|
||||
}
|
||||
function getAddFunc(type){
|
||||
vdata.tableType = type
|
||||
jeepayApplicationSave.value.show()
|
||||
}
|
||||
|
||||
function getMchAppSave(e){
|
||||
if(e.type == 1){
|
||||
vdata.tableType = e.tableType
|
||||
queryFunc()
|
||||
}
|
||||
|
||||
}
|
||||
function showLookModal(record,type=1){
|
||||
vdata.tableType = 'appSaveEdit'
|
||||
jeepayApplicationSave.value.show(record,type)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
253
jeepay-ui-merchant/src/views/mchApp/Product.vue
Normal file
253
jeepay-ui-merchant/src/views/mchApp/Product.vue
Normal file
@@ -0,0 +1,253 @@
|
||||
<!-- 复制自: 运营平台
|
||||
差异: 删除商户号mchNo 的input即可。
|
||||
|
||||
-->
|
||||
<template>
|
||||
<a-drawer
|
||||
:visible="vdata.visible"
|
||||
title="产品绑定"
|
||||
width="90%"
|
||||
:maskClosable="false"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" layout="vertical" :rules="vdata.rules">
|
||||
<div class="box-div">
|
||||
<!-- <div class="box-div-top">
|
||||
<span class="box-div-top-span1">绑定产品</span>
|
||||
<span class="box-div-top-span2">已绑定9个产品</span>
|
||||
</div> -->
|
||||
|
||||
<JeepayTable
|
||||
ref="paywayTable"
|
||||
class="table-item"
|
||||
:initData="true"
|
||||
:searchData="vdata.searchData"
|
||||
:reqTableDataFunc="reqPaywayTableDataFunc"
|
||||
:tableColumns="paywayTableColumns"
|
||||
rowKey="wayCode"
|
||||
:scrollX="500"
|
||||
:topRowIsShow="false"
|
||||
>
|
||||
<template #bodyCell="{column,record}">
|
||||
|
||||
<!-- <template v-if="column.key == 'checkState'">
|
||||
<a-badge status="processing" text="未开通" v-if="record.checkState == 0"/>
|
||||
<a-badge status="warning" text="审核中" v-if="record.checkState == 1"/>
|
||||
<a-badge status="error" text="审核驳回" v-if="record.checkState == 2"/>
|
||||
<a-badge status="success" text="已开通" v-if="record.checkState == 3"/>
|
||||
<a-badge status="default" text="已取消" v-if="record.checkState == 4"/>
|
||||
</template> -->
|
||||
<template v-if="column.key == 'state'">
|
||||
<a-badge status="default" text="未绑定" v-if="record.state == 0"/>
|
||||
<a-badge status="success" text="已绑定" v-if="record.state == 1"/>
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<div >
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" @click="prodUrlFunc(record.productUrl)">查看文档</a-button>
|
||||
<!-- <a-button type="link" @click="prodStatusFunc(record.productId,1)" v-if="record.state == 0">立即关联</a-button>-->
|
||||
<!-- <a-button type="link" style="color: red" @click="prodStatusFunc(record.productId,0)" v-if="record.state == 1">取消关联</a-button>-->
|
||||
</JeepayTableColumns>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
|
||||
<!-- <div class="box-div-list">
|
||||
<ul class="box-div-ul">
|
||||
<li class="box-div-li">产品名称</li>
|
||||
<li class="box-div-li2">产品介绍</li>
|
||||
<li class="box-div-li">产品开通状态</li>
|
||||
<li class="box-div-li">操作</li>
|
||||
</ul>
|
||||
<ul class="box-div-ul-list">
|
||||
<li class="box-div-li box-div-list-li">产品名称</li>
|
||||
<li class="box-div-li2 box-div-list-li">产品介绍</li>
|
||||
<li class="box-div-li box-div-list-li">产品开通状态</li>
|
||||
<li class="box-div-li box-div-list-li">操作</li>
|
||||
</ul>
|
||||
</div> -->
|
||||
</div>
|
||||
</a-form>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose"><close-outlined />取消</a-button>
|
||||
<!-- <a-button type="primary" :loading="vdata.btnLoading" @click="onSubmit"><check-outlined />保存</a-button> -->
|
||||
</div>
|
||||
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_APP, req, $getSysRSA2PublicKey, $mchAppSecret,API_URL_MCH_PAYPASSAGE_LIST,API_APP_PRODUCT_LIST,API_URL_PRODUCT_START_LIST,API_APP_PRODUCT_LIST_STATE } from '@/api/manage'
|
||||
import {ref, reactive,getCurrentInstance} from 'vue'
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
|
||||
// 支付方式(左侧)的列表
|
||||
const paywayTableColumns = reactive([
|
||||
{ key: 'productName', title: '产品名称', dataIndex: 'productName', align: 'center' ,width:80},
|
||||
{ key: 'productDesc', title: '产品介绍', dataIndex: 'productDesc', align: 'center' ,width:400},
|
||||
// { key: 'checkState', title: '审核状态' ,fixed:"right" ,width:200},
|
||||
{ key: 'state', title: '关联状态' ,fixed:"right", align: 'center' ,width:200},
|
||||
{ key: 'op', title: '操作' ,fixed:"right", align: 'center',width:200}
|
||||
])
|
||||
|
||||
const vdata : any = reactive({
|
||||
isAdd: true, // 新增 or 修改
|
||||
isShow: false,
|
||||
visible: false, // 抽屉开关
|
||||
appId: '', // 应用AppId
|
||||
saveObject: {}, // 数据对象
|
||||
viewInfo: {}, // 数据对象
|
||||
btnLoading:false,
|
||||
sysRSA2PublicKey: '',
|
||||
rules: {
|
||||
}
|
||||
})
|
||||
|
||||
// 表单组件
|
||||
const infoFormModel = ref()
|
||||
const signInfo = ref()
|
||||
const paywayTable = ref()
|
||||
|
||||
// 抽屉显示
|
||||
const show = (appId) => {
|
||||
vdata.isAdd = !appId
|
||||
// 数据清空
|
||||
vdata.saveObject = {
|
||||
'state': 1,
|
||||
'appSecret': '',
|
||||
'defaultFlag': 1,
|
||||
'appSecret_ph': '请输入',
|
||||
appSignTypeObject: ['MD5']
|
||||
}
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.appId = appId
|
||||
console.log(vdata.appId,'vdata.appId')
|
||||
vdata.visible = true
|
||||
reqPaywayTableDataFunc({pageNumber:1,pageSize:10})
|
||||
} else {
|
||||
|
||||
vdata.visible = true // 展示弹层信息
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function queryFunc () {
|
||||
vdata.btnLoading = true
|
||||
paywayTable.value.refTable(true)
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
paywayTable.value.refTable(true)
|
||||
}
|
||||
// function prodEditFunc (appId) {
|
||||
// $infoBox.confirmDanger('确认删除?', '', () => {
|
||||
// req.delById(API_URL_MCH_APP, appId).then(res => {
|
||||
// $infoBox.message.success('删除成功!')
|
||||
// searchFunc()
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
function prodStatusFunc(productId,state){
|
||||
const text = "确认关联产品?";
|
||||
if(state == 0){
|
||||
const text ="确认取消关联产品?";
|
||||
}
|
||||
console.log(vdata.appId,'vdata.appIdvdata.appId')
|
||||
$infoBox.confirmPrimary(text, '', () => {
|
||||
req.add(API_APP_PRODUCT_LIST_STATE, { productId: productId,state:state,appId:vdata.appId }).then(data => {
|
||||
console.log(data,'resresres')
|
||||
$infoBox.message.success(data)
|
||||
queryFunc()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function prodUrlFunc(url){
|
||||
window.open(url)
|
||||
}
|
||||
|
||||
|
||||
function reqPaywayTableDataFunc (params) {
|
||||
// params.state = 3 as any
|
||||
params.appId = vdata.appId
|
||||
return req.list(API_APP_PRODUCT_LIST, Object.assign(params))
|
||||
}
|
||||
|
||||
// 表单提交
|
||||
const onSubmit = () => {
|
||||
|
||||
// 处理签名方式
|
||||
vdata.saveObject.appSignType = JSON.stringify(vdata.saveObject.appSignTypeObject)
|
||||
vdata.visible = false
|
||||
|
||||
vdata.btnLoading = false
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const onClose = () => {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
<style>
|
||||
.box-div{
|
||||
/* background: #fafafa; */
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
.box-div-top{
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid #EDEDED;
|
||||
}
|
||||
.box-div-top-span1{
|
||||
font-size: 17px;
|
||||
font-weight: 400;
|
||||
font-family: Source Han Sans-Regular;
|
||||
}
|
||||
.box-div-top-span2{
|
||||
font-size: 13px;
|
||||
color: #767676;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.box-div-ul{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-top: 26px;
|
||||
background: #F9FAFA;
|
||||
}
|
||||
.box-div-li{
|
||||
width: 20%;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.box-div-li2{
|
||||
width: 40%;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.box-div-ul-list{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-top: 26px;
|
||||
}
|
||||
.table-item{
|
||||
margin-top: 30px;
|
||||
}
|
||||
</style>
|
||||
|
||||
283
jeepay-ui-merchant/src/views/mchApp/Shop.vue
Normal file
283
jeepay-ui-merchant/src/views/mchApp/Shop.vue
Normal file
@@ -0,0 +1,283 @@
|
||||
<!-- 复制自: 运营平台
|
||||
差异: 删除商户号mchNo 的input即可。
|
||||
|
||||
-->
|
||||
<template>
|
||||
<a-drawer
|
||||
:visible="vdata.visible"
|
||||
title="关联商户"
|
||||
width="90%"
|
||||
:maskClosable="false"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-button type="primary" @click="addRelevance"><plus-outlined />一键关联商户</a-button>
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" layout="vertical" :rules="vdata.rules">
|
||||
<div class="box-div">
|
||||
<JeepayTable
|
||||
ref="paywayTable"
|
||||
class="table-item"
|
||||
:initData="true"
|
||||
:searchData="vdata.searchData"
|
||||
:reqTableDataFunc="reqPaywayTableDataFunc"
|
||||
:tableColumns="paywayTableColumns"
|
||||
rowKey="wayCode"
|
||||
:scrollX="500"
|
||||
:topRowIsShow="false"
|
||||
>
|
||||
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'status'">
|
||||
<a-badge status="default" text="禁用" v-if="record.status == 0"/>
|
||||
<a-badge status="success" text="正常" v-if="record.status == 1"/>
|
||||
</template>
|
||||
|
||||
|
||||
<template v-if="column.key == 'remark'">
|
||||
{{ record.remark??"--" }}
|
||||
</template>
|
||||
<template v-if="column.key == 'wxWeight'">
|
||||
{{ record.ysfWeight }}
|
||||
</template>
|
||||
<template v-if="column.key == 'ysfWeight'">
|
||||
{{ record.ysfWeight }}
|
||||
</template>
|
||||
<template v-if="column.key == 'aliWeight'">
|
||||
{{ record.aliWeight }}
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<div >
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" @click="shopFunc(record)">修改</a-button>
|
||||
</JeepayTableColumns>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</div>
|
||||
</a-form>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose"><close-outlined />取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="onSubmit"><check-outlined />保存</a-button>
|
||||
</div>
|
||||
|
||||
</a-drawer>
|
||||
|
||||
|
||||
<a-modal v-model:visible="vdata.visibleShop" title="轮询设置" :footer="null" width="50%" @cancel="handleCancel">
|
||||
<div style="height: 20vh; overflow: auto;" >
|
||||
<div class="code code-layout-item" style="display: flex;justify-content:center">
|
||||
<a-form-item label="商户简称" required style="width: 80%;">
|
||||
<a-input v-model:value="vdata.shopInfo.mchShortName"> </a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="商户编号" required style="width: 80%;">
|
||||
<a-input v-model:value="vdata.shopInfo.mchApplyId"> </a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="权重" required style="width: 80%;">
|
||||
<a-input v-model:value="vdata.shopInfo.mchApplyId"> </a-input>
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center;margin-top: 34px;">
|
||||
<a-button type="primary" :disabled="vdata.isDisabled" @click="sendNotes()">
|
||||
确定
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<script setup lang="ts">
|
||||
import { req,API_APP_SHOP_LIST,API_APP_SHOP_LIST_STATUS,API_APP_SHOP_LIST_RELEVANCE} from '@/api/manage'
|
||||
import {ref, reactive,getCurrentInstance} from 'vue'
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
|
||||
// 支付方式(左侧)的列表
|
||||
const paywayTableColumns = reactive([
|
||||
{ key: 'mchNo', title: '所属商户', dataIndex: 'mchNo' },
|
||||
{ key: 'wxWeight', title: '微信权重', dataIndex: 'wxWeight' },
|
||||
{ key: 'aliWeight', title: '支付宝权重', dataIndex: 'aliWeight' },
|
||||
{ key: 'ysfWeight', title: '银联权重', dataIndex: 'ysfWeight' },
|
||||
{ key: 'status', title: '状态' ,},
|
||||
{ key: 'remark', title: '备注' ,},
|
||||
{ key: 'createdAt', title: '时间' ,dataIndex: 'createdAt'},
|
||||
{ key: 'op', title: '操作' ,fixed:"right", align: 'center' ,width:200}
|
||||
])
|
||||
|
||||
const vdata : any = reactive({
|
||||
isAdd: true, // 新增 or 修改
|
||||
isShow: false,
|
||||
visibleShop: false, // 抽屉开关
|
||||
visible: false, // 抽屉开关
|
||||
appId: '', // 应用AppId
|
||||
saveObject: {}, // 数据对象
|
||||
viewInfo: {}, // 数据对象
|
||||
btnLoading:false,
|
||||
sysRSA2PublicKey: '',
|
||||
shopInfo:{},
|
||||
rules: {
|
||||
}
|
||||
})
|
||||
|
||||
// 表单组件
|
||||
const infoFormModel = ref()
|
||||
const signInfo = ref()
|
||||
const paywayTable = ref()
|
||||
|
||||
// 抽屉显示
|
||||
const show = (appId) => {
|
||||
vdata.isAdd = !appId
|
||||
// 数据清空
|
||||
vdata.saveObject = {
|
||||
'state': 1,
|
||||
'appSecret': '',
|
||||
'defaultFlag': 1,
|
||||
'appSecret_ph': '请输入',
|
||||
appSignTypeObject: ['MD5']
|
||||
}
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.appId = appId
|
||||
console.log(vdata.appId,'vdata.appId')
|
||||
vdata.visible = true
|
||||
reqPaywayTableDataFunc({pageNumber:1,pageSize:10})
|
||||
} else {
|
||||
|
||||
vdata.visible = true // 展示弹层信息
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function addRelevance(){
|
||||
$infoBox.confirmPrimary('是否重置并一键关联商户?', '', () => {
|
||||
req.add(API_APP_SHOP_LIST_RELEVANCE, { appId: vdata.appId }).then(data => {
|
||||
console.log(data,'resresres')
|
||||
$infoBox.message.success('关联成功')
|
||||
queryFunc()
|
||||
})
|
||||
})
|
||||
}
|
||||
function queryFunc () {
|
||||
vdata.btnLoading = true
|
||||
paywayTable.value.refTable(true)
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
paywayTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function prodStatusFunc(productId,state){
|
||||
const text = "确认关联产品?";
|
||||
if(state == 0){
|
||||
const text ="确认取消关联产品?";
|
||||
}
|
||||
console.log(vdata.appId,'vdata.appIdvdata.appId')
|
||||
$infoBox.confirmPrimary(text, '', () => {
|
||||
req.add(API_APP_SHOP_LIST_STATUS, { productId: productId,state:state,appId:vdata.appId }).then(data => {
|
||||
console.log(data,'resresres')
|
||||
$infoBox.message.success(data)
|
||||
queryFunc()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function shopFunc(data){
|
||||
vdata.shopInfo = data
|
||||
vdata.visibleShop = true
|
||||
}
|
||||
function sendNotes(){
|
||||
req.add('', {
|
||||
remark:vdata.notes.value,
|
||||
applyId:vdata.notes.appid
|
||||
}).then(msg => {
|
||||
console.log(msg,'resresres')
|
||||
$infoBox.message.success('编辑成功')
|
||||
searchFunc() // 更新列表
|
||||
vdata.visibleShop = false
|
||||
})
|
||||
}
|
||||
|
||||
function reqPaywayTableDataFunc (params) {
|
||||
// params.state = 3 as any
|
||||
params.mchAppId = vdata.appId
|
||||
return req.list(API_APP_SHOP_LIST, Object.assign(params))
|
||||
}
|
||||
function handleCancel (e) {
|
||||
vdata.visibleNotes = false
|
||||
}
|
||||
// 表单提交
|
||||
const onSubmit = () => {
|
||||
|
||||
// 处理签名方式
|
||||
vdata.saveObject.appSignType = JSON.stringify(vdata.saveObject.appSignTypeObject)
|
||||
vdata.visible = false
|
||||
|
||||
vdata.btnLoading = false
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const onClose = () => {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
<style>
|
||||
.box-div{
|
||||
/* background: #fafafa; */
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
.box-div-top{
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid #EDEDED;
|
||||
}
|
||||
.box-div-top-span1{
|
||||
font-size: 17px;
|
||||
font-weight: 400;
|
||||
font-family: Source Han Sans-Regular;
|
||||
}
|
||||
.box-div-top-span2{
|
||||
font-size: 13px;
|
||||
color: #767676;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.box-div-ul{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-top: 26px;
|
||||
background: #F9FAFA;
|
||||
}
|
||||
.box-div-li{
|
||||
width: 20%;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.box-div-li2{
|
||||
width: 40%;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.box-div-ul-list{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-top: 26px;
|
||||
}
|
||||
.table-item{
|
||||
margin-top: 30px;
|
||||
}
|
||||
</style>
|
||||
|
||||
221
jeepay-ui-merchant/src/views/mchApp/SignConfig.vue
Normal file
221
jeepay-ui-merchant/src/views/mchApp/SignConfig.vue
Normal file
@@ -0,0 +1,221 @@
|
||||
<!-- 复制自: 运营平台
|
||||
差异: 删除商户号mchNo 的input即可。
|
||||
|
||||
-->
|
||||
<template>
|
||||
<a-drawer
|
||||
:visible="vdata.visible"
|
||||
title="签名配置"
|
||||
width="40%"
|
||||
:maskClosable="false"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" layout="vertical" :rules="vdata.rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="24">
|
||||
<a-form-item name="appSignType">
|
||||
<template #label>
|
||||
<span>支持的签名方式</span>
|
||||
<a-popover placement="top">
|
||||
<template #title><span>签名方式</span></template>
|
||||
<template #content>
|
||||
<p>若需要使用系统测试则必须支持MD5, 若仅通过API调用则根据需求进行选择。 </p>
|
||||
</template>
|
||||
<question-circle-outlined />
|
||||
</a-popover>
|
||||
</template>
|
||||
|
||||
<a-checkbox-group v-model:value="vdata.saveObject.appSignTypeObject">
|
||||
<a-checkbox value="MD5">MD5</a-checkbox>
|
||||
<a-checkbox value="RSA2">RSA2</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-show="vdata.saveObject.appSignTypeObject && vdata.saveObject.appSignTypeObject.indexOf('MD5') >= 0" label="设置MD5秘钥" name="appSecret">
|
||||
<a-textarea v-model:value="vdata.saveObject['appSecret']" :placeholder="vdata.saveObject['appSecret_ph']" type="textarea" />
|
||||
<a-button type="primary" style="margin-top: 5px;" ghost @click="randomKey(false, 128, 0)"><file-sync-outlined />随机生成私钥</a-button>
|
||||
<a-button type="primary" danger style="margin-top: 5px;margin-left: 20px;" ghost @click="showKey()"><file-search-outlined />查看完整秘钥</a-button>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-show="vdata.saveObject.appSignTypeObject && vdata.saveObject.appSignTypeObject.indexOf('RSA2') >= 0" label="设置RSA2应用公钥" name="appRsa2PublicKey">
|
||||
<a-textarea v-model:value="vdata.saveObject['appRsa2PublicKey']" type="textarea" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-show="vdata.saveObject.appSignTypeObject && vdata.saveObject.appSignTypeObject.indexOf('RSA2') >= 0" label="支付网关系统公钥(回调验签使用)">
|
||||
<a-textarea :rows="6" :value="vdata.sysRSA2PublicKey" :disabled="true" type="textarea" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose"><close-outlined />取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="onSubmit"><check-outlined />保存</a-button>
|
||||
</div>
|
||||
|
||||
<a-modal v-model:visible="vdata.isShow" title="验证密码" @ok="handleOk">
|
||||
<a-form ref="signInfo" :rules="rules" :model="vdata.viewInfo">
|
||||
<a-form-item label="支付密码" name="password">
|
||||
<a-input v-model:value="vdata.viewInfo.password" maxlength="6" type="password" autocomplete="off" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_APP, req, $getSysRSA2PublicKey, $mchAppSecret } from '@/api/manage'
|
||||
import {ref, reactive, getCurrentInstance} from 'vue'
|
||||
|
||||
const { $SYS_NAME_MAP } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
|
||||
const vdata : any = reactive({
|
||||
isAdd: true, // 新增 or 修改
|
||||
isShow: false,
|
||||
visible: false, // 抽屉开关
|
||||
appId: '', // 应用AppId
|
||||
saveObject: {}, // 数据对象
|
||||
viewInfo: {}, // 数据对象
|
||||
btnLoading:false,
|
||||
sysRSA2PublicKey: '',
|
||||
rules: {
|
||||
appSecret: [{
|
||||
validator: (rule, value) => {
|
||||
|
||||
// 新增 & 选择了MD5 : 必须输入MD5私钥
|
||||
if(vdata.isAdd && vdata.saveObject.appSignTypeObject.indexOf('MD5') >= 0 && !value){
|
||||
return Promise.reject('请输入MD5秘钥')
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
}],
|
||||
appRsa2PublicKey: [{
|
||||
validator: (rule, value) => {
|
||||
|
||||
// 新增 & 选择了MD5 : 必须输入MD5私钥
|
||||
if(vdata.saveObject.appSignTypeObject.indexOf('RSA2') >= 0 && !value){
|
||||
return Promise.reject('请输入RSA2应用公钥')
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
const rules = {
|
||||
password: [{required: true, trigger: 'blur', message: '请输入支付密码' }],
|
||||
}
|
||||
|
||||
// 表单组件
|
||||
const infoFormModel = ref()
|
||||
const signInfo = ref()
|
||||
|
||||
// 抽屉显示
|
||||
const show = (appId) => {
|
||||
vdata.isAdd = !appId
|
||||
// 数据清空
|
||||
vdata.saveObject = {
|
||||
'state': 1,
|
||||
'appSecret': '',
|
||||
'defaultFlag': 1,
|
||||
'appSecret_ph': '请输入',
|
||||
appSignTypeObject: ['MD5']
|
||||
}
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.appId = appId
|
||||
// 拉取详情
|
||||
req.getById(API_URL_MCH_APP, appId).then(res => {
|
||||
vdata.saveObject = res
|
||||
vdata.saveObject['appSecret_ph'] = res.appSecret
|
||||
vdata.saveObject['appSecret'] = ''
|
||||
|
||||
vdata.saveObject.appSignTypeObject = []
|
||||
if(res.appSignType){
|
||||
vdata.saveObject.appSignTypeObject = JSON.parse(res.appSignType)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
vdata.visible = true
|
||||
} else {
|
||||
|
||||
vdata.visible = true // 展示弹层信息
|
||||
}
|
||||
|
||||
// 查询系统公钥
|
||||
$getSysRSA2PublicKey().then((res) => {
|
||||
vdata.sysRSA2PublicKey = res
|
||||
})
|
||||
|
||||
}
|
||||
// 表单提交
|
||||
const onSubmit = () => {
|
||||
|
||||
// 处理签名方式
|
||||
vdata.saveObject.appSignType = JSON.stringify(vdata.saveObject.appSignTypeObject)
|
||||
|
||||
infoFormModel.value.validate().then(() => {
|
||||
|
||||
vdata.btnLoading = true
|
||||
let reqObject = Object.assign({}, vdata.saveObject) // 请求数据
|
||||
|
||||
delete reqObject['appSecret_ph']
|
||||
if (!vdata.isAdd && reqObject['appSecret'] === '') {
|
||||
delete reqObject['appSecret']
|
||||
}
|
||||
|
||||
req.addOrUpdate(vdata.isAdd ? null : vdata.appId, API_URL_MCH_APP, reqObject).then(res => {
|
||||
vdata.visible = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).finally(() => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function randomKey(randomFlag, min, max) { // 生成随机128位私钥
|
||||
let str = ''
|
||||
let range = min
|
||||
const arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
|
||||
// 随机产生
|
||||
if (randomFlag) {
|
||||
range = Math.round(Math.random() * (max - min)) + min
|
||||
}
|
||||
for (var i = 0; i < range; i++) {
|
||||
var pos = Math.round(Math.random() * (arr.length - 1))
|
||||
str += arr[ pos ]
|
||||
}
|
||||
vdata.saveObject['appSecret'] = str
|
||||
}
|
||||
|
||||
function showKey () {
|
||||
vdata.viewInfo.password = ''
|
||||
vdata.isShow = true
|
||||
}
|
||||
|
||||
function handleOk() {
|
||||
signInfo.value.validate().then(valid =>{
|
||||
$mchAppSecret(vdata.viewInfo.password, vdata.appId).then((res) => {
|
||||
vdata.saveObject['appSecret'] = res
|
||||
vdata.isShow = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
|
||||
692
jeepay-ui-merchant/src/views/mchconfig/MchConfig.vue
Normal file
692
jeepay-ui-merchant/src/views/mchconfig/MchConfig.vue
Normal file
@@ -0,0 +1,692 @@
|
||||
<template>
|
||||
<div style="background: #fff">
|
||||
<a-tabs @change="selectTabs">
|
||||
<a-tab-pane key="orderConfig" tab="系统配置">
|
||||
<div v-if="vdata.groupKey == 'orderConfig'" class="account-settings-info-view">
|
||||
<a-form ref="configFormModel" :model="vdata.mchConfigData" layout="vertical">
|
||||
<a-row justify="start" type="flex" style="margin-top: 20px">
|
||||
<a-col v-for="(item, config) in vdata.mchConfigData" :key="config" :span="7" :offset="1">
|
||||
<a-form-item :label="item.configName">
|
||||
<a-radio-group v-if="item.type === 'radio'" v-model:value="item.configVal">
|
||||
<a-radio value="1">启用</a-radio>
|
||||
<a-radio value="0">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item class="bottom-btn">
|
||||
<a-button :disabled="!$access('ENT_MCH_CONFIG_EDIT')" type="primary" :loading="vdata.btnLoading"
|
||||
@click="confirm">
|
||||
<check-circle-outlined/>
|
||||
确认更新
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
|
||||
<!-- <a-tab-pane key="mchLevel" tab="功能配置">
|
||||
<div v-if="vdata.groupKey == 'mchLevel'" class="account-settings-info-view" style="margin-left: 40px">
|
||||
<a-form layout="vertical">
|
||||
<a-row justify="start" type="flex" style="margin-top: 20px">
|
||||
<a-form-item label="商户等级切换">
|
||||
<div class="typePopover">
|
||||
<a-popover placement="top">
|
||||
<template #title><span>商户级别</span></template>
|
||||
<template #content>
|
||||
<p>M0商户:简单模式(页面简洁,仅基础收款功能)</p>
|
||||
<p>M1商户:高级模式(支持api调用, 支持配置应用及分账、转账功能)</p>
|
||||
</template>
|
||||
<question-circle-outlined />
|
||||
</a-popover>
|
||||
</div>
|
||||
<a-radio-group v-model:value="vdata.mchLevel">
|
||||
<a-radio value="M0">M0</a-radio>
|
||||
<a-radio value="M1">M1</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
<a-form-item class="bottom-btn">
|
||||
<a-button :disabled="!$access('ENT_MCH_CONFIG_EDIT')" type="primary" :loading="vdata.btnLoading" @click="confirmUpdateLevel"><check-circle-outlined />确认更新</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</a-tab-pane> -->
|
||||
|
||||
|
||||
<a-tab-pane v-if="userStore.userInfo.mchLevel == 'M1'" key="payOrderNotifyExtParams" tab="回调和查单参数">
|
||||
<div v-if="vdata.groupKey == 'payOrderNotifyExtParams'" class="account-settings-info-view"
|
||||
style="margin-left: 40px">
|
||||
<a-form :label-col="{span: 2}" :wrapper-col="{span: 12}">
|
||||
<a-form-item name="mchPayNotifyUrl">
|
||||
<span slot="lable" class="label_box">POS支付回调地址</span>
|
||||
<a-input v-model:value="vdata.mchPayNotifyUrl"/>
|
||||
</a-form-item>
|
||||
<a-form-item name="mchRefundNotifyUrl">
|
||||
<span slot="lable" class="label_box1">POS退款回调地址</span>
|
||||
<div>
|
||||
<a-input v-model:value="vdata.mchRefundNotifyUrl"/>
|
||||
<div class="jeepay-tip-text">
|
||||
<p>智能POS收款、退款等场景下,需要配置商户回调地址</p>
|
||||
<p>接口下单以下单传参为准</p>
|
||||
</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<template #label>
|
||||
<span>回调方式</span>
|
||||
<a-popover placement="top">
|
||||
<template #title><span>回调方式</span></template>
|
||||
<template #content>
|
||||
<p>设置后该商户接收支付网关所有的通知(支付、退款等回调)将全部以此方式发送。</p>
|
||||
<p>POST(Body形式): method: POST; Content-Type: application/x-www-form-urlencoded; 回调参数(
|
||||
例如a=1&b=2 )放置在Body 发送。</p>
|
||||
<p>POST(QueryString形式): method: POST; Content-Type: application/x-www-form-urlencoded; 回调参数(
|
||||
例如a=1&b=2 )放置在QueryString 发送。</p>
|
||||
<p>POST(JSON形式): method: POST; Content-Type: application/json; 回调参数( 例如{a: 1, b: 2} )放置在Body
|
||||
发送。</p>
|
||||
</template>
|
||||
<question-circle-outlined/>
|
||||
</a-popover>
|
||||
|
||||
</template>
|
||||
<a-radio-group v-model:value="vdata.mchNotifyPostType">
|
||||
<a-radio value="POST_BODY">POST(Body 形式)</a-radio>
|
||||
<a-radio value="POST_QUERYSTRING">POST(QueryString 形式)</a-radio>
|
||||
<a-radio value="POST_JSON">POST(JSON 形式)</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-table :dataSource="vdata.notifyTableData" :columns="vdata.notifyTableColumns" :pagination="false"
|
||||
size="small">
|
||||
<!-- header 标题 插槽 -->
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'batch'">
|
||||
<a-checkbox @change="(e) => notifyAllCehcked(e.target.checked)"/>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'batch'">
|
||||
<a-checkbox v-model:checked="record.checked" :disabled="record.disabled"/>
|
||||
</template>
|
||||
<template v-if="column.key === 'wayName'">{{ record.wayName }}[{{ record.wayCode }}]</template>
|
||||
</template>
|
||||
|
||||
<template #title>回调参数配置</template>
|
||||
</a-table>
|
||||
|
||||
|
||||
<a-form-item class="bottom-btn">
|
||||
<a-button :disabled="!$access('ENT_MCH_CONFIG_EDIT')" type="primary" :loading="vdata.btnLoading"
|
||||
@click="confirmByNotify">
|
||||
<check-circle-outlined/>
|
||||
确认更新
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
|
||||
<!-- <a-tab-pane key="divisionManage" tab="分账管理">
|
||||
<div v-if="vdata.groupKey == 'divisionManage' && vdata.divisionConfig.mchDivisionEntFlag == 0" style="height: 200px">
|
||||
<a-divider orientation="left"><info-circle-outlined /> 当前没有可配置的选项</a-divider>
|
||||
</div>
|
||||
<div v-if="vdata.groupKey == 'divisionManage' && vdata.divisionConfig.mchDivisionEntFlag == 1" class="account-settings-info-view" style="margin-top: 20px">
|
||||
<a-form :label-col="{ span: 4 }" :wrapper-col="{ span: 12 }">
|
||||
<a-form-item>
|
||||
<template #label>
|
||||
<span>全局自动分账</span>
|
||||
<a-popover placement="top">
|
||||
<template #title><span>全局自动分账</span></template>
|
||||
<template #content>
|
||||
<p>开启:将根据[全局自动分账规则]进行自动分账处理(屏蔽下单API的分账参数, 订单标识都是自动分账模式)</p>
|
||||
<p>关闭:以API传参为准</p>
|
||||
</template>
|
||||
<question-circle-outlined />
|
||||
</a-popover>
|
||||
|
||||
</template>
|
||||
<a-radio-group v-model:value="vdata.divisionConfig.overrideAutoFlag">
|
||||
<a-radio :value="1">开启</a-radio>
|
||||
<a-radio :value="0">关闭</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<div v-if="vdata.divisionConfig.overrideAutoFlag == 1" style="margin-left: 50px">
|
||||
<a-divider orientation="left">全局自动分账规则</a-divider>
|
||||
|
||||
<a-form-item label="金额限制">
|
||||
<span style="line-height: 30px;">当订单金额大于等于 </span>
|
||||
<a-input-number v-model:value="vdata.divisionConfig.autoDivisionRules.amountLimit" :min="0" :precision="2" style="width:140px">
|
||||
<template #addonAfter>元</template>
|
||||
</a-input-number>
|
||||
<span style="line-height: 30px;"> 时自动分账</span>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="自动分账时间">
|
||||
订单支付成功: <a-select v-model:value="vdata.divisionConfig.autoDivisionRules.delayTime" style="width: 110px" placeholder="时间">
|
||||
<a-select-option :value=" (2 * 60) ">2分钟</a-select-option>
|
||||
<a-select-option :value=" (5 * 60) ">5分钟</a-select-option>
|
||||
<a-select-option :value=" (10 * 60) ">10分钟</a-select-option>
|
||||
<a-select-option :value=" (30 * 60) ">30分钟</a-select-option>
|
||||
<a-select-option :value=" (60 * 60) ">1小时</a-select-option>
|
||||
<a-select-option :value=" (2 * 60 * 60) ">2小时</a-select-option>
|
||||
</a-select> 后
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
<a-form-item class="bottom-btn">
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="confirmByDivisionManage"><check-circle-outlined />保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</a-tab-pane> -->
|
||||
|
||||
<a-tab-pane key="securityConfig" tab="安全管理">
|
||||
<div v-if="vdata.groupKey == 'securityConfig'">
|
||||
<a-form ref="sipwFormModel" :model="vdata.sipwObject" :label-col="{span: 3}" :wrapper-col="{span: 6}"
|
||||
:rules="sipwRules">
|
||||
<a-form-item v-if="vdata.sipwObject.isShow" label="原支付密码:" name="originalPwd">
|
||||
<a-input-password v-model:value="vdata.sipwObject.originalPwd" maxlength="6" autocomplete="new-password"
|
||||
placeholder="请输入原密码"/>
|
||||
</a-form-item>
|
||||
<a-form-item label="新支付密码:" name="newPwd">
|
||||
<a-input-password v-model:value="vdata.sipwObject.newPwd" maxlength="6" autocomplete="new-password"
|
||||
placeholder="请输入新密码"/>
|
||||
</a-form-item>
|
||||
<a-form-item label="确认新支付密码:" name="confirmPwd">
|
||||
<a-input-password v-model:value="vdata.sipwObject.confirmPwd" maxlength="6" autocomplete="new-password"
|
||||
placeholder="确认新密码"/>
|
||||
</a-form-item>
|
||||
<a-form-item class="bottom-btn">
|
||||
<a-button :disabled="!$access('ENT_MCH_CONFIG_EDIT')" type="primary" :loading="vdata.btnLoading"
|
||||
@click="confirmUpdateSipw">
|
||||
<check-circle-outlined/>
|
||||
确认更改
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="zfbkey" tab="支付宝代运营">
|
||||
<div class="c-content-right" style="padding:10px 30px;width:50%">
|
||||
<div class="c-header h-flex">
|
||||
<a-tag v-if="vdata.showAuthStatus" :color="calcZfbStatus(vdata.alipayAuthData.handleStatus,'color')"
|
||||
style="padding:5px 18px;">{{ calcZfbStatus(vdata.alipayAuthData.handleStatus, 'text') }}
|
||||
</a-tag>
|
||||
</div>
|
||||
<a-alert message="注意!!!仅当使用支付宝如意lite产品时使用" type="info" style="margin-bottom: 20px;"/>
|
||||
<!-- :label-col="labelCol"-->
|
||||
<a-form
|
||||
ref="configFormModelRef"
|
||||
labelAlign="right"
|
||||
labelWidth="120"
|
||||
:model="vdata.alipayAuthData"
|
||||
layout="horizontal"
|
||||
>
|
||||
<a-form-item label="授权方式" name="authType" :rules="[{ required: true, message: '请选择授权方式' }]">
|
||||
<a-radio-group v-model:value="vdata.alipayAuthData.authType">
|
||||
<a-radio value="qrcode">使用支付宝扫授权码</a-radio>
|
||||
<a-radio value="apply">发送支付宝授权消息</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="支付宝账号" name="alipayAccount"
|
||||
:rules="[{ required: true, message: '请输入支付宝账号' }]">
|
||||
<a-input v-model:value="vdata.alipayAuthData.alipayAccount" style="width: 70%;"
|
||||
placeholder="请输入支付宝账号(一般为手机或邮箱)"/>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<div class="sub-but">
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="alipayAuthFunc">
|
||||
<check-circle-outlined/>
|
||||
发起授权
|
||||
</a-button>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
||||
<!-- 扫码授权弹窗 -->
|
||||
<a-modal v-model:visible="vdata.showAuthQrCodeUrl" title="二维码" :footer="null" :width="350"
|
||||
@ok="() => vdata.showAuthQrCodeUrl = false">
|
||||
<span>请使用支付宝账号【{{ vdata.alipayAuthData.alipayAccount }}】绑定的支付宝扫码,根据页面指引完成授权</span>
|
||||
<img :src="vdata.authQrCodeUrl" style="width: 300px;height: 300px;text-align: center;">
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
API_ALIPAY_SP_OPERATION,
|
||||
reqLoad,
|
||||
API_URL_MCH_CONFIG,
|
||||
req,
|
||||
$getMainUserInfo,
|
||||
$updateMchLevel,
|
||||
$updateMchSipw,
|
||||
$isSipw
|
||||
} from '@/api/manage'
|
||||
import {ref, reactive, onMounted, getCurrentInstance} from 'vue'
|
||||
import {useUserStore} from '@/store/modules/user'
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
// store对象
|
||||
const userStore = useUserStore()
|
||||
|
||||
const {$infoBox, $access} = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const configFormModel = ref()
|
||||
|
||||
const sipwFormModel = ref()
|
||||
|
||||
const sipwRules = {
|
||||
originalPwd: [{required: true, pattern: /^\d{6}$/, message: '请输入原密码(6位数字格式)', trigger: 'blur'}],
|
||||
newPwd: [{required: true, pattern: /^\d{6}$/, message: '请输入新支付密码(6位数字格式)', trigger: 'blur'}],
|
||||
confirmPwd: [
|
||||
{
|
||||
required: true, trigger: 'blur', validator: (rule, value) => {
|
||||
if (vdata.sipwObject.newPwd != value) {
|
||||
return Promise.reject('新密码与确认新密码不一致')
|
||||
}
|
||||
return Promise.resolve()
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
// 计算授权状态
|
||||
function calcZfbStatus(sta: String, key: any) {
|
||||
const staObj: any = {}
|
||||
switch (sta) {
|
||||
case 'SUCCESS':
|
||||
staObj.text = '授权成功'
|
||||
staObj.color = 'success'
|
||||
break
|
||||
case 'PROCESS':
|
||||
staObj.text = '待确认授权'
|
||||
staObj.color = 'warning'
|
||||
break
|
||||
default:
|
||||
staObj.text = '暂未授权'
|
||||
staObj.color = 'default'
|
||||
break
|
||||
}
|
||||
return staObj[key]
|
||||
}
|
||||
|
||||
// 查询当前授权信息
|
||||
function queryAuthInfo() {
|
||||
return req.getById(API_ALIPAY_SP_OPERATION, 'authInfo')
|
||||
}
|
||||
|
||||
// 发起支付宝代运营授权
|
||||
function alipayAuthFunc() {
|
||||
queryAuthInfo().then(res => {
|
||||
if (res && res.handleStatus == 'SUCCESS') {
|
||||
/* if (res.alipayAccount == vdata.alipayAuthData.alipayAccount) {
|
||||
$infoBox.message.success('当前支付宝账号已授权通过,无需再次授权')
|
||||
return
|
||||
} */
|
||||
// 支付宝账号【' + res.alipayAccount + '】已授权成功。重新授权的同时,需要重新同步店铺,否则可能会导致无法绑定如意设备
|
||||
$infoBox.confirmDanger('授权', '确认授权?', () => {
|
||||
sendAuth()
|
||||
}, undefined, {okText: '确认授权'})
|
||||
} else {
|
||||
sendAuth()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const configFormModelRef = ref()
|
||||
|
||||
// 支付宝代运营授权请求
|
||||
function sendAuth() {
|
||||
configFormModelRef.value.validate().then(valid => {
|
||||
if (vdata.alipayAuthData.authType == 'qrcode') {
|
||||
reqLoad.getById(API_ALIPAY_SP_OPERATION, 'queryQrcode', {alipayAccount: vdata.alipayAuthData.alipayAccount}).then(res => {
|
||||
vdata.authQrCodeUrl = decodeURIComponent(res.qrCodeUrl)
|
||||
vdata.showAuthQrCodeUrl = true
|
||||
vdata.showAuthStatus = true
|
||||
})
|
||||
} else if (vdata.alipayAuthData.authType == 'apply') {
|
||||
reqLoad.add(API_ALIPAY_SP_OPERATION + '/apply', {alipayAccount: vdata.alipayAuthData.alipayAccount}).then(res => {
|
||||
vdata.showAuthStatus = true
|
||||
$infoBox.modalSuccess('发送成功', '授权消息已发送至支付宝:' + vdata.alipayAuthData.alipayAccount + ',请前往支付宝App处理')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const vdata: any = reactive({
|
||||
btnLoading: false,
|
||||
groupKey: 'orderConfig',
|
||||
mchConfigData: [] as any, // 配置保存对象
|
||||
alipayAuthData: {},
|
||||
defaultConfig: [
|
||||
{
|
||||
configKey: 'appVoice',
|
||||
configName: '是否启用app订单语音播报',
|
||||
configVal: '1',
|
||||
type: 'radio'
|
||||
},
|
||||
{
|
||||
configKey: 'weChatVoice',
|
||||
configName: '是否启用小程序订单语音播报',
|
||||
configVal: '1',
|
||||
type: 'radio'
|
||||
},
|
||||
{
|
||||
configKey: 'qrcEscaping',
|
||||
configName: '是否启用码牌防逃单功能',
|
||||
configVal: '1',
|
||||
type: 'radio'
|
||||
}
|
||||
], // 默认配置项
|
||||
|
||||
mchLevel: '',
|
||||
|
||||
mchPayNotifyUrl: '', // 商户支付回调地址
|
||||
mchRefundNotifyUrl: '', // 商户退款回调地址
|
||||
mchNotifyPostType: 'POST_BODY', // 发送商户通知的方式 POST_BODY POST_QUERYSTRING POST_JSON
|
||||
notifyTableColumns: [
|
||||
{key: 'batch', title: '批量选择'},
|
||||
{key: 'key', dataIndex: 'key', title: '参数KEY'},
|
||||
{key: 'name', dataIndex: 'name', title: '参数名称'},
|
||||
// {key: 'desc', dataIndex: 'desc', title: '参数描述' }
|
||||
],
|
||||
|
||||
notifyTableData: [
|
||||
{key: 'payOrderId', name: '支付订单号', desc: '', checked: true, disabled: true},
|
||||
{key: 'mchNo', name: '用户号', desc: '用户号', checked: true, disabled: true},
|
||||
{key: 'appId', name: '应用ID', desc: '', checked: true, disabled: true},
|
||||
{key: 'mchOrderNo', name: '商户订单号', desc: '', checked: true, disabled: true},
|
||||
{key: 'ifCode', name: '支付接口', desc: '', checked: true, disabled: true},
|
||||
{key: 'wayCode', name: '支付方式', desc: '', checked: true, disabled: true},
|
||||
{key: 'amount', name: '支付金额', desc: '', checked: true, disabled: true},
|
||||
{key: 'currency', name: '货币代码', desc: '', checked: true, disabled: true},
|
||||
{key: 'state', name: '订单状态', desc: '', checked: true, disabled: true},
|
||||
{key: 'clientIp', name: '客户端IP', desc: '', checked: true, disabled: true},
|
||||
{key: 'subject', name: '商品标题', desc: '', checked: true, disabled: true},
|
||||
{key: 'body', name: '商品描述', desc: '', checked: true, disabled: true},
|
||||
{key: 'channelOrderNo', name: '渠道订单号', desc: '', checked: true, disabled: true},
|
||||
{key: 'errCode', name: '渠道错误码', desc: '', checked: true, disabled: true},
|
||||
{key: 'errMsg', name: '渠道错误描述', desc: '', checked: true, disabled: true},
|
||||
{key: 'extParam', name: '扩展参数', desc: '', checked: true, disabled: true},
|
||||
{key: 'successTime', name: '支付成功时间', desc: '', checked: true, disabled: true},
|
||||
{key: 'createdAt', name: '创建时间', desc: '', checked: true, disabled: true},
|
||||
{key: 'sign', name: '签名', desc: '', checked: true, disabled: true},
|
||||
|
||||
{key: 'storeId', name: '门店ID', desc: '', checked: false, disabled: false},
|
||||
{key: 'lng', name: '经度', desc: '', checked: false, disabled: false},
|
||||
{key: 'lat', name: '纬度', desc: '', checked: false, disabled: false},
|
||||
{key: 'qrcId', name: '码牌ID', desc: '', checked: false, disabled: false},
|
||||
{key: 'wayCodeType', name: '支付方式代码分类', desc: '', checked: false, disabled: false},
|
||||
{key: 'mchFeeRate', name: '商户手续费费率快照', desc: '', checked: false, disabled: false},
|
||||
{key: 'mchFeeAmount', name: '商户手续费,单位分', desc: '', checked: false, disabled: false},
|
||||
{key: 'channelUser', name: '渠道用户标识,如微信openId,支付宝账号', desc: '', checked: false, disabled: false},
|
||||
{key: 'divisionMode', name: '订单分账模式', desc: '', checked: false, disabled: false},
|
||||
{key: 'buyerRemark', name: '买家备注', desc: '买家备注', checked: false, disabled: false},
|
||||
{key: 'sellerRemark', name: '卖家备注', desc: '卖家备注', checked: false, disabled: false},
|
||||
{key: 'expiredTime', name: '订单失效时间', desc: '', checked: false, disabled: false},
|
||||
],
|
||||
|
||||
sipwObject: {}, // 支付密码保存对象
|
||||
|
||||
// 分账管理菜单
|
||||
divisionConfig: {
|
||||
overrideAutoFlag: 0,
|
||||
autoDivisionRules: {amountLimit: 0, delayTime: 120},
|
||||
mchDivisionEntFlag: 1,
|
||||
calBaseAmountType: 'INCOME_AMOUNT'
|
||||
},
|
||||
|
||||
})
|
||||
const isSipw = () => {
|
||||
$isSipw().then((res) => {
|
||||
vdata.sipwObject.isShow = res
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
selectTabs(vdata.groupKey) //初始化数据
|
||||
isSipw()
|
||||
|
||||
// console.log(useRoute().query.groupKey,'useRoutequerygroupKey')
|
||||
//
|
||||
// if(useRoute().query.groupKey){
|
||||
// vdata.groupKey = useRoute().query.groupKey
|
||||
// }
|
||||
})
|
||||
|
||||
|
||||
function selectTabs(key) { // 清空必填提示
|
||||
if (key) {
|
||||
vdata.groupKey = key
|
||||
|
||||
if (key == 'orderConfig') {
|
||||
|
||||
req.list(API_URL_MCH_CONFIG, {groupKey: vdata.groupKey}).then(res => {
|
||||
if (res != null && res.length > 0) {
|
||||
vdata.mchConfigData = res
|
||||
} else {
|
||||
vdata.mchConfigData = vdata.defaultConfig
|
||||
}
|
||||
})
|
||||
} else if (key == 'payOrderNotifyExtParams') {
|
||||
|
||||
// 恢复初始值
|
||||
vdata.notifyTableData.filter(r => !r.disabled).forEach(r => {
|
||||
r.checked = false
|
||||
})
|
||||
vdata.mchNotifyPostType = 'POST_BODY'
|
||||
vdata.mchPayNotifyUrl = ''
|
||||
vdata.mchRefundNotifyUrl = ''
|
||||
|
||||
req.list(API_URL_MCH_CONFIG, {groupKey: vdata.groupKey}).then(res => {
|
||||
if (res != null && res.length > 0) {
|
||||
res.forEach(item => {
|
||||
if (item.configKey == 'payOrderNotifyExtParams') {
|
||||
let arr = JSON.parse(item.configVal)
|
||||
vdata.notifyTableData.filter(r => !r.disabled).forEach(r => {
|
||||
r.checked = arr.indexOf(r.key) >= 0
|
||||
})
|
||||
} else if (item.configKey == 'mchPayNotifyUrl') {
|
||||
vdata.mchPayNotifyUrl = item.configVal
|
||||
} else if (item.configKey == 'mchRefundNotifyUrl') {
|
||||
vdata.mchRefundNotifyUrl = item.configVal
|
||||
} else if (item.configKey == 'mchNotifyPostType') {
|
||||
vdata.mchNotifyPostType = item.configVal
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
} else if (key == 'mchLevel') {
|
||||
|
||||
$getMainUserInfo().then((res) => {
|
||||
vdata.mchLevel = res.mchLevel
|
||||
})
|
||||
} else if (key == 'divisionManage') {
|
||||
|
||||
// 分账管理恢复默认
|
||||
vdata.divisionConfig = {
|
||||
overrideAutoFlag: 0,
|
||||
autoDivisionRules: {amountLimit: 0, delayTime: 120},
|
||||
mchDivisionEntFlag: 1,
|
||||
calBaseAmountType: 'INCOME_AMOUNT'
|
||||
}
|
||||
|
||||
req.list(API_URL_MCH_CONFIG, {groupKey: vdata.groupKey, mchNo: vdata.recordId}).then(res => {
|
||||
if (res != null && res.length > 0) {
|
||||
vdata.divisionConfig = JSON.parse(res[0].configVal)
|
||||
if (!vdata.divisionConfig.calBaseAmountType) {
|
||||
vdata.divisionConfig.calBaseAmountType = 'INCOME_AMOUNT' // 存量数据为空, 默认为: 入账金额。
|
||||
}
|
||||
vdata.divisionConfig.autoDivisionRules.amountLimit = Number.parseFloat((vdata.divisionConfig.autoDivisionRules.amountLimit / 100).toFixed(2))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 确认更新
|
||||
function confirm(e) {
|
||||
configFormModel.value.validate().then(valid => {
|
||||
$infoBox.confirmPrimary('确认修改系统配置吗?', '', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
let reqObject: any = JSON.parse(JSON.stringify(vdata.mchConfigData))
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {configData: reqObject}).then(res => {
|
||||
$infoBox.message.success('修改成功')
|
||||
vdata.btnLoading = false
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 确认更新
|
||||
function confirmByNotify(e) {
|
||||
|
||||
$infoBox.confirmPrimary('确认修改回调参数吗?', '更新完成后请尽快检查回调接收地址,避免验签失败造成业务损失!', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
|
||||
let arr: any = []
|
||||
vdata.notifyTableData.filter(r => !r.disabled).forEach(r => {
|
||||
if (r.checked) {
|
||||
arr.push(r.key)
|
||||
}
|
||||
})
|
||||
|
||||
let configItem = [{
|
||||
groupKey: vdata.groupKey,
|
||||
configName: '支付订单回调和查单参数',
|
||||
configKey: 'payOrderNotifyExtParams',
|
||||
configVal: JSON.stringify(arr)
|
||||
},
|
||||
{
|
||||
groupKey: vdata.groupKey,
|
||||
configName: 'POS支付回调地址',
|
||||
configKey: 'mchPayNotifyUrl',
|
||||
configVal: vdata.mchPayNotifyUrl
|
||||
},
|
||||
{
|
||||
groupKey: vdata.groupKey,
|
||||
configName: 'POS退款回调地址',
|
||||
configKey: 'mchRefundNotifyUrl',
|
||||
configVal: vdata.mchRefundNotifyUrl
|
||||
},
|
||||
{
|
||||
groupKey: vdata.groupKey,
|
||||
configName: '商户接收通知方式',
|
||||
configKey: 'mchNotifyPostType',
|
||||
configVal: vdata.mchNotifyPostType
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {configData: JSON.stringify(configItem)}).then(res => {
|
||||
$infoBox.message.success('修改成功')
|
||||
vdata.btnLoading = false
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 更新商户等级
|
||||
function confirmUpdateLevel() {
|
||||
$updateMchLevel(vdata.mchLevel).then(() => {
|
||||
$infoBox.modalWarning('提示', '更新成功,重新登录后将切换功能模式!')
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 全选,反选
|
||||
function notifyAllCehcked(isChekced) {
|
||||
vdata.notifyTableData.filter(r => !r.disabled).forEach(r => {
|
||||
r.checked = isChekced
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 更新支付密码
|
||||
function confirmUpdateSipw() {
|
||||
|
||||
sipwFormModel.value.validate().then(() => {
|
||||
return $updateMchSipw(vdata.sipwObject.originalPwd, vdata.sipwObject.confirmPwd)
|
||||
}).then((res) => {
|
||||
$infoBox.message.success('更新成功')
|
||||
})
|
||||
}
|
||||
|
||||
function confirmByDivisionManage() {
|
||||
|
||||
$infoBox.confirmPrimary('确认修改分账设置?', '', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
let reqObject: any = JSON.parse(JSON.stringify(vdata.divisionConfig))
|
||||
reqObject.autoDivisionRules.amountLimit = Number.parseInt((reqObject.autoDivisionRules.amountLimit * 100) + '')
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {
|
||||
mchNo: vdata.recordId,
|
||||
configData: [{configKey: 'divisionConfig', configName: '分账管理', configVal: JSON.stringify(reqObject)}]
|
||||
}).then(res => {
|
||||
$infoBox.message.success('修改成功')
|
||||
vdata.btnLoading = false
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.bottom-btn {
|
||||
/deep/ div {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.typePopover {
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
left: 93px;
|
||||
}
|
||||
|
||||
.label_box {
|
||||
width: 20%; // 建议80%,太长就会超出内容
|
||||
display: inline-block;
|
||||
height: auto;
|
||||
white-space: break-spaces;
|
||||
line-height: 32px;
|
||||
text-align: left;
|
||||
vertical-align: bottom; // 这是为了让整体的字往下移动一点
|
||||
}
|
||||
|
||||
.label_box1 {
|
||||
width: 16.5%; // 建议80%,太长就会超出内容
|
||||
display: inline-block;
|
||||
height: auto;
|
||||
white-space: break-spaces;
|
||||
line-height: 32px;
|
||||
text-align: left;
|
||||
vertical-align: bottom; // 这是为了让整体的字往下移动一点
|
||||
}
|
||||
|
||||
/deep/ .ant-form-item-control-input-content {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
124
jeepay-ui-merchant/src/views/member/account/Detail.vue
Normal file
124
jeepay-ui-merchant/src/views/member/account/Detail.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
:visible="vdata.visible"
|
||||
title="流水详情"
|
||||
width="40%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="记录ID">
|
||||
{{ vdata.detailData['hid'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="关联订单号">
|
||||
{{ vdata.detailData['relaBizOrderId'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="会员名称">
|
||||
{{ vdata.detailData['mbrName'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="会员ID">
|
||||
{{ vdata.detailData['mbrId'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="会员手机号">
|
||||
{{ vdata.detailData['mbrTel'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="业务类型">
|
||||
{{ vdata.detailData['bizType'] == 1 ? '支付充值':vdata.detailData['bizType'] == 2 ? '现金充值':vdata.detailData['bizType'] == 3 ? '会员消费':vdata.detailData['bizType'] == 4 ? '消费退款':vdata.detailData['bizType'] == 5 ? '人工调账':'其他' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="变动前余额">
|
||||
<b>¥{{ vdata.detailData['beforeAmount'] / 100 }}</b>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="变动金额">
|
||||
<b>¥{{ vdata.detailData['changeAmount'] / 100 }}</b>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="变动后余额">
|
||||
<b>¥{{ vdata.detailData['afterAmount'] / 100 }}</b>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.detailData.remark" :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="备注">
|
||||
{{ vdata.detailData.remark }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MEMBER_ACCOUNT_HISTORY_LIST, req } from '@/api/manage'
|
||||
import {ref, reactive} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
|
||||
const vdata : any = reactive({
|
||||
isAdd: true, // 新增 or 修改
|
||||
visible: false, // 抽屉开关
|
||||
mbrId: '', // 会员ID
|
||||
detailData: {}, // 数据对象
|
||||
btnLoading:false,
|
||||
})
|
||||
|
||||
// 表单组件
|
||||
const infoFormModel = ref()
|
||||
|
||||
// 抽屉显示
|
||||
const show = (recordId) => {
|
||||
vdata.visible = true
|
||||
// 数据清空
|
||||
vdata.saveObject = { state:1 }
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
// 拉取详情
|
||||
req.getById(API_URL_MEMBER_ACCOUNT_HISTORY_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="dateTime" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mbrId" :placeholder="'会员ID'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mbrTel" :placeholder="'会员手机号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mbrName" :placeholder="'会员名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.relaBizOrderId" :placeholder="'关联订单号'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.bizType" placeholder="业务类型">
|
||||
<a-select-option value="">全部类型</a-select-option>
|
||||
<a-select-option value="1">支付充值</a-select-option>
|
||||
<a-select-option value="2">现金充值</a-select-option>
|
||||
<a-select-option value="3">会员消费</a-select-option>
|
||||
<a-select-option value="4">消费退款</a-select-option>
|
||||
<a-select-option value="5">人工调账</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
:statisticsIsShow="$access('ENT_MEMBER_ACCOUNT_HISTORY_LIST')"
|
||||
rowKey="hid"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in countList" :key="index" class="item">
|
||||
<div v-if="item.type == 'line'" class="line" />
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div v-if="item.title" class="amount" :style="{color: item.textColor}">
|
||||
<span class="amount-num">{{ item.content }}</span>
|
||||
<span v-if="item.isAmount">元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #topBtnSlot />
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'beforeAmount'">
|
||||
<b>¥{{ record.beforeAmount / 100 }}</b>
|
||||
</template>
|
||||
<template v-if="column.key == 'changeAmount'">
|
||||
<b>¥{{ record.changeAmount / 100 }}</b>
|
||||
</template>
|
||||
<template v-if="column.key == 'afterAmount'">
|
||||
<b>¥{{ record.afterAmount / 100 }}</b>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'bizType'">
|
||||
{{ record.bizType === 1?'支付充值':record.bizType === 2?'现金充值':record.bizType === 3?'会员消费':record.bizType === 4?'消费退款':record.bizType === 5?'人工调账':'其他' }}
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_MEMBER_ACCOUNT_HISTORY_VIEW')" type="link" @click="detailFunc(record.hid)">详情</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增 -->
|
||||
<Detail ref="detail" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MEMBER_ACCOUNT_HISTORY_LIST, req, $memberAccountHistoryCount } from '@/api/manage'
|
||||
import Detail from './Detail.vue'
|
||||
import {ref, onMounted, reactive, getCurrentInstance } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = reactive([
|
||||
{ key: 'hid', fixed: 'left', title: '流水ID', dataIndex: 'hid' },
|
||||
{ key: 'relaBizOrderId', title: '关联订单号', dataIndex: 'relaBizOrderId' },
|
||||
// { key: 'mbrId', title: '会员ID', dataIndex: 'mbrId' },
|
||||
{ key: 'mbrTel', title: '手机号', dataIndex: 'mbrTel' },
|
||||
{ key: 'mbrName', title: '会员名称', dataIndex: 'mbrName' },
|
||||
{ key: 'beforeAmount', title: '变动前余额', dataIndex: 'beforeAmount' },
|
||||
{ key: 'changeAmount', title: '变动金额', dataIndex: 'changeAmount' },
|
||||
{ key: 'afterAmount', title: '变动后余额', dataIndex: 'afterAmount' },
|
||||
{ key: 'bizType', title: '业务类型' },
|
||||
{ key: 'createdAt', title: '创建日期', dataIndex: 'createdAt' },
|
||||
{ key: 'op', title: '操作', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
const detail = ref()
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
let countList:any = ref([]) // 数据统计数组
|
||||
|
||||
onMounted(()=>{
|
||||
vdata.searchData.mbrId = useRoute().query.mbrId
|
||||
queryFunc()
|
||||
getCount()
|
||||
})
|
||||
|
||||
// 数据统计
|
||||
const getCount = () => {
|
||||
$memberAccountHistoryCount(vdata.searchData).then( res => {
|
||||
countList.value = [
|
||||
{title: '变动条数', content: res.countNum, isAmount: false},
|
||||
{type: 'line'},
|
||||
{title: '变动金额', textColor: '#1A66FF', isAmount: true, content: (Math.abs(res.changeAmount) / 100).toFixed(2)},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
const queryFunc = () => {
|
||||
console.log(vdata.searchData.mbrId)
|
||||
vdata.btnLoading = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {} as any
|
||||
})
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_MEMBER_ACCOUNT_HISTORY_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
getCount()
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function detailFunc (recordId) { // 业务通用【详情】 函数
|
||||
detail.value.show(recordId)
|
||||
}
|
||||
|
||||
function onReset(){
|
||||
//重置搜索内容
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: '' }
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
122
jeepay-ui-merchant/src/views/member/config/MemberConfigPage.vue
Normal file
122
jeepay-ui-merchant/src/views/member/config/MemberConfigPage.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<div style="background: #fff">
|
||||
<a-tabs @change="selectTabs">
|
||||
<a-tab-pane key="memberConfig" tab="会员管理">
|
||||
<div v-if="vdata.groupKey == 'memberConfig'" class="account-settings-info-view">
|
||||
<a-form ref="configFormModel" :model="vdata.memberConfigData" layout="vertical">
|
||||
<a-row justify="start" type="flex" style="margin-top: 20px">
|
||||
<a-col v-for="(item, config) in vdata.memberConfigData" :key="config" :span="7" :offset="1">
|
||||
<a-form-item :label="item.configName">
|
||||
<a-radio-group v-if="item.type === 'radio'" v-model:value="item.configVal">
|
||||
<a-radio value="1">启用</a-radio>
|
||||
<a-radio value="0">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<!-- 仅做数据展示 -->
|
||||
<a-row justify="start" type="flex" style="margin-top: 20px">
|
||||
<a-col :span="7" :offset="1">
|
||||
<a-form-item label="会员最大储值余额(元)">
|
||||
<view>{{ vdata.mbrMaxBalance != 0 ? Number.parseFloat((vdata.mbrMaxBalance/100).toFixed(2)) : '不限制' }}</view>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item class="bottom-btn">
|
||||
<a-button :disabled="!$access('ENT_MCH_CONFIG_EDIT')" type="primary" :loading="vdata.btnLoading" @click="confirm"><check-circle-outlined />保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_CONFIG, req } from '@/api/manage'
|
||||
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const configFormModel = ref()
|
||||
|
||||
const vdata : any = reactive ({
|
||||
btnLoading: false,
|
||||
groupKey: 'memberConfig',
|
||||
// 会员配置
|
||||
memberConfigData: [
|
||||
{ configKey: 'memberPayState', configName: '会员支付开关', configVal: '0', type: 'radio' },
|
||||
{ configKey: 'memberCustomAmountState', configName: '充值自定义金额', configVal: '1', type: 'radio' }
|
||||
],
|
||||
mbrMaxBalance: 0
|
||||
})
|
||||
onMounted(()=>{
|
||||
selectTabs(vdata.groupKey) //初始化数据
|
||||
})
|
||||
|
||||
function selectTabs (key) { // 清空必填提示
|
||||
if (key) {
|
||||
vdata.groupKey = key
|
||||
|
||||
if(key == 'memberConfig'){
|
||||
req.list(API_URL_MCH_CONFIG, {groupKey: vdata.groupKey}).then(res => {
|
||||
if (res != null && res.length > 0) {
|
||||
|
||||
res = res.filter( element => {
|
||||
return element.configKey != 'memberModelState'
|
||||
})
|
||||
|
||||
// val赋值
|
||||
vdata.memberConfigData.forEach(item =>{
|
||||
res.forEach(res => {
|
||||
if (item.configKey == res.configKey) {
|
||||
item.configVal = res.configVal
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
req.getById(API_URL_MCH_CONFIG, 'mbrMaxBalance').then(res => {
|
||||
if (res != null) {
|
||||
vdata.mbrMaxBalance = res
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 确认更新
|
||||
function confirm (e) {
|
||||
configFormModel.value.validate().then(valid => {
|
||||
$infoBox.confirmPrimary('确认修改会员配置吗?', '', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
let reqObject : any = JSON.parse(JSON.stringify(vdata.memberConfigData))
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {configData: reqObject}).then(res => {
|
||||
$infoBox.message.success('修改成功')
|
||||
vdata.btnLoading = false
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.bottom-btn{
|
||||
/deep/ div{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.typePopover {
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
left: 93px;
|
||||
}
|
||||
</style>
|
||||
115
jeepay-ui-merchant/src/views/member/memberInfo/AddOrEdit.vue
Normal file
115
jeepay-ui-merchant/src/views/member/memberInfo/AddOrEdit.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
:visible="vdata.visible"
|
||||
:title=" vdata.isAdd ? '新增会员' : '修改会员'"
|
||||
width="40%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" layout="vertical" :rules="vdata.rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="会员名称" name="mbrName">
|
||||
<a-input v-model:value="vdata.saveObject['mbrName']" placeholder="请输入会员名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="状态" name="state">
|
||||
<a-radio-group v-model:value="vdata.saveObject['state']">
|
||||
<a-radio :value="1">启用</a-radio>
|
||||
<a-radio :value="0">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="会员手机号" name="mbrTel">
|
||||
<a-input v-model:value="vdata.saveObject['mbrTel']" :disabled="!vdata.isAdd" placeholder="请输入会员手机号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="会员备注" name="remark" class="m-b-50 ">
|
||||
<a-textarea v-model:value="vdata.saveObject['remark']" placeholder="请输入会员备注" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose"><close-outlined />取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="onSubmit"><check-outlined />保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MEMBER_LIST, req } from '@/api/manage'
|
||||
import {ref, reactive} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
|
||||
const vdata : any = reactive({
|
||||
isAdd: true, // 新增 or 修改
|
||||
visible: false, // 抽屉开关
|
||||
mbrId: '', // 会员ID
|
||||
saveObject: {}, // 数据对象
|
||||
btnLoading:false,
|
||||
rules: {
|
||||
mbrName: [{ required: true, message: '请输入会员名称', trigger: 'blur' }],
|
||||
mbrTel: [{ required: true, pattern: /^1\d{10}$/, message: '请输入正确的手机号', trigger: 'blur' }],
|
||||
state: [{ required: true, message: '请输选择状态', trigger: 'blur' }],
|
||||
}
|
||||
})
|
||||
|
||||
// 表单组件
|
||||
const infoFormModel = ref()
|
||||
|
||||
// 抽屉显示
|
||||
const show = (mbrId) => {
|
||||
vdata.isAdd = !mbrId
|
||||
// 数据清空
|
||||
vdata.saveObject = { state:1 }
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.mbrId = mbrId
|
||||
// 拉取详情
|
||||
req.getById(API_URL_MEMBER_LIST, mbrId).then(res => {
|
||||
vdata.saveObject = res
|
||||
})
|
||||
|
||||
vdata.visible = true
|
||||
} else {
|
||||
|
||||
vdata.visible = true // 展示弹层信息
|
||||
}
|
||||
}
|
||||
// 表单提交
|
||||
const onSubmit = () => {
|
||||
|
||||
infoFormModel.value.validate().then(() => {
|
||||
|
||||
vdata.btnLoading = true
|
||||
let reqObject = Object.assign({}, vdata.saveObject) // 请求数据
|
||||
|
||||
req.addOrUpdate(vdata.isAdd ? null : vdata.mbrId, API_URL_MEMBER_LIST, reqObject).then(res => {
|
||||
vdata.visible = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).finally(() => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
|
||||
140
jeepay-ui-merchant/src/views/member/memberInfo/ChangeBalance.vue
Normal file
140
jeepay-ui-merchant/src/views/member/memberInfo/ChangeBalance.vue
Normal file
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:mask-closable="false"
|
||||
title="调账"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="40%"
|
||||
class="drawer-width"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form v-if="vdata.visible" ref="infoFormModel" :model="vdata.reqObject" layout="vertical" :rules="vdata.rules">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10" style="position:relative">
|
||||
<p style="margin:10px">账户余额: {{ ( vdata.dbRecord.balance / 100 ).toFixed(2) }}元</p>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="调账方式" name="type">
|
||||
<a-radio-group v-model:value="vdata.reqObject.type">
|
||||
<a-radio :value="'add'"> 加款 (+) </a-radio>
|
||||
<a-radio :value="'sub'"> 减款(-) </a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="金额" name="changeAmount">
|
||||
<!-- 金额上限1亿 最低不能小于0 -->
|
||||
<a-input-number v-model:value="vdata.reqObject.changeAmount" :min="0.01" :max="1000000000" placeholder="请输入金额" style="width: 93%"><template #addonBefore>{{ vdata.reqObject.type == 'add' ? ' + ' : ' - ' }}</template><template #addonAfter>元</template></a-input-number>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="支付密码" name="currentPassword">
|
||||
<a-input v-model:value="vdata.reqObject.currentPassword" autocomplete="new-password" type="password" placeholder="请输入支付密码" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" style="margin-right:8px" @click="onClose"><close-outlined /> 取消 </a-button>
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="handleOkFunc"><check-outlined /> 保存 </a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MEMBER_LIST, req, $memberChangeBalancePage } from '@/api/manage'
|
||||
import { defineProps, reactive, ref, getCurrentInstance } from 'vue'
|
||||
import ruleGenerator from '@/utils/ruleGenerator'
|
||||
import { Base64 } from 'js-base64'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const vdata : any = reactive({
|
||||
btnLoading: false,
|
||||
dbRecord: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
|
||||
reqObject: { type: 'add', changeAmount: 0, currentPassword: '' }, //调账方式 add or sub
|
||||
|
||||
rules: {
|
||||
|
||||
type: [{ required: true, message: '请选择调账方式', trigger: 'blur' }],
|
||||
changeAmount: [ ruleGenerator.requiredInput('金额', 'number') ],
|
||||
currentPassword: [ ruleGenerator.requiredInput('支付密码')],
|
||||
}
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
|
||||
vdata.btnLoading = false
|
||||
vdata.recordId = recordId
|
||||
|
||||
vdata.reqObject = { type: 'add' }
|
||||
|
||||
if (infoFormModel.value != undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
req.getById(API_URL_MEMBER_LIST, recordId).then(res => {
|
||||
vdata.dbRecord = res
|
||||
})
|
||||
vdata.visible = true // 立马展示弹层信息
|
||||
}
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
|
||||
infoFormModel.value.validate().then(valid =>{
|
||||
|
||||
if (vdata.reqObject.changeAmount <= 0) {
|
||||
vdata.confirmLoading = false
|
||||
return $infoBox.message.error('调账金额不可为0')
|
||||
}
|
||||
|
||||
vdata.btnLoading = true
|
||||
|
||||
let realReqObject = Object.assign({}, vdata.reqObject)
|
||||
if(realReqObject.type != 'add'){
|
||||
realReqObject.changeAmount = 0 - realReqObject.changeAmount
|
||||
}
|
||||
|
||||
// 密码加密
|
||||
realReqObject.currentPassword = Base64.encode(realReqObject.currentPassword)
|
||||
|
||||
delete realReqObject.type
|
||||
|
||||
$memberChangeBalancePage(vdata.recordId, realReqObject).then( (res) => {
|
||||
$infoBox.message.success('更新成功')
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.visible = false
|
||||
|
||||
}).finally(() => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
</style>
|
||||
188
jeepay-ui-merchant/src/views/member/memberInfo/MemberPage.vue
Normal file
188
jeepay-ui-merchant/src/views/member/memberInfo/MemberPage.vue
Normal file
@@ -0,0 +1,188 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="date" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mbrId" :placeholder="'会员ID'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mbrName" :placeholder="'会员名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mbrTel" :placeholder="'会员手机号'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">禁用</a-select-option>
|
||||
<a-select-option value="1">启用</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="mbrId"
|
||||
:statisticsIsShow="$access('ENT_MEMBER_LIST')"
|
||||
:tableExportFunc="tableExportFunc"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in countList" :key="index" class="item">
|
||||
<div v-if="item.type == 'line'" class="line" />
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div v-if="item.title" class="amount" :style="{color: item.textColor}">
|
||||
<span class="amount-num">{{ item.content }}</span>
|
||||
<span v-if="item.isAmount">元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #topBtnSlot>
|
||||
<div>
|
||||
<a-button v-if="$access('ENT_MEMBER_ADD')" type="primary" class="mg-b-30" @click="addFunc"><plus-outlined />新建</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'balance'">
|
||||
<b>¥{{ record.balance / 100 }}</b>
|
||||
</template> <!-- 自定义插槽 -->
|
||||
<template v-if="column.key == 'state'">
|
||||
<a-badge :status="record.state === 0?'error':'processing'" :text="record.state === 0?'禁用':'启用'" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_MEMBER_EDIT')" type="link" @click="editFunc(record.mbrId)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_MEMBER_MANUAL')" type="link" @click="accountChangeFunc(record.mbrId)">调账</a-button>
|
||||
<a-button v-if="$access('ENT_MEMBER_ACCOUNT_HISTORY_LIST')" type="link" @click="accountFunc(record.mbrId)">账户流水</a-button>
|
||||
<a-button v-if="$access('ENT_MEMBER_RECHARGE_RECORD_LIST')" type="link" @click="rechargeFunc(record.mbrId)">充值流水</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_MEMBER_DELETE')" type="link" style="color: red" @click="delFunc(record.mbrId)">删除</a-button> -->
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增 -->
|
||||
<MemberAddOrEdit ref="memberAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<!-- 调账 -->
|
||||
<ChangeBalance ref="changeBalance" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MEMBER_LIST, req, $exportExcel, exportExcelUrl, $memberInfoCount } from '@/api/manage'
|
||||
import MemberAddOrEdit from './AddOrEdit.vue'
|
||||
import ChangeBalance from './ChangeBalance.vue'
|
||||
import {ref, reactive, getCurrentInstance } from 'vue'
|
||||
import router from '@/router'
|
||||
import fileDownload from 'js-file-download'
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = reactive([
|
||||
{ key: 'mbrId', fixed: 'left', title: '会员ID', dataIndex: 'mbrId' },
|
||||
{ key: 'mbrName', title: '会员名称', dataIndex: 'mbrName' },
|
||||
{ key: 'mbrTel', title: '手机号', dataIndex: 'mbrTel' },
|
||||
{ key: 'balance', title: '账户余额', dataIndex: 'balance' },
|
||||
{ key: 'state', title: '状态',},
|
||||
{ key: 'createdAt', title: '创建日期', dataIndex: 'createdAt',},
|
||||
{ key: 'op', title: '操作', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
const memberAddOrEdit = ref()
|
||||
const changeBalance = ref()
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
let countList:any = ref([]) // 数据统计数组
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {} as any
|
||||
})
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
getCount()
|
||||
return req.list(API_URL_MEMBER_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
getCount()
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function addFunc() { // 业务通用【新增】 函数
|
||||
memberAddOrEdit.value.show()
|
||||
}
|
||||
|
||||
function editFunc (recordId) { // 业务通用【修改】 函数
|
||||
memberAddOrEdit.value.show(recordId)
|
||||
}
|
||||
|
||||
function accountChangeFunc (recordId) { // 调账 函数
|
||||
changeBalance.value.show(recordId)
|
||||
}
|
||||
|
||||
function accountFunc (recordId: any) { // 账户流水
|
||||
router.push({
|
||||
path: '/member/account',
|
||||
query: { mbrId: recordId }
|
||||
})
|
||||
}
|
||||
|
||||
function rechargeFunc (recordId: any) { // 充值记录
|
||||
router.push({
|
||||
path: '/member/recharge',
|
||||
query: { mbrId: recordId }
|
||||
})
|
||||
}
|
||||
|
||||
function delFunc (appId) {
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
req.delById(API_URL_MEMBER_LIST, appId).then(res => {
|
||||
$infoBox.message.success('删除成功!')
|
||||
searchFunc()
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
|
||||
// 数据统计
|
||||
const getCount = () => {
|
||||
$memberInfoCount(vdata.searchData).then( res => {
|
||||
console.log(res)
|
||||
countList.value = [
|
||||
{title: '会员总数', symbol: 'add', content: res.memberNum, isAmount: false},
|
||||
{type: 'line'},
|
||||
{title: '会员总余额', symbol: 'add', textColor: '#1A66FF', isAmount: true, content: ((res.balance) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '充值支付金额', textColor: '#1A66FF', isAmount: true, content: (res.payAmount / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '消费金额',symbol: 'sub', isAmount: true, content: (Math.abs(res.changeAmount) / 100).toFixed(2)},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
function tableExportFunc(){
|
||||
return $exportExcel(exportExcelUrl.memberInfo, Object.assign({}, vdata.searchData, {'pageSize': -1})).then(res => {
|
||||
fileDownload(res.data, '会员信息.xlsx')
|
||||
}).catch ((error) =>{console.log(error)} )
|
||||
}
|
||||
|
||||
function onReset(){
|
||||
//重置搜索内容
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: '' }
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
158
jeepay-ui-merchant/src/views/member/recharge/Detail.vue
Normal file
158
jeepay-ui-merchant/src/views/member/recharge/Detail.vue
Normal file
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
:visible="vdata.visible"
|
||||
title="充值详情"
|
||||
width="40%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="记录ID">
|
||||
{{ vdata.detailData['rechargeRecordId'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="关联订单号">
|
||||
{{ vdata.detailData['payOrderId'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="会员名称">
|
||||
{{ vdata.detailData['mbrName'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="会员手机号">
|
||||
{{ vdata.detailData['mbrTel'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="会员ID">
|
||||
{{ vdata.detailData['mbrId'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="充值状态">
|
||||
<a-tag
|
||||
:key="vdata.detailData['state']"
|
||||
:color="vdata.detailData['state'] === 0?'blue':vdata.detailData['state'] === 1?'orange':vdata.detailData['state'] === 2?'green':'volcano'"
|
||||
>
|
||||
{{ vdata.detailData['state'] === 0?'初始化':vdata.detailData['state'] === 1?'充值中':vdata.detailData['state'] === 2?'充值成功':'充值失败' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付金额">
|
||||
<b>¥{{ vdata.detailData['payAmount'] / 100 }}</b>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="入账金额">
|
||||
<b>¥{{ vdata.detailData['entryAmount'] / 100 }}</b>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="赠送金额">
|
||||
<b>¥{{ vdata.detailData['giveAmount'] / 100 }}</b>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="异步通知地址">
|
||||
{{ vdata.detailData['notifyUrl'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="创建时间">
|
||||
{{ vdata.detailData['createdAt'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付成功时间">
|
||||
{{ vdata.detailData['successTime'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付错误码">{{ vdata.detailData['errCode'] }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付错误描述">{{ vdata.detailData['errMsg'] }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="充值备注">{{ vdata.detailData['remark'] }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MEMBER_RECHARGE_RECORD_LIST, req } from '@/api/manage'
|
||||
import {ref, reactive} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
|
||||
const vdata : any = reactive({
|
||||
isAdd: true, // 新增 or 修改
|
||||
visible: false, // 抽屉开关
|
||||
mbrId: '', // 会员ID
|
||||
detailData: {}, // 数据对象
|
||||
btnLoading:false,
|
||||
})
|
||||
|
||||
// 表单组件
|
||||
const infoFormModel = ref()
|
||||
|
||||
// 抽屉显示
|
||||
const show = (recordId) => {
|
||||
vdata.visible = true
|
||||
// 数据清空
|
||||
vdata.saveObject = { state:1 }
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
// 拉取详情
|
||||
req.getById(API_URL_MEMBER_RECHARGE_RECORD_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="dateTime" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mbrId" :placeholder="'会员ID'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mbrTel" :placeholder="'会员手机号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mbrName" :placeholder="'会员名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.payOrderId" :placeholder="'关联订单号'" />
|
||||
<a-form-item v-if="$access('ENT_PAY_ORDER_SEARCH_PAY_WAY')" label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.wayCode" placeholder="支付方式">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option v-for="item in vdata.payWayList" :key="item.wayCode" :value="item.wayCode">
|
||||
{{ item.wayName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.wayCodeType" placeholder="支付类型">
|
||||
<a-select-option value="">全部类型</a-select-option>
|
||||
<a-select-option value="ALIPAY">支付宝</a-select-option>
|
||||
<a-select-option value="YSFPAY">云闪付</a-select-option>
|
||||
<a-select-option value="WECHAT">微信</a-select-option>
|
||||
<a-select-option value="UNIONPAY">银联</a-select-option>
|
||||
<a-select-option value="DCEPPAY">数字人民币</a-select-option>
|
||||
<a-select-option value="OTHER">其他</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="充值状态">
|
||||
<a-select-option value="">全部状态</a-select-option>
|
||||
<a-select-option value="0">初始化</a-select-option>
|
||||
<a-select-option value="1">充值中</a-select-option>
|
||||
<a-select-option value="2">充值成功</a-select-option>
|
||||
<a-select-option value="3">充值失败</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="rechargeRecordId"
|
||||
:statisticsIsShow="$access('ENT_MEMBER_RECHARGE_RECORD_LIST')"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in countList" :key="index" class="item">
|
||||
<div v-if="item.type == 'line'" class="line" />
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div v-if="item.title" class="amount" :style="{color: item.textColor}">
|
||||
<span class="amount-num">{{ item.content }}</span>元
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #topBtnSlot />
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'payAmount'">
|
||||
<b>¥{{ record.payAmount / 100 }}</b>
|
||||
</template>
|
||||
<template v-if="column.key == 'giveAmount'">
|
||||
<b>¥{{ record.giveAmount / 100 }}</b>
|
||||
</template>
|
||||
<template v-if="column.key == 'entryAmount'">
|
||||
<b>¥{{ record.entryAmount / 100 }}</b>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'state'">
|
||||
<a-tag
|
||||
:key="record.state"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':'volcano'"
|
||||
>
|
||||
{{ record.state === 0?'初始化':record.state === 1?'充值中':record.state === 2?'充值成功':'充值失败' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_MEMBER_RECHARGE_RECORD_VIEW')" type="link" @click="detailFunc(record.rechargeRecordId)">详情</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增 -->
|
||||
<Detail ref="detail" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MEMBER_RECHARGE_RECORD_LIST, API_URL_PAYWAYS_LIST, $rechargeRecordCount, req } from '@/api/manage'
|
||||
import Detail from './Detail.vue'
|
||||
import {ref, onMounted, reactive, getCurrentInstance } from 'vue'
|
||||
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = reactive([
|
||||
{ key: 'rechargeRecordId', fixed: 'left', title: '充值记录ID', dataIndex: 'rechargeRecordId' },
|
||||
{ key: 'payOrderId', title: '关联订单号', dataIndex: 'payOrderId' },
|
||||
// { key: 'mbrId', title: '会员ID', dataIndex: 'mbrId' },
|
||||
{ key: 'mbrTel', title: '手机号', dataIndex: 'mbrTel' },
|
||||
{ key: 'mbrName', title: '会员名称', dataIndex: 'mbrName' },
|
||||
{ key: 'payAmount', title: '支付金额', dataIndex: 'payAmount' },
|
||||
{ key: 'giveAmount', title: '赠送金额', dataIndex: 'giveAmount' },
|
||||
{ key: 'entryAmount', title: '入账金额', dataIndex: 'entryAmount' },
|
||||
{ key: 'wayName', title: '支付方式', dataIndex: 'wayName' },
|
||||
{ key: 'state', title: '充值状态', dataIndex: 'state' },
|
||||
{ key: 'successTime', title: '成功时间', dataIndex: 'successTime',},
|
||||
{ key: 'createdAt', title: '创建日期', dataIndex: 'createdAt',},
|
||||
{ key: 'op', title: '操作', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
const detail = ref()
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
let countList:any = ref([]) // 数据统计数组
|
||||
|
||||
onMounted(()=>{
|
||||
vdata.searchData.mbrId = useRoute().query.mbrId
|
||||
|
||||
if ($access('ENT_PAY_ORDER_SEARCH_PAY_WAY')) {
|
||||
initPayWay()
|
||||
}
|
||||
queryFunc()
|
||||
getCount()
|
||||
})
|
||||
|
||||
// 数据统计
|
||||
const getCount = () => {
|
||||
$rechargeRecordCount(vdata.searchData).then( res => {
|
||||
console.log(res)
|
||||
|
||||
countList.value = [
|
||||
{title: '总支付金额', symbol: 'add', textColor: '#1A66FF', content: ((res.payAmount) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总赠送金额', content: (res.giveAmount / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总入账金额',symbol: 'sub', content: (res.entryAmount / 100).toFixed(2)},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
const queryFunc = () => {
|
||||
|
||||
vdata.btnLoading = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {} as any,
|
||||
payWayList: [] as any
|
||||
})
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_MEMBER_RECHARGE_RECORD_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
getCount()
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function detailFunc (recordId) { // 业务通用【详情】 函数
|
||||
detail.value.show(recordId)
|
||||
}
|
||||
|
||||
function initPayWay () {
|
||||
req.list(API_URL_PAYWAYS_LIST, { 'pageSize': -1 }).then(res => { // 支付方式下拉列表
|
||||
vdata.payWayList = res.records
|
||||
})
|
||||
}
|
||||
|
||||
function onReset(){
|
||||
//重置搜索内容
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: '' }
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
189
jeepay-ui-merchant/src/views/member/rechargeRule/AddOrEdit.vue
Normal file
189
jeepay-ui-merchant/src/views/member/rechargeRule/AddOrEdit.vue
Normal file
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
:visible="vdata.visible"
|
||||
:title=" vdata.isAdd ? '新增充值规则' : '修改充值规则'"
|
||||
width="40%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" layout="vertical" :rules="vdata.rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="充值金额" name="rechargeAmount">
|
||||
<a-input-number
|
||||
v-model:value="vdata.saveObject['rechargeAmount']"
|
||||
:min="0.01"
|
||||
:max="1000000000"
|
||||
:precision="2"
|
||||
placeholder="请输入充值金额"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="状态" name="state">
|
||||
<a-radio-group v-model:value="vdata.saveObject['state']">
|
||||
<a-radio :value="1">启用</a-radio>
|
||||
<a-radio :value="0">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="赠送金额" name="giveAmount">
|
||||
<a-input-number
|
||||
v-model:value="vdata.saveObject['giveAmount']"
|
||||
:min="0.01"
|
||||
:max="1000000000"
|
||||
:precision="2"
|
||||
placeholder="请输入赠送金额"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="排序" name="sort">
|
||||
<a-input-number v-model:value="vdata.saveObject['sort']" placeholder="请输入排列顺序" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24" v-if="vdata.isAdd">
|
||||
<a-form-item label="将规则配置到门店" name="isAllStore">
|
||||
<a-radio-group v-model:value="vdata.saveObject['isAllStore']">
|
||||
<a-radio :value="0">配置到所有门店</a-radio>
|
||||
<a-radio :value="1" @click="getUserMchList()">配置到指定门店</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-form-item label="备注" name="remark" class="m-b-50 ">
|
||||
<a-input v-model:value="vdata.saveObject['remark']" placeholder="请输入备注" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose"><close-outlined />取消</a-button>
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="onSubmit"><check-outlined />保存</a-button>
|
||||
</div>
|
||||
|
||||
<JeepayRedMchList
|
||||
ref="jeepayRedMchListRef"
|
||||
:showType="'STORE'"
|
||||
:onlyMchNo="false"
|
||||
:onlyMchName="false"
|
||||
:mchNoAndName="false"
|
||||
:datas="vdata.searchState"
|
||||
v-show="vdata.searchState"
|
||||
class="jeepayRedMchListRef"
|
||||
@selectFinishFunc="searchMchFinishFunc"
|
||||
/>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MEMBER_RECHARGE_RULE_LIST, req } from '@/api/manage'
|
||||
import {ref, reactive,getCurrentInstance} from 'vue'
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
|
||||
const jeepayRedMchListRef = ref()
|
||||
|
||||
const vdata : any = reactive({
|
||||
searchState:false,
|
||||
storeId:[],
|
||||
isAdd: true, // 新增 or 修改
|
||||
visible: false, // 抽屉开关
|
||||
recordId: '', // ID
|
||||
saveObject: {}, // 数据对象
|
||||
btnLoading:false,
|
||||
rules: {
|
||||
rechargeAmount: [{ required: true, message: '请输入充值金额', trigger: 'blur' }],
|
||||
state: [{ required: true, message: '请输选择状态', trigger: 'blur' }],
|
||||
isAllStore: [{ required: true, message: '请输选择配置门店类型', trigger: 'blur' }],
|
||||
}
|
||||
})
|
||||
|
||||
// 表单组件
|
||||
const infoFormModel = ref()
|
||||
|
||||
// 抽屉显示
|
||||
const show = (recordId) => {
|
||||
vdata.isAdd = !recordId
|
||||
|
||||
vdata.recordId = recordId
|
||||
// 数据清空
|
||||
vdata.saveObject = { state: 1 }
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
if (recordId) { // 修改信息 延迟展示弹层
|
||||
// 拉取详情
|
||||
req.getById(API_URL_MEMBER_RECHARGE_RULE_LIST, recordId).then(res => {
|
||||
vdata.saveObject = res
|
||||
if (vdata.saveObject.rechargeAmount) {
|
||||
vdata.saveObject.rechargeAmount = vdata.saveObject.rechargeAmount / 100
|
||||
}
|
||||
if (vdata.saveObject.giveAmount) {
|
||||
vdata.saveObject.giveAmount = vdata.saveObject.giveAmount / 100
|
||||
}
|
||||
vdata.saveObject.isAllStore = 1;
|
||||
vdata.storeId.push(res.storeId)
|
||||
})
|
||||
|
||||
vdata.visible = true
|
||||
} else {
|
||||
vdata.visible = true // 展示弹层信息
|
||||
}
|
||||
}
|
||||
// 表单提交
|
||||
const onSubmit = () => {
|
||||
|
||||
infoFormModel.value.validate().then(() => {
|
||||
|
||||
vdata.btnLoading = true
|
||||
let reqObject = Object.assign({}, vdata.saveObject) // 请求数据
|
||||
|
||||
if(vdata.saveObject.isAllStore == 1 && vdata.storeId.length == 0){
|
||||
$infoBox.message.error('请选择指定门店!')
|
||||
vdata.btnLoading = false
|
||||
return false;
|
||||
}
|
||||
reqObject.storeId = '' as any
|
||||
if(vdata.storeId){
|
||||
reqObject.storeId = vdata.storeId.join(',')
|
||||
}
|
||||
|
||||
req.addOrUpdate(vdata.isAdd ? null : vdata.recordId, API_URL_MEMBER_RECHARGE_RULE_LIST, reqObject).then(res => {
|
||||
vdata.visible = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).finally(() => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
vdata.visible = false
|
||||
}
|
||||
function getUserMchList(){
|
||||
vdata.searchState = true
|
||||
jeepayRedMchListRef.value.show()
|
||||
}
|
||||
function searchMchFinishFunc(e){
|
||||
vdata.searchState = false
|
||||
jeepayRedMchListRef.value.close()
|
||||
if(e.store.length == 0){
|
||||
$infoBox.message.error('请选择指定门店!')
|
||||
return false;
|
||||
}
|
||||
vdata.storeId = e.store
|
||||
|
||||
}
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="date" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['storeId']" :placeholder="'门店ID/门店名称'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">禁用</a-select-option>
|
||||
<a-select-option value="1">启用</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="ruleId"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<div>
|
||||
<a-button v-if="$access('ENT_MEMBER_RECHARGE_ADD')" type="primary" class="mg-b-30" @click="addFunc"><plus-outlined />新建</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'rechargeAmount'">
|
||||
<b>¥{{ record.rechargeAmount / 100 }}</b>
|
||||
</template>
|
||||
<template v-if="column.key == 'giveAmount'">
|
||||
<b>¥{{ record.giveAmount / 100 }}</b>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'storeId'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
门店ID:{{record.storeId}}
|
||||
</template>
|
||||
{{record.storeName}}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key == 'state'">
|
||||
<a-badge :status="record.state === 0?'error':'processing'" :text="record.state === 0?'禁用':'启用'" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_MEMBER_RECHARGE_EDIT')" type="link" @click="editFunc(record.ruleId)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_MEMBER_RECHARGE_DELETE')" type="link" style="color: red" @click="delFunc(record.ruleId)">删除</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增 -->
|
||||
<AddOrEdit ref="addOrEdit" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MEMBER_RECHARGE_RULE_LIST, req } from '@/api/manage'
|
||||
import AddOrEdit from './AddOrEdit.vue'
|
||||
import {ref, reactive, getCurrentInstance } from 'vue'
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const tableColumns = reactive([
|
||||
{ key: 'ruleId', fixed: 'left', title: '规则ID', dataIndex: 'ruleId' },
|
||||
{ key: 'storeId', title: '门店名称', dataIndex: 'storeId', },
|
||||
{ key: 'rechargeAmount', title: '充值金额', dataIndex: 'rechargeAmount' },
|
||||
{ key: 'giveAmount', title: '赠送金额', dataIndex: 'giveAmount' },
|
||||
{ key: 'state', title: '状态',},
|
||||
{ key: 'sort', title: '排序', dataIndex: 'sort' },
|
||||
{ key: 'createdAt', title: '创建日期', dataIndex: 'createdAt',},
|
||||
{ key: 'op', title: '操作', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
const addOrEdit = ref()
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {} as any
|
||||
})
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_MEMBER_RECHARGE_RULE_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function addFunc() { // 业务通用【新增】 函数
|
||||
addOrEdit.value.show()
|
||||
}
|
||||
|
||||
function editFunc (recordId) { // 业务通用【修改】 函数
|
||||
addOrEdit.value.show(recordId)
|
||||
}
|
||||
|
||||
function delFunc (appId) {
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
req.delById(API_URL_MEMBER_RECHARGE_RULE_LIST, appId).then(res => {
|
||||
$infoBox.message.success('删除成功!')
|
||||
searchFunc()
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
|
||||
function onReset(){
|
||||
//重置搜索内容
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: '' }
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
59
jeepay-ui-merchant/src/views/notice/AddOrEdit.vue
Normal file
59
jeepay-ui-merchant/src/views/notice/AddOrEdit.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="新建接收人"
|
||||
width="40%"
|
||||
:maskClosable="true"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-steps direction="vertical" :current="-1">
|
||||
<a-step title="第一步,使用【微信扫一扫】扫描下列二维码并点击 [确认授权] 按钮" disabled status="process">
|
||||
<template #description>
|
||||
<img :src="vdata.wxmpConfig.authQr" alt="扫码授权" style="width: 200px;">
|
||||
</template>
|
||||
</a-step>
|
||||
<a-step title="第二步,页面提示 [授权成功]。 按照手机端的提示关注公众号完成消息推送的开启操作。" disabled status="process">
|
||||
<template #description>
|
||||
<img :src="vdata.wxmpConfig.wxmpQr" alt="关注微信公众号" style="width: 200px;">
|
||||
</template>
|
||||
</a-step>
|
||||
</a-steps>
|
||||
|
||||
<a-descriptions style="margin-bottom: 50px;">
|
||||
<a-descriptions-item label="提示">若未关注公众号则无法正确接收到提示信息!</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose"><close-outlined />关闭</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { $getWxmpInfo } from '@/api/manage'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
const infoFormModel =ref()
|
||||
const vdata = reactive({
|
||||
visible: false, // 抽屉开关
|
||||
wxmpConfig: {} as any
|
||||
})
|
||||
|
||||
defineExpose({show})
|
||||
|
||||
// 抽屉显示
|
||||
function show () {
|
||||
|
||||
// 拉取详情
|
||||
$getWxmpInfo().then(res => {
|
||||
vdata.wxmpConfig = res
|
||||
})
|
||||
vdata.visible = true // 展示弹层信息~
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
97
jeepay-ui-merchant/src/views/notice/NoticePage.vue
Normal file
97
jeepay-ui-merchant/src/views/notice/NoticePage.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="searchData['nickname']" :placeholder="'微信昵称'" />
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="searchData"
|
||||
row-key="userId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button v-if="$access('ENT_MCH_WXMP_USER_ADD')" type="primary" @click="addFunc"><plus-outlined />新建接收人</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'sendStatus'">
|
||||
<JeepayTableColState :state="record.sendStatus" :showSwitchType="$access('ENT_MCH_WXMP_USER_EDIT')" :onChange="(sendStatus) => { return updateState(record.userId, sendStatus)}" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<a-button v-if="$access('ENT_MCH_WXMP_USER_DELETE')" type="link" style="color: red" @click="delFunc(record.userId)">删除</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_WXMP_UESR, req, reqLoad } from '@/api/manage'
|
||||
import InfoAddOrEdit from './AddOrEdit.vue'
|
||||
import { ref, reactive, getCurrentInstance } from 'vue'
|
||||
|
||||
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
const infoAddOrEdit = ref()
|
||||
const infoTable = ref()
|
||||
let tableColumns = reactive([
|
||||
{ key: 'sysUserId', fixed: 'left', title: '系统用户ID', dataIndex: 'sysUserId', },
|
||||
{ key: 'nickname', title: '微信昵称', dataIndex: 'nickname'},
|
||||
{ key: 'wxOpenId', title: 'openId', dataIndex: 'wxOpenId', },
|
||||
{ key: 'wxAppId', title: 'appId', dataIndex: 'wxAppId'},
|
||||
{ key: 'sendStatus', title: '状态' },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期', },
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let searchData = ref({})
|
||||
|
||||
function reqTableDataFunc(params: any) { // 请求table接口数据
|
||||
return req.list(API_URL_MCH_WXMP_UESR, params)
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
btnLoading.value = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show()
|
||||
}
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger('确认修改?', '', () => {
|
||||
return reqLoad.updateById(API_URL_MCH_WXMP_UESR, recordId, { sendStatus: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function delFunc (recordId: any) { // 业务通用【删除】 函数
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
reqLoad.delById(API_URL_MCH_WXMP_UESR, recordId).then((res: any) => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('删除成功')
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
function onReset(){ //重置搜索内容
|
||||
searchData.value = {}
|
||||
}
|
||||
</script>
|
||||
128
jeepay-ui-merchant/src/views/order/pay/PayDetail.vue
Normal file
128
jeepay-ui-merchant/src/views/order/pay/PayDetail.vue
Normal file
@@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<a-modal v-model:visible="visible" :footer="null">
|
||||
<div class="modal-title">预计入账详细</div>
|
||||
<div class="statistics-list" style="padding-bottom: 20px;">
|
||||
<div v-for="(item, index) in props.countDetailList[0] as any" :key="index" class="item item-box-title">
|
||||
<!-- <div v-if="item.type == 'line'" class="line" />-->
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div v-if="item.title" class="amount">
|
||||
<a-tooltip v-if="item.title == '实付金额'">
|
||||
<template #title>{{ item.content }}元</template>
|
||||
<span class="amount-num">{{ item.content }}</span><span>元</span>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-else>
|
||||
<template #title> - {{ item.content }}元</template>
|
||||
<span class="amount-num">-{{ item.content }}</span><span>元</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div v-if="item.count >= 0" class="detail">
|
||||
<span>{{ item.count }}笔</span>
|
||||
</div>
|
||||
<span class="item-box-title-border"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="statistics-list" style="padding-bottom: 55px;">
|
||||
<div v-for="(item, index) in props.countDetailList[1] as any" :key="index" class="item item-box-title">
|
||||
<!-- <div v-if="item.type == 'line'" class="line" />-->
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div v-if="item.title" class="amount">
|
||||
<a-tooltip v-if="item.title == '补贴金额'">
|
||||
<template #title> {{ item.content }}元</template>
|
||||
<span class="amount-num">{{ item.content }}</span><span>元</span>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-else>
|
||||
<template #title>- {{ item.content }}元</template>
|
||||
<span class="amount-num">-{{ item.content }}</span><span>元</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div v-if="item.count >= 0" class="detail">
|
||||
<span>{{ item.count }}笔</span>
|
||||
</div>
|
||||
<span class="item-box-title-border"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="statistics-list" style="padding-bottom: 55px;">
|
||||
<div v-for="(item, index) in props.countDetailList[2] as any" :key="index" class="item item-box-title-price">
|
||||
<!-- <div v-if="item.type == 'line'" class="line" />-->
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div v-if="item.title" class="amount">
|
||||
<a-tooltip v-if="item.title == '补贴金额'">
|
||||
<template #title> {{ item.content }}元</template>
|
||||
<span class="amount-num">{{ item.content }}</span><span>元</span>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-else>
|
||||
<template #title>- {{ item.content }}元</template>
|
||||
<span class="amount-num">-{{ item.content }}</span><span>元</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div v-if="item.count >= 0" class="detail">
|
||||
<span>{{ item.count }}笔</span>
|
||||
</div>
|
||||
<span class="item-box-title-border"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="close" @click=" visible = false">
|
||||
<a-button type="primary">知道了</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
const visible = ref<boolean>(false)
|
||||
|
||||
const props = defineProps({
|
||||
countDetailList: {type: Array, default: () => []},
|
||||
sucDetailList: {type: Array, default: () => []}
|
||||
})
|
||||
|
||||
const showModal = () => visible.value = true
|
||||
|
||||
defineExpose({showModal})
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.modal-title, .modal-describe{
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.modal-title {
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.close {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
border-top: 1px solid #EFEFEF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.amount {
|
||||
//max-width:150px;
|
||||
//overflow:hidden;
|
||||
//text-overflow:ellipsis;
|
||||
//white-space:nowrap;
|
||||
}
|
||||
.item-box-title{
|
||||
min-width: 33%;
|
||||
text-align: center
|
||||
}
|
||||
.item-box-title-price{
|
||||
min-width: 33%;
|
||||
text-align: center
|
||||
}
|
||||
.item-box-title:nth-child(1){;
|
||||
border-right: 1px solid #efefef;
|
||||
}
|
||||
.item-box-title:nth-child(2){;
|
||||
border-right: 1px solid #efefef;
|
||||
}
|
||||
.item-box-title-border{
|
||||
//border-right: 1px solid #EFEFEF !important;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
429
jeepay-ui-merchant/src/views/order/pay/PayLogDetail.vue
Normal file
429
jeepay-ui-merchant/src/views/order/pay/PayLogDetail.vue
Normal file
@@ -0,0 +1,429 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
width="50%"
|
||||
placement="right"
|
||||
:closable="true"
|
||||
:title="vdata.visible === true? '订单详情':''"
|
||||
@close="onClose"
|
||||
>
|
||||
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">订单信息</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="平台订单号">
|
||||
{{ vdata.detailData.payOrderId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="通道订单号">
|
||||
{{ vdata.detailData.channelOrderNo??"--" }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道订单号">
|
||||
{{ vdata.detailData.platformOrderNo??"--" }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户订单号">
|
||||
{{ vdata.detailData.mchOrderNo??"--" }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="落单订单号">
|
||||
{{ vdata.detailData.platformMchOrderNo??"--" }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">基础信息</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户简称">
|
||||
{{ vdata.detailData.mchName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户号">
|
||||
{{ vdata.detailData.mchExtNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="门店名称">
|
||||
{{ vdata.detailData.storeName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="门店编号">
|
||||
{{ vdata.detailData.storeId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="应用名称">
|
||||
{{ vdata.detailData.appName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="应用ID">
|
||||
{{ vdata.detailData.appId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商名称">
|
||||
{{ vdata.detailData.agentName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商号">
|
||||
{{ vdata.detailData.agentNo }} [ {{vdata.detailData.agentContactTel}} ]
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付金额(元)">
|
||||
<a-tag color="green">
|
||||
{{ vdata.detailData.amount/100 }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="订单状态">
|
||||
<span v-if="vdata.detailData.state !== 5 ">
|
||||
<a-tag
|
||||
:key="vdata.detailData.state"
|
||||
:color="vdata.detailData.state === 0?'blue':vdata.detailData.state === 1?'orange':vdata.detailData.state === 2?'green':vdata.detailData.state === 6?'':'volcano'"
|
||||
>
|
||||
{{ vdata.detailData.state === 0?'订单生成':vdata.detailData.state === 1?'支付中':vdata.detailData.state === 2?'支付成功':vdata.detailData.state === 3?'支付失败':vdata.detailData.state === 4?'已撤销':vdata.detailData.state === 6?'订单关闭':'未知' }}
|
||||
|
||||
</a-tag>
|
||||
</span>
|
||||
<span v-else-if="vdata.detailData.state === 5 ">
|
||||
<a-tag
|
||||
:key="vdata.detailData.refundState"
|
||||
:color="vdata.detailData.refundState === 0?'red':vdata.detailData.refundState === 1?'orange':vdata.detailData.refundState === 2?'red':'red'"
|
||||
>
|
||||
{{ vdata.detailData.refundState === 0?'':vdata.detailData.refundState === 1?'部分退款':vdata.detailData.refundState === 2?'全额退款':'未知' }}
|
||||
</a-tag>
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions><a-descriptions-item label="实际手续费"><a-tag color="pink">{{ vdata.detailData.mchFeeAmount/100 }}</a-tag></a-descriptions-item></a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions><a-descriptions-item label="收单手续费"><a-tag color="pink">{{ vdata.detailData.mchOrderFeeAmount/100 }}</a-tag></a-descriptions-item></a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
|
||||
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions><a-descriptions-item label="商家费率">{{ vdata.detailData.mchFeeRate }}</a-descriptions-item></a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="收单费率">{{ vdata.detailData.mchFeeRateNum }}%</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<!-- <a-descriptions><a-descriptions-item label="收单手续费(元)">{{ (vdata.detailData.findAmt / 100).toFixed(2) }} * {{ vdata.detailData.mchFeeRateNum }} = {{ (vdata.detailData.mchOrderFeeAmount / 100).toFixed(2) }}</a-descriptions-item></a-descriptions>-->
|
||||
|
||||
收单手续费(元)
|
||||
<a-popover placement="top">
|
||||
<template #content>
|
||||
<p>收单手续费 = 实付金额 - * 收单费率</p>
|
||||
</template>
|
||||
<question-circle-outlined/>:
|
||||
</a-popover>
|
||||
{{ (vdata.detailData.findAmt / 100).toFixed(2) }} * {{ vdata.detailData.mchFeeRateNum }} = {{ (vdata.detailData.mchOrderFeeAmount / 100).toFixed(2) }}
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="垫资费率">{{ vdata.detailData.cashRate }}%</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
垫资手续费(元)
|
||||
<a-popover placement="top">
|
||||
<template #content>
|
||||
<p>垫资手续费 = 实付金额 - * 垫资费率</p>
|
||||
</template>
|
||||
<question-circle-outlined/>:
|
||||
</a-popover>
|
||||
{{ (vdata.detailData.findAmt / 100).toFixed(2) }} * {{ vdata.detailData.cashRate }} = {{ (vdata.detailData.cashFee / 100).toFixed(2) }}
|
||||
|
||||
</a-col>
|
||||
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="退款次数">
|
||||
{{ vdata.detailData.refundTimes }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="退款总额">
|
||||
<a-tag v-if="vdata.detailData.refundAmount" color="cyan">
|
||||
{{ (vdata.detailData.refundAmount / 100).toFixed(2)}}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="优惠金额">¥{{ (vdata.detailData.discountAmt / 100).toFixed(2) }}</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="补贴金额">
|
||||
¥{{ (vdata.detailData.marketAmt / 100).toFixed(2) }}</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12" style="margin-bottom: 12px">
|
||||
预计入账金额
|
||||
<!-- <a-tooltip title="入账金额 = 实付金额 - 收单手续费 - 垫资手续费 - 退款总额" >-->
|
||||
<!-- <question-circle-outlined style="padding-right: 10px"/>:-->
|
||||
<!-- </a-tooltip>-->
|
||||
<a-popover placement="top">
|
||||
<template #content>
|
||||
<p>入账金额 = 实付金额 - 收单手续费 - 垫资手续费 - 退款总额</p>
|
||||
</template>
|
||||
<question-circle-outlined/>:
|
||||
</a-popover>
|
||||
{{vdata.detailData.findAmt / 100}} - {{vdata.detailData.mchOrderFeeAmount / 100}} - {{vdata.detailData.cashFee / 100}} - {{vdata.detailData.refundAmount / 100}} = {{ ((vdata.detailData.findAmt - vdata.detailData.mchOrderFeeAmount - vdata.detailData.cashFee - vdata.detailData.refundAmount + vdata.detailData.marketAmt) / 100).toFixed(2) }}
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12"></a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付错误码">
|
||||
{{ vdata.detailData.errCode }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付错误描述">
|
||||
{{ vdata.detailData.errMsg }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="买家备注">
|
||||
{{ vdata.detailData.buyerRemark }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="卖家备注">
|
||||
{{ vdata.detailData.sellerRemark }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="订单失效时间">
|
||||
{{ vdata.detailData.expiredTime }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="创建时间">
|
||||
{{ vdata.detailData.createdAt }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="更新时间">
|
||||
{{ vdata.detailData.updatedAt }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付成功时间">
|
||||
{{ vdata.detailData.successTime??"--" }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
|
||||
|
||||
</a-row>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">其他信息</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商品标题">
|
||||
{{ vdata.detailData.subject }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商品描述">
|
||||
{{ vdata.detailData.body }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="接口代码">
|
||||
{{ vdata.detailData.ifCode }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="货币代码">
|
||||
{{ vdata.detailData.currency }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付方式">
|
||||
{{ vdata.detailData.wayCode }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="客户端IP">
|
||||
{{ vdata.detailData.clientIp }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="用户标识">
|
||||
{{ vdata.detailData.channelUser }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="异步通知地址">
|
||||
{{ vdata.detailData.notifyUrl }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="页面跳转地址">
|
||||
{{ vdata.detailData.returnUrl }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">分账信息</a-divider>
|
||||
<a-row justify="start" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="订单分账模式">
|
||||
<span v-if="vdata.detailData.divisionMode == 0">该笔订单不允许分账</span>
|
||||
<span v-else-if="vdata.detailData.divisionMode == 1">支付成功按配置自动完成分账</span>
|
||||
<span v-else-if="vdata.detailData.divisionMode == 2">商户手动分账(解冻商户金额)</span>
|
||||
<span v-else>未知</span>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="分账状态">
|
||||
<a-tag v-if="vdata.detailData.divisionState == 0" color="blue">未发生分账</a-tag>
|
||||
<a-tag v-else-if="vdata.detailData.divisionState == 1" color="orange">待分账</a-tag>
|
||||
<a-tag v-else-if="vdata.detailData.divisionState == 2" color="red">分账处理中</a-tag>
|
||||
<a-tag v-else-if="vdata.detailData.divisionState == 3" color="green">任务已结束</a-tag>
|
||||
<a-tag v-else color="#f50">未知</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="最新分账发起时间">{{ vdata.detailData.divisionLastTime }}</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<!-- <a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">扩展信息</a-divider>-->
|
||||
<!-- <a-row justify="start" type="flex">-->
|
||||
<!-- <a-col :sm="24">-->
|
||||
<!-- <span style="color: black;">扩展参数:</span>-->
|
||||
<!-- <a-form-item>-->
|
||||
<!-- <a-input-->
|
||||
<!-- v-model:value="vdata.detailData.extParam"-->
|
||||
<!-- type="textarea"-->
|
||||
<!-- disabled="disabled"-->
|
||||
<!-- style="height: 100px;color: black;margin-top: 10px;"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- </a-row>-->
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MCH_APPLYMENT_LIST, req } from '@/api/manage'
|
||||
import {defineProps,reactive, getCurrentInstance} from 'vue'
|
||||
const { $hasAgentEnt, $SYS_NAME_MAP } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata:any = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
termNo: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (data) { // 弹层打开事件
|
||||
vdata.detailData = data // 数据清空
|
||||
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
895
jeepay-ui-merchant/src/views/order/pay/PayOrderList.vue
Normal file
895
jeepay-ui-merchant/src/views/order/pay/PayOrderList.vue
Normal file
@@ -0,0 +1,895 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="dateTime" />
|
||||
</a-form-item>
|
||||
|
||||
<!-- <JeepaySelect ref="orderKeyTypeRef">-->
|
||||
<!-- <a-select v-model:value="vdata.orderKeyType" @change="orderKeyTypeChangeFunc">-->
|
||||
<!-- <a-select-option v-for="item in orderKeyList" :key="item.key" :value="item.key">{{ item.desc }}</a-select-option>-->
|
||||
<!-- </a-select>-->
|
||||
<!-- </JeepaySelect>-->
|
||||
<jeepay-text-up v-model:value="vdata.searchData['unionOrderId']" :placeholder="'订单号'" class="table-search-item" />
|
||||
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mchExtNo" :placeholder="'商户名称/商户号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.storeInfo" :placeholder="'门店名称/门店编号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.ifCode" :placeholder="'支付通道'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.isvNo" :placeholder="'渠道名称/渠道号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appId" :placeholder="'应用名称/应用ID'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="支付状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">订单生成</a-select-option>
|
||||
<a-select-option value="1">支付中</a-select-option>
|
||||
<a-select-option value="2">支付成功</a-select-option>
|
||||
<a-select-option value="3">支付失败</a-select-option>
|
||||
<a-select-option value="4">已撤销</a-select-option>
|
||||
<a-select-option value="5">已退款</a-select-option>
|
||||
<a-select-option value="6">订单关闭</a-select-option>
|
||||
<a-select-option value="20">部分退款</a-select-option>
|
||||
<a-select-option value="21">全额退款</a-select-option>
|
||||
<a-select-option value="22">退款中</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="$access('ENT_PAY_ORDER_SEARCH_PAY_WAY')" label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.wayCode" placeholder="支付方式">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option v-for="item in vdata.payWayList" :key="item.wayCode" :value="item.wayCode">
|
||||
{{ item.wayName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.settleType" placeholder="结算类型">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="D0">D0</a-select-option>
|
||||
<a-select-option value="D1">D1</a-select-option>
|
||||
<a-select-option value="T1">T1</a-select-option>
|
||||
<a-select-option value="定时结算">定时结算</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.drType" placeholder="借贷标识">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="00">借记卡</a-select-option>
|
||||
<a-select-option value="01">贷记卡</a-select-option>
|
||||
<a-select-option value="02">零钱/余额</a-select-option>
|
||||
<a-select-option value="03">支付宝花呗</a-select-option>
|
||||
<a-select-option value="04">数字货币</a-select-option>
|
||||
<a-select-option value="99">其他</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.divisionState" placeholder="分账状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">未发生分账</a-select-option>
|
||||
<a-select-option value="1">等待分账任务处理</a-select-option>
|
||||
<a-select-option value="2">分账处理中</a-select-option>
|
||||
<a-select-option value="3">分账任务已结束(状态请看分账记录)</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
|
||||
<jeepay-text-up v-if="$hasMemberEnt()" v-model:value="vdata.searchData.mbrTel" :placeholder="'会员手机号'" />
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
:statisticsIsShow="$access('ENT_ORDER_COUNT')"
|
||||
rowKey="payOrderId"
|
||||
:tableRowCrossColor="true"
|
||||
:tableExportFunc="tableExportFunc"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in orderCountList" :key="index" class="item">
|
||||
<div v-if="item.type == 'line'" class="line" />
|
||||
<div class="title">
|
||||
{{ item.title }}
|
||||
<a-tooltip v-if="item.title == '成功金额'"
|
||||
title="包含支付成功和已退款订单"
|
||||
><question-circle-outlined style="padding-left: 10px"
|
||||
/></a-tooltip>
|
||||
</div>
|
||||
<div v-if="item.title" class="amount" :style="{color: item.textColor}">
|
||||
<!-- <span v-if="item.symbol" class="symbol">{{ item.symbol == 'add' ? '+' : '-' }}</span> -->
|
||||
<span class="amount-num">{{ item.content }}</span>元
|
||||
</div>
|
||||
<div v-if="item.count >= 0" class="detail">
|
||||
<span>{{ item.count + '笔' }}</span>
|
||||
<span v-if="item.detail" class="detail-text" @click="payDetail.showModal()">明细</span>
|
||||
</div>
|
||||
<div v-if="item.payCount >= 0" class="detail">
|
||||
<span>{{ item.payCount + '笔' }}</span>
|
||||
<span v-if="item.detail" class="detail-text" @click="paySucDetail.showModal()">明细</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'settleType'">
|
||||
<Tooltip color="#3b4146">
|
||||
<template #title>
|
||||
<div style="color: #ffffff">提示内容</div>
|
||||
</template>
|
||||
<div style="cursor: pointer; width: 100%">
|
||||
结算类型
|
||||
<a-tooltip>
|
||||
<template #title>
|
||||
<p>T1:工作日次日到账,交易资金于周末和法定节假日次日的6点-12点自动结算至银行卡</p>
|
||||
<p>D1:自然日次日到账,全年365天(不分节假日)的交易资金于自然日的次日6点-12点自动结算至银行卡</p>
|
||||
<p>D0:实时到账,全年365天24小时(不分节假日)的交易资金笔笔实时秒到至银行卡,更放心更快捷</p>
|
||||
<p>定时结算,在一天24个整点时辰,根据入账需求选择结算范围,可任意指定一个或多个结算时间点</p>
|
||||
</template>
|
||||
<question-circle-outlined style="padding-left: 10px"/>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'amount'">
|
||||
<!-- <a-tooltip>-->
|
||||
<!-- <template #title >-->
|
||||
<!-- <span>实付金额:¥{{ (record.findAmt / 100).toFixed(2) }}</span><br>-->
|
||||
<!-- <span>实际手续费:¥{{ (record.mchFeeAmount / 100).toFixed(2) }}</span><br>-->
|
||||
<!-- <span>收单手续费:¥{{ (record.mchOrderFeeAmount / 100).toFixed(2) }}</span><br>-->
|
||||
<!-- <span>退款金额:¥{{ (record.refundAmount / 100).toFixed(2) }}</span><br>-->
|
||||
<!-- <span v-if="record.discountScale >0">优惠折扣:{{record.discountScale}}折</span><br>-->
|
||||
<!-- <span>优惠金额:¥{{ (record.discountAmt / 100).toFixed(2) }}</span><br>-->
|
||||
<!-- <span>入账金额:¥{{ ((record.findAmt - record.extDivAmt- record.mchFeeAmount + record.marketAmt) / 100).toFixed(2) }}</span><br>-->
|
||||
<!-- <span>补贴金额:¥{{ (record.marketAmt / 100).toFixed(2) }}</span><br>-->
|
||||
<!-- </template>-->
|
||||
<!-- <b style="color: #1890ff">¥{{ record.amount/100 }} </b>-->
|
||||
<!-- </a-tooltip>-->
|
||||
<a-popover placement="top" style="background: #0c2640 !important;">
|
||||
<template #content style="background: #ff0 !important;">
|
||||
<p>实付金额:¥{{ (record.findAmt / 100).toFixed(2) }}</p>
|
||||
<p>实际手续费:¥{{ (record.mchFeeAmount / 100).toFixed(2) }}</p>
|
||||
<p>收单手续费:¥{{ (record.mchOrderFeeAmount / 100).toFixed(2) }}</p>
|
||||
<p>垫资手续费:¥{{ (record.cashFee / 100).toFixed(2) }}</p>
|
||||
<p>退款金额:¥{{ (record.refundAmount / 100).toFixed(2) }}</p>
|
||||
<p v-if="record.discountScale >0">优惠折扣:{{record.discountScale}}折</p>
|
||||
<p>优惠金额:¥{{ (record.discountAmt / 100).toFixed(2) }}</p>
|
||||
<p>入账金额:¥{{ ((record.findAmt - record.extDivAmt- record.mchFeeAmount - record.cashFee + record.marketAmt) / 100).toFixed(2) }}</p>
|
||||
<p>补贴金额:¥{{ (record.marketAmt / 100).toFixed(2) }}</p>
|
||||
</template>
|
||||
<b style="color: #1890ff">¥{{ (record.amount/100).toFixed(2) }} </b>
|
||||
</a-popover>
|
||||
</template>
|
||||
<!-- <template v-if="column.key == 'refundAmount'">¥{{ record.refundAmount/100 }}</template>-->
|
||||
<!-- <template v-if="column.key == 'mchFeeAmount'">¥{{ (record.mchFeeAmount / 100).toFixed(2) }}</template>-->
|
||||
<!-- <template v-if="column.key == 'mchOrderFeeAmount'">¥{{ (record.mchOrderFeeAmount / 100).toFixed(2) }}</template>-->
|
||||
<template v-if="column.key == 'state'">
|
||||
<span v-if="record.state !== 5 ">
|
||||
<a-tag
|
||||
:key="record.state"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':record.state === 6?'':'volcano'"
|
||||
>
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'支付中':record.state === 2?'支付成功':record.state === 3?'支付失败':record.state === 4?'已撤销':record.state === 6?'订单关闭':record.state === 22?'退款中':'未知' }}
|
||||
|
||||
</a-tag>
|
||||
</span>
|
||||
<span v-else-if="record.state === 5 ">
|
||||
<a-tag
|
||||
:key="record.refundState"
|
||||
:color="record.refundState === 0?'red':record.refundState === 1?'orange':record.refundState === 2?'red':'red'"
|
||||
>
|
||||
{{ record.refundState === 0?'':record.refundState === 1?'部分退款':record.refundState === 2?'全额退款':'未知' }}
|
||||
</a-tag>
|
||||
</span>
|
||||
<a-tag v-else></a-tag>
|
||||
|
||||
|
||||
<a-tooltip title="拉卡拉通道单笔结算金额低于11元、银联云闪付交易或单笔超限交易均转为D1次日到账" v-if="record.state == 2 && record.ifCode == 'lklspay' && record.settleType == 'D0'">
|
||||
<question-circle-outlined style="color: #FF0000;"/>
|
||||
</a-tooltip>
|
||||
<a-tooltip :title="record.errMsg" v-if="record.state == 3">
|
||||
<info-circle-outlined style="color: #FFD080;margin-left: 10px"/>
|
||||
</a-tooltip>
|
||||
|
||||
<TransactionOutlined @click="getRefund(record)" style="color: #FF0000;" v-if="record.state == 5 || record.state == 22" />
|
||||
|
||||
<reload-outlined @click="getReload(record)" style="color: #1890ff;margin-left: 10px" v-if="record.state == 1" />
|
||||
|
||||
</template>
|
||||
<template v-if="column.key == 'divisionState'">
|
||||
<!-- <span v-if="record.divisionState == 0">不分账</span>-->
|
||||
<a-tag v-if="record.divisionState == 0" color="orange">否</a-tag>
|
||||
<a-tag v-if="record.divisionState != 0" color="green">是</a-tag>
|
||||
<!-- <a-tag v-else-if="record.divisionState != 0" color="orange">待分账</a-tag>-->
|
||||
<!-- <a-tag v-else-if="record.divisionState == 2" color="red">分账处理中</a-tag>-->
|
||||
<!-- <a-tag v-else-if="record.divisionState == 3" color="green">任务已结束</a-tag>-->
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<template v-if="column.key === 'isvName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>渠道名称:{{record.isvName}}</span><br>
|
||||
<span>渠道号:{{record.isvNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.isvName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'appId'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>应用名称:{{record.appName}}</span><br>
|
||||
<span>应用ID:{{record.appId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.appName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>商户名称:{{record.mchName}}</span><br>
|
||||
<span>商户号:{{record.mchExtNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'storeName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>门店名称:{{record.storeName}}</span><br>
|
||||
<span>门店编号:{{record.storeId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.storeName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<template v-if="column.key == 'drType'">
|
||||
<span v-if="record.drType == '00'">借记卡</span>
|
||||
<span v-if="record.drType == '01'">贷记卡</span>
|
||||
<span v-if="record.drType == '02'">零钱/余额</span>
|
||||
<span v-if="record.drType == '03'">支付宝花呗</span>
|
||||
<span v-if="record.drType == '04'">数字货币</span>
|
||||
<span v-if="record.drType == '99'">其他</span>
|
||||
<span v-if="!record.drType">--</span>
|
||||
</template>
|
||||
<template v-if="column.key == 'ifName'">
|
||||
{{record.ifName??"--"}}
|
||||
</template>
|
||||
<template v-if="column.key == 'settleType'">
|
||||
{{record.settleType??"--"}}
|
||||
</template>
|
||||
<template v-if="column.key == 'orderNo'">
|
||||
|
||||
<a-popover placement="top">
|
||||
<template #content>
|
||||
<p>平台订单号:{{ record.payOrderId??"--" }}</p>
|
||||
<p>通道订单号:{{record.channelOrderNo??"--"}}</p>
|
||||
<p>渠道订单号:{{ record.platformOrderNo??"--" }}</p>
|
||||
<p>商户订单号:{{ record.mchOrderNo ??"--"}}</p>
|
||||
<p>落单订单号:{{ record.platformMchOrderNo??"--" }}</p>
|
||||
</template>
|
||||
<b style="color: #1890ff"> {{ record.payOrderId??"--" }} </b>
|
||||
</a-popover>
|
||||
|
||||
<!-- <a-tooltip defaultVisible="true">-->
|
||||
<!-- <template #title>-->
|
||||
<!-- <div class="order-list-payOrderId">-->
|
||||
<!-- <p>平台订单号:{{ record.payOrderId??"--" }}</p>-->
|
||||
<!-- <p>通道订单号:{{record.channelOrderNo??"--"}}</p>-->
|
||||
<!-- <p>渠道订单号:{{ record.platformOrderNo??"--" }}</p>-->
|
||||
<!-- <p>商户订单号:{{ record.mchOrderNo ??"--"}}</p>-->
|
||||
<!-- <p>落单订单号:{{ record.platformMchOrderNo??"--" }}</p>-->
|
||||
<!-- </div>-->
|
||||
<!-- </template>-->
|
||||
<!-- <b style="color: #1890ff"> {{ record.payOrderId??"--" }} </b>-->
|
||||
<!-- </a-tooltip>-->
|
||||
|
||||
<!-- <div class="order-list">-->
|
||||
<!-- <p><span style="color:#729ED5;background:#e7f5f7">支付</span>{{ record.payOrderId }}</p>-->
|
||||
|
||||
<!-- <p style="margin-bottom: 0">-->
|
||||
<!-- <span style="color:#56cf56;background:#d8eadf">商户</span>-->
|
||||
<!-- <a-tooltip v-if="record.mchOrderNo.length > record.payOrderId.length" placement="bottom" style="font-weight: normal;">-->
|
||||
<!-- <template #title>-->
|
||||
<!-- <span>{{ record.mchOrderNo }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- {{ changeStr2ellipsis(record.mchOrderNo, record.payOrderId.length) }}-->
|
||||
<!-- </a-tooltip>-->
|
||||
<!-- <span v-else style="font-weight: normal;">{{ record.mchOrderNo }}</span>-->
|
||||
<!-- </p>-->
|
||||
<!-- <p v-if="record.channelOrderNo" style="margin-bottom: 0;margin-top: 10px">-->
|
||||
<!-- <span style="color:#fff;background:#E09C4D">渠道</span>-->
|
||||
<!-- <a-tooltip v-if="record.channelOrderNo.length > record.payOrderId.length" placement="bottom" style="font-weight: normal;">-->
|
||||
<!-- <template #title>-->
|
||||
<!-- <span>{{ record.channelOrderNo }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- {{ changeStr2ellipsis(record.channelOrderNo, record.payOrderId.length) }}-->
|
||||
<!-- </a-tooltip>-->
|
||||
<!-- <span v-else style="font-weight: normal;">{{ record.channelOrderNo }}</span>-->
|
||||
<!-- </p>-->
|
||||
<!-- </div>-->
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
|
||||
<!-- <a-button v-if="$access('ENT_PAY_ORDER_VIEW')" type="link" @click="detailFunc(record.payOrderId)">详情</a-button>-->
|
||||
<a-button v-if="$access('ENT_PAY_ORDER_VIEW')" type="link" @click="payLogDetail.show(record)">详情</a-button>
|
||||
<a-button v-if="$access('ENT_PAY_ORDER_REFUND')" v-show="(record.state === 2 || record.refundState === 1)" type="link" style="color: red" @click="openFunc(record, record.payOrderId)">退款</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 退款弹出框 -->
|
||||
<refund-modal ref="refundModalInfo" :callbackFunc="searchFunc" />
|
||||
<!-- 日志详情抽屉 -->
|
||||
<!-- <template>-->
|
||||
<!-- <a-drawer-->
|
||||
<!-- v-model:visible="vdata.visible"-->
|
||||
<!-- width="50%"-->
|
||||
<!-- placement="right"-->
|
||||
<!-- :closable="true"-->
|
||||
<!-- :title="vdata.visible === true? '订单详情':''"-->
|
||||
<!-- @close="onClose"-->
|
||||
<!-- >-->
|
||||
<!-- <a-row justify="space-between" type="flex">-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="服务商号">-->
|
||||
<!-- {{ vdata.detailData.isvNo }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="支付订单号">-->
|
||||
<!-- <a-tag color="purple">-->
|
||||
<!-- {{ vdata.detailData.payOrderId }}-->
|
||||
<!-- </a-tag>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="用户号">-->
|
||||
<!-- {{ vdata.detailData.mchNo }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="商户订单号">-->
|
||||
<!-- {{ vdata.detailData.mchOrderNo }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="用户名称">-->
|
||||
<!-- {{ vdata.detailData.mchName }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="应用APPID">-->
|
||||
<!-- {{ vdata.detailData.appId }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="门店名称">-->
|
||||
<!-- {{ vdata.detailData.storeName }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="门店ID">-->
|
||||
<!-- {{ vdata.detailData.storeId }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="订单状态">-->
|
||||
<!-- <a-tag :color="vdata.detailData.state === 0?'blue':vdata.detailData.state === 1?'orange':vdata.detailData.state === 2?'green':vdata.detailData.state === 6?'':'volcano'">-->
|
||||
<!-- {{ vdata.detailData.state === 0?'订单生成':vdata.detailData.state === 1?'支付中':vdata.detailData.state === 2?'支付成功':vdata.detailData.state === 3?'支付失败':vdata.detailData.state === 4?'已撤销':vdata.detailData.state === 5?'已退款':vdata.detailData.state === 6?'订单关闭':'未知' }}-->
|
||||
<!-- </a-tag>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="支付金额(元)">-->
|
||||
<!-- <a-tag color="green">-->
|
||||
<!-- {{ vdata.detailData.amount/100 }}-->
|
||||
<!-- </a-tag>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions><a-descriptions-item label="实际手续费"><a-tag color="pink">{{ vdata.detailData.mchFeeAmount/100 }}</a-tag></a-descriptions-item></a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions><a-descriptions-item label="收单手续费"><a-tag color="pink">{{ vdata.detailData.mchOrderFeeAmount/100 }}</a-tag></a-descriptions-item></a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions><a-descriptions-item label="商家费率">{{ vdata.detailData.mchFeeRate }}</a-descriptions-item></a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="支付错误码">-->
|
||||
<!-- {{ vdata.detailData.errCode }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="支付错误描述">-->
|
||||
<!-- {{ vdata.detailData.errMsg }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="买家备注">-->
|
||||
<!-- {{ vdata.detailData.buyerRemark }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="卖家备注">-->
|
||||
<!-- {{ vdata.detailData.sellerRemark }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col v-if="$hasMemberEnt() && vdata.detailData.mbrId" :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="会员ID">-->
|
||||
<!-- {{ vdata.detailData.mbrId }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col v-if="$hasMemberEnt() && vdata.detailData.mbrTel" :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="会员手机号">-->
|
||||
<!-- {{ vdata.detailData.mbrTel }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="订单失效时间">-->
|
||||
<!-- {{ vdata.detailData.expiredTime }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="支付成功时间">-->
|
||||
<!-- {{ vdata.detailData.successTime }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="创建时间">-->
|
||||
<!-- {{ vdata.detailData.createdAt }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="更新时间">-->
|
||||
<!-- {{ vdata.detailData.updatedAt }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-divider />-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="商品标题">-->
|
||||
<!-- {{ vdata.detailData.subject }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="商品描述">-->
|
||||
<!-- {{ vdata.detailData.body }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="接口代码">-->
|
||||
<!-- {{ vdata.detailData.ifCode }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="货币代码">-->
|
||||
<!-- {{ vdata.detailData.currency }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="支付方式">-->
|
||||
<!-- {{ vdata.detailData.wayCode }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="客户端IP">-->
|
||||
<!-- {{ vdata.detailData.clientIp }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="用户标识">-->
|
||||
<!-- {{ vdata.detailData.channelUser }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="渠道订单号">-->
|
||||
<!-- {{ vdata.detailData.channelOrderNo }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="异步通知地址">-->
|
||||
<!-- {{ vdata.detailData.notifyUrl }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="页面跳转地址">-->
|
||||
<!-- {{ vdata.detailData.returnUrl }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="退款次数">-->
|
||||
<!-- {{ vdata.detailData.refundTimes }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="退款总额">-->
|
||||
<!-- <a-tag v-if="vdata.detailData.refundAmount" color="cyan">-->
|
||||
<!-- {{ vdata.detailData.refundAmount/100 }}-->
|
||||
<!-- </a-tag>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
|
||||
<!-- <a-divider />-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="订单分账模式">-->
|
||||
<!-- <span v-if="vdata.detailData.divisionMode == 0">该笔订单不允许分账</span>-->
|
||||
<!-- <span v-else-if="vdata.detailData.divisionMode == 1">支付成功按配置自动完成分账</span>-->
|
||||
<!-- <span v-else-if="vdata.detailData.divisionMode == 2">商户手动分账(解冻商户金额)</span>-->
|
||||
<!-- <span v-else>未知</span>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="分账状态">-->
|
||||
<!-- <a-tag v-if="vdata.detailData.divisionState == 0" color="blue">未发生分账</a-tag>-->
|
||||
<!-- <a-tag v-else-if="vdata.detailData.divisionState == 1" color="orange">待分账</a-tag>-->
|
||||
<!-- <a-tag v-else-if="vdata.detailData.divisionState == 2" color="red">分账处理中</a-tag>-->
|
||||
<!-- <a-tag v-else-if="vdata.detailData.divisionState == 3" color="green">任务已结束</a-tag>-->
|
||||
<!-- <a-tag v-else color="#f50">未知</a-tag>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions><a-descriptions-item label="最新分账发起时间">{{ vdata.detailData.divisionLastTime }}</a-descriptions-item></a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- </a-row>-->
|
||||
<!-- <a-divider />-->
|
||||
<!-- <a-row justify="start" type="flex">-->
|
||||
<!-- <a-col :sm="24">-->
|
||||
<!-- <span style="color: black;">扩展参数:</span>-->
|
||||
<!-- <a-form-item>-->
|
||||
<!-- <a-input-->
|
||||
<!-- v-model:value="vdata.detailData.extParam"-->
|
||||
<!-- type="textarea"-->
|
||||
<!-- disabled="disabled"-->
|
||||
<!-- style="height: 100px;color: black;margin-top: 10px;"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- </a-row>-->
|
||||
<!-- </a-drawer>-->
|
||||
<!-- </template>-->
|
||||
<PayLogDetail ref="payLogDetail" :countDetailList="countDetailList" />
|
||||
</page-header-wrapper>
|
||||
|
||||
<!-- 数据统计对话框 -->
|
||||
<PayDetail ref="payDetail" :countDetailList="countDetailList" />
|
||||
<PaySucDetail ref="paySucDetail" :sucDetailList="sucDetailList" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import RefundModal from './RefundModal.vue' // 退款弹出框
|
||||
import {
|
||||
API_URL_MCH_LIST,
|
||||
API_URL_PAY_ORDER_LIST,
|
||||
API_URL_PAYWAYS_LIST,
|
||||
req,
|
||||
$exportExcel,
|
||||
exportExcelUrl,
|
||||
$payOrderCount,
|
||||
API_MCH_PAY_DEFINES,
|
||||
$getPayOrderRefresh,
|
||||
$unbindDevice
|
||||
} from '@/api/manage'
|
||||
import {ref, onMounted, reactive, getCurrentInstance} from 'vue'
|
||||
import fileDownload from 'js-file-download'
|
||||
import { message } from 'ant-design-vue'
|
||||
import PayDetail from './PayDetail.vue' // 数据统计详情弹出框
|
||||
import PayLogDetail from './PayLogDetail.vue' // 数据统计详情弹出框
|
||||
import PaySucDetail from './PaySucDetail.vue'
|
||||
import router from "@/router"; // 数据统计详情弹出框
|
||||
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
const routerPath = useRouter() //这是全部路由
|
||||
|
||||
const payDetail = ref() // 对话框
|
||||
const payLogDetail = ref() // 对话框
|
||||
const paySucDetail = ref() // 对话框
|
||||
// 获取全局函数
|
||||
const { $hasMemberEnt,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const orderKeyList = ref([
|
||||
{ 'key': 'payOrderId', 'desc': '支付订单号' },
|
||||
{ 'key': 'mchOrderNo', 'desc': '商户订单号' },
|
||||
{ 'key': 'channelOrderNo', 'desc': '渠道订单号' },
|
||||
{ 'key': 'platformOrderNo', 'desc': '用户支付凭证交易单号' },
|
||||
{ 'key': 'platformMchOrderNo', 'desc': '用户支付凭证商户单号' }])
|
||||
|
||||
const tableColumns = reactive([
|
||||
{ key: 'orderNo', title: '订单号'},
|
||||
{ key: 'mchName', title: '商户名称', dataIndex: 'mchName' },
|
||||
{ key: 'storeName', title: '门店名称', dataIndex: 'storeName' },
|
||||
{ key: 'ifName', title: '支付通道', dataIndex: 'ifName',},
|
||||
{ key: 'isvName', title: '所属渠道', dataIndex: 'isvName' },
|
||||
{ key: 'amount', title: '支付金额(元)' },
|
||||
// { key: 'refundAmount', title: '退款金额' },
|
||||
// { key: 'mchFeeAmount', title: '实际手续费', dataIndex: 'mchFeeAmount' },
|
||||
// { key: 'mchOrderFeeAmount', title: '收单手续费', dataIndex: 'mchOrderFeeAmount' },
|
||||
// { key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
// { key: 'mchOrderNo', title: '商户订单号', dataIndex: 'mchOrderNo' },
|
||||
{ key: 'state', title: '支付状态',},
|
||||
{ key: 'appId', title: '应用名称', dataIndex: 'appId' },
|
||||
{ key: 'wayName', title: '支付方式', dataIndex: 'wayName',},
|
||||
{ key: 'settleType', title: '结算类型', dataIndex: 'settleType', align: 'center'},
|
||||
{ key: 'drType', title: '借贷标识', dataIndex: 'drType', align: 'center'},
|
||||
{ key: 'divisionState', title: '分账状态', align: 'center' },
|
||||
{ key: 'buyerRemark', title: '买家备注', dataIndex: 'buyerRemark', defaultHidden: true },
|
||||
{ key: 'platformMchOrderNo', title: '支付凭证商户单号', dataIndex: 'platformMchOrderNo', defaultHidden: true },
|
||||
{ key: 'platformOrderNo', title: '支付凭证交易单号', dataIndex: 'platformOrderNo', defaultHidden: true },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
|
||||
{ key: 'op', title: '操作', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
const refundModalInfo = ref()
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
payDefines: [] as any,
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {queryDateRange: 'today'} as any,
|
||||
visible: false,
|
||||
detailData: {} as any,
|
||||
payWayList: [] as any,
|
||||
channelList:[] as any,
|
||||
orderKeyType: 'payOrderId'
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
if ($access('ENT_PAY_ORDER_SEARCH_PAY_WAY')) {
|
||||
initPayWay()
|
||||
}
|
||||
if(useRoute().query.unionOrderId !== undefined){
|
||||
vdata.searchData['unionOrderId'] = useRoute().query.unionOrderId
|
||||
setTimeout(()=>{
|
||||
searchFunc()
|
||||
},500)
|
||||
}
|
||||
})
|
||||
|
||||
let orderCountList:any = ref([]) // 数据统计数组
|
||||
let countDetailList: any = ref([]) // 数据统计明细数组
|
||||
let sucDetailList: any = ref([]) // 数据统计明细数组
|
||||
// 数据统计
|
||||
const getOrderCount = () => {
|
||||
$payOrderCount(vdata.searchData).then( res => {
|
||||
orderCountList.value = [
|
||||
{title: '订单金额', textColor: '#1A66FF', content: (res.totalAmt/ 100).toFixed(2),count: res.totalNum},
|
||||
{type: 'line'},
|
||||
{title: '成交金额', content: (res.totalSuccAmt / 100).toFixed(2),count:res.totalSuccNum, detail: false},
|
||||
{type: 'line'},
|
||||
// {title: '入账金额',symbol: 'sub', content: ((res.totalFindAmt - res.totalExtDivAmt- res.mchFeeAmount + res.totalMarketAmt) / 100).toFixed(2), count: res.totalNum, detail: true},
|
||||
{title: '入账金额',symbol: 'sub', content: ((res.totalEntryAmt) / 100).toFixed(2), count: res.totalSuccNum, detail: true},
|
||||
{type: 'line'},
|
||||
{title: '退款金额', content: (res.totalRefundAmt / 100).toFixed(2), count: res.totalRefundNum, textColor: '#faad14'},
|
||||
]
|
||||
// orderCountList.value = [
|
||||
// {title: '实际收款金额', symbol: 'add', textColor: '#1A66FF', content: ((res.allAmount - res.mchFeeAmount) / 100).toFixed(2)},
|
||||
// {type: 'line'},
|
||||
// {title: '成交订单', content: (res.allAmount / 100).toFixed(2), count: res.allCount, detail: true},
|
||||
// {type: 'line'},
|
||||
// {title: '实际手续费金额',symbol: 'sub', content: (res.mchFeeAmount / 100).toFixed(2)},
|
||||
// {type: 'line'},
|
||||
// {title: '退款订单', content: (res.refundAmount / 100).toFixed(2), count: res.refundCount, textColor: '#faad14'},
|
||||
// ]
|
||||
sucDetailList.value = [
|
||||
{title: '创建订单', content: (res.allPayAmount / 100).toFixed(2), count: res.allPayCount},
|
||||
{type: 'line'},
|
||||
{title: '成交订单', content: (res.allAmount / 100).toFixed(2), count: res.allCount},
|
||||
{type: 'line'},
|
||||
{title: '未付款订单', content: (res.failPayAmount / 100).toFixed(2), count: res.failPayCount},
|
||||
]
|
||||
countDetailList.value = [
|
||||
[
|
||||
{title: '支付金额', content: (res.totalFinalAmt / 100).toFixed(2), type: 1},
|
||||
// {type: 'line'},
|
||||
{title: '收单手续费', content: (res.totalFeeAmt / 100).toFixed(2), type: 1},
|
||||
// {type: 'line'},
|
||||
{title: '垫资手续费', content: (res.totalCashFee / 100).toFixed(2), type: 1},
|
||||
],
|
||||
[
|
||||
{title: '退款金额', content: (res.totalRefundAmt / 100).toFixed(2), type: 2},
|
||||
// {type: 'line'},
|
||||
{title: '优惠金额', content: (res.totalDiscountAmt / 100).toFixed(2), type: 2},
|
||||
// {type: 'line'},
|
||||
{title: '补贴金额', content: (res.totalMarketAmt / 100).toFixed(2), type: 2},
|
||||
],
|
||||
[
|
||||
{title: '预计入账金额', content: ((res.totalEntryAmt) / 100).toFixed(2), type: 3},
|
||||
]
|
||||
]
|
||||
})
|
||||
}
|
||||
getOrderCount() // 进入页面时调用一次
|
||||
getChannelList()
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_PAY_ORDER_LIST, params)
|
||||
}
|
||||
function searchFunc(){ // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
getOrderCount() // 数据统计函数
|
||||
}
|
||||
// 打开退款弹出框
|
||||
function openFunc (record, recordId) {
|
||||
if (record.refundState === 2) {
|
||||
return message.error('订单无可退款金额')
|
||||
}
|
||||
refundModalInfo.value.show(record)
|
||||
}
|
||||
function detailFunc(recordId) {
|
||||
|
||||
req.getById(API_URL_PAY_ORDER_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
|
||||
payFefines();
|
||||
//通道
|
||||
function payFefines() {
|
||||
req.list(API_MCH_PAY_DEFINES,{ 'pageSize': -1 }).then(res => {
|
||||
vdata.payDefines = res
|
||||
})
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
function initPayWay () {
|
||||
req.list(API_URL_PAYWAYS_LIST, { 'pageSize': -1 }).then(res => { // 支付方式下拉列表
|
||||
vdata.payWayList = res.records
|
||||
})
|
||||
}
|
||||
function changeStr2ellipsis (orderNo, baseLength) {
|
||||
const halfLengh = baseLength / 2
|
||||
return orderNo.substring(0, halfLengh - 1) + '...' + orderNo.substring(orderNo.length - halfLengh, orderNo.length)
|
||||
}
|
||||
|
||||
function tableExportFunc(){
|
||||
return $exportExcel(exportExcelUrl.payOrder, Object.assign({}, vdata.searchData, {'pageSize': -1})).then(res => {
|
||||
fileDownload(res.data, '订单列表.xlsx')
|
||||
}).catch ((error) =>{console.log(error)} )
|
||||
}
|
||||
|
||||
function onReset(){
|
||||
//重置搜索内容
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: 'today' }
|
||||
}
|
||||
|
||||
function orderKeyTypeChangeFunc() {
|
||||
vdata.searchData.payOrderId = ''
|
||||
vdata.searchData.mchOrderNo = ''
|
||||
vdata.searchData.channelOrderNo = ''
|
||||
vdata.searchData.platformMchOrderNo = ''
|
||||
vdata.searchData.platformOrderNo = ''
|
||||
}
|
||||
|
||||
function getChannelList(){
|
||||
// req.list(API_URL_MCH_APP, { 'pageSize': -1 }).then(res => { // 支付方式下拉列表
|
||||
// vdata.channelList = res.records
|
||||
// })
|
||||
}
|
||||
function getReload(data){
|
||||
return $getPayOrderRefresh(data.payOrderId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
message.success('刷新成功')
|
||||
})
|
||||
}
|
||||
|
||||
function getRefund(data) {
|
||||
routerPath.push({
|
||||
path:'/refund',
|
||||
query:{payOrderId:data.payOrderId}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
.order-list {
|
||||
padding:0 10px;
|
||||
-webkit-text-size-adjust:none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
white-space:nowrap;
|
||||
span {
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 35px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.order-list-payOrderId{
|
||||
padding: 10px !important;
|
||||
//width: 500px !important;
|
||||
}
|
||||
</style>
|
||||
66
jeepay-ui-merchant/src/views/order/pay/PaySucDetail.vue
Normal file
66
jeepay-ui-merchant/src/views/order/pay/PaySucDetail.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<a-modal v-model:visible="visible" :footer="null">
|
||||
<div class="modal-title">成交订单详细</div>
|
||||
<div class="modal-describe">创建订单金额/笔数 = 成交订单金额/笔数 + 未付款订单金额/笔数</div>
|
||||
<div class="statistics-list" style="padding-bottom: 55px;">
|
||||
<div v-for="(item, index) in props.sucDetailList as any" :key="index" class="item">
|
||||
<div v-if="item.type == 'line'" class="line" />
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div v-if="item.title" class="amount">
|
||||
<a-tooltip>
|
||||
<template #title>{{ item.content }}元</template>
|
||||
<span class="amount-num">{{ item.content }}</span><span>元</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div v-if="item.count >= 0" class="detail">
|
||||
<span>{{ item.count }}笔</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="close" @click=" visible = false">
|
||||
<a-button type="primary">知道了</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
const visible = ref<boolean>(false)
|
||||
|
||||
const props = defineProps({
|
||||
countDetailList: {type: Array, default: () => []},
|
||||
sucDetailList: {type: Array, default: () => []}
|
||||
})
|
||||
|
||||
const showModal = () => visible.value = true
|
||||
|
||||
defineExpose({showModal})
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.modal-title, .modal-describe{
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.modal-title {
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.close {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
border-top: 1px solid #EFEFEF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.amount {
|
||||
max-width:150px;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
}
|
||||
</style>
|
||||
317
jeepay-ui-merchant/src/views/order/pay/RefundModal.vue
Normal file
317
jeepay-ui-merchant/src/views/order/pay/RefundModal.vue
Normal file
@@ -0,0 +1,317 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-modal
|
||||
v-model:visible="vdata.visible"
|
||||
title="退款"
|
||||
:confirm-loading="vdata.confirmLoading"
|
||||
:closable="false"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
style="position: relative;top: 50px !important;"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付订单号">
|
||||
{{ vdata.detailData.payOrderId }}
|
||||
<!-- <a-tag color="purple">-->
|
||||
<!-- {{ vdata.detailData.payOrderId }}-->
|
||||
<!-- </a-tag>-->
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付通道">
|
||||
{{vdata.detailData.ifName}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算类型">
|
||||
{{vdata.detailData.settleType}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付金额">
|
||||
¥ {{ (vdata.detailData.amount/100).toFixed(2) }}
|
||||
<!-- <a-tag color="green">-->
|
||||
<!-- {{ vdata.detailData.amount/100 }}-->
|
||||
<!-- </a-tag>-->
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="可退金额">
|
||||
¥{{ nowRefundAmount }}
|
||||
<!-- <a-tag color="pink">-->
|
||||
<!-- {{ nowRefundAmount }}-->
|
||||
<!-- </a-tag>-->
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form ref="refundInfo" :rules="rules" :model="vdata.refund">
|
||||
|
||||
<a-form-item label="退款模式" name="refundModel">
|
||||
<div style="display: grid">
|
||||
<a-radio-group v-model:value="vdata.refund.refundModel">
|
||||
<a-radio :style="radioStyle" :value="1" :disabled="!vdata.settleTypeRefundState">收款商户号退款
|
||||
<a-tooltip class="my-tooltip">
|
||||
<template #title>
|
||||
需要今日存在正向交易订单且交易金额大于退款金额
|
||||
</template>
|
||||
<question-circle-outlined style="font-size: 12px" />
|
||||
</a-tooltip>
|
||||
</a-radio>
|
||||
<span class="jeepay-tip-text">仅T1、D1、定时结算类型订单支持,需要今日存在正向交易订单且交易金额大于退款金额</span>
|
||||
|
||||
<a-radio :style="radioStyle" :value="2" :disabled="!vdata.settleTypePaymentState">退款专用账户
|
||||
<a-tooltip class="my-tooltip">
|
||||
<template #title>
|
||||
一般户充值退款
|
||||
</template>
|
||||
<question-circle-outlined style="font-size: 12px;" />
|
||||
</a-tooltip>
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
|
||||
<span class="jeepay-tip-text" v-if="vdata.detailData.ifCode !='lklspay' || vdata.isPlatCheck == 1">(退款专用账户余额:{{(vdata.balacnePrice / 100).toFixed(2)}} 元,<a href="javascript:void(0)" @click="getfundRecharge">前往充值</a>)</span>
|
||||
<span class="jeepay-tip-text" v-else>当前商户暂未申请绑定拉卡拉退款专用账户,<a href="javascript:void(0)" @click="getLklspay">点击申请</a></span>
|
||||
|
||||
</div>
|
||||
|
||||
</a-form-item>
|
||||
<a-form-item label="退款金额" name="refundAmount">
|
||||
<a-input-number v-model:value="vdata.refund.refundAmount" placeholder="请输入退款金额" :precision="2" style="width:100%" />
|
||||
</a-form-item>
|
||||
<a-form-item label="支付密码" name="refundPassword">
|
||||
<a-input v-model:value="vdata.refund.refundPassword" maxlength="6" type="password" autocomplete="off" />
|
||||
<span class="jeepay-tip-text">(如果当前未设置支付密码,请进入 <a href="javascript:void(0)" @click="getSetConfig">【账号中心-系统配置-安全管理】</a> 设置支付密码)</span>
|
||||
</a-form-item>
|
||||
<a-form-item label="退款原因" name="refundReason">
|
||||
<a-input v-model:value="vdata.refund.refundReason" type="textarea" autocomplete="off" />
|
||||
</a-form-item>
|
||||
|
||||
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="tsx">
|
||||
import {
|
||||
API_URL_PAY_ORDER_LIST,
|
||||
req,
|
||||
$payOrderRefund,
|
||||
API_MCH_PAY_ACCOUNT,
|
||||
$getUserInfo,
|
||||
$payOrderCount, $getPayOrderRefundsIsPlatCheck, $unbindQrc, $getPayOrderRefundsApply
|
||||
} from '@/api/manage'
|
||||
import {ref, onMounted, reactive, getCurrentInstance,computed} from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
const routerPath = useRouter() //这是全部路由
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// 获取全局函数
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps ({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
const radioStyle = reactive({
|
||||
display: 'block',
|
||||
height: '25px',
|
||||
lineHeight: '25px',
|
||||
});
|
||||
const refundModel =ref()
|
||||
const refundInfo = ref()
|
||||
const vdata : any = reactive({
|
||||
settleTypePaymentState:true,
|
||||
settleTypeRefundState:true,
|
||||
isPlatCheck:true,
|
||||
sipw:2,
|
||||
refundErrorModal: null, // 退款错误信息的modal对象
|
||||
recordId: '',
|
||||
labelCol: { span: 4 },
|
||||
wrapperCol: { span: 16 },
|
||||
visible: false,
|
||||
confirmLoading: false,
|
||||
balacnePrice:0,
|
||||
detailData: {} as any,
|
||||
accountList:[] as any,
|
||||
refund: {
|
||||
refundModel:"",
|
||||
refundReason: '', // 退款原因
|
||||
refundAmount: '' // 退款金额
|
||||
} as any,
|
||||
|
||||
})
|
||||
|
||||
const rules = {
|
||||
refundModel: [{required: true, trigger: 'blur', message: '请输入退款模式' }],
|
||||
refundReason: [{ min: 0, max: 256, required: true, trigger: 'blur', message: '请输入退款原因,最长不超过256个字符' }],
|
||||
refundPassword: [{required: true, trigger: 'blur', message: '请输入支付密码' }],
|
||||
refundAmount: [{ required: true, message: '请输入金额', trigger: 'blur',type:'number' },
|
||||
{
|
||||
validator: (rule, value) => {
|
||||
console.log(value)
|
||||
|
||||
if (value < 0.01 || value > nowRefundAmount.value) {
|
||||
return Promise.reject('退款金额不能小于0.01并且不能大于可退金额')
|
||||
}else{
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
const nowRefundAmount = computed(()=>{
|
||||
return ((vdata.detailData.amount - vdata.detailData.refundAmount) / 100).toFixed(2)
|
||||
})
|
||||
|
||||
defineExpose({show})
|
||||
function show (record) {
|
||||
|
||||
if (refundInfo.value !== undefined) {
|
||||
refundInfo.value.resetFields()
|
||||
}
|
||||
vdata.recordId = record.payOrderId
|
||||
vdata.visible = true
|
||||
vdata.refund = {}
|
||||
userDetail()
|
||||
getAccount()
|
||||
vdata.detailData = record
|
||||
// if(vdata.detailData.settleType == 'D1'){
|
||||
// vdata.refund.refundModel = 1
|
||||
// }else{
|
||||
// vdata.refund.refundModel = 2
|
||||
// }
|
||||
getPayOrderRefundsIsPlatCheck()
|
||||
// req.getById(API_URL_PAY_ORDER_LIST, recordId).then(res => {
|
||||
//
|
||||
// })
|
||||
}
|
||||
function userDetail () { // 获取基本信息
|
||||
|
||||
$getUserInfo().then(res => {
|
||||
vdata.sipw = res.sipw
|
||||
})
|
||||
}
|
||||
function handleOk () {
|
||||
if(vdata.detailData.ifCode =='lklspay' && vdata.isPlatCheck != 1){
|
||||
$infoBox.message.error('请申请拉卡拉退款专用账户')
|
||||
return false;
|
||||
}
|
||||
refundInfo.value.validate().then(valid =>{
|
||||
vdata.confirmLoading = true
|
||||
|
||||
// 退款接口
|
||||
$payOrderRefund(vdata.recordId, vdata.refund.refundAmount, vdata.refund.refundReason, vdata.refund.refundPassword, vdata.refund.refundModel).then(res => {
|
||||
vdata.visible = false // 关闭弹窗
|
||||
vdata.confirmLoading = false // 取消按钮转圈
|
||||
|
||||
if (res.state === 0 || res.state === 3) { // 订单生成 || 失败
|
||||
vdata.refundErrorModal = $infoBox.modalError('退款失败', buildModalText(res))
|
||||
} else if (res.state === 1) { // 退款中
|
||||
vdata.refundErrorModal = $infoBox.modalWarning('退款中', buildModalText(res))
|
||||
props.callbackFunc()
|
||||
} else if (res.state === 2) { // 退款成功
|
||||
$infoBox.message.success('退款成功')
|
||||
props.callbackFunc()
|
||||
} else {
|
||||
vdata.refundErrorModal = $infoBox.modalWarning('退款状态未知', buildModalText(res))
|
||||
}
|
||||
}).catch(() => {
|
||||
vdata.confirmLoading = false // 取消按钮转圈
|
||||
})
|
||||
})
|
||||
}
|
||||
function handleCancel (e) {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
// 跳转到退款列表函数
|
||||
function toRefundList () {
|
||||
vdata.refundErrorModal.destroy()
|
||||
router.push({
|
||||
path: '/refund',
|
||||
})
|
||||
}
|
||||
|
||||
function buildModalText (res) {
|
||||
return <div>
|
||||
{ res.errCode? <div>错误码:{res.errCode} </div> : '' }
|
||||
{ res.errMsg? <div>错误信息:{res.errMsg} </div> : '' }
|
||||
<div>请到<a onClick={ toRefundList }>退款列表</a>中查看详细信息</div>
|
||||
</div>
|
||||
}
|
||||
function getSetConfig(){
|
||||
router.push({
|
||||
path: '/config',
|
||||
query:{groupKey:"securityConfig"}
|
||||
})
|
||||
}
|
||||
function getAccount(){
|
||||
req.list(API_MCH_PAY_ACCOUNT,{}).then(res => {
|
||||
vdata.accountList = res
|
||||
vdata.balacnePrice = res[0].balacne
|
||||
})
|
||||
}
|
||||
function getfundRecharge() {
|
||||
routerPath.push({
|
||||
path:'/fundRecharge',
|
||||
query:{index:0}
|
||||
})
|
||||
}
|
||||
|
||||
//验证一般户
|
||||
function getPayOrderRefundsIsPlatCheck(){
|
||||
|
||||
$getPayOrderRefundsIsPlatCheck(vdata.recordId).then( res => {
|
||||
|
||||
vdata.settleTypePaymentState = res.isPlatAccount; //退款专用账户
|
||||
vdata.settleTypeRefundState = res.isDefaultAccount; //收款商户号退款
|
||||
vdata.isPlatCheck = res.bindStatus;
|
||||
if(vdata.detailData.settleType == 'D1'){
|
||||
if(vdata.settleTypePaymentState ){
|
||||
vdata.refund.refundModel = 1 //收款商户号退款
|
||||
}
|
||||
}else{
|
||||
if(vdata.settleTypeRefundState ){
|
||||
vdata.refund.refundModel = 2 //退款专用账户
|
||||
}
|
||||
}
|
||||
console.log(vdata.refund.refundModel,'vdata.refund.refundModel')
|
||||
})
|
||||
}
|
||||
//申请拉卡拉申请
|
||||
function getLklspay(){
|
||||
const title = '确认申请?'
|
||||
const content = '是否申请绑定拉卡拉退款专用账户?'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $getPayOrderRefundsApply(vdata.recordId).then(res => {
|
||||
$infoBox.message.success('申请成功')
|
||||
setTimeout(() => {
|
||||
routerPath.push({
|
||||
path:'/applymentsOne',
|
||||
})
|
||||
},2000)
|
||||
})
|
||||
},() => {
|
||||
console.log(1111)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
deep(.ant-modal-content svg){
|
||||
color: #0c2640 !important;
|
||||
}
|
||||
</style>
|
||||
355
jeepay-ui-merchant/src/views/order/refund/RefundDetail.vue
Normal file
355
jeepay-ui-merchant/src/views/order/refund/RefundDetail.vue
Normal file
@@ -0,0 +1,355 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
width="60%"
|
||||
placement="right"
|
||||
:closable="true"
|
||||
:title="vdata.visible === true? '退款订单详情':''"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">订单信息</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="退款订单号">
|
||||
{{ vdata.detailData.refundOrderId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="通道订单号">
|
||||
{{ vdata.detailData.channelPayOrderNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="平台订单号">
|
||||
{{ vdata.detailData.payOrderId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户退款订单号">
|
||||
{{ vdata.detailData.mchRefundNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道订单号">
|
||||
--
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="落单订单号">
|
||||
--
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-divider class="jeepay-m-divider" orientation="left" style="color: #1A66FF;">其他信息</a-divider>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户简称">
|
||||
{{ vdata.detailData.mchName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户号">
|
||||
{{ vdata.detailData.mchExtNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="门店名称">
|
||||
{{ vdata.detailData.storeName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="门店编号">
|
||||
{{ vdata.detailData.storeId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道名称">
|
||||
{{ vdata.detailData.isvName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道号">
|
||||
{{ vdata.detailData.isvNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="应用名称">
|
||||
{{ vdata.detailData.appName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="应用ID">
|
||||
{{ vdata.detailData.appId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商名称">
|
||||
{{ vdata.detailData.agentName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商号">
|
||||
{{ vdata.detailData.agentNo }} [ {{vdata.detailData.agentContactTel}} ]
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付金额">
|
||||
<a-tag color="green">
|
||||
{{ vdata.detailData.payAmount/100 }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="退款金额">
|
||||
<a-tag color="red">
|
||||
{{ vdata.detailData.refundAmount/100 }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="手续费退还金额">
|
||||
<a-tag color="green">
|
||||
{{ vdata.detailData.refundFeeAmount/100 }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="退款状态">
|
||||
<a-tag :color="vdata.detailData.state === 0?'blue':vdata.detailData.state === 1?'orange':vdata.detailData.state === 2?'green':'volcano'">
|
||||
{{ vdata.detailData.state === 0?'订单生成':vdata.detailData.state === 1?'退款中':vdata.detailData.state === 2?'退款成功':vdata.detailData.state === 3?'退款失败':vdata.detailData.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
<a-tooltip :title="vdata.detailData.errMsg" v-if="vdata.detailData.state == 3">
|
||||
<question-circle-outlined style="color: #FF0000;"/>
|
||||
</a-tooltip>
|
||||
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="退款类型">
|
||||
<a-tag
|
||||
:key="vdata.detailData.refundType"
|
||||
:color="vdata.detailData.refundType === 0?'blue':vdata.detailData.refundType === 1?'red':vdata.detailData.refundType === 2?'orange':'volcano'"
|
||||
>
|
||||
{{ vdata.detailData.refundType === 1?'全额退款':vdata.detailData.refundType === 2?'部分退款':'' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="退款模式">
|
||||
<a-tag
|
||||
:key="vdata.detailData.extParam"
|
||||
:color="vdata.detailData.extParam === '1'?'blue':vdata.detailData.extParam === '2'?'orange':'volcano'"
|
||||
>
|
||||
{{ vdata.detailData.extParam === '1'?'收款商户号':vdata.detailData.extParam === '2'?'退款专用账户':'' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="退款成功时间">
|
||||
{{ vdata.detailData.successTime }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="创建时间">
|
||||
{{ vdata.detailData.createdAt }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="更新时间">
|
||||
{{ vdata.detailData.updatedAt }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
|
||||
</a-row>
|
||||
|
||||
|
||||
<!-- <a-divider />-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="接口代码">-->
|
||||
<!-- {{ vdata.detailData.ifCode }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="货币代码">-->
|
||||
<!-- {{ vdata.detailData.currency }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="方式代码">-->
|
||||
<!-- {{ vdata.detailData.wayCode }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="客户端IP">-->
|
||||
<!-- {{ vdata.detailData.clientIp }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="24">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="异步通知地址">-->
|
||||
<!-- {{ vdata.detailData.notifyUrl }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- </a-row>-->
|
||||
<!-- <a-divider />-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="渠道订单号">-->
|
||||
<!-- {{ vdata.detailData.channelOrderNo }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="渠道错误码">-->
|
||||
<!-- {{ vdata.detailData.errCode }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="渠道错误描述">-->
|
||||
<!-- {{ vdata.detailData.errMsg }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="24">-->
|
||||
<!-- <span style="color: black;">渠道额外参数:</span>-->
|
||||
<!-- <a-form-item>-->
|
||||
<!-- <a-input-->
|
||||
<!-- v-model:value="vdata.detailData.channelExtra"-->
|
||||
<!-- type="textarea"-->
|
||||
<!-- disabled="disabled"-->
|
||||
<!-- style="height: 100px;color: black;margin-top: 10px;"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-divider />-->
|
||||
<!-- <a-col :sm="24">-->
|
||||
<!-- <span style="color: black;">扩展参数:</span>-->
|
||||
<!-- <a-form-item>-->
|
||||
<!-- <a-input-->
|
||||
<!-- v-model:value="vdata.detailData.extParam"-->
|
||||
<!-- type="textarea"-->
|
||||
<!-- disabled="disabled"-->
|
||||
<!-- style="height: 100px;color: black;margin-top: 10px;"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<a-col :sm="24">
|
||||
<span style="color: black;">备注:</span>
|
||||
<a-form-item>
|
||||
<a-input
|
||||
v-model:value="vdata.detailData.remark"
|
||||
type="textarea"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black;margin-top: 10px;"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { req } from '@/api/manage'
|
||||
import {defineProps,reactive, getCurrentInstance} from 'vue'
|
||||
const { $hasAgentEnt, $SYS_NAME_MAP } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata:any = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
termNo: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (data) { // 弹层打开事件
|
||||
vdata.detailData = data // 数据清空
|
||||
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
625
jeepay-ui-merchant/src/views/order/refund/RefundOrderList.vue
Normal file
625
jeepay-ui-merchant/src/views/order/refund/RefundOrderList.vue
Normal file
@@ -0,0 +1,625 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="dateTime" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.unionOrderId" :placeholder="'订单号'" />
|
||||
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mchInfo" :placeholder="'商户名称/商户号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.storeInfo" :placeholder="'门店名称/门店编号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.ifCode" :placeholder="'支付通道'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.isvNo" :placeholder="'渠道名称/渠道号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appId" :placeholder="'应用名称/应用ID'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="退款状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">订单生成</a-select-option>
|
||||
<a-select-option value="1">退款中</a-select-option>
|
||||
<a-select-option value="2">退款成功</a-select-option>
|
||||
<a-select-option value="3">退款失败</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.refundType" placeholder="退款类型">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="1">全额退款</a-select-option>
|
||||
<a-select-option value="2">部分退款</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.extParam" placeholder="退款模式">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="1">收款商户号</a-select-option>
|
||||
<a-select-option value="2">退款专用账户</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="" class="table-search-item">-->
|
||||
<!-- <a-select v-model:value="vdata.searchData.ifCode" placeholder="支付通道">-->
|
||||
|
||||
<!-- <a-select-option v-for="item in vdata.payDefines" :key="item.ifCode" :value="item.ifCode">{{ item.ifName }}</a-select-option>-->
|
||||
<!-- </a-select>-->
|
||||
<!-- </a-form-item>-->
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:closable="true"
|
||||
:searchData="vdata.searchData"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
rowKey="refundOrderId"
|
||||
:tableRowCrossColor="true"
|
||||
:statisticsIsShow="true"
|
||||
:tableExportFunc="tableExportFunc"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in orderCountList" :key="index" class="item">
|
||||
<div v-if="item.type == 'line'" class="line" />
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div v-if="item.title" class="amount" :style="{color: item.textColor}">
|
||||
<!-- <span v-if="item.symbol" class="symbol">{{ item.symbol == 'add' ? '+' : '-' }}</span> -->
|
||||
<span class="amount-num">{{ item.content }}</span>{{ item.unit?item.unit:'元' }}
|
||||
</div>
|
||||
<div v-if="item.title" class="amount" >
|
||||
<!-- <span v-if="item.symbol" class="symbol">{{ item.symbol == 'add' ? '+' : '-' }}</span> -->
|
||||
<span class="amount-num">{{ item.num }}</span>笔
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<!-- <template v-if="column.key == 'payAmount'"><b>¥{{ record.payAmount/100 }}</b></template>-->
|
||||
<template v-if="column.key == 'refundAmount'">
|
||||
<a-tooltip>
|
||||
<template #title>
|
||||
<p>退款金额:¥{{ record.payAmount/100 }}</p>
|
||||
<p>手续费退还金额:¥{{ record.refundFeeAmount/100 }}</p>
|
||||
</template>
|
||||
<b style="color: #1890ff">¥{{ record.refundAmount/100 }}</b>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<!-- <template v-if="column.key == 'refundFeeAmount'"><b>¥{{ record.refundFeeAmount/100 }}</b></template>-->
|
||||
<template v-if="column.key == 'state'">
|
||||
<div>
|
||||
<a-tag
|
||||
:key="record.state"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':'volcano'"
|
||||
>
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'退款中':record.state === 2?'退款成功':record.state === 3?'退款失败':record.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
<a-tooltip :title="record.errMsg" v-if="record.state == 3">
|
||||
<question-circle-outlined style="color: #FF0000;"/>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="快钱通道部分退款类型的退款金额将于第二个工作日凌晨4-5点到账" v-if="record.ifCode == 'kqpay' && record.state==2 && record.refundType ==2">
|
||||
<question-circle-outlined style="color: #FF0000;"/>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
<template v-if="column.key == 'refundType'">
|
||||
<div>
|
||||
<a-tag
|
||||
:key="record.state"
|
||||
:color="record.refundType === 0?'blue':record.refundType === 1?'red':record.refundType === 2?'orange':'volcano'"
|
||||
>
|
||||
{{ record.refundType === 1?'全额退款':record.refundType === 2?'部分退款':'' }}
|
||||
</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'extParam'">
|
||||
<div>
|
||||
<a-tag
|
||||
:key="record.extParam"
|
||||
:color="record.extParam === '1'?'blue':record.extParam === '2'?'orange':''"
|
||||
>
|
||||
{{ record.extParam === "1"?'收款商户号':record.extParam === "2"?'退款专用账户':'' }}
|
||||
</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<template v-if="column.key === 'appId'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>应用名称:{{record.appName}}</span><br>
|
||||
<span>应用ID:{{record.appId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.appName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>商户名称:{{record.mchName}}</span><br>
|
||||
<span>商户号:{{record.mchExtNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'storeName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>门店名称:{{record.storeName}}</span><br>
|
||||
<span>门店编号:{{record.storeId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.storeName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'isvName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>渠道名称:{{record.isvName}}</span><br>
|
||||
<span>渠道号:{{record.isvNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.isvName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
|
||||
<template v-if="column.key == 'refund'">
|
||||
<!-- <div class="order-list">-->
|
||||
<!-- <p><span style="color:#729ED5;background:#e7f5f7">支付</span>{{ record.payOrderId }}</p>-->
|
||||
<!-- <p v-if="record.channelPayOrderNo" style="margin-bottom: 0;">-->
|
||||
<!-- <span style="color:#fff;background:#E09C4D">渠道</span>-->
|
||||
<!-- <a-tooltip v-if="record.channelPayOrderNo.length > record.payOrderId.length" placement="bottom" style="font-weight: normal;">-->
|
||||
<!-- <template #title>-->
|
||||
<!-- <span>{{ record.channelPayOrderNo }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- {{ changeStr2ellipsis(record.channelPayOrderNo, record.payOrderId.length) }}-->
|
||||
<!-- </a-tooltip>-->
|
||||
<!-- <span v-else style="font-weight: normal;">{{ record.channelPayOrderNo }}</span>-->
|
||||
<!-- </p>-->
|
||||
<!-- </div>-->
|
||||
<a-tooltip>
|
||||
<template #title>
|
||||
<p>渠道:{{ record.channelPayOrderNo }}</p>
|
||||
</template>
|
||||
<b style="color: #1890ff">{{ record.payOrderId }}</b>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key == 'pay'">
|
||||
<!-- <a-tooltip>-->
|
||||
<!-- <template #title>-->
|
||||
<!-- <p>商户退款单号:{{ record.mchRefundNo }}</p>-->
|
||||
<!-- <p>渠道退款单号:{{ record.channelPayOrderNo }}</p>-->
|
||||
<!-- <p>订单号:{{ record.payOrderId }}</p>-->
|
||||
<!-- </template>-->
|
||||
<!-- <b style="color: #1890ff">{{ record.refundOrderId }}</b>-->
|
||||
<!-- </a-tooltip>-->
|
||||
|
||||
<a-popover placement="top">
|
||||
<template #content>
|
||||
<p>商户退款单号:{{ record.mchRefundNo }}</p>
|
||||
<p>渠道退款单号:{{ record.channelPayOrderNo }}</p>
|
||||
<p>平台订单号:{{ record.payOrderId }}</p>
|
||||
</template>
|
||||
<b style="color: #1890ff"> {{ record.refundOrderId??"--" }} </b>
|
||||
</a-popover>
|
||||
|
||||
|
||||
<!-- <div class="order-list">-->
|
||||
<!-- <p><span style="color:#729ED5;background:#e7f5f7">退款</span>{{ record.refundOrderId }}</p>-->
|
||||
<!-- <p style="margin-bottom: 0;">-->
|
||||
<!-- <span style="color:#56cf56;background:#d8eadf">商户</span>-->
|
||||
<!-- <a-tooltip v-if="record.mchRefundNo.length > record.refundOrderId.length" placement="bottom" style="font-weight: normal;">-->
|
||||
<!-- <template #title>-->
|
||||
<!-- <span>{{ record.mchRefundNo }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- {{ changeStr2ellipsis(record.mchRefundNo, record.refundOrderId.length) }}-->
|
||||
<!-- </a-tooltip>-->
|
||||
<!-- <span v-else style="font-weight: normal;">{{ record.mchRefundNo }}</span>-->
|
||||
<!-- </p>-->
|
||||
<!-- </div>-->
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<a-button v-if="$access('ENT_REFUND_ORDER_VIEW')" type="link" @click="detailFunc(record)">详情</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 日志详情抽屉 -->
|
||||
<!-- <template>-->
|
||||
<!-- <a-drawer-->
|
||||
<!-- v-model:visible="vdata.visible"-->
|
||||
<!-- width="50%"-->
|
||||
<!-- placement="right"-->
|
||||
<!-- :closable="true"-->
|
||||
<!-- :title="vdata.visible === true? '退款订单详情':''"-->
|
||||
<!-- @close="onClose"-->
|
||||
<!-- >-->
|
||||
<!-- <a-row justify="space-between" type="flex">-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="所属系统">-->
|
||||
<!-- {{ vdata.detailData.mchType === 1?'普通商户':vdata.detailData.mchType === 2?'特约商户':'未知' }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="服务商号">-->
|
||||
<!-- {{ vdata.detailData.isvNo }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="退款订单号">-->
|
||||
<!-- <a-tag color="purple">-->
|
||||
<!-- {{ vdata.detailData.refundOrderId }}-->
|
||||
<!-- </a-tag>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="用户号">-->
|
||||
<!-- {{ vdata.detailData.mchNo }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="支付订单号">-->
|
||||
<!-- {{ vdata.detailData.payOrderId }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="商户退款单号">-->
|
||||
<!-- {{ vdata.detailData.mchRefundNo }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="渠道支付订单号">-->
|
||||
<!-- {{ vdata.detailData.channelPayOrderNo }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="应用APPID">-->
|
||||
<!-- {{ vdata.detailData.appId }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="门店ID">-->
|
||||
<!-- {{ vdata.detailData.storeId }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="名店名称">-->
|
||||
<!-- {{ vdata.detailData.storeName }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="支付金额">-->
|
||||
<!-- <a-tag color="green">-->
|
||||
<!-- {{ vdata.detailData.payAmount/100 }}-->
|
||||
<!-- </a-tag>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="退款金额">-->
|
||||
<!-- <a-tag color="green">-->
|
||||
<!-- {{ vdata.detailData.refundAmount/100 }}-->
|
||||
<!-- </a-tag>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="手续费退还金额">-->
|
||||
<!-- <a-tag color="green">-->
|
||||
<!-- {{ vdata.detailData.refundFeeAmount/100 }}-->
|
||||
<!-- </a-tag>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="订单状态">-->
|
||||
<!-- <a-tag :color="vdata.detailData.state === 0?'blue':vdata.detailData.state === 1?'orange':vdata.detailData.state === 2?'green':'volcano'">-->
|
||||
<!-- {{ vdata.detailData.state === 0?'订单生成':vdata.detailData.state === 1?'退款中':vdata.detailData.state === 2?'退款成功':vdata.detailData.state === 3?'退款失败':vdata.detailData.state === 4?'任务关闭':'未知' }}-->
|
||||
<!-- </a-tag>-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="24">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="退款成功时间">-->
|
||||
<!-- {{ vdata.detailData.successTime }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="创建时间">-->
|
||||
<!-- {{ vdata.detailData.createdAt }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="更新时间">-->
|
||||
<!-- {{ vdata.detailData.updatedAt }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-divider />-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="接口代码">-->
|
||||
<!-- {{ vdata.detailData.ifCode }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="货币代码">-->
|
||||
<!-- {{ vdata.detailData.currency }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="方式代码">-->
|
||||
<!-- {{ vdata.detailData.wayCode }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="客户端IP">-->
|
||||
<!-- {{ vdata.detailData.clientIp }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="24">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="异步通知地址">-->
|
||||
<!-- {{ vdata.detailData.notifyUrl }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- </a-row>-->
|
||||
<!-- <a-divider />-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="渠道订单号">-->
|
||||
<!-- {{ vdata.detailData.channelOrderNo }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="渠道错误码">-->
|
||||
<!-- {{ vdata.detailData.errCode }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="渠道错误描述">-->
|
||||
<!-- {{ vdata.detailData.errMsg }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="24">-->
|
||||
<!-- <span style="color: black;">渠道额外参数:</span>-->
|
||||
<!-- <a-form-item>-->
|
||||
<!-- <a-input-->
|
||||
<!-- v-model:value="vdata.detailData.channelExtra"-->
|
||||
<!-- type="textarea"-->
|
||||
<!-- disabled="disabled"-->
|
||||
<!-- style="height: 100px;color: black;margin-top: 10px;"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-divider />-->
|
||||
<!-- <a-col :sm="24">-->
|
||||
<!-- <span style="color: black;">扩展参数:</span>-->
|
||||
<!-- <a-form-item>-->
|
||||
<!-- <a-input-->
|
||||
<!-- v-model:value="vdata.detailData.extParam"-->
|
||||
<!-- type="textarea"-->
|
||||
<!-- disabled="disabled"-->
|
||||
<!-- style="height: 100px;color: black;margin-top: 10px;"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- <a-col :sm="24">-->
|
||||
<!-- <span style="color: black;">备注:</span>-->
|
||||
<!-- <a-form-item>-->
|
||||
<!-- <a-input-->
|
||||
<!-- v-model:value="vdata.detailData.remark"-->
|
||||
<!-- type="textarea"-->
|
||||
<!-- disabled="disabled"-->
|
||||
<!-- style="height: 100px;color: black;margin-top: 10px;"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- </a-col>-->
|
||||
<!-- </a-drawer>-->
|
||||
<!-- </template>-->
|
||||
</page-header-wrapper>
|
||||
|
||||
<RefundDetail ref="refundDetail" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
API_URL_REFUND_ORDER_LIST,
|
||||
req,
|
||||
$exportExcel,
|
||||
exportExcelUrl,
|
||||
$refundOrderCount,
|
||||
API_MCH_PAY_DEFINES
|
||||
} from '@/api/manage'
|
||||
import moment from 'moment'
|
||||
import fileDownload from 'js-file-download'
|
||||
import {ref, onMounted, reactive, getCurrentInstance} from 'vue'
|
||||
import {useRoute} from "vue-router";
|
||||
import RefundDetail from "@/views/order/refund/RefundDetail.vue";
|
||||
const refundDetail = ref() // 对话框
|
||||
// 获取全局函数
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = reactive([
|
||||
// { key: 'pay', title: '退款订单号', scopedSlots: { customRender: 'refundOrderSlot' } },
|
||||
{ key: 'pay', title: '退款订单号' },
|
||||
{ key: 'mchName', title: '商户名称', dataIndex: 'mchName' },
|
||||
{ key: 'storeName', title: '门店名称', dataIndex: 'storeName' },
|
||||
// { key: 'refund', title: '支付订单号', scopedSlots: { customRender: 'payOrderSlot' }, width: '260px' },
|
||||
{ key: 'ifName', title: '支付通道', dataIndex: 'ifName',},
|
||||
{ key: 'isvName', title: '所属渠道', dataIndex: 'isvName' },
|
||||
// { key: 'payAmount', title: '支付金额' },
|
||||
{ key: 'refundAmount', title: '退款金额(元)' },
|
||||
// { key: 'refundFeeAmount', title: '手续费退还金额' },
|
||||
// { key: 'refundOrderId', title: '退款订单号', dataIndex: 'refundOrderId' },
|
||||
// { key: 'mchRefundNo', title: '商户退款单号', dataIndex: 'mchRefundNo' },
|
||||
// { key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
// { key: 'channelPayOrderNo', title: '渠道订单号', dataIndex: 'channelPayOrderNo' },
|
||||
{ key: 'state', title: '退款状态', scopedSlots: { customRender: 'stateSlot' } },
|
||||
{ key: 'appId', title: '所属应用', dataIndex: 'appId' },
|
||||
{ key: 'refundType', title: '退款类型', scopedSlots: { customRender: 'stateSlot' } },
|
||||
{ key: 'extParam', title: '退款模式' },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
|
||||
{ key: 'op', title: '操作', width: '100px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
])
|
||||
|
||||
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
payDefines: [] as any,
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {queryDateRange: 'today'} as any,
|
||||
createdStart: '', // 选择开始时间
|
||||
createdEnd: '', // 选择结束时间
|
||||
visible: false,
|
||||
detailData: {} as any
|
||||
})
|
||||
|
||||
onMounted( () => {
|
||||
getOrderCount()
|
||||
payFefines();
|
||||
if(useRoute().query.payOrderId !== undefined){
|
||||
vdata.searchData.unionOrderId = useRoute().query.payOrderId
|
||||
vdata.searchData.queryDateRange = ''
|
||||
|
||||
setTimeout(function (){
|
||||
searchFunc()
|
||||
},500)
|
||||
}
|
||||
})
|
||||
//通道
|
||||
function payFefines() {
|
||||
req.list(API_MCH_PAY_DEFINES,{ 'pageSize': -1 }).then(res => {
|
||||
vdata.payDefines = res
|
||||
})
|
||||
}
|
||||
|
||||
let orderCountList:any = ref([]) // 数据统计数组
|
||||
// 数据统计
|
||||
const getOrderCount = () => {
|
||||
|
||||
// if(!$access('ENT_REFUND_ORDER_COUNT')){
|
||||
// return false
|
||||
// }
|
||||
|
||||
$refundOrderCount(vdata.searchData).then( res => {
|
||||
orderCountList.value = [
|
||||
{title: '退款金额', symbol: 'add', textColor: '#1A66FF', content: (res.allCountAmount / 100).toFixed(2), num:res.allCount },
|
||||
{type: 'line'},
|
||||
{title: '退款成功金额',symbol: 'add', textColor: '#389e0d',content: (res.succesAmount / 100).toFixed(2), num:res.succesCount },
|
||||
{type: 'line'},
|
||||
{title: '手续费退款金额',symbol: 'add',textColor: '#FF0000', content: (res.feeAmount / 100).toFixed(2), num:res.feeCount},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
function queryFunc () {
|
||||
vdata.btnLoading = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_REFUND_ORDER_LIST, params)
|
||||
}
|
||||
function searchFunc() { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
getOrderCount()
|
||||
}
|
||||
function detailFunc(record) {
|
||||
refundDetail.value.show(record)
|
||||
// req.getById(API_URL_REFUND_ORDER_LIST, record.refundOrderId).then(res => {
|
||||
// vdata.detailData = res
|
||||
// console.log(res,'res')
|
||||
// })
|
||||
vdata.visible = true
|
||||
}
|
||||
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
function changeStr2ellipsis (orderNo, baseLength) {
|
||||
const halfLengh = baseLength / 2
|
||||
return orderNo.substring(0, halfLengh - 1) + '...' + orderNo.substring(orderNo.length - halfLengh, orderNo.length)
|
||||
}
|
||||
|
||||
function tableExportFunc(){
|
||||
return $exportExcel(exportExcelUrl.refundOrder, Object.assign({}, vdata.searchData, {'pageSize': -1})).then(res => {
|
||||
fileDownload(res.data, '退款订单.xlsx')
|
||||
}).catch ((error) =>{console.log(error)} )
|
||||
}
|
||||
|
||||
function onReset(){
|
||||
//重置搜索内容
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: 'today' }
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.order-list {
|
||||
-webkit-text-size-adjust:none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
white-space:nowrap;
|
||||
span {
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 35px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
378
jeepay-ui-merchant/src/views/order/settle/settleList.vue
Normal file
378
jeepay-ui-merchant/src/views/order/settle/settleList.vue
Normal file
@@ -0,0 +1,378 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="dateTime" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mchExtNo" :placeholder="'商户名称/商户号'" />
|
||||
|
||||
<jeepay-text-up v-model:value="vdata.searchData.ifCode" :placeholder="'支付通道'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.isvNo" :placeholder="'渠道名称/渠道号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appid" :placeholder="'应用名称/应用ID'" />
|
||||
<!-- <jeepay-text-up v-model:value="vdata.searchData.nameAndNo" :placeholder="'结算姓名/结算卡号'" />-->
|
||||
<!-- <a-form-item label="" class="table-search-item">-->
|
||||
<!-- <a-select v-model:value="vdata.searchData.ifCode" placeholder="支付通道">-->
|
||||
<!-- <a-select-option v-for="item in vdata.payDefines" :key="item.ifCode" :value="item.ifCode">{{ item.ifName }}</a-select-option>-->
|
||||
<!-- </a-select>-->
|
||||
<!-- </a-form-item>-->
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.settleType" placeholder="结算类型">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="D0">D0</a-select-option>
|
||||
<a-select-option value="D1">D1</a-select-option>
|
||||
<a-select-option value="T1">T1</a-select-option>
|
||||
<!-- <a-select-option value="4">定时结算</a-select-option>-->
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="结算状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="-1">结算失败</a-select-option>
|
||||
<a-select-option value="0">待结算</a-select-option>
|
||||
<a-select-option value="1">结算中</a-select-option>
|
||||
<a-select-option value="2">结算成功</a-select-option>
|
||||
<a-select-option value="3">暂缓</a-select-option>
|
||||
<a-select-option value="4">冻结</a-select-option>
|
||||
<a-select-option value="5">退票</a-select-option>
|
||||
<a-select-option value="98">待查看</a-select-option>
|
||||
<a-select-option value="99">其他</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
|
||||
<!-- :statisticsIsShow="$access('ENT_ORDER_COUNT')"-->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="payOrderId"
|
||||
:tableRowCrossColor="true"
|
||||
:statisticsIsShow="true"
|
||||
:tableExportFunc="tableExportFunc"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in orderCountList" :key="index" class="item">
|
||||
<div v-if="item.type == 'line'" class="line" />
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div v-if="item.title" class="amount" :style="{color: item.textColor}">
|
||||
<span class="amount-num">{{ item.content }}</span>元
|
||||
</div>
|
||||
<div v-if="item.count >= 0" class="detail">
|
||||
<span>{{ item.count + '笔' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'settleType'">
|
||||
<Tooltip color="#3b4146">
|
||||
<template #title>
|
||||
<div style="color: #ffffff">提示内容</div>
|
||||
</template>
|
||||
<div style="cursor: pointer; width: 100%">
|
||||
结算类型
|
||||
<a-tooltip>
|
||||
<template #title>
|
||||
<p>T1:工作日次日到账,交易资金于周末和法定节假日次日的6点-12点自动结算至银行卡</p>
|
||||
<p>D1:自然日次日到账,全年365天(不分节假日)的交易资金于自然日的次日6点-12点自动结算至银行卡</p>
|
||||
<p>D0:实时到账,全年365天24小时(不分节假日)的交易资金笔笔实时秒到至银行卡,更放心更快捷</p>
|
||||
<p>定时结算,在一天24个整点时辰,根据入账需求选择结算范围,可任意指定一个或多个结算时间点</p>
|
||||
</template>
|
||||
<question-circle-outlined style="padding-left: 10px"/>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key === 'appid'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>应用名称:{{record.appName}}</span><br>
|
||||
<span>应用ID:{{record.appid}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.appName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>商户名称:{{record.mchName}}</span><br>
|
||||
<span>商户号:{{record.mchExtNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'isvNo'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>渠道名称:{{record.isvName}}</span><br>
|
||||
<span>渠道号:{{record.isvNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.isvName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key == 'state'">
|
||||
<a-tag
|
||||
:key="record.state"
|
||||
:color="record.state === -1?'red':record.state === 1?'orange':record.state === 2?'green':record.state === 6?'':'volcano'"
|
||||
>
|
||||
{{ record.state === -1?'结算失败':record.state === 0?'待结算':record.state === 1?'结算中':record.state === 2?'结算成功':record.state === 3?'暂缓':record.state === 4?'冻结':record.state === 5?'退票':record.state === 98?'待查看':record.state === 99?'待查看':'--' }}
|
||||
|
||||
</a-tag>
|
||||
<a-tooltip :title="record.errMsg" v-if="record.state == 3">
|
||||
<info-circle-outlined style="color: #FFD080;margin-left: 5px"/>
|
||||
</a-tooltip>
|
||||
|
||||
|
||||
<a-tooltip :title="record.remark" v-if="record.state == 98 && record.settleType == 'D0'">
|
||||
<question-circle-outlined style="padding-left: 5px"/>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-if="record.state == -1" :title="record.remark">
|
||||
<info-circle-outlined style="font-size: 16px; padding-left: 5px;color: #FF0000"/>
|
||||
</a-tooltip>
|
||||
|
||||
<reload-outlined v-if="$access('ENT_SETTLE_SYNC') && record.state < 2" @click="getReload(record)" style="color: #1890ff;margin-left: 5px" />
|
||||
|
||||
|
||||
</template>
|
||||
<template v-if="column.key == 'accountName'">
|
||||
<!-- 操作列插槽 -->
|
||||
<!-- <a-tooltip >-->
|
||||
<!-- <template #title>-->
|
||||
<!-- 卡号:-->
|
||||
<!-- </template>-->
|
||||
<!-- -->
|
||||
<!-- </a-tooltip>-->
|
||||
{{record.accountName}}<br>
|
||||
{{record.accountNo}}
|
||||
</template>
|
||||
<template v-if="column.key == 'settleAmt'">
|
||||
<!-- 操作列插槽 -->
|
||||
<a-tooltip >
|
||||
<template #title>
|
||||
<div v-if="record.state == 1 || record.state == 0">
|
||||
<p>预付金额:数据同步中</p>
|
||||
<p>交易手续费:数据同步中</p>
|
||||
<p>垫资手续费:数据同步中</p>
|
||||
<p>结算金额:数据同步中</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>预付金额:{{(record.planAmt / 100).toFixed(2)}}</p>
|
||||
<p>交易手续费:{{(record.fee / 100).toFixed(2)}}</p>
|
||||
<p>垫资手续费:{{(record.cashFee / 100).toFixed(2)}}</p>
|
||||
<p>结算金额:{{(record.settleAmt / 100).toFixed(2)}}</p>
|
||||
</div>
|
||||
</template>
|
||||
<b style="color: #1890ff">¥{{ (record.settleAmt / 100).toFixed(2)}} </b>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'transactionAmount'">
|
||||
¥{{ (record.transactionAmount / 100).toFixed(2)}}
|
||||
</template>
|
||||
<template v-if="column.key == 'fee'">
|
||||
¥{{ (record.fee / 100).toFixed(2)}}
|
||||
</template>
|
||||
<template v-if="column.key == 'cashFee'">
|
||||
¥{{ (record.cashFee / 100).toFixed(2)}}
|
||||
</template>
|
||||
<template v-if="column.key == 'settleName'">
|
||||
<!-- 操作列插槽 -->
|
||||
--
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
</page-header-wrapper>
|
||||
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
API_URL_MCH_LIST,
|
||||
API_URL_PAY_ORDER_LIST,
|
||||
API_URL_PAYWAYS_LIST,
|
||||
req,
|
||||
$exportExcel,
|
||||
exportExcelUrl,
|
||||
$payOrderCount,
|
||||
API_MCH_PAY_SETTLE_LOG, API_MCH_PAY_DEFINES, $settleOrderCount, $getPayOrderRefresh, $getSettTypeSync
|
||||
} from '@/api/manage'
|
||||
import {ref, onMounted, reactive, getCurrentInstance} from 'vue'
|
||||
import fileDownload from 'js-file-download'
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
// 获取全局函数
|
||||
const { $hasMemberEnt,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const tableColumns = reactive([
|
||||
{ key: 'mchName', title: '商户名称', dataIndex: 'mchName' },
|
||||
{ key: 'ifName', title: '支付通道', dataIndex: 'ifName',},
|
||||
{ key: 'isvNo', title: '所属渠道', dataIndex: 'isvNo',},
|
||||
{ key: 'accountName', title: '结算账户',fixed: "left", dataIndex: 'accountName', align: 'center'},
|
||||
// { key: 'transactionNumber', title: '成功交易笔数', dataIndex: 'transactionNumber', align: 'center'},
|
||||
// { key: 'transactionAmount', title: '成功交易金额', dataIndex: 'transactionAmount', align: 'center'},
|
||||
// { key: 'fee', title: '交易手续费', dataIndex: 'fee', align: 'center'},
|
||||
// { key: 'cashFee', title: '垫资手续费', dataIndex: 'cashFee', align: 'center'},
|
||||
{ key: 'settleAmt', title: '结算金额(元)', dataIndex: 'settleAmt', align: 'center' },
|
||||
{ key: 'appid', title: '应用名称', dataIndex: 'appid' },
|
||||
{ key: 'settleType', title: '结算类型', dataIndex: 'settleType', align: 'center'},
|
||||
// { key: 'remark', title: '附言信息', dataIndex: 'remark' },
|
||||
{ key: 'updatedAt', dataIndex: 'updatedAt', title: '结算日期' },
|
||||
// { key: 'createdAt', dataIndex: 'createdAt', title: '结算日期' },
|
||||
{ key: 'state', title: '结算状态',fixed: "right",},
|
||||
])
|
||||
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {queryDateRange: 'today'} as any,
|
||||
visible: false,
|
||||
detailData: {} as any,
|
||||
payWayList: [] as any,
|
||||
channelList:[] as any,
|
||||
payDefines: [] as any,
|
||||
orderKeyType: 'payOrderId'
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
if ($access('ENT_PAY_ORDER_SEARCH_PAY_WAY')) {
|
||||
initPayWay()
|
||||
}
|
||||
})
|
||||
|
||||
let orderCountList:any = ref([]) // 数据统计数组
|
||||
let countDetailList: any = ref([]) // 数据统计明细数组
|
||||
// 数据统计
|
||||
const getOrderCount = () => {
|
||||
$settleOrderCount(vdata.searchData).then( res => {
|
||||
orderCountList.value = [
|
||||
{title: '成功交易金额',symbol: 'add', textColor: '#1A66FF', content: ((res.successAmount) / 100).toFixed(2), count: res.successAll},
|
||||
{type: 'line'},
|
||||
{title: '交易手续费',symbol: 'add',textColor: '#1A66FF', content: (res.feeAmount / 100).toFixed(2), count: res.feeAll},
|
||||
{type: 'line'},
|
||||
{title: '垫资手续费',symbol: 'add',textColor: '#1A66FF', content: (res.cashFeeAmount / 100).toFixed(2), count: res.cashFeeAll},
|
||||
{type: 'line'},
|
||||
{title: '结算金额', symbol: 'add',textColor: '#1A66FF', content: (res.allAmount / 100).toFixed(2), count: res.allSettle},
|
||||
{type: 'line'},
|
||||
{title: '待结算金额',symbol: 'add',textColor: '#1A66FF', content: (res.waitAmount / 100).toFixed(2), count: res.waitAll},
|
||||
]
|
||||
})
|
||||
}
|
||||
getOrderCount() // 进入页面时调用一次
|
||||
getChannelList()
|
||||
|
||||
payFefines();
|
||||
//通道
|
||||
function payFefines() {
|
||||
req.list(API_MCH_PAY_DEFINES,{ 'pageSize': -1 }).then(res => {
|
||||
vdata.payDefines = res
|
||||
})
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_MCH_PAY_SETTLE_LOG, params)
|
||||
}
|
||||
function searchFunc(){ // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
getOrderCount() // 数据统计函数
|
||||
}
|
||||
// 打开退款弹出框
|
||||
function openFunc (record, recordId) {
|
||||
if (record.refundState === 2) {
|
||||
return message.error('订单无可退款金额')
|
||||
}
|
||||
}
|
||||
function detailFunc(recordId) {
|
||||
|
||||
req.getById(API_MCH_PAY_SETTLE_LOG, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
function initPayWay () {
|
||||
req.list(API_URL_PAYWAYS_LIST, { 'pageSize': -1 }).then(res => { // 支付方式下拉列表
|
||||
vdata.payWayList = res.records
|
||||
})
|
||||
}
|
||||
function changeStr2ellipsis (orderNo, baseLength) {
|
||||
const halfLengh = baseLength / 2
|
||||
return orderNo.substring(0, halfLengh - 1) + '...' + orderNo.substring(orderNo.length - halfLengh, orderNo.length)
|
||||
}
|
||||
|
||||
function tableExportFunc(){
|
||||
return $exportExcel(exportExcelUrl.settleOrder, Object.assign({}, vdata.searchData, {'pageSize': -1})).then(res => {
|
||||
fileDownload(res.data, '结算订单列表.xlsx')
|
||||
}).catch ((error) =>{console.log(error)} )
|
||||
}
|
||||
|
||||
function onReset(){
|
||||
//重置搜索内容
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: 'today' }
|
||||
}
|
||||
|
||||
function orderKeyTypeChangeFunc() {
|
||||
vdata.searchData.payOrderId = ''
|
||||
vdata.searchData.mchOrderNo = ''
|
||||
vdata.searchData.channelOrderNo = ''
|
||||
vdata.searchData.platformMchOrderNo = ''
|
||||
vdata.searchData.platformOrderNo = ''
|
||||
}
|
||||
|
||||
function getChannelList(){
|
||||
// req.list(API_URL_MCH_APP, { 'pageSize': -1 }).then(res => { // 支付方式下拉列表
|
||||
// vdata.channelList = res.records
|
||||
// })
|
||||
}
|
||||
function getReload(data) {
|
||||
$getSettTypeSync(data.settleNo).then(res => {
|
||||
message.success('同步成功')
|
||||
infoTable.value.refTable(true)
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
.order-list {
|
||||
-webkit-text-size-adjust:none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
white-space:nowrap;
|
||||
span {
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 35px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,189 @@
|
||||
<!-- 订单详情抽屉 -->
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.isShow"
|
||||
width="50%"
|
||||
placement="right"
|
||||
:closable="true"
|
||||
title="转账订单详情"
|
||||
@close="vdata.isShow = false"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="应用APPID">{{ vdata.detailData.appId }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="转账订单号">
|
||||
<a-tag color="purple">{{ vdata.detailData.transferId }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户转账单号">{{ vdata.detailData.mchOrderNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道订单号">{{ vdata.detailData.channelOrderNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="金额">
|
||||
<a-tag color="green">{{ vdata.detailData.amount/100 }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="货币代码">{{ vdata.detailData.currency }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收款账号">
|
||||
<a-tag color="green">{{ vdata.detailData.accountNo }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收款人姓名">{{ vdata.detailData.accountName }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col v-if="typeof vdata.detailData.mchOrderFeeAmount != 'undefined'" :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="手续费">
|
||||
<a-tag color="blue">{{ vdata.detailData.mchOrderFeeAmount/100 }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="typeof vdata.detailData.mchOrderFeeAmount != 'undefined'" :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="手续费公式">
|
||||
{{ vdata.detailData.mchFeeRate }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="转账备注">{{ vdata.detailData.transferDesc }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="订单状态">
|
||||
<a-tag :color="vdata.detailData.state === 0?'blue':vdata.detailData.state === 1?'orange':vdata.detailData.state === 2?'green':'volcano'">
|
||||
{{ vdata.detailData.state === 0?'订单生成':vdata.detailData.state === 1?'转账中':vdata.detailData.state === 2?'转账成功':vdata.detailData.state === 3?'转账失败':vdata.detailData.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="转账成功时间">{{ vdata.detailData.successTime }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="创建时间">{{ vdata.detailData.createdAt }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="更新时间">{{ vdata.detailData.updatedAt }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-divider />
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="接口代码">{{ vdata.detailData.ifCode }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="入账类型">{{ vdata.detailData.entryType }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="客户端IP">{{ vdata.detailData.clientIp }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="异步通知地址">{{ vdata.detailData.notifyUrl }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道订单号">{{ vdata.detailData.channelOrderNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道错误码">{{ vdata.detailData.errCode }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道错误描述">{{ vdata.detailData.errMsg }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<span style="color: black;">渠道额外参数:</span>
|
||||
<a-form-item>
|
||||
<a-input
|
||||
v-model:value="vdata.detailData.channelExtra"
|
||||
type="textarea"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black;margin-top: 10px;"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-divider />
|
||||
<a-col :sm="24">
|
||||
<span style="color: black;">扩展参数:</span>
|
||||
<a-form-item>
|
||||
<a-input
|
||||
v-model:model="vdata.detailData.extParam"
|
||||
type="textarea"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black;margin-top: 10px;"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_TRANSFER_ORDER_LIST, req } from '@/api/manage'
|
||||
import {ref, onMounted, reactive, getCurrentInstance} from 'vue'
|
||||
// 获取全局函数
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const vdata = reactive({
|
||||
detailData: {} as any,
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
recordId: null // 更新对象ID
|
||||
})
|
||||
|
||||
defineExpose({show})
|
||||
function show (recordId) {
|
||||
req.getById(API_URL_TRANSFER_ORDER_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.isShow = true
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="queryFunc" :resetFunc="onReset">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="dateTime" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.unionOrderId" :placeholder="'转账/商户/渠道订单号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appId" :placeholder="'应用AppId'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" placeholder="转账状态">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">订单生成</a-select-option>
|
||||
<a-select-option value="1">转账中</a-select-option>
|
||||
<a-select-option value="2">转账成功</a-select-option>
|
||||
<a-select-option value="3">转账失败</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="transferId"
|
||||
:statisticsIsShow="$access('ENT_TRANSFER_ORDER_COUNT')"
|
||||
:tableExportFunc="tableExportFunc"
|
||||
:tableRowCrossColor="true"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in orderCountList" :key="index" class="item">
|
||||
<div v-if="item.type == 'line'" class="line" />
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div v-if="item.title" class="amount" :style="{color: item.textColor}">
|
||||
<span class="amount-num">{{ item.content }}</span>
|
||||
<span v-if="item.isAmount">元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key == 'amount'"><b>¥{{ record.amount/100 }}</b></template>
|
||||
|
||||
<template v-if="column.key == 'mchFeeRate' && typeof record.mchOrderFeeAmount != 'undefined'">
|
||||
<a-popover placement="top">
|
||||
<template #title> <b>¥转账手续费</b></template>
|
||||
<template #content>
|
||||
{{ record.mchFeeRate }}
|
||||
</template>
|
||||
<b>¥{{ record.mchOrderFeeAmount/100 }}</b>
|
||||
</a-popover>
|
||||
</template>
|
||||
|
||||
|
||||
<template v-if="column.key == 'state'">
|
||||
<a-tag
|
||||
:key="record.state"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':'volcano'"
|
||||
>
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'转账中':record.state === 2?'转账成功':record.state === 3?'转账失败':record.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key == 'orderNo'">
|
||||
<div class="order-list">
|
||||
<p><span style="color:#729ED5;background:#e7f5f7">转账</span>{{ record.transferId }}</p>
|
||||
<p style="margin-bottom: 0">
|
||||
<span style="color:#56cf56;background:#d8eadf">商户</span>
|
||||
<a-tooltip v-if="record.mchOrderNo.length > record.transferId.length" placement="bottom" style="font-weight: normal;">
|
||||
<template #title>
|
||||
<span>{{ record.mchOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.mchOrderNo, record.transferId.length) }}
|
||||
</a-tooltip>
|
||||
<span v-else style="font-weight: normal;">{{ record.mchOrderNo }}</span>
|
||||
</p>
|
||||
<p v-if="record.channelOrderNo" style="margin-bottom: 0;margin-top: 10px">
|
||||
<span style="color:#fff;background:#E09C4D">渠道</span>
|
||||
<a-tooltip v-if="record.channelOrderNo.length > record.transferId.length" placement="bottom" style="font-weight: normal;">
|
||||
<template #title>
|
||||
<span>{{ record.channelOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.channelOrderNo, record.transferId.length) }}
|
||||
</a-tooltip>
|
||||
<span v-else style="font-weight: normal;">{{ record.channelOrderNo }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<a-button v-if="$access('ENT_TRANSFER_ORDER_VIEW')" type="link" @click="detailFunc(record.transferId)">详情</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 订单详情 页面组件 -->
|
||||
<TransferOrderDetail ref="transferOrderDetail" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TransferOrderDetail from './TransferOrderDetail.vue'
|
||||
import { API_URL_TRANSFER_ORDER_LIST, req, $exportExcel, exportExcelUrl, $transferOrdersCount } from '@/api/manage'
|
||||
import fileDownload from 'js-file-download'
|
||||
import {ref, onMounted, reactive, getCurrentInstance} from 'vue'
|
||||
// 获取全局函数
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = reactive([
|
||||
{ key: 'orderNo', title: '订单号', width: 260 },
|
||||
{key:'amount', title: '转账金额'},
|
||||
{key:'mchFeeRate', title: '手续费'},
|
||||
// { title: '转账订单号', dataIndex: 'transferId' },
|
||||
// { title: '商户转账单号', dataIndex: 'mchOrderNo' },
|
||||
// { title: '渠道订单号', dataIndex: 'channelOrderNo' },
|
||||
{ title: '收款账号', dataIndex: 'accountNo', width: 200 },
|
||||
{ title: '收款人姓名', dataIndex: 'accountName' },
|
||||
{ title: '转账备注', dataIndex: 'transferDesc' },
|
||||
{key:'state', title: '状态', width: 100 },
|
||||
{ title: '创建日期', dataIndex: 'createdAt' },
|
||||
{key:'op', title: '操作', width: '100px', fixed: 'right', align: 'center' }
|
||||
])
|
||||
const transferOrderDetail = ref()
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
let orderCountList:any = ref([]) // 数据统计数组
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {queryDateRange: 'today'} as any,
|
||||
createdStart: '', // 选择开始时间
|
||||
createdEnd: '' // 选择结束时间
|
||||
})
|
||||
|
||||
// 数据统计
|
||||
const getOrderCount = () => {
|
||||
if(!$access('ENT_TRANSFER_ORDER_COUNT')){
|
||||
return false
|
||||
}
|
||||
|
||||
$transferOrdersCount(vdata.searchData).then( res => {
|
||||
orderCountList.value = [
|
||||
{title: '转账金额', symbol: 'add', isAmount: true, textColor: '#1A66FF', content: (res.transAmount / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '转账笔数', content: res.transCount, isAmount: false, count: res.allCount, detail: true},
|
||||
{type: 'line'},
|
||||
{title: '手续费金额',symbol: 'sub', isAmount: true, content: (res.mchOrderFeeAmount / 100).toFixed(2)},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
getOrderCount()
|
||||
function queryFunc () {
|
||||
getOrderCount()
|
||||
vdata.btnLoading = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_TRANSFER_ORDER_LIST, params)
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function detailFunc(recordId) {
|
||||
transferOrderDetail.value.show(recordId)
|
||||
}
|
||||
|
||||
function changeStr2ellipsis (orderNo, baseLength:number) {
|
||||
const halfLengh = baseLength / 2
|
||||
return orderNo.substring(0, halfLengh - 1) + '...' + orderNo.substring(orderNo.length - halfLengh, orderNo.length)
|
||||
}
|
||||
|
||||
function tableExportFunc(){
|
||||
return $exportExcel(exportExcelUrl.transferOrder, Object.assign({}, vdata.searchData, {'pageSize': -1})).then(res => {
|
||||
fileDownload(res.data, '转账订单.xlsx')
|
||||
}).catch ((error) =>{console.log(error)} )
|
||||
}
|
||||
|
||||
function onReset(){
|
||||
//重置搜索内容
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: 'today' }
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.order-list {
|
||||
-webkit-text-size-adjust:none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
white-space:nowrap;
|
||||
span {
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 35px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
21
jeepay-ui-merchant/src/views/out/index.vue
Normal file
21
jeepay-ui-merchant/src/views/out/index.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onMounted,getCurrentInstance} from 'vue'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const userStore = useUserStore()
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
onMounted(()=>{
|
||||
$infoBox.confirmDanger('是否退出登录?', `你好${userStore.userInfo['realname']}确认退出登录吗?`, () => {
|
||||
userStore.logout()
|
||||
},() => {
|
||||
window.history.go(-1);
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
|
||||
568
jeepay-ui-merchant/src/views/payTest/PayTest.vue
Normal file
568
jeepay-ui-merchant/src/views/payTest/PayTest.vue
Normal file
@@ -0,0 +1,568 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-card style="box-sizing:border-box;padding:30px">
|
||||
<!-- 选择下单的应用列表 -->
|
||||
<a-form>
|
||||
<div style="display:flex;flex-direction:row">
|
||||
<!-- <p style="margin-top:9px;margin-right:10px;"></p> -->
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<span>应用:</span>
|
||||
<a-select v-model:value="vdata.appId" style="width:300px" @change="changeAppId">
|
||||
<a-select-option key="">应用APPID</a-select-option>
|
||||
<a-select-option v-for="(item) in vdata.mchAppList" :key="item.appId">{{ item.appName }} [{{ item.appId }}]</a-select-option>
|
||||
</a-select>
|
||||
<span style="margin-left: 30px;">门店:</span>
|
||||
<a-select v-model:value="vdata.storeId" style="width:300px;">
|
||||
<a-select-option key="">选择门店</a-select-option>
|
||||
<a-select-option v-for="(item) in vdata.mchStoreList" :key="item.storeId">{{ item.storeName }} [{{ item.storeId }}]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-form>
|
||||
|
||||
<!-- 未配置支付方式提示框 -->
|
||||
<a-divider v-if="!vdata.appId">请选择应用APPID</a-divider>
|
||||
<a-divider v-else-if="vdata.noConfigText">您尚未配置任何支付方式</a-divider>
|
||||
<a-divider v-else />
|
||||
|
||||
<!-- 支付测试面板 v-if=""-->
|
||||
<div v-if="payTestShow()" style="width: 100%;" class="paydemo">
|
||||
<div class="paydemo-type-content">
|
||||
<div v-show="showTitle('WX')" class="paydemo-type-name article-title">微信支付</div>
|
||||
<div class="paydemo-type-body">
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('WX_NATIVE') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'WX_NATIVE')}"
|
||||
@click="changeCurrentWayCode('WX_NATIVE', 'codeImgUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/wx_native.svg" class="paydemo-type-img"><span class="color-change">微信二维码</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('WX_BAR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'WX_BAR')}"
|
||||
@click="changeCurrentWayCode('WX_BAR', '')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/wx_bar.svg" class="paydemo-type-img"><span class="color-change">微信条码</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('WX_JSAPI') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'WX_JSAPI')}"
|
||||
@click="changeCurrentWayCode('WX_JSAPI', 'codeImgUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/wx_jsapi.svg" class="paydemo-type-img"><span class="color-change">公众号/小程序</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('WX_H5') >= 0"
|
||||
class="paydemo-type-h5"
|
||||
:class="{this:(vdata.currentWayCode === 'WX_H5')}"
|
||||
@click="changeCurrentWayCode('WX_H5', 'payurl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/wx_h5.svg" class="paydemo-type-img"><span class="color-change">微信H5</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="showTitle('ALI')" class="paydemo-type-name article-title">支付宝支付</div>
|
||||
<div class="paydemo-type-body">
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('ALI_QR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'ALI_QR')}"
|
||||
@click="changeCurrentWayCode('ALI_QR', 'codeImgUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/ali_qr.svg" class="paydemo-type-img"><span class="color-change">支付宝二维码</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('ALI_BAR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'ALI_BAR')}"
|
||||
@click="changeCurrentWayCode('ALI_BAR', '')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/ali_bar.svg" class="paydemo-type-img"><span class="color-change">支付宝条码</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('ALI_JSAPI') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'ALI_JSAPI')}"
|
||||
@click="changeCurrentWayCode('ALI_JSAPI', 'codeImgUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/ali_jsapi.svg" class="paydemo-type-img"><span class="color-change">支付宝生活号</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('ALI_PC') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'ALI_PC')}"
|
||||
@click="changeCurrentWayCode('ALI_PC', 'payurl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/ali_pc.svg" class="paydemo-type-img"><span class="color-change">支付宝PC网站</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('ALI_WAP') >= 0"
|
||||
class="paydemo-type-h5"
|
||||
:class="{this:(vdata.currentWayCode === 'ALI_WAP')}"
|
||||
@click="changeCurrentWayCode('ALI_WAP', 'payurl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/ali_wap.svg" class="paydemo-type-img"><span class="color-change">支付宝WAP</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="showTitle('WX')" class="paydemo-type-name article-title">银联支付</div>
|
||||
<div class="paydemo-type-body">
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('UP_QR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'UP_QR')}"
|
||||
@click="changeCurrentWayCode('UP_QR', 'codeImgUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/upacp_qr.svg" class="paydemo-type-img"><span class="color-change">银联二维码</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('UP_BAR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'UP_BAR')}"
|
||||
@click="changeCurrentWayCode('UP_BAR', '')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/upacp_bar.svg" class="paydemo-type-img"><span class="color-change">银联条码</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('UP_WAP') >= 0"
|
||||
class="paydemo-type-h5"
|
||||
:class="{this:(vdata.currentWayCode === 'UP_WAP')}"
|
||||
@click="changeCurrentWayCode('UP_WAP', 'payurl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/upacp_wap.svg" class="paydemo-type-img"><span class="color-change">银联手机网站支付</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('UP_PC') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'UP_PC')}"
|
||||
@click="changeCurrentWayCode('UP_PC', 'payurl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/upacp_pc.svg" class="paydemo-type-img"><span class="color-change">银联网关支付</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('UP_B2B') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'UP_B2B')}"
|
||||
@click="changeCurrentWayCode('UP_B2B', 'payurl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/upacp_b2b.svg" class="paydemo-type-img"><span class="color-change">银联企业网银支付</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('YSF_JSAPI') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'YSF_JSAPI')}"
|
||||
@click="changeCurrentWayCode('YSF_JSAPI', 'codeImgUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/upacp_qr.svg" class="paydemo-type-img"><span class="color-change">云闪付JS</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('YSF_BAR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'YSF_BAR')}"
|
||||
@click="changeCurrentWayCode('YSF_BAR', '')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/upacp_bar.svg" class="paydemo-type-img"><span class="color-change">云闪付条码</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="showQtTitle()" class="paydemo-type-name article-title">数字人民币</div>
|
||||
<div class="paydemo-type-body">
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('DCEP_BAR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'DCEP_BAR')}"
|
||||
@click="changeCurrentWayCode('DCEP_BAR', 'codeImgUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/dcep_bar.svg" class="paydemo-type-img"><span class="color-change">数币条码</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('DCEP_QR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'DCEP_QR')}"
|
||||
@click="changeCurrentWayCode('DCEP_QR', 'codeImgUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/dcep_qr.svg" class="paydemo-type-img"><span class="color-change">数币二维码</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="showQtTitle()" class="paydemo-type-name article-title">其它支付</div>
|
||||
<div class="paydemo-type-body">
|
||||
<div
|
||||
v-if="vdata.webCashierIsShow"
|
||||
v-show="vdata.appPaywayList.length > 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'WEB_CASHIER')}"
|
||||
@click="changeCurrentWayCode('WEB_CASHIER', 'payUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/web_cashier.svg" class="paydemo-type-img"><span class="color-change">WEB统一收银台</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('WX_JSAPI') >= 0 || vdata.appPaywayList.indexOf('ALI_JSAPI') >= 0 || vdata.appPaywayList.indexOf('YSF_JSAPI') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'QR_CASHIER')}"
|
||||
@click="changeCurrentWayCode('QR_CASHIER', 'codeImgUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/qr_cashier.svg" class="paydemo-type-img"><span class="color-change">聚合主扫</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('WX_BAR') >= 0 || vdata.appPaywayList.indexOf('ALI_BAR') >= 0 || vdata.appPaywayList.indexOf('UP_BAR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'AUTO_BAR')}"
|
||||
@click="changeCurrentWayCode('AUTO_BAR', 'codeImgUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/auto_bar.svg" class="paydemo-type-img"><span class="color-change">聚合被扫</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('AUTO_POS') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'AUTO_POS')}"
|
||||
@click="changeCurrentWayCode('AUTO_POS', '')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/auto_pos.svg" class="paydemo-type-img"><span class="color-change">智能POS</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('PP_PC') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'PP_PC')}"
|
||||
@click="changeCurrentWayCode('PP_PC', 'payurl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/pp_pc.svg" class="paydemo-type-img"><span class="color-change">PayPal支付</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.length > 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'CHANNEL_CASHIER')}"
|
||||
@click="changeCurrentWayCode('CHANNEL_CASHIER', 'payUrl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/web_cashier.svg" class="paydemo-type-img"><span class="color-change">渠道收银台</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-divider />
|
||||
<!-- 订单信息 -->
|
||||
<div class="paydemo-type-content">
|
||||
<div class="paydemo-type-name article-title">支付信息</div>
|
||||
<form class="layui-form">
|
||||
<div class="paydemo-form-item">
|
||||
<label>订单编号:</label><span id="payMchOrderNo">{{ vdata.mchOrderNo }}</span>
|
||||
<span class=" paydemo-btn" style="padding:0 3px" @click="randomOrderNo">刷新订单号</span>
|
||||
</div>
|
||||
<div class="paydemo-form-item">
|
||||
<label>订单标题:</label>
|
||||
<a-input v-model:value="vdata.orderTitle" style="width: 200px" />
|
||||
</div>
|
||||
|
||||
<div class="paydemo-form-item">
|
||||
<label>分账方式:</label>
|
||||
<a-radio-group v-model:value="vdata.divisionMode" style="display:flex">
|
||||
<div style="display:flex">
|
||||
<a-radio :value="0">订单不分账</a-radio>
|
||||
<a-radio :value="1">支付完成自动分账(需包含自动分账接收方)</a-radio>
|
||||
<a-radio :value="2">手动分账(冻结商户资金, 只能通过API发起分账后解冻)</a-radio>
|
||||
</div>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
|
||||
<a-divider />
|
||||
|
||||
<div class="paydemo-form-item">
|
||||
<span>支付金额(元):</span>
|
||||
|
||||
<a-radio-group v-model:value="vdata.divisionMode1" name="radioGroup" :default-value="0.01" style="display:flex">
|
||||
<div style="display:flex" @click="vdata.amountInput=false">
|
||||
<a-radio :value="0.01" @click="vdata.paytestAmount=0.01">¥0.01</a-radio>
|
||||
<a-radio :value="0.15" @click="vdata.paytestAmount=0.15">¥0.15</a-radio>
|
||||
<a-radio :value="0.21" @click="vdata.paytestAmount=0.21">¥0.21</a-radio>
|
||||
<a-radio :value="0.29" @click="vdata.paytestAmount=0.29">¥0.29</a-radio>
|
||||
<a-radio :value="0.64" @click="vdata.paytestAmount=0.64">¥0.64</a-radio>
|
||||
</div>
|
||||
<a-radio @click="amountInputShow">
|
||||
<span style="margin-right:3px">自定义金额</span>
|
||||
<a-input-number
|
||||
v-show="vdata.amountInput"
|
||||
ref="amountInputFocus"
|
||||
v-model:value="vdata.paytestAmount"
|
||||
:max="100000"
|
||||
:min="0.01"
|
||||
:precision="2"
|
||||
/>
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:20px;text-align: left">
|
||||
<!-- <span style="color: #FD482C;font-size: 18px;padding-right: 10px;" id="amountShow">{{ paytestAmount }}</span> -->
|
||||
<a-button v-if="$access('ENT_MCH_PAY_TEST_DO')" style="padding:5px 20px;background-color: #1953ff;border-radius: 5px;color:#fff" @click="immediatelyPay">立即支付</a-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
<!-- 二维码弹窗 -->
|
||||
<pay-test-modal ref="payTestModal" @closeBarCode="closeBarCodeFunc" />
|
||||
|
||||
<!-- 条码弹框 -->
|
||||
<pay-test-bar-code ref="payTestBarCode" @barCodeValue="barCodeChange" />
|
||||
|
||||
<!-- 智能POS弹框 -->
|
||||
<pay-test-auto-pos ref="payTestAutoPos" @autoPosBizData="autoPosBizDataSelected" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_APP, API_URL_MCH_STORE_LIST, req, $payTest, $payTestOrder } from '@/api/manage' // 接口
|
||||
import PayTestModal from './PayTestModal.vue' // 二维码对话框组件
|
||||
import PayTestBarCode from './PayTestBarCode.vue' // 条码对话框组件
|
||||
import PayTestAutoPos from './PayTestAutoPos.vue' // 智能POS对话框组件
|
||||
import {ref, onMounted, reactive, getCurrentInstance,nextTick} from 'vue'
|
||||
import {useRoute} from 'vue-router'
|
||||
// 获取全局函数
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
const route = useRoute()
|
||||
const vdata = reactive({
|
||||
mchAppList: [] as any, // app列表
|
||||
mchStoreList: [] as any, // 门店列表
|
||||
appId: '', // 已选择的appId
|
||||
storeId: '', // 已选择的门店ID
|
||||
appPaywayList: [] as any, // 商户app支持的支付方式
|
||||
currentWayCode: '', // 以何种方式进行支付,默认是微信二维码
|
||||
currentPayDataType: '', // 支付参数
|
||||
mchOrderNo: '', // 模拟商户订单号
|
||||
authCode: '', // 条码的值
|
||||
autoPosExtra: {}, // 智能POS参数
|
||||
paytestAmount: 0.01, // 支付金额,默认为0.01
|
||||
amountInput: false, // 自定金额输入框是否展示
|
||||
noConfigText: false, // 尚无任何配置分割线提示文字
|
||||
divisionMode: 0, // 订单分账模式
|
||||
orderTitle: '接口调试', // 订单标题
|
||||
divisionMode1:0.01, //默认支付金额绑定
|
||||
webCashierIsShow: true // 是否显示web统一收银台
|
||||
|
||||
})
|
||||
const payTestBarCode =ref()
|
||||
const payTestModal = ref()
|
||||
const payTestAutoPos = ref()
|
||||
const amountInputFocus = ref()
|
||||
onMounted(()=>{
|
||||
// 获取传入的参数,如果参数存在,则为appId 重新赋值
|
||||
const appId = route.params.appId as string
|
||||
console.log(appId)
|
||||
|
||||
if (appId) {
|
||||
vdata.appId = appId // appId赋值
|
||||
|
||||
appPaywayListHandle(appId) // 调用appPaywayListHandle,展示支付方式
|
||||
}
|
||||
|
||||
|
||||
// 请求接口,获取所有的appid,只有此处进行pageSize=-1传参
|
||||
req.list(API_URL_MCH_APP, { pageSize: -1 }).then(res => {
|
||||
vdata.mchAppList = res.records
|
||||
if (vdata.mchAppList.length > 0) {
|
||||
// 赋予默认值
|
||||
//vdata.appId = vdata.mchAppList[0].appId
|
||||
//TODO
|
||||
if(vdata.appId == '') vdata.appId = vdata.mchAppList[0].appId
|
||||
console.log(vdata.appId)
|
||||
|
||||
// 根据appId的值,动态显示支付方式
|
||||
appPaywayListHandle(vdata.appId)
|
||||
}
|
||||
})
|
||||
|
||||
// 请求接口,获取商户所有门店,只有次数进行pageSize=-1传参
|
||||
req.list(API_URL_MCH_STORE_LIST, { pageSize: -1 }).then(res => {
|
||||
vdata.mchStoreList = res.records
|
||||
if (vdata.mchStoreList.length > 0) {
|
||||
// 赋予默认值
|
||||
if(vdata.storeId == '') vdata.storeId = vdata.mchStoreList[0].storeId
|
||||
}
|
||||
})
|
||||
|
||||
// 在进入页面时刷新订单号
|
||||
randomOrderNo()
|
||||
})
|
||||
|
||||
|
||||
// 支付板块是否展示
|
||||
function payTestShow () {
|
||||
// 如果未选择appid,或者支付方式列表为0,则不显示支付体验板块
|
||||
if (vdata.appId === '' || vdata.appPaywayList.length === 0) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function changeCurrentWayCode (wayCode, currentPayDataType) { // 切换支付方式
|
||||
vdata.currentWayCode = wayCode
|
||||
vdata.currentPayDataType = currentPayDataType
|
||||
}
|
||||
|
||||
// 变更 appId的事件
|
||||
function changeAppId (value) {
|
||||
appPaywayListHandle(value) // 根据appId的值,动态显示支付方式
|
||||
}
|
||||
|
||||
// 刷新订单号
|
||||
function randomOrderNo () {
|
||||
vdata.mchOrderNo = 'M' + new Date().getTime() + Math.floor(Math.random() * (9999 - 1000) + 1000)
|
||||
}
|
||||
|
||||
// 获取条码的值
|
||||
function barCodeChange (value) {
|
||||
vdata.authCode = value
|
||||
immediatelyPay()
|
||||
}
|
||||
|
||||
// 获取智能pos参数
|
||||
function autoPosBizDataSelected (value) {
|
||||
vdata.autoPosExtra = value
|
||||
immediatelyPay()
|
||||
}
|
||||
|
||||
// 根据不同的appId展示不同的支付方式(在下拉框切换时和在携带参数进入页面时调用)
|
||||
function appPaywayListHandle (value) {
|
||||
if (!value) {
|
||||
vdata.appPaywayList = []
|
||||
return false
|
||||
}
|
||||
|
||||
$payTest(value).then(res => {
|
||||
vdata.appPaywayList = res.payWaySet
|
||||
vdata.webCashierIsShow = res.webCashierIsShow
|
||||
if (res.payWaySet.length === 0) {
|
||||
vdata.noConfigText = true
|
||||
} else {
|
||||
vdata.noConfigText = false
|
||||
}
|
||||
})
|
||||
}
|
||||
// 立即支付按钮
|
||||
function immediatelyPay () {
|
||||
// 判断支付金额是否为0
|
||||
if (!vdata.paytestAmount || vdata.paytestAmount === 0.00) {
|
||||
return $infoBox.message.error('请输入支付金额')
|
||||
}
|
||||
|
||||
// 判断是否选择支付方式
|
||||
if (vdata.currentWayCode === '') {
|
||||
return $infoBox. message.error('请选择支付方式')
|
||||
}
|
||||
|
||||
// 判断是否选择门店
|
||||
if (vdata.storeId === '') {
|
||||
return $infoBox. message.error('请选择一个门店')
|
||||
}
|
||||
|
||||
// 请输入订单标题
|
||||
if (!vdata.orderTitle || vdata.orderTitle.length > 20) {
|
||||
return $infoBox. message.error('请输入正确的订单标题[20字以内]')
|
||||
}
|
||||
|
||||
// 判断是否为条码支付
|
||||
if (!payTestBarCode.value.getVisible() && (vdata.currentWayCode === 'WX_BAR' || vdata.currentWayCode === 'ALI_BAR'
|
||||
|| vdata.currentWayCode === 'UP_BAR' || vdata.currentWayCode === 'YSF_BAR' || vdata.currentWayCode === 'AUTO_BAR' || vdata.currentWayCode === 'DCEP_BAR')) {
|
||||
payTestBarCode.value.showModal()
|
||||
return
|
||||
}
|
||||
|
||||
// 判断是否为智能POS
|
||||
if (!payTestAutoPos.value.getVisible() && vdata.currentWayCode === 'AUTO_POS') {
|
||||
payTestAutoPos.value.showModal(vdata.appId)
|
||||
return
|
||||
}
|
||||
|
||||
$payTestOrder({
|
||||
// jsapi 默认使用聚合二维码支付
|
||||
wayCode: (vdata.currentWayCode === 'WX_JSAPI' || vdata.currentWayCode === 'ALI_JSAPI' || vdata.currentWayCode === 'YSF_JSAPI') ? 'QR_CASHIER' : vdata.currentWayCode, // 支付方式
|
||||
amount: vdata.paytestAmount, // 支付金额
|
||||
appId: vdata.appId, // appId
|
||||
storeId: vdata.storeId, // storeId
|
||||
mchOrderNo: vdata.mchOrderNo, // 订单编号
|
||||
payDataType: vdata.currentPayDataType, // 支付参数(二维码,条码)
|
||||
authCode: vdata.authCode,
|
||||
divisionMode: vdata.divisionMode,
|
||||
orderTitle: vdata.orderTitle,
|
||||
autoPosExtra: vdata.autoPosExtra
|
||||
}).then(res => {
|
||||
payTestModal.value.showModal(vdata.currentWayCode, res) // 打开弹窗
|
||||
randomOrderNo() // 刷新订单号
|
||||
}).catch(() => {
|
||||
payTestBarCode.value.processCatch()
|
||||
randomOrderNo() // 刷新订单号
|
||||
})
|
||||
}
|
||||
|
||||
// 此处判断,微信,支付宝,聚合码,哪种支付方式一个都没配置,如果未配置,则不显示该板块,若等于-1 则表示不存在
|
||||
function showTitle (parameterA) {
|
||||
if (vdata.appPaywayList.toString().indexOf(parameterA) === -1) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// 其它支付标题显示
|
||||
function showQtTitle () {
|
||||
if (vdata.appPaywayList.toString().indexOf('WX') !== -1 || vdata.appPaywayList.toString().indexOf('ALI') !== -1 || vdata.appPaywayList.toString().indexOf('PP') !== -1) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义金额输入框是否展示
|
||||
function amountInputShow () {
|
||||
nextTick(() => { // 输入框默认展示焦点
|
||||
amountInputFocus.value.focus()
|
||||
})
|
||||
vdata.amountInput = true
|
||||
vdata.paytestAmount = 0
|
||||
}
|
||||
|
||||
// handleCloseBarCode () {
|
||||
// this.$refs.payTestBarCode.visible = false
|
||||
// }
|
||||
|
||||
function closeBarCodeFunc(){
|
||||
if(payTestBarCode.value){
|
||||
payTestBarCode.value.closeVisible()
|
||||
}
|
||||
|
||||
if(payTestAutoPos.value){
|
||||
payTestAutoPos.value.closeVisible()
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="css">
|
||||
@import './payTest.css';
|
||||
</style>
|
||||
158
jeepay-ui-merchant/src/views/payTest/PayTestAutoPos.vue
Normal file
158
jeepay-ui-merchant/src/views/payTest/PayTestAutoPos.vue
Normal file
@@ -0,0 +1,158 @@
|
||||
<!-- 等待支付的弹层: -->
|
||||
<template>
|
||||
<div>
|
||||
<a-modal
|
||||
v-model:visible="vdata.visible"
|
||||
title="智能POS支付"
|
||||
:footer="null"
|
||||
width="80%"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :span="9" :offset="1">
|
||||
<a-form-item label="支付渠道">
|
||||
<a-radio-group v-model:value="vdata.channelExtra.channelType">
|
||||
<a-radio value="SCAN">扫一扫</a-radio>
|
||||
<a-radio value="CARD">银行卡</a-radio>
|
||||
<a-radio value="QRCODE">付款码</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<a-form-item label="支付方式">
|
||||
<a-radio-group v-model:value="vdata.channelExtra.payType">
|
||||
<a-radio value="ALIPAY">支付宝</a-radio>
|
||||
<a-radio value="WECHAT">微信</a-radio>
|
||||
<a-radio value="UNIONPAY">银联钱包</a-radio>
|
||||
<a-radio value="QR_CASHIER">聚合码</a-radio>
|
||||
<a-radio value="DCEP">数字人民币</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-card class="table-card">
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:rowSelection="{ type: 'radio', selectedRowKeys: vdata.selectedRowKeys, onChange: infoTableSelectChangeFunc }"
|
||||
:customRow="customRow"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'provider'">
|
||||
<a-tag :key="record.provider" color="processing">
|
||||
{{ (vdata.ifCodeList.find(item => item.ifCode == record.provider) as any)?.ifName || '其他' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
|
||||
<div style="display:flex;flex-direction:row;justify-content: center;margin-bottom:14px;">
|
||||
<a-button type="primary" style="margin-left:10px;" :loading="vdata.loading" @click="handleOk">确认支付</a-button>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, API_URL_IFDEFINES_LIST, req, $getAvailablePayInterfaceList } from '@/api/manage'
|
||||
import { dataTool } from 'echarts'
|
||||
import { ref, nextTick, reactive, onMounted } from 'vue'
|
||||
|
||||
const emit = defineEmits(['autoPosBizData'])
|
||||
|
||||
const infoTable = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
visible: false,
|
||||
selectedRowKeys: [],
|
||||
channelExtra: {
|
||||
deviceNo: '', // 设备号
|
||||
channelType: 'SCAN', // 支付渠道
|
||||
payType: 'ALIPAY', // 支付方式
|
||||
} as any,
|
||||
ifCodeList: [], // 通道列表
|
||||
}) as any
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ title: '设备号', dataIndex: 'deviceNo', key: 'deviceNo' },
|
||||
{ key: 'provider', title: '所属支付接口', dataIndex: 'provider'},
|
||||
{ title: '设备名称', dataIndex: 'deviceName', },
|
||||
{ title: '门店编号', dataIndex: 'storeId',},
|
||||
{ key: 'appId', dataIndex: 'appId', title: '应用ID', }
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
req.list(API_URL_IFDEFINES_LIST, { 'state': 1 }).then(res => { // 通道下拉选择列表
|
||||
vdata.ifCodeList = res.filter(r => r.wayCodes.some(s => s.wayCode == 'AUTO_POS'))
|
||||
})
|
||||
})
|
||||
|
||||
function reqTableDataFunc(params: any) { // 请求table接口数据
|
||||
return req.list(API_URL_STORE_DEVICE, Object.assign({ deviceType: 4, bindState: 1, state: 1, provider: vdata.ifCode ? vdata.ifCode : -1 }, params))
|
||||
}
|
||||
|
||||
function showModal (appId) {
|
||||
vdata.loading = false
|
||||
vdata.visible = true
|
||||
|
||||
// 请求支付通道数据
|
||||
$getAvailablePayInterfaceList(appId, 'AUTO_POS').then(r => {
|
||||
const channel = r.records.find(item => item.configState == 1)
|
||||
if(channel) {
|
||||
vdata.ifCode = channel.ifCode
|
||||
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 按钮的点击事件,当使用扫码设备扫码后,也会自动吊起该事件
|
||||
function handleOk () {
|
||||
if (vdata.barCodeValue === '') {
|
||||
return
|
||||
}
|
||||
|
||||
vdata.loading = true
|
||||
emit('autoPosBizData', vdata.channelExtra)
|
||||
}
|
||||
function infoTableSelectChangeFunc(e, record) {
|
||||
const selectRecord = record[0]
|
||||
vdata.selectedRowKeys = []
|
||||
vdata.selectedRowKeys.push(selectRecord.deviceId)
|
||||
|
||||
vdata.channelExtra.deviceNo = selectRecord.deviceNo
|
||||
}
|
||||
function customRow(record) {
|
||||
return {
|
||||
onClick: () => {
|
||||
infoTableSelectChangeFunc(null, [record])
|
||||
},
|
||||
}
|
||||
}
|
||||
function getVisible () {
|
||||
return vdata.visible
|
||||
}
|
||||
function processCatch () {
|
||||
vdata.loading = false
|
||||
}
|
||||
function closeVisible(){
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({showModal,getVisible,processCatch, closeVisible})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.describe {
|
||||
img {
|
||||
width: 30px;
|
||||
height: 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
68
jeepay-ui-merchant/src/views/payTest/PayTestBarCode.vue
Normal file
68
jeepay-ui-merchant/src/views/payTest/PayTestBarCode.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<!-- 条码支付的弹层 -->
|
||||
<template>
|
||||
<div>
|
||||
<a-modal
|
||||
v-model:visible="vdata.visible"
|
||||
title="条码支付"
|
||||
:footer="null"
|
||||
:width="350"
|
||||
>
|
||||
<div>
|
||||
<p>请输入用户条形码:</p>
|
||||
<div style="display:flex;flex-direction:row;margin-bottom:14px;">
|
||||
<a-input ref="barCodeInput" v-model:value="vdata.barCodeValue" @keyup.enter="handleOk" />
|
||||
<a-button type="primary" style="margin-left:10px;" :loading="vdata.loading" @click="handleOk">确认支付</a-button>
|
||||
</div>
|
||||
<p>或者使用(扫码枪/扫码盒)扫码:</p>
|
||||
<div style="text-align:center">
|
||||
<img src="@/assets/payTestImg/scan.svg" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {ref, onMounted, reactive, getCurrentInstance,nextTick} from 'vue'
|
||||
// 获取全局函数
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const barCodeInput =ref()
|
||||
const emit = defineEmits(['barCodeValue','CodeAgainChange'])
|
||||
const vdata = reactive({
|
||||
visible: false,
|
||||
barCodeValue: '', // 条码的值
|
||||
loading: false // 按钮的loading状态
|
||||
})
|
||||
|
||||
|
||||
defineExpose({showModal,getVisible,processCatch, closeVisible})
|
||||
function showModal () {
|
||||
vdata.loading = false
|
||||
vdata.barCodeValue = ''// 清空条码的值
|
||||
vdata.visible = true
|
||||
nextTick(() => { // 弹窗展示后,输入框默认展示焦点
|
||||
barCodeInput.value.focus()
|
||||
})
|
||||
}
|
||||
|
||||
// 按钮的点击事件,当使用扫码设备扫码后,也会自动吊起该事件
|
||||
function handleOk () {
|
||||
if (vdata.barCodeValue === '') {
|
||||
return
|
||||
}
|
||||
|
||||
// 传递条码值给父组件
|
||||
vdata.loading = true
|
||||
emit('barCodeValue', vdata.barCodeValue)
|
||||
}
|
||||
function getVisible () {
|
||||
return vdata.visible
|
||||
}
|
||||
function processCatch () {
|
||||
vdata.loading = false
|
||||
}
|
||||
|
||||
function closeVisible(){
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
</script>
|
||||
162
jeepay-ui-merchant/src/views/payTest/PayTestModal.vue
Normal file
162
jeepay-ui-merchant/src/views/payTest/PayTestModal.vue
Normal file
@@ -0,0 +1,162 @@
|
||||
<!-- 等待支付的弹层: -->
|
||||
<template>
|
||||
<div>
|
||||
<a-modal v-model:visible="vdata.visible" title="等待支付" :footer="null" :width="300" @ok="handleClose">
|
||||
<div style="width:100%;margin-bottom:20px;text-align:center">
|
||||
<img v-if="vdata.apiRes.payDataType == 'codeImgUrl'" :src="vdata.apiRes.payData" alt="">
|
||||
<span v-else-if="vdata.apiRes.payDataType == 'payurl'">等待用户支付
|
||||
<hr> 如浏览器未正确跳转请点击: <a :href="vdata.apiRes.payData" target="_blank">支付地址</a>
|
||||
<a-button size="small" class="copy-btn" @click="onCopy">复制链接</a-button>
|
||||
</span>
|
||||
<span v-else>等待用户支付,请稍后</span>
|
||||
</div>
|
||||
<p class="describe">
|
||||
<img v-show="vdata.wxApp" src="@/assets/payTestImg/wx_app.svg" alt=""><!-- 微信图标 -->
|
||||
<img v-show="vdata.aliApp" src="@/assets/payTestImg/ali_app.svg" alt=""><!-- 支付宝图标 -->
|
||||
<span>{{ vdata.payText }}</span>
|
||||
</p>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import ReconnectingWebSocket from 'reconnectingwebsocket'
|
||||
import { $getWebSocketPrefix } from '@/api/manage'
|
||||
import {ref, onMounted, reactive, getCurrentInstance} from 'vue'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import useClipboard from 'vue-clipboard3'
|
||||
// 获取全局函数
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const { toClipboard } = useClipboard()
|
||||
const vdata = reactive({
|
||||
visible: false,
|
||||
payText: '', // 二维码底部描述文字
|
||||
wxApp: false, // 微信二维码图片是否展示
|
||||
aliApp: false, // 支付宝二维码图片是否展示
|
||||
apiRes: {} as any, // 接口返回数据包
|
||||
payOrderWebSocket: null as any// 支付订单webSocket对象
|
||||
})
|
||||
const emit = defineEmits(['closeBarCode'])
|
||||
|
||||
function onCopy () {
|
||||
// $infoBox.message.success('复制成功')
|
||||
const Msg = vdata.apiRes.payData
|
||||
copy(Msg)
|
||||
}
|
||||
|
||||
const copy = async (Msg) => {
|
||||
try {
|
||||
//复制
|
||||
await toClipboard(Msg)
|
||||
console.log(Msg,123)
|
||||
//下面可以设置复制成功的提示框等操作
|
||||
$infoBox.message.success('复制成功')
|
||||
} catch (e) {
|
||||
//复制失败
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
defineExpose({showModal})
|
||||
// 二维码以及条码弹窗
|
||||
function showModal (wayCode, apiRes) {
|
||||
// 关闭上一个webSocket监听
|
||||
if (vdata.payOrderWebSocket) {
|
||||
vdata.payOrderWebSocket.close()
|
||||
}
|
||||
vdata.apiRes = apiRes
|
||||
vdata.wxApp = false
|
||||
vdata.aliApp = false
|
||||
vdata.visible = true // 打开弹窗
|
||||
|
||||
// 根据不同的支付方式,展示不同的信息
|
||||
vdata.payText = ''
|
||||
if (wayCode === 'WX_NATIVE' || wayCode === 'WX_JSAPI') { // 微信二维码
|
||||
vdata.wxApp = true
|
||||
vdata.payText = '请使用微信"扫一扫"扫码支付'
|
||||
} else if (wayCode === 'ALI_QR' || wayCode === 'ALI_JSAPI') { // 支付宝二维码
|
||||
vdata.aliApp = true
|
||||
vdata.payText = '请使用支付宝"扫一扫"扫码支付'
|
||||
} else if (wayCode === 'YSF_JSAPI') { // 云闪付二维码
|
||||
vdata.payText = '请使用云闪付"扫一扫"扫码支付'
|
||||
} else if (wayCode === 'QR_CASHIER') { // 聚合支付二维码
|
||||
vdata.wxApp = true
|
||||
vdata.aliApp = true
|
||||
vdata.payText = '支持微信、支付宝扫码'
|
||||
}
|
||||
|
||||
// 此处判断接口中返回的orderState,值为0,1 代表支付中,直接放行无需处理,2 成功 3 失败
|
||||
if (apiRes.orderState === 2 || apiRes.orderState === 3) {
|
||||
if (apiRes.orderState === 2) {
|
||||
handleClose()
|
||||
const succModal = Modal.success({
|
||||
title:'支付成功',
|
||||
content:'2秒后自动关闭'
|
||||
})
|
||||
// message.success('支付成功')
|
||||
setTimeout(() => { succModal.destroy() }, 2000)
|
||||
emit('closeBarCode') // 关闭条码框
|
||||
} else if (apiRes.orderState === 3) {
|
||||
|
||||
handleClose()
|
||||
Modal.error({
|
||||
title:'支付失败',
|
||||
content:`错误码:${apiRes.errCode} ,错误描述:${apiRes.errMsg} `
|
||||
})
|
||||
// message.error(`支付失败,${apiRes.errCode}`)
|
||||
emit('closeBarCode') // 关闭条码框
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// h5 或者 wap
|
||||
if (wayCode === 'WX_H5' || wayCode === 'ALI_WAP') {
|
||||
vdata.payText = '请复制链接到手机端打开'
|
||||
} else {
|
||||
// 跳转到PC网站
|
||||
if (apiRes.payDataType === 'payurl') {
|
||||
window.open(apiRes.payData)
|
||||
}
|
||||
}
|
||||
|
||||
// 如果上面未关闭条码框,则代表进入webScoket,那么先在此处关闭条码框
|
||||
emit('closeBarCode') // 关闭条码框
|
||||
// 监听响应结果
|
||||
vdata.payOrderWebSocket = new ReconnectingWebSocket($getWebSocketPrefix() + '/api/anon/ws/payOrder/' + apiRes.payOrderId + '/' + new Date().getTime())
|
||||
vdata.payOrderWebSocket.onopen = () => {}
|
||||
vdata.payOrderWebSocket.onmessage = (msgObject) => {
|
||||
const resMsgObject = JSON.parse(msgObject.data)
|
||||
console.log(resMsgObject,'msgObjectmsgObject')
|
||||
if (resMsgObject.state === 2) {
|
||||
handleClose()
|
||||
// const succModal = $infoBox.modalSuccess('支付成功', '2s后自动关闭')
|
||||
const succModal = Modal.success({
|
||||
title:'支付成功',
|
||||
content:'2秒后自动关闭'
|
||||
})
|
||||
setTimeout(() => { succModal.destroy() }, 2000)
|
||||
} else {
|
||||
handleClose()
|
||||
// TODO 待更改 that.$infoBox.modalError('支付失败', <div><div>错误码:{ apiRes.errCode}</div>
|
||||
Modal.error({
|
||||
title:'支付失败',
|
||||
content:`错误码:${apiRes.errCode} ,错误描述:${apiRes.errMsg} `
|
||||
})
|
||||
// message.error(`支付失败,${apiRes.errCode}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
function handleClose () {
|
||||
if (vdata.payOrderWebSocket) {
|
||||
vdata.payOrderWebSocket.close()
|
||||
}
|
||||
vdata.visible = false
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.describe {
|
||||
img {
|
||||
width: 30px;
|
||||
height: 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
128
jeepay-ui-merchant/src/views/payTest/payTest.css
Normal file
128
jeepay-ui-merchant/src/views/payTest/payTest.css
Normal file
@@ -0,0 +1,128 @@
|
||||
.paydemo .content {
|
||||
max-width: 1120px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.paydemo .paydemo-type-content {
|
||||
padding:20px 0;
|
||||
margin-bottom:20px;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.paydemo .paydemo-type-name {
|
||||
font-size: 16px;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.paydemo .paydemo-type-body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.paydemo .paydemo-type {
|
||||
padding: 12px;
|
||||
border: solid 1px #e2e2e2;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.paydemo .paydemo-type-h5 {
|
||||
padding: 12px;
|
||||
border: solid 1px #e2e2e2;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.paydemo .codeImg_wx_h5 {
|
||||
position: absolute;
|
||||
z-index:1001;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: #ffffff;
|
||||
width: 160px;
|
||||
}
|
||||
.paydemo .paydemo-type-img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
vertical-align: center;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.paydemo .this {
|
||||
color: #1953ff;
|
||||
border-color: #1953ff;
|
||||
}
|
||||
.paydemo .layui-input {
|
||||
width: 50%;
|
||||
display: inline;
|
||||
font-size: 14px;
|
||||
}
|
||||
.paydemo .paydemo-form-item {
|
||||
height: 38px;
|
||||
margin-bottom: 5px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.paydemo .layui-form-radio i:hover, .layui-form-radioed i {
|
||||
color: #1953ff;
|
||||
}
|
||||
.paydemo .layui-anim.layui-icon {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.paydemo .layui-form-radio {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.paydemo .paydemo-scan {
|
||||
padding-top: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.paydemo .layui-laypage .layui-laypage-curr .layui-laypage-em {
|
||||
background-color: #1953ff;
|
||||
}
|
||||
.paydemo .layui-laypage a:hover {
|
||||
color: #1953ff;
|
||||
}
|
||||
.paydemo-type-content p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.paydemo .layui-table-view .layui-table {
|
||||
width: 100%;
|
||||
}
|
||||
.paydemo .paydemo-btn {
|
||||
border: 1px solid #e2e2e2;
|
||||
background-color: #ffffff;
|
||||
color:#000000;
|
||||
margin-left: 8px;
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.paydemo #paydemo-amount {
|
||||
display: flex;
|
||||
align-items: inherit;
|
||||
}
|
||||
.paydemo #paydemo-amount .layui-unselect{
|
||||
margin-right:15px
|
||||
}
|
||||
|
||||
#randomOrderNo:hover {
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.paydemo-form-item label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right:15px;
|
||||
flex-wrap:wrap
|
||||
}
|
||||
.paydemo-form-item label input {
|
||||
margin-left:3px;
|
||||
}
|
||||
|
||||
.paydemo .article-title {
|
||||
font-weight: 600
|
||||
}
|
||||
149
jeepay-ui-merchant/src/views/paydf/aqf/List.vue
Normal file
149
jeepay-ui-merchant/src/views/paydf/aqf/List.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<SybAqfList configMode="mch" title="资金账户" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {req} from '@/api/manage'
|
||||
import { ref, onMounted, reactive, getCurrentInstance, nextTick } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { dataTool } from 'echarts'
|
||||
|
||||
const router = useRouter() //这是全部路由
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.div-top {
|
||||
background: #ffffff;
|
||||
padding: 20px 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.div-top-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.div-top-des {
|
||||
color: #2C6EF6;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.div-top-line {
|
||||
border-bottom: 1px solid #EDEDED;
|
||||
}
|
||||
|
||||
.div-top-status {
|
||||
display: flex;
|
||||
margin: 18px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.div-top-status-title {
|
||||
padding-right: 10px;
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.div-top-status-title-span {
|
||||
padding: 0 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.div-top-active {
|
||||
color: #2C6EF6;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*列表 */
|
||||
.product {
|
||||
background: #ffffff;
|
||||
padding: 0 20px;
|
||||
border-radius: 10px;
|
||||
margin-top: 20px;
|
||||
;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.product-list {
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.product-list-li {
|
||||
background: #F9FAFA;
|
||||
width: 30%;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.product-list-li-span1 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.product-list-li-span2 {
|
||||
font-size: 13px;
|
||||
color: #2C6EF6;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.product-list-li-desc {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.product-list-li-span3 {
|
||||
font-size: 13px;
|
||||
color: #767676;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* 在超出时显示省略号 */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
/* 限制显示的行数为2行 */
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.color-e3 {
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.color-yellow {
|
||||
color: rgb(250, 118, 0);
|
||||
}
|
||||
|
||||
.color-red {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
.color-blue {
|
||||
color: #2C6EF6;
|
||||
}
|
||||
|
||||
.color-cancel {
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.table-card-bottom {
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
|
||||
.table-card-hide {
|
||||
display: none;
|
||||
}</style>
|
||||
149
jeepay-ui-merchant/src/views/paydf/aqf/settleStatistics.vue
Normal file
149
jeepay-ui-merchant/src/views/paydf/aqf/settleStatistics.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<SybSettleListStatics configMode="mch" title="结算数据" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {req} from '@/api/manage'
|
||||
import { ref, onMounted, reactive, getCurrentInstance, nextTick } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { dataTool } from 'echarts'
|
||||
|
||||
const router = useRouter() //这是全部路由
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.div-top {
|
||||
background: #ffffff;
|
||||
padding: 20px 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.div-top-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.div-top-des {
|
||||
color: #2C6EF6;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.div-top-line {
|
||||
border-bottom: 1px solid #EDEDED;
|
||||
}
|
||||
|
||||
.div-top-status {
|
||||
display: flex;
|
||||
margin: 18px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.div-top-status-title {
|
||||
padding-right: 10px;
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.div-top-status-title-span {
|
||||
padding: 0 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.div-top-active {
|
||||
color: #2C6EF6;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*列表 */
|
||||
.product {
|
||||
background: #ffffff;
|
||||
padding: 0 20px;
|
||||
border-radius: 10px;
|
||||
margin-top: 20px;
|
||||
;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.product-list {
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.product-list-li {
|
||||
background: #F9FAFA;
|
||||
width: 30%;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.product-list-li-span1 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.product-list-li-span2 {
|
||||
font-size: 13px;
|
||||
color: #2C6EF6;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.product-list-li-desc {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.product-list-li-span3 {
|
||||
font-size: 13px;
|
||||
color: #767676;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* 在超出时显示省略号 */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
/* 限制显示的行数为2行 */
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.color-e3 {
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.color-yellow {
|
||||
color: rgb(250, 118, 0);
|
||||
}
|
||||
|
||||
.color-red {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
.color-blue {
|
||||
color: #2C6EF6;
|
||||
}
|
||||
|
||||
.color-cancel {
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.table-card-bottom {
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
|
||||
.table-card-hide {
|
||||
display: none;
|
||||
}</style>
|
||||
149
jeepay-ui-merchant/src/views/paydf/aqf/userList.vue
Normal file
149
jeepay-ui-merchant/src/views/paydf/aqf/userList.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<SybAqfUserList configMode="mch" title="收款账户" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {req} from '@/api/manage'
|
||||
import { ref, onMounted, reactive, getCurrentInstance, nextTick } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { dataTool } from 'echarts'
|
||||
|
||||
const router = useRouter() //这是全部路由
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.div-top {
|
||||
background: #ffffff;
|
||||
padding: 20px 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.div-top-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.div-top-des {
|
||||
color: #2C6EF6;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.div-top-line {
|
||||
border-bottom: 1px solid #EDEDED;
|
||||
}
|
||||
|
||||
.div-top-status {
|
||||
display: flex;
|
||||
margin: 18px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.div-top-status-title {
|
||||
padding-right: 10px;
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.div-top-status-title-span {
|
||||
padding: 0 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.div-top-active {
|
||||
color: #2C6EF6;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*列表 */
|
||||
.product {
|
||||
background: #ffffff;
|
||||
padding: 0 20px;
|
||||
border-radius: 10px;
|
||||
margin-top: 20px;
|
||||
;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.product-list {
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.product-list-li {
|
||||
background: #F9FAFA;
|
||||
width: 30%;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.product-list-li-span1 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.product-list-li-span2 {
|
||||
font-size: 13px;
|
||||
color: #2C6EF6;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.product-list-li-desc {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.product-list-li-span3 {
|
||||
font-size: 13px;
|
||||
color: #767676;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* 在超出时显示省略号 */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
/* 限制显示的行数为2行 */
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.color-e3 {
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.color-yellow {
|
||||
color: rgb(250, 118, 0);
|
||||
}
|
||||
|
||||
.color-red {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
.color-blue {
|
||||
color: #2C6EF6;
|
||||
}
|
||||
|
||||
.color-cancel {
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.table-card-bottom {
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
|
||||
.table-card-hide {
|
||||
display: none;
|
||||
}</style>
|
||||
149
jeepay-ui-merchant/src/views/paydf/settle/List.vue
Normal file
149
jeepay-ui-merchant/src/views/paydf/settle/List.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<SybTaskSettleList configMode="mch" title="付款列表" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {req} from '@/api/manage'
|
||||
import { ref, onMounted, reactive, getCurrentInstance, nextTick } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { dataTool } from 'echarts'
|
||||
|
||||
const router = useRouter() //这是全部路由
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.div-top {
|
||||
background: #ffffff;
|
||||
padding: 20px 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.div-top-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.div-top-des {
|
||||
color: #2C6EF6;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.div-top-line {
|
||||
border-bottom: 1px solid #EDEDED;
|
||||
}
|
||||
|
||||
.div-top-status {
|
||||
display: flex;
|
||||
margin: 18px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.div-top-status-title {
|
||||
padding-right: 10px;
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.div-top-status-title-span {
|
||||
padding: 0 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.div-top-active {
|
||||
color: #2C6EF6;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*列表 */
|
||||
.product {
|
||||
background: #ffffff;
|
||||
padding: 0 20px;
|
||||
border-radius: 10px;
|
||||
margin-top: 20px;
|
||||
;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.product-list {
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.product-list-li {
|
||||
background: #F9FAFA;
|
||||
width: 30%;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.product-list-li-span1 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.product-list-li-span2 {
|
||||
font-size: 13px;
|
||||
color: #2C6EF6;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.product-list-li-desc {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.product-list-li-span3 {
|
||||
font-size: 13px;
|
||||
color: #767676;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* 在超出时显示省略号 */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
/* 限制显示的行数为2行 */
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.color-e3 {
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.color-yellow {
|
||||
color: rgb(250, 118, 0);
|
||||
}
|
||||
|
||||
.color-red {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
.color-blue {
|
||||
color: #2C6EF6;
|
||||
}
|
||||
|
||||
.color-cancel {
|
||||
color: #767676;
|
||||
}
|
||||
|
||||
.table-card-bottom {
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
|
||||
.table-card-hide {
|
||||
display: none;
|
||||
}</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user