完成订单的分账逻辑

This commit is contained in:
terrfly 2021-08-26 16:58:18 +08:00
parent f538736894
commit c44723198d
15 changed files with 1198 additions and 11 deletions

View File

@ -46,6 +46,15 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="" class="table-head-layout">
<a-select v-model="searchData.divisionState" placeholder="分账状态" default-value="">
<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>
<span class="table-page-search-submitButtons">
<a-button type="primary" icon="search" @click="queryFunc" :loading="btnLoading">搜索</a-button>
<a-button style="margin-left: 8px" icon="reload" @click="() => this.searchData = {}">重置</a-button>
@ -82,6 +91,13 @@
{{ record.refundState === 0?'未发起':record.refundState === 1?'部分退款':record.refundState === 2?'全额退款':'未知' }}
</a-tag>
</template>
<template slot="divisionStateSlot" slot-scope="{record}">
<a-tag color="blue" v-if="record.divisionState == 0">未发生分账</a-tag>
<a-tag color="orange" v-else-if="record.divisionState == 1">待分账</a-tag>
<a-tag color="red" v-else-if="record.divisionState == 2">分账处理中</a-tag>
<a-tag color="green" v-else-if="record.divisionState == 3">任务已结束</a-tag>
<a-tag color="#f50" v-else>未知</a-tag>
</template>
<template slot="notifySlot" slot-scope="{record}">
<a-badge :status="record.notifyState === 1?'processing':'error'" :text="record.notifyState === 1?'已发送':'未发送'" />
</template>
@ -160,6 +176,12 @@
</a-descriptions-item>
</a-descriptions>
</a-col>
<a-col :sm="12">
<a-descriptions><a-descriptions-item label="手续费"><a-tag color="pink">{{ detailData.mchFeeAmount/100 }}</a-tag></a-descriptions-item></a-descriptions>
</a-col>
<a-col :sm="12">
<a-descriptions><a-descriptions-item label="商家费率">{{ (detailData.mchFeeRate*100).toFixed(2) }}%</a-descriptions-item></a-descriptions>
</a-col>
<a-col :sm="12">
<a-descriptions>
<a-descriptions-item label="订单状态">
@ -323,6 +345,27 @@
</a-descriptions-item>
</a-descriptions>
</a-col>
<a-divider />
<a-col :sm="12">
<a-descriptions><a-descriptions-item label="订单分账模式">
<span v-if="detailData.divisionMode == 0">该笔订单不允许分账</span>
<span v-else-if="detailData.divisionMode == 1">支付成功按配置自动完成分账</span>
<span v-else-if="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 color="blue" v-if="detailData.divisionState == 0">未发生分账</a-tag>
<a-tag color="orange" v-else-if="detailData.divisionState == 1">待分账</a-tag>
<a-tag color="red" v-else-if="detailData.divisionState == 2">分账处理中</a-tag>
<a-tag color="green" v-else-if="detailData.divisionState == 3">任务已结束</a-tag>
<a-tag color="#f50" v-else>未知</a-tag>
</a-descriptions-item></a-descriptions>
</a-col>
<a-col :sm="12">
<a-descriptions><a-descriptions-item label="最新分账发起时间">{{ detailData.divisionLastTime }}</a-descriptions-item></a-descriptions>
</a-col>
</a-row>
<a-divider />
<a-row justify="start" type="flex">
@ -352,12 +395,14 @@ import moment from 'moment'
// eslint-disable-next-line no-unused-vars
const tableColumns = [
{ key: 'amount', title: '支付金额', ellipsis: true, width: '130px', fixed: 'left', scopedSlots: { customRender: 'amountSlot' } },
{ key: 'mchFeeAmount', dataIndex: 'mchFeeAmount', title: '手续费', customRender: (text) => '¥' + (text / 100).toFixed(2) },
{ key: 'mchName', title: '商户名称', dataIndex: 'mchName', ellipsis: true, width: '100px' },
{ key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
{ key: 'mchOrderNo', title: '商户订单号', dataIndex: 'mchOrderNo' },
{ key: 'wayName', title: '支付方式', dataIndex: 'wayName', width: 150 },
{ key: 'state', title: '支付状态', scopedSlots: { customRender: 'stateSlot' }, width: 100 },
{ key: 'refundState', title: '退款状态', scopedSlots: { customRender: 'refundStateSlot' }, width: 100 },
{ key: 'divisionState', title: '分账状态', scopedSlots: { customRender: 'divisionStateSlot' } },
{ key: 'notifyState', title: '回调状态', scopedSlots: { customRender: 'notifySlot' }, width: 100 },
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期', width: 180 },
{ key: 'op', title: '操作', width: '160px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }

View File

@ -89,6 +89,15 @@ export const API_URL_MCH_PAYPASSAGE_LIST = '/api/mch/payPassages'
/** 转账订单管理 **/
export const API_URL_TRANSFER_ORDER_LIST = '/api/transferOrders'
/** 分账组管理 **/
export const API_URL_DIVISION_RECEIVER_GROUP = '/api/divisionReceiverGroups'
/** 分账账号管理 **/
export const API_URL_DIVISION_RECEIVER = '/api/divisionReceivers'
/** 分账记录管理 **/
export const API_URL_PAY_ORDER_DIVISION_RECORD_LIST = '/api/division/records'
/** 上传图片/文件地址 **/
export const upload = {
avatar: request.baseUrl + '/api/ossFiles/avatar',
@ -271,3 +280,11 @@ export function doTransfer (parameter) {
data: parameter
}, true, true, true)
}
/** 查询当前应用支持的支付接口 **/
export function getIfCodeByAppId (appId) {
return request.request({
url: '/api/mch/payConfigs/ifCodes/' + appId,
method: 'GET'
}, true, true, true)
}

View File

@ -23,14 +23,16 @@ export default {
visible: false,
qrImgUrl: '',
payText: '', //
transferOrderWebSocket: null // webSocket
transferOrderWebSocket: null, // webSocket
extObject: null //
}
},
methods: {
// show
showModal (appId, ifCode) {
showModal (appId, ifCode, extObject) {
const that = this
that.extObject = extObject
// webSocket
if (this.transferOrderWebSocket) {
this.transferOrderWebSocket.close()
@ -56,7 +58,7 @@ export default {
that.transferOrderWebSocket = new ReconnectingWebSocket(getWebSocketPrefix() + '/api/anon/ws/channelUserId/' + appId + '/' + cid)
that.transferOrderWebSocket.onopen = () => {}
that.transferOrderWebSocket.onmessage = (msgObject) => {
that.$emit('changeChannelUserId', msgObject.data) //
that.$emit('changeChannelUserId', { channelUserId: msgObject.data, extObject: that.extObject }) //
that.handleClose()
}
})

View File

@ -30,6 +30,10 @@ export const asyncRouteDefine = {
'PayOrderListPage': { defaultPath: '/payOrder', component: () => import('@/views/order/pay/PayOrderList') }, // 支付订单列表
'RefundOrderListPage': { defaultPath: '/refundOrder', component: () => import('@/views/order/refund/RefundOrderList') }, // 退款订单列表
'TransferOrderListPage': { defaultPath: '/transferOrder', component: () => import('@/views/order/transfer/TransferOrderList') } // 转账订单
'TransferOrderListPage': { defaultPath: '/transferOrder', component: () => import('@/views/order/transfer/TransferOrderList') }, // 转账订单
'DivisionReceiverGroupPage': { defaultPath: '/divisionReceiverGroup', component: () => import('@/views/division/group/DivisionReceiverGroupPage') }, // 分账账号组管理
'DivisionReceiverPage': { defaultPath: '/divisionReceiver', component: () => import('@/views/division/receiver/DivisionReceiverPage') }, // 分账账号管理
'DivisionRecordPage': { defaultPath: '/divisionRecord', component: () => import('@/views/division/record/DivisionRecordPage') } // 分账记录
}

View File

@ -1,3 +1,7 @@
// 定义全局自增ID
var atomicLong = 1
export function timeFix () {
const time = new Date()
const hour = time.getHours()
@ -10,3 +14,8 @@ export function isIE () {
const ie11 = (() => 'ActiveXObject' in window)()
return compare('MSIE') || ie11
}
/** 生成自增序列号(不重复) **/
export function genRowKey () {
return new Date().getTime() + '_' + (atomicLong++)
}

View File

@ -0,0 +1,96 @@
<template>
<a-modal v-model="isShow" :title=" isAdd ? '新增菜单' : '修改菜单' " @ok="handleOkFunc" :confirmLoading="confirmLoading">
<a-form-model ref="infoFormModel" :model="saveObject" :label-col="{span: 6}" :wrapper-col="{span: 15}" :rules="rules">
<a-form-model-item label="组名称:" prop="receiverGroupName">
<a-input v-model="saveObject.receiverGroupName" />
</a-form-model-item>
<a-form-model-item label="自动分账组" prop="autoDivisionFlag">
<a-radio-group v-model="saveObject.autoDivisionFlag">
<a-radio :value="1"></a-radio> <a-radio :value="0"></a-radio>
</a-radio-group>
<hr/>
<p style="color: indianred">1. 自动分账组: 当订单分账模式为自动分账该组下的所有正常分账状态的账号将作为订单分账对象</p>
<p style="color: indianred">2. 每个商户仅有一个默认分账组 当该组更新为自动分账时其他组将改为否</p>
</a-form-model-item>
</a-form-model>
</a-modal>
</template>
<script>
import { API_URL_DIVISION_RECEIVER_GROUP, req } from '@/api/manage'
export default {
props: {
callbackFunc: { type: Function }
},
data () {
return {
confirmLoading: false, // loading
isAdd: true, // or
isShow: false, // /
saveObject: { autoDivisionFlag: 0 }, //
recordId: null, // ID
rules: {
receiverGroupName: [
{ required: true, message: '请输入组名称', trigger: 'blur' }
]
}
}
},
created () {
},
methods: {
show: function (recordId) { //
this.isAdd = !recordId
this.saveObject = { autoDivisionFlag: 0 } //
this.confirmLoading = false // loading
if (this.$refs.infoFormModel !== undefined) {
this.$refs.infoFormModel.resetFields()
}
const that = this
if (!this.isAdd) { //
that.recordId = recordId
req.getById(API_URL_DIVISION_RECEIVER_GROUP, recordId).then(res => {
that.saveObject = res
that.isShow = true
})
} else {
that.isShow = true //
}
},
handleOkFunc: function () { //
const that = this
this.$refs.infoFormModel.validate(valid => {
if (valid) { //
//
that.confirmLoading = true // loading
if (that.isAdd) {
req.add(API_URL_DIVISION_RECEIVER_GROUP, that.saveObject).then(res => {
that.$message.success('添加成功')
that.isShow = false
that.callbackFunc() //
}).catch(res => { that.confirmLoading = false })
} else {
req.updateById(API_URL_DIVISION_RECEIVER_GROUP, that.recordId, that.saveObject).then(res => {
that.$message.success('修改成功')
that.isShow = false
that.callbackFunc() //
}).catch(res => { that.confirmLoading = false })
}
}
})
}
}
}
</script>

View File

@ -0,0 +1,109 @@
<template>
<page-header-wrapper>
<a-card>
<div v-if="$access('ENT_DIVISION_RECEIVER_GROUP_LIST')" class="table-page-search-wrapper">
<a-form layout="inline" class="table-head-ground">
<div
class="table-layer"
>
<jeepay-text-up :placeholder="'组ID'" :msg="searchData.receiverGroupId" v-model="searchData.receiverGroupId" />
<jeepay-text-up :placeholder="'组名称'" :msg="searchData.receiverGroupName" v-model="searchData.receiverGroupName" />
<span class="table-page-search-submitButtons">
<a-button type="primary" @click="searchFunc" icon="search" :loading="btnLoading">查询</a-button>
<a-button style="margin-left: 8px;" @click="() => this.searchData = {}" icon="reload">重置</a-button>
</span>
</div>
</a-form>
<div>
<a-button v-if="$access('ENT_DIVISION_RECEIVER_GROUP_ADD')" type="primary" icon="plus" @click="addFunc" class="mg-b-30">新建</a-button>
</div>
</div>
<!-- 列表渲染 -->
<JeepayTable
ref="infoTable"
:initData="true"
:reqTableDataFunc="reqTableDataFunc"
:tableColumns="tableColumns"
:searchData="searchData"
@btnLoadClose="btnLoading=false"
:scrollX="500"
rowKey="receiverGroupId"
>
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
<JeepayTableColumns>
<a v-if="$access('ENT_DIVISION_RECEIVER_GROUP_EDIT')" @click="editFunc(record.receiverGroupId)">修改</a>
<a style="color: red" v-if="$access('ENT_DIVISION_RECEIVER_GROUP_DELETE')" @click="delFunc(record.receiverGroupId)">删除</a>
</JeepayTableColumns>
</template>
</JeepayTable>
</a-card>
<!-- 新增 / 修改 页面组件 -->
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
</page-header-wrapper>
</template>
<script>
import JeepayTable from '@/components/JeepayTable/JeepayTable'
import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
import { API_URL_DIVISION_RECEIVER_GROUP, req } from '@/api/manage'
import InfoAddOrEdit from './AddOrEdit'
import JeepayTextUp from '@/components/JeepayTextUp/JeepayTextUp' //
// eslint-disable-next-line no-unused-vars
const tableColumns = [
{ key: 'receiverGroupId', dataIndex: 'receiverGroupId', title: '组ID' },
{ key: 'receiverGroupName', dataIndex: 'receiverGroupName', title: '组名称' },
{ key: 'autoDivisionFlag', dataIndex: 'autoDivisionFlag', title: '自动分账组', customRender: (text, record, index) => text === 1 ? '是' : '否' },
{ key: 'createdBy', dataIndex: 'createdBy', title: '创建人' },
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建时间' },
{ key: 'op', title: '操作', width: '200px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
]
export default {
name: 'RolePage',
components: { JeepayTable, JeepayTableColumns, InfoAddOrEdit, JeepayTextUp },
data () {
return {
tableColumns: tableColumns,
searchData: {},
btnLoading: false
}
},
mounted () {
},
methods: {
// table
reqTableDataFunc: (params) => {
return req.list(API_URL_DIVISION_RECEIVER_GROUP, params)
},
searchFunc: function () { //
this.btnLoading = true // loading
this.$refs.infoTable.refTable(true)
},
addFunc: function () { //
this.$refs.infoAddOrEdit.show()
},
editFunc: function (recordId) { //
this.$refs.infoAddOrEdit.show(recordId)
},
delFunc: function (recordId) { //
const that = this
this.$infoBox.confirmDanger('确认删除?', '', () => {
// loading promise null
return req.delById(API_URL_DIVISION_RECEIVER_GROUP, recordId).then(res => {
that.$message.success('删除成功!')
that.$refs.infoTable.refTable(false)
})
})
}
}
}
</script>

View File

@ -0,0 +1,160 @@
<template>
<page-header-wrapper>
<a-card>
<div v-if="$access('ENT_DIVISION_RECEIVER_LIST')" class="table-page-search-wrapper">
<a-form layout="inline" class="table-head-ground">
<div class="table-layer">
<a-form-item label="" class="table-head-layout" :wrapper-col="{span: 16}">
<a-select v-model="searchData.appId" placeholder="选择应用">
<a-select-option key="" >全部应用</a-select-option>
<a-select-option v-for="(item) in mchAppList" :key="item.appId" >{{ item.appName }} [{{ item.appId }}]</a-select-option>
</a-select>
</a-form-item>
<jeepay-text-up placeholder="分账接收者ID[精准]" :msg="searchData.receiverId" v-model="searchData.receiverId" />
<jeepay-text-up placeholder="接收者账号别名[模糊]" :msg="searchData.receiverAlias" v-model="searchData.receiverAlias" />
<jeepay-text-up placeholder="组ID[精准]" :msg="searchData.receiverGroupId" v-model="searchData.receiverGroupId" />
<a-form-item label="" class="table-head-layout">
<a-select v-model="searchData.state" placeholder="账号状态(本系统)" default-value="">
<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>
<span class="table-page-search-submitButtons">
<a-button type="primary" @click="searchFunc" icon="search" :loading="btnLoading">查询</a-button>
<a-button style="margin-left: 8px;" @click="() => this.searchData = {}" icon="reload">重置</a-button>
</span>
</div>
</a-form>
<div>
<a-button v-if="$access('ENT_DIVISION_RECEIVER_ADD')" type="danger" icon="plus" @click="addFunc" class="mg-b-30">新建</a-button>
</div>
</div>
<!-- 列表渲染 -->
<JeepayTable
ref="infoTable"
:initData="false"
:reqTableDataFunc="reqTableDataFunc"
:tableColumns="tableColumns"
:searchData="searchData"
@btnLoadClose="btnLoading=false"
:scrollX="500"
rowKey="receiverId"
>
<!-- 渠道类型 -->
<template slot="ifCodeSlot" slot-scope="{record}">
<template v-if="record.ifCode === 'wxpay'" ><span style="color: green"><a-icon type="wechat" /> 微信</span></template>
<template v-else-if="record.ifCode == 'alipay'" ><span style="color: dodgerblue"><a-icon type="alipay-circle" /> 支付宝</span></template>
<template v-else >{{record.ifCode}}</template>
</template>
<!-- 状态本系统 -->
<template slot="stateSlot" slot-scope="{record}">
<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 slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
<JeepayTableColumns>
<a v-if="$access('ENT_DIVISION_RECEIVER_EDIT')" @click="editFunc(record.receiverId)">修改</a>
</JeepayTableColumns>
</template>
</JeepayTable>
<!-- 新增收款账号页面 -->
<ReceiverAdd ref="receiverAdd" :callbackFunc="searchFunc"/>
<!-- 修改 页面组件 -->
<ReceiverEdit ref="receiverEdit" :callbackFunc="searchFunc"/>
</a-card>
</page-header-wrapper>
</template>
<script>
import JeepayTable from '@/components/JeepayTable/JeepayTable'
import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
import { API_URL_DIVISION_RECEIVER, API_URL_MCH_APP, req } from '@/api/manage'
import JeepayTextUp from '@/components/JeepayTextUp/JeepayTextUp' //
import ReceiverAdd from './ReceiverAdd'
import ReceiverEdit from './ReceiverEdit'
// eslint-disable-next-line no-unused-vars
const tableColumns = [
{ key: 'receiverId', dataIndex: 'receiverId', title: '绑定ID' },
{ key: 'ifCode', title: '渠道类型', scopedSlots: { customRender: 'ifCodeSlot' } },
{ key: 'receiverAlias', dataIndex: 'receiverAlias', title: '账号别名' },
{ key: 'receiverGroupName', dataIndex: 'receiverGroupName', title: '组名称' },
{ key: 'accNo', dataIndex: 'accNo', title: '分账接收账号' },
{ key: 'accName', dataIndex: 'accName', title: '分账接收账号名称' },
{ key: 'relationTypeName', dataIndex: 'relationTypeName', title: '分账关系类型' },
{ title: '状态', scopedSlots: { customRender: 'stateSlot' }, align: 'center' },
{ key: 'bindSuccessTime', dataIndex: 'bindSuccessTime', title: '绑定成功时间' },
{ key: 'divisionProfit', dataIndex: 'divisionProfit', title: '默认分账比例', customRender: (text, record, index) => (text * 100).toFixed(2) + '%' },
{ key: 'op', title: '操作', width: '200px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
]
export default {
components: { JeepayTable, JeepayTableColumns, JeepayTextUp, ReceiverAdd, ReceiverEdit },
data () {
return {
tableColumns: tableColumns,
searchData: { appId: '' },
btnLoading: false,
mchAppList: [] // app
}
},
mounted () {
const that = this // this
// appidpageSize=-1
req.list(API_URL_MCH_APP, { pageSize: -1 }).then(res => {
that.mchAppList = res.records
// &
if (that.mchAppList && that.mchAppList.length > 0) {
that.searchData.appId = that.mchAppList[0].appId + ''
that.searchFunc()
}
})
},
methods: {
// table
reqTableDataFunc: (params) => {
return req.list(API_URL_DIVISION_RECEIVER, params)
},
searchFunc: function () { //
this.btnLoading = true // loading
this.$refs.infoTable.refTable(true)
},
addFunc: function () { //
if (this.mchAppList.length <= 0) {
return this.$message.error('当前商户无任何应用,请先创建应用后再试。')
}
if (!this.searchData.appId) {
return this.$message.error('请先选择应用。')
}
//
this.$refs.receiverAdd.show(this.mchAppList.filter((item) => item.appId === this.searchData.appId)[0])
},
editFunc: function (recordId) { //
this.$refs.receiverEdit.show(recordId)
}
}
}
</script>

View File

@ -0,0 +1,355 @@
<template>
<a-drawer
v-if="visible"
:visible="visible"
@close="onClose"
:closable="true"
:body-style="{ paddingBottom: '80px' }"
:drawer-style="{ backgroundColor: '#f0f2f5' }"
width="80%"
>
<a-descriptions title="绑定分账接收者账号">
<a-descriptions-item label="当前应用">
<span style="color: red">{{ appInfo.appName }} [{{ appInfo.appId }}]</span>
</a-descriptions-item>
<a-descriptions-item label="选择要加入到的账号分组">
<a-select style="width: 210px" placeholder="账号分组" v-model="selectedReceiverGroupId">
<a-select-option v-for="(item) in allReceiverGroup" :key="item.receiverGroupId" :value="item.receiverGroupId">{{ item.receiverGroupName }}</a-select-option>
</a-select>
</a-descriptions-item>
</a-descriptions>
<a-divider></a-divider>
<a-card title="微信账号" v-show="appSupportIfCodes.indexOf('wxpay') >= 0">
<a slot="extra" href="#">
<a-button style="background: green; color: white" icon="wechat" @click="addReceiverRow('wxpay')">添加微信官方分账接收账号</a-button>
</a>
<a-table :columns="accTableColumns" :data-source="receiverTableData.filter((item) => item.ifCode == 'wxpay')" :pagination="false" rowKey="rowKey">
<!-- 账号类型 -->
<template slot="reqBindStateSlot" slot-scope="record">
<div style="color: salmon " v-show="record.reqBindState == 0">
<a-icon type="info-circle" /> 待绑定
</div>
<div style="color: green; " v-show="record.reqBindState == 1">
<a-icon type="check-circle" /> 绑定成功
</div>
<div style="color: red; " v-show="record.reqBindState == 2">
<a-icon type="close-circle" /> 绑定异常
</div>
</template>
<!-- 账号别名 -->
<template slot="receiverAliasSlot" slot-scope="record">
<a-input v-model="record.receiverAlias" style="width: 150px" placeholder="(选填)默认为账号"/>
</template>
<!-- 账号类型 -->
<template slot="accTypeSlot" slot-scope="record">
<a-select style="width: 110px" v-model="record.accType" placeholder="账号类型" default-value="0">
<a-select-option value="0">个人</a-select-option>
<a-select-option value="1">微信商户</a-select-option>
</a-select>
</template>
<!-- 接收方账号 -->
<template slot="accNoSlot" slot-scope="record">
<a-input v-model="record.accNo" style="width: 150px"/>
<a-button type="link" v-if="record.accType == 0" @click="showChannelUserModal('wxpay', record)">扫码获取</a-button>
</template>
<!-- 接收方姓名 -->
<template slot="accNameSlot" slot-scope="record">
<a-input v-model="record.accName"/>
</template>
<!-- 分账关系 -->
<template slot="relationTypeSlot" slot-scope="record">
<a-select style="width: 110px" labelInValue placeholder="分账关系类型" :defaultValue="{key: 'PARTNER'}" @change="changeRelationType(record, $event)">
<a-select-option key="PARTNER">合作伙伴</a-select-option>
<a-select-option key="SERVICE_PROVIDER">服务商</a-select-option>
<a-select-option key="STORE">门店</a-select-option>
<a-select-option key="STAFF">员工</a-select-option>
<a-select-option key="STORE_OWNER">店主</a-select-option>
<a-select-option key="HEADQUARTER">总部</a-select-option>
<a-select-option key="BRAND">品牌方</a-select-option>
<a-select-option key="DISTRIBUTOR">分销商</a-select-option>
<a-select-option key="USER">用户</a-select-option>
<a-select-option key="SUPPLIER">供应商</a-select-option>
<a-select-option key="CUSTOM">自定义</a-select-option>
</a-select>
</template>
<!-- 关系名称 -->
<template slot="relationTypeNameSlot" slot-scope="record">
<a-input :disabled="record.relationType !== 'CUSTOM'" v-model="record.relationTypeName"/>
</template>
<!-- 默认分账比例 -->
<template slot="divisionProfitSlot" slot-scope="record">
<a-input v-model="record.divisionProfit" style="width: 65px"/> %
</template>
<template slot="opSlot" slot-scope="record"><a-button type="link" @click="delRow(record)">删除</a-button></template>
</a-table>
</a-card>
<br />
<a-card title="支付宝账号" v-show="appSupportIfCodes.indexOf('alipay') >= 0">
<a slot="extra" href="#">
<a-button style="background: dodgerblue; color: white" icon="alipay-circle" @click="addReceiverRow('alipay')" >添加支付宝官方分账接收账号</a-button>
</a>
<a-table :columns="accTableColumns" :data-source="receiverTableData.filter((item) => item.ifCode == 'alipay')" :pagination="false" rowKey="rowKey">
<!-- 账号类型 -->
<template slot="reqBindStateSlot" slot-scope="record">
<div style="color: salmon " v-show="record.reqBindState == 0">
<a-icon type="info-circle" /> 待绑定
</div>
<div style="color: green; " v-show="record.reqBindState == 1">
<a-icon type="check-circle" /> 绑定成功
</div>
<div style="color: red; " v-show="record.reqBindState == 2">
<a-icon type="close-circle" /> 绑定异常
</div>
</template>
<!-- 账号别名 -->
<template slot="receiverAliasSlot" slot-scope="record">
<a-input v-model="record.receiverAlias" style="width: 150px" placeholder="(选填)默认为账号"/>
</template>
<!-- 账号类型 -->
<template slot="accTypeSlot" slot-scope="record">
<a-select style="width: 110px" v-model="record.accType" placeholder="账号类型" default-value="0">
<a-select-option value="0">个人</a-select-option>
<a-select-option value="1">微信商户</a-select-option>
</a-select>
</template>
<!-- 接收方账号 -->
<template slot="accNoSlot" slot-scope="record">
<a-input v-model="record.accNo" style="width: 150px"/>
<a-button type="link" v-if="record.accType == 0" @click="showChannelUserModal('alipay', record)">扫码获取</a-button>
</template>
<!-- 接收方姓名 -->
<template slot="accNameSlot" slot-scope="record">
<a-input v-model="record.accName"/>
</template>
<!-- 分账关系 -->
<template slot="relationTypeSlot" slot-scope="record">
<a-select style="width: 110px" labelInValue placeholder="分账关系类型" :defaultValue="{key: 'PARTNER'}" @change="changeRelationType(record, $event)">
<a-select-option key="PARTNER">合作伙伴</a-select-option>
<a-select-option key="SERVICE_PROVIDER">服务商</a-select-option>
<a-select-option key="STORE">门店</a-select-option>
<a-select-option key="STAFF">员工</a-select-option>
<a-select-option key="STORE_OWNER">店主</a-select-option>
<a-select-option key="HEADQUARTER">总部</a-select-option>
<a-select-option key="BRAND">品牌方</a-select-option>
<a-select-option key="DISTRIBUTOR">分销商</a-select-option>
<a-select-option key="USER">用户</a-select-option>
<a-select-option key="SUPPLIER">供应商</a-select-option>
<a-select-option key="CUSTOM">自定义</a-select-option>
</a-select>
</template>
<!-- 关系名称 -->
<template slot="relationTypeNameSlot" slot-scope="record">
<a-input :disabled="record.relationType !== 'CUSTOM'" v-model="record.relationTypeName"/>
</template>
<!-- 默认分账比例 -->
<template slot="divisionProfitSlot" slot-scope="record">
<a-input v-model="record.divisionProfit" style="width: 65px"/> %
</template>
<template slot="opSlot" slot-scope="record"><a-button type="link" @click="delRow(record)">删除</a-button></template>
</a-table>
</a-card>
<div class="drawer-btn-center ">
<a-button type="primary" icon="rocket" :style="{ marginRight: '8px' }" @click="reqBatchBindReceiver(0)">发起绑定请求</a-button>
<a-button icon="close" @click="onClose">关闭</a-button>
</div>
<ChannelUserModal ref="channelUserModal" @changeChannelUserId="changeChannelUserIdFunc($event)"/>
</a-drawer>
</template>
<script>
// eslint-disable-next-line no-unused-vars
import { genRowKey } from '@/utils/util'
import ChannelUserModal from '@/components/ChannelUser/ChannelUserModal'
import { API_URL_DIVISION_RECEIVER, API_URL_DIVISION_RECEIVER_GROUP, req, getIfCodeByAppId } from '@/api/manage'
// eslint-disable-next-line no-unused-vars
const accTableColumns = [
{ key: 'reqBindState', title: '状态', scopedSlots: { customRender: 'reqBindStateSlot' } },
{ key: 'receiverAlias', title: '账号别名', scopedSlots: { customRender: 'receiverAliasSlot' } },
{ key: 'accType', title: '账号类型', scopedSlots: { customRender: 'accTypeSlot' } },
{ key: 'accNo', width: '300px', title: '接收方账号', scopedSlots: { customRender: 'accNoSlot' } },
{ key: 'accName', width: '180px', title: '接收方姓名', scopedSlots: { customRender: 'accNameSlot' } },
{ key: 'relationType', title: '分账关系', scopedSlots: { customRender: 'relationTypeSlot' } },
{ key: 'relationTypeName', width: '200px', title: '关系名称', scopedSlots: { customRender: 'relationTypeNameSlot' } },
{ key: 'divisionProfit', title: '默认分账比例', scopedSlots: { customRender: 'divisionProfitSlot' } },
{ key: 'op', title: '操作', scopedSlots: { customRender: 'opSlot' } }
]
const defaultReceiverTemplate = {
reqBindState: 0, //
receiverAlias: '',
receiverGroupId: '',
appId: '',
ifCode: '',
accType: '0',
accNo: '',
accName: '',
relationType: 'PARTNER', // , selectdefaultValue
relationTypeName: '合作伙伴',
divisionProfit: ''
}
export default {
components: { ChannelUserModal },
props: {
callbackFunc: {
type: Function,
default: () => ({})
}
},
data () {
return {
visible: false, //
appInfo: null, // app
accTableColumns: accTableColumns, //
allReceiverGroup: [], //
selectedReceiverGroupId: '', // ID
appSupportIfCodes: [], //
receiverTableData: [] //
}
},
methods: {
//
show (appInfo) {
const that = this // this
this.appSupportIfCodes = [] //
this.receiverTableData = [] //
// pageSize=-1
req.list(API_URL_DIVISION_RECEIVER_GROUP, { pageSize: -1 }).then(res => {
that.allReceiverGroup = res.records
if (that.allReceiverGroup && that.allReceiverGroup.length > 0) { // &
that.selectedReceiverGroupId = that.allReceiverGroup[0].receiverGroupId
}
})
//
getIfCodeByAppId(appInfo.appId).then((res) => {
that.appSupportIfCodes = res
})
this.appInfo = appInfo //
this.visible = true //
},
//
onClose () {
this.callbackFunc() //
this.visible = false
},
//
delRow (item) {
const index = this.receiverTableData.indexOf(item)
if (index > -1) {
this.receiverTableData.splice(index, 1)
}
},
changeRelationType (record, value) {
record.relationType = value.key
if (value.key !== 'CUSTOM') {
record.relationTypeName = value.label
} else {
record.relationTypeName = ''
}
},
// ID
showChannelUserModal (ifCode, record) {
this.$refs.channelUserModal.showModal(this.appInfo.appId, ifCode, record)
},
// ID
changeChannelUserIdFunc ({ channelUserId, extObject }) {
console.log(channelUserId, extObject)
extObject.accNo = channelUserId
},
//
addReceiverRow (ifCode) {
if (!this.selectedReceiverGroupId) {
return this.$message.error('请选选择要加入的分组')
}
this.receiverTableData.push(Object.assign({}, defaultReceiverTemplate, { rowKey: genRowKey(), ifCode: ifCode, appId: this.appInfo.appId }))
},
//
reqBatchBindReceiver (i) {
const that = this
if (that.receiverTableData.length <= 0) {
return that.$message.error('请先添加账号')
}
//
if (i >= that.receiverTableData.length) {
return this.$message.success('已完成所有账号的绑定操作')
}
//
const currentReceiver = that.receiverTableData[i]
currentReceiver.receiverGroupId = that.selectedReceiverGroupId // ID
if (currentReceiver.reqBindState === 1) { //
return that.reqBatchBindReceiver(++i) //
}
if (!currentReceiver.accNo) {
return this.$message.error(`${i + 1 }条: 接收方账号不能为空`)
}
if (currentReceiver.relationType === 'CUSTOM' && !currentReceiver.relationTypeName) {
return this.$message.error(`${i + 1 }条: 自定义类型时接收方账号名称不能为空`)
}
if (!currentReceiver.divisionProfit || currentReceiver.divisionProfit <= 0 || currentReceiver.divisionProfit > 100) {
return this.$message.error(`${i + 1 }条: 默认分账比例请设置在[0.01% ~ 100% ] 之间`)
}
req.add(API_URL_DIVISION_RECEIVER, currentReceiver).then(apiRes => {
//
if (apiRes.bindState === 1) {
that.reqBatchBindReceiver(++i) //
currentReceiver.reqBindState = 1 //
} else {
currentReceiver.reqBindState = 2 //
that.$infoBox.modalError(`${i + 1 }条: 绑定异常`, <div><div>错误码{ apiRes.errCode}</div><div>错误信息{ apiRes.errMsg}</div></div>)
}
}).catch(() => {
currentReceiver.reqBindState = 2 //
})
}
}
}
</script>

View File

@ -0,0 +1,109 @@
<template>
<a-drawer :visible="isShow" title="修改分账用户信息" width="30%" :maskClosable="false" @close="isShow = false">
<a-form-model ref="infoFormModel" :model="saveObject" :label-col="{span: 6}" :wrapper-col="{span: 15}" :rules="rules">
<a-form-model-item label="账号别名:" prop="receiverAlias">
<a-input v-model="saveObject.receiverAlias" />
</a-form-model-item>
<a-form-model-item label="默认分账比例:" prop="divisionProfit">
<a-input v-model="saveObject.divisionProfit" style="width: 100px" /> %
</a-form-model-item>
<a-form-model-item label="状态" prop="state">
<a-radio-group v-model="saveObject.state">
<a-radio :value="1">正常分账</a-radio> <a-radio :value="0"></a-radio>
</a-radio-group>
</a-form-model-item>
<a-form-model-item label="分组变更:" prop="receiverGroupId">
<a-select style="width: 210px" placeholder="账号分组" v-model="saveObject.receiverGroupId">
<a-select-option v-for="(item) in allReceiverGroup" :key="item.receiverGroupId" :value="item.receiverGroupId">{{ item.receiverGroupName }}</a-select-option>
</a-select>
</a-form-model-item>
</a-form-model>
<div class="drawer-btn-center">
<a-button :style="{ marginRight: '8px' }" @click="isShow = false" icon="close">取消</a-button>
<a-button type="primary" @click="handleOkFunc" :loading="confirmLoading" icon="check">保存</a-button>
</div>
</a-drawer>
</template>
<script>
import { API_URL_DIVISION_RECEIVER, API_URL_DIVISION_RECEIVER_GROUP, req } from '@/api/manage'
export default {
props: {
callbackFunc: { type: Function }
},
data () {
return {
confirmLoading: false, // loading
isShow: false, // /
saveObject: {}, //
recordId: null, // ID
allReceiverGroup: [], //
rules: {
receiverAlias: [{ required: true, message: '请输入别名', trigger: 'blur' }],
receiverGroupId: [{ required: true, message: '请选择分组', trigger: 'blur' }],
divisionProfit: [{ required: true, message: '请录入默认分账比例', trigger: 'blur' }],
state: [{ required: true, message: '请选择状态', trigger: 'blur' }]
}
}
},
created () {
},
methods: {
show: function (recordId) { //
this.saveObject = {} //
this.confirmLoading = false // loading
if (this.$refs.infoFormModel !== undefined) {
this.$refs.infoFormModel.resetFields()
}
const that = this
that.recordId = recordId
//
req.getById(API_URL_DIVISION_RECEIVER, recordId).then(res => {
res.divisionProfit = (res.divisionProfit * 100).toFixed(2)
that.saveObject = res
})
// pageSize=-1
req.list(API_URL_DIVISION_RECEIVER_GROUP, { pageSize: -1 }).then(res => { that.allReceiverGroup = res.records })
this.isShow = true
},
handleOkFunc: function () { //
const that = this
this.$refs.infoFormModel.validate(valid => {
if (valid) { //
that.confirmLoading = true // loading
var reqObject = {
receiverAlias: that.saveObject.receiverAlias,
receiverGroupId: that.saveObject.receiverGroupId,
divisionProfit: that.saveObject.divisionProfit,
state: that.saveObject.state
}
req.updateById(API_URL_DIVISION_RECEIVER, that.recordId, reqObject).then(res => {
that.$message.success('修改成功')
that.isShow = false
that.callbackFunc() //
}).catch(res => { that.confirmLoading = false })
}
})
}
}
}
</script>

View File

@ -0,0 +1,69 @@
<!-- 详情抽屉 -->
<template>
<a-drawer
width="50%"
:closable="true"
:visible="visible"
title="记录详情"
@close="visible = false"
>
<a-row justify="space-between" type="flex">
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账记录ID">{{ detailData.recordId }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="商户号">{{ detailData.mchNo }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="应用ID">{{ detailData.appId }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="支付接口代码">{{ detailData.ifCode }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="系统支付订单号">{{ detailData.payOrderId }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="支付订单渠道支付订单号">{{ detailData.payOrderChannelOrderNo }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="订单金额">{{ detailData.payOrderAmount / 100}}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="待计算分账金额">{{ detailData.payOrderDivisionAmount / 100 }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="系统分账批次号">{{ detailData.batchOrderId }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="上游分账批次号">{{ detailData.channelBatchOrderId }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="状态">
<a-tag :key="detailData.state" :color="detailData.state === 0?'orange':detailData.state === 1?'blue':detailData.state === 2?'volcano':'volcano'">
{{ detailData.state === 0?'分账中':detailData.state === 1?'分账成功':detailData.state === 2?'分账失败' : '未知' }}
</a-tag>
</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收者ID">{{ detailData.receiverId }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="收款账号组ID">{{ detailData.receiverGroupId }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="收款账号别名">{{ detailData.receiverAlias }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号类型">{{ detailData.accType == 0 ? '个人' : '商户' }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号">{{ detailData.accNo }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号名称">{{ detailData.accName }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账关系类型">{{ detailData.relationType }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账关系类型名称">{{ detailData.relationTypeName }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="实际分账比例">{{ (detailData.divisionProfit * 100).toFixed(2) }}%</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账金额">{{ detailData.calDivisionAmount / 100 }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="创建时间">{{ detailData.createdAt }}</a-descriptions-item></a-descriptions></a-col>
<a-col :sm="12"><a-descriptions><a-descriptions-item label="更新时间">{{ detailData.updatedAt }}</a-descriptions-item></a-descriptions></a-col>
</a-row>
<a-divider />
<a-row justify="start" type="flex">
<a-col :sm="24">
<a-form-model-item label="上游返回数据包">
<a-input type="textarea" disabled="disabled" style="height: 100px;color: black" v-model="detailData.channelRespResult"/>
</a-form-model-item>
</a-col>
</a-row>
</a-drawer>
</template>
<script>
import { API_URL_PAY_ORDER_DIVISION_RECORD_LIST, req } from '@/api/manage'
export default {
data () {
return {
visible: false,
detailData: {}
}
},
methods: {
show: function (recordId) {
const that = this
req.getById(API_URL_PAY_ORDER_DIVISION_RECORD_LIST, recordId).then(res => {
that.detailData = res
})
this.visible = true
}
}
}
</script>

View File

@ -0,0 +1,140 @@
<template>
<page-header-wrapper>
<a-card>
<div class="table-page-search-wrapper">
<a-form layout="inline" class="table-head-ground">
<div class="table-layer">
<a-form-item label="" class="table-head-layout" style="max-width:350px;min-width:300px">
<a-range-picker
@change="onChange"
:show-time="{ format: 'HH:mm:ss' }"
format="YYYY-MM-DD HH:mm:ss"
:disabled-date="disabledDate"
>
<a-icon slot="suffixIcon" type="sync" />
</a-range-picker>
</a-form-item>
<jeepay-text-up placeholder="分账接受者ID" :msg="searchData.receiverId" v-model="searchData.receiverId" />
<jeepay-text-up placeholder="分账账号组ID" :msg="searchData.receiverGroupId" v-model="searchData.receiverGroupId" />
<jeepay-text-up placeholder="应用AppId" :msg="searchData.appId" v-model="searchData.appId"/>
<jeepay-text-up placeholder="支付订单号" :msg="searchData.payOrderId" v-model="searchData.payOrderId"/>
<jeepay-text-up placeholder="分账接收账号" :msg="searchData.accNo" v-model="searchData.accNo"/>
<a-form-item label="" class="table-head-layout">
<a-select v-model="searchData.state" placeholder="分账状态" default-value="">
<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>
<span class="table-page-search-submitButtons">
<a-button type="primary" icon="search" @click="queryFunc" :loading="btnLoading">搜索</a-button>
<a-button style="margin-left: 8px" icon="reload" @click="() => this.searchData = {}">重置</a-button>
</span>
</div>
</a-form>
</div>
<!-- 列表渲染 -->
<JeepayTable
@btnLoadClose="btnLoading=false"
ref="infoTable"
:initData="true"
:reqTableDataFunc="reqTableDataFunc"
:tableColumns="tableColumns"
:searchData="searchData"
rowKey="recordId"
>
<template slot="amountSlot" slot-scope="{record}"><b>{{ record.calDivisionAmount/100 }}</b></template> <!-- 自定义插槽 -->
<template slot="stateSlot" slot-scope="{record}">
<a-tag
:key="record.state"
:color="record.state === 0?'orange':record.state === 1?'blue':record.state === 2?'volcano':'volcano'"
>
{{ record.state === 0?'分账中':record.state === 1?'分账成功':record.state === 2?'分账失败' : '未知' }}
</a-tag>
</template>
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
<JeepayTableColumns>
<a-button type="link" v-if="$access('ENT_DIVISION_RECORD_VIEW')" @click="detailFunc(record.recordId)">详情</a-button>
</JeepayTableColumns>
</template>
</JeepayTable>
</a-card>
<Detail ref="recordDetail" />
</page-header-wrapper>
</template>
<script>
import JeepayTextUp from '@/components/JeepayTextUp/JeepayTextUp' //
import JeepayTable from '@/components/JeepayTable/JeepayTable'
import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
import { API_URL_PAY_ORDER_DIVISION_RECORD_LIST, req } from '@/api/manage'
import moment from 'moment'
import Detail from './Detail'
// eslint-disable-next-line no-unused-vars
const tableColumns = [
{ key: 'calDivisionAmount', title: '分账金额', scopedSlots: { customRender: 'amountSlot' } },
{ key: 'batchOrderId', title: '分账批次号', dataIndex: 'batchOrderId' },
{ key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
{ key: 'ifCode', title: '接口代码', dataIndex: 'ifCode' },
{ key: 'payOrderAmount', dataIndex: 'payOrderAmount', title: '订单金额', customRender: (text) => (text / 100).toFixed(2) },
{ key: 'payOrderDivisionAmount', dataIndex: 'payOrderDivisionAmount', title: '订单商户入账金额', customRender: (text) => (text / 100).toFixed(2) },
{ 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: '分账比例', customRender: (text, record, index) => (text * 100).toFixed(2) + '%' },
{ key: 'state', title: '分账状态', scopedSlots: { customRender: 'stateSlot' } },
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
{ key: 'op', title: '操作', width: '100px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
]
export default {
components: { JeepayTable, JeepayTableColumns, JeepayTextUp, Detail },
data () {
return {
btnLoading: false,
tableColumns: tableColumns,
searchData: {},
createdStart: '', //
createdEnd: '' //
}
},
computed: {
},
mounted () {
},
methods: {
queryFunc () {
this.btnLoading = true
this.$refs.infoTable.refTable(true)
},
// table
reqTableDataFunc: (params) => {
return req.list(API_URL_PAY_ORDER_DIVISION_RECORD_LIST, params)
},
searchFunc: function () { //
this.$refs.infoTable.refTable(true)
},
detailFunc: function (recordId) {
this.$refs.recordDetail.show(recordId)
},
moment,
onChange (date, dateString) {
this.searchData.createdStart = dateString[0] //
this.searchData.createdEnd = dateString[1] //
},
disabledDate (current) { //
return current && current > moment().endOf('day')
},
onClose () {
this.visible = false
}
}
}
</script>

View File

@ -39,6 +39,16 @@
</a-select>
</a-form-item>
<a-form-item label="" class="table-head-layout">
<a-select v-model="searchData.divisionState" placeholder="分账状态" default-value="">
<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>
<span class="table-page-search-submitButtons">
<a-button type="primary" icon="search" @click="queryFunc" :loading="btnLoading">搜索</a-button>
<a-button style="margin-left: 8px" icon="reload" @click="() => this.searchData = {}">重置</a-button>
@ -67,6 +77,15 @@
{{ record.state === 0?'订单生成':record.state === 1?'支付中':record.state === 2?'支付成功':record.state === 3?'支付失败':record.state === 4?'已撤销':record.state === 5?'已退款':record.state === 6?'订单关闭':'未知' }}
</a-tag>
</template>
<template slot="divisionStateSlot" slot-scope="{record}">
<a-tag color="blue" v-if="record.divisionState == 0">未发生分账</a-tag>
<a-tag color="orange" v-else-if="record.divisionState == 1">待分账</a-tag>
<a-tag color="red" v-else-if="record.divisionState == 2">分账处理中</a-tag>
<a-tag color="green" v-else-if="record.divisionState == 3">任务已结束</a-tag>
<a-tag color="#f50" v-else>未知</a-tag>
</template>
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
<JeepayTableColumns>
<a-button type="link" v-if="$access('ENT_PAY_ORDER_VIEW')" @click="detailFunc(record.payOrderId)">详情</a-button>
@ -147,6 +166,12 @@
</a-descriptions-item>
</a-descriptions>
</a-col>
<a-col :sm="12">
<a-descriptions><a-descriptions-item label="手续费"><a-tag color="pink">{{ detailData.mchFeeAmount/100 }}</a-tag></a-descriptions-item></a-descriptions>
</a-col>
<a-col :sm="12">
<a-descriptions><a-descriptions-item label="商家费率">{{ (detailData.mchFeeRate*100).toFixed(2) }}%</a-descriptions-item></a-descriptions>
</a-col>
<a-col :sm="12">
<a-descriptions>
<a-descriptions-item label="支付错误码">
@ -276,6 +301,28 @@
</a-descriptions-item>
</a-descriptions>
</a-col>
<a-divider />
<a-col :sm="12">
<a-descriptions><a-descriptions-item label="订单分账模式">
<span v-if="detailData.divisionMode == 0">该笔订单不允许分账</span>
<span v-else-if="detailData.divisionMode == 1">支付成功按配置自动完成分账</span>
<span v-else-if="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 color="blue" v-if="detailData.divisionState == 0">未发生分账</a-tag>
<a-tag color="orange" v-else-if="detailData.divisionState == 1">待分账</a-tag>
<a-tag color="red" v-else-if="detailData.divisionState == 2">分账处理中</a-tag>
<a-tag color="green" v-else-if="detailData.divisionState == 3">任务已结束</a-tag>
<a-tag color="#f50" v-else>未知</a-tag>
</a-descriptions-item></a-descriptions>
</a-col>
<a-col :sm="12">
<a-descriptions><a-descriptions-item label="最新分账发起时间">{{ detailData.divisionLastTime }}</a-descriptions-item></a-descriptions>
</a-col>
</a-row>
<a-divider />
<a-row justify="start" type="flex">
@ -304,10 +351,12 @@ import moment from 'moment'
// eslint-disable-next-line no-unused-vars
const tableColumns = [
{ key: 'amount', title: '支付金额', scopedSlots: { customRender: 'amountSlot' } },
{ key: 'mchFeeAmount', dataIndex: 'mchFeeAmount', title: '手续费', customRender: (text) => '¥' + (text / 100).toFixed(2) },
{ key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
{ key: 'mchOrderNo', title: '商户订单号', dataIndex: 'mchOrderNo' },
{ key: 'wayName', title: '支付方式', dataIndex: 'wayName', width: 150 },
{ key: 'state', title: '支付状态', scopedSlots: { customRender: 'stateSlot' } },
{ key: 'divisionState', title: '分账状态', scopedSlots: { customRender: 'divisionStateSlot' } },
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
{ key: 'op', title: '操作', width: '100px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
]

View File

@ -92,9 +92,23 @@
<span @click="randomOrderNo" class=" paydemo-btn" style="padding:0 3px">刷新订单号</span>
</div>
<div class="paydemo-form-item">
<label>商品名称</label>
<span id="paySubject">支付接口演示</span>
<label>订单标题</label>
<a-input v-model="orderTitle" style="width: 200px"/>
</div>
<div class="paydemo-form-item">
<label>分账方式</label>
<a-radio-group v-model="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 ></a-divider>
<div class="paydemo-form-item">
<span>支付金额()</span>
@ -118,8 +132,8 @@
</a-input-number>
</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 @click="immediatelyPay" style="padding:5px 20px;background-color: #1953ff;border-radius: 5px;color:#fff">立即支付</a-button>
@ -154,7 +168,9 @@ export default {
authCode: '', //
paytestAmount: '0.01', // 0.01
amountInput: false, //
noConfigText: false // 线
noConfigText: false, // 线
divisionMode: 0, //
orderTitle: '接口调试' //
}
},
@ -236,6 +252,11 @@ export default {
return this.$message.error('请选择支付方式')
}
//
if (!this.orderTitle || this.orderTitle.length > 20) {
return this.$message.error('请输入正确的订单标题[20字以内]')
}
//
if (!this.$refs.payTestBarCode.getVisible() && (this.currentWayCode === 'WX_BAR' || this.currentWayCode === 'ALI_BAR' || this.currentWayCode === 'AUTO_BAR')) {
this.$refs.payTestBarCode.showModal()
@ -250,7 +271,9 @@ export default {
appId: this.appId, // appId
mchOrderNo: this.mchOrderNo, //
payDataType: this.currentPayDataType, //
authCode: this.authCode
authCode: this.authCode,
divisionMode: this.divisionMode,
orderTitle: this.orderTitle
}).then(res => {
that.$refs.payTestModal.showModal(this.currentWayCode, res) //
that.randomOrderNo() //

View File

@ -92,7 +92,7 @@
<script>
import { API_URL_MCH_APP, req, queryMchTransferIfCode, doTransfer } from '@/api/manage' //
import ChannelUserModal from './ChannelUserModal'
import ChannelUserModal from '@/components/ChannelUser/ChannelUserModal'
export default {
components: { ChannelUserModal },
data () {
@ -205,7 +205,7 @@ export default {
},
//
changeChannelUserIdFunc (channelUserId) {
changeChannelUserIdFunc ({ channelUserId }) {
this.$message.success('成功获取渠道用户ID')
this.reqData.accountNo = channelUserId
}