源文件
This commit is contained in:
126
jeepay-ui-agent/src/views/accountCenter/history/Detail.vue
Normal file
126
jeepay-ui-agent/src/views/accountCenter/history/Detail.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:title=" true ? '流水详情' : '' "
|
||||
: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['infoName'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="流水号">
|
||||
{{ vdata.detailData['hid'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="账户类型">
|
||||
{{ vdata.detailData['opAccountType'] === 1 ? '钱包账户' : '在途账户' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="关联订单类型">
|
||||
<template v-if="vdata.detailData['relaBizOrderType'] === 1">支付订单</template>
|
||||
<template v-if="vdata.detailData['relaBizOrderType'] === 2">退款订单</template>
|
||||
<template v-if="vdata.detailData['relaBizOrderType'] === 3">提现订单</template>
|
||||
<template v-if="vdata.detailData['relaBizOrderType'] === 4">转账订单</template>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item v-if="vdata.detailData['relaBizOrderType'] === 1" label="支付订单号">
|
||||
{{ vdata.detailData['relaBizOrderId'] }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="vdata.detailData['relaBizOrderType'] === 2" label="退款订单号">
|
||||
{{ vdata.detailData['relaBizOrderId'] }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="vdata.detailData['relaBizOrderType'] === 3" label="提现订单号">
|
||||
{{ vdata.detailData['relaBizOrderId'] }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="vdata.detailData['relaBizOrderType'] === 4" label="转账订单">
|
||||
{{ vdata.detailData['relaBizOrderId'] }}
|
||||
</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['opBeforeAmount'] / 100 }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="变动金额">
|
||||
{{ vdata.detailData['opAmount'] / 100 }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="变动后账户余额">
|
||||
{{ vdata.detailData['opAfterAmount'] / 100 }}
|
||||
</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 lang="ts" setup>
|
||||
import { API_URL_WALLET_HISTORY_LIST, req } from '@/api/manage'
|
||||
import {defineProps,reactive} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
isvList: [], // 服务商下拉列表
|
||||
isvName: '' // 服务商名称
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_WALLET_HISTORY_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
17
jeepay-ui-agent/src/views/accountCenter/history/History.vue
Normal file
17
jeepay-ui-agent/src/views/accountCenter/history/History.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<HistoryPanel ref="historyPanelRef" :default-query-condition="vdata.defSearchData" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import { ref, reactive } from 'vue'
|
||||
import HistoryPanel from './HistoryPanel.vue'
|
||||
|
||||
const historyPanelRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
defSearchData: {infoType: 'PLATFORM', opAccountType: 1}
|
||||
})
|
||||
|
||||
</script>
|
||||
122
jeepay-ui-agent/src/views/accountCenter/history/HistoryPanel.vue
Normal file
122
jeepay-ui-agent/src/views/accountCenter/history/HistoryPanel.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<!--
|
||||
历史记录的通用组件, 可抽屉可 页面
|
||||
|
||||
@author terrfly
|
||||
@site https://www.jeequan.com
|
||||
@date 2022/03/23 20:23
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm v-if="props.showSearch" :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>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData['opAccountType']" 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>
|
||||
|
||||
<jeepay-text-up v-model:value="vdata.searchData['hid']" :placeholder="'流水号'" />
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="hid"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'infoId'">
|
||||
<span v-if="record.infoType == 'AGENT'">服务商: {{ record.infoName }}({{ record.infoId }})</span>
|
||||
|
||||
<span v-if="record.infoId == 'PLATFORM_INACCOUNT'">运营平台入账账户</span>
|
||||
|
||||
<span v-if="record.infoId == 'PLATFORM_PROFIT'">运营平台利润账户</span>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'opBeforeAmount'">
|
||||
<span>{{ record.opBeforeAmount / 100 }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'opAmount'">
|
||||
<span>{{ record.opAmount / 100 }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'opAfterAmount'">
|
||||
<span>{{ record.opAfterAmount / 100 }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" @click="detailFunc(record.hid)">详情</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 详情页面组件 -->
|
||||
<InfoDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import { API_URL_WALLET_HISTORY_LIST, req, reqLoad } from '@/api/manage'
|
||||
import InfoDetail from './Detail.vue'
|
||||
import { ref, reactive, defineProps, getCurrentInstance, onMounted } from 'vue'
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
// 定义父组件的传值
|
||||
const props = defineProps({
|
||||
defaultQueryCondition: { type: Object, default: () => {} }, // 查询集合的条件
|
||||
showSearch: { type: Boolean, default: true } //是否显示搜索面板
|
||||
})
|
||||
|
||||
const infoDetail = ref()
|
||||
|
||||
const infoTable = ref()
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ key: 'hid', title: '流水号', fixed: 'left', dataIndex: 'hid', },
|
||||
{ key: 'opBeforeAmount', title: '变动前账户余额', dataIndex: 'opBeforeAmount', },
|
||||
{ key: 'opAmount', title: '变动金额', dataIndex: 'opAmount', },
|
||||
{ key: 'opAfterAmount', title: '变动后账户余额', dataIndex: 'opAfterAmount' , },
|
||||
{ key: 'relaBizOrderId', title: '关联订单号', dataIndex: 'relaBizOrderId' , },
|
||||
{ key: 'createdAt', title: '时间', dataIndex: 'createdAt' , width: 200,},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
const dateRangePicker = ref()
|
||||
const vdata : any = reactive({
|
||||
searchData : { queryDateRange: 'today' }
|
||||
})
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
Object.assign(vdata.searchData, props.defaultQueryCondition)
|
||||
infoTable.value.refTable(true)
|
||||
})
|
||||
|
||||
function resetFunc() {
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: 'today', opAccountType: 1 }
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params: any) {
|
||||
return req.list(API_URL_WALLET_HISTORY_LIST, params)
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function detailFunc (recordId: any) { // 钱包流水详情页
|
||||
infoDetail.value.show(recordId)
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,39 @@
|
||||
<!-- 通用抽屉 -->
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="流水记录"
|
||||
:closable="true"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
:drawer-style="{ backgroundColor: '#f0f2f5' }"
|
||||
width="85%"
|
||||
@close="vdata.visible = false"
|
||||
>
|
||||
<div>
|
||||
<HistoryPanel v-if="vdata.visible" ref="historyPanelRef" :showSearch="vdata.showSearch" :defaultQueryCondition="vdata.defaultQueryCondition" />
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup >
|
||||
import { ref, reactive, defineExpose } from 'vue'
|
||||
import HistoryPanel from './HistoryPanel.vue'
|
||||
|
||||
const historyPanelRef = ref()
|
||||
|
||||
|
||||
const vdata : any = reactive({
|
||||
visible: false, // 一级抽屉开关
|
||||
defaultQueryCondition: { type: Object, default: () => {} }, // 查询集合的条件
|
||||
showSearch: { type: Boolean, default: true } //是否显示搜索面板
|
||||
})
|
||||
|
||||
// 弹层打开事件
|
||||
function show (queryObject, isShow) {
|
||||
vdata.defaultQueryCondition = queryObject
|
||||
vdata.showSearch = isShow
|
||||
vdata.visible = true
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<div style="background-color: white; min-height: 100%">
|
||||
<!-- <JeepayPayConfigPanel-->
|
||||
<!-- ref="jeepayPaywayRatePanelRef"-->
|
||||
<!-- configMode="agentSelf"-->
|
||||
<!-- infoId="CURRENTAGENT"-->
|
||||
<!-- isvNo="CURRENTAGENT"-->
|
||||
<!-- />-->
|
||||
<!-- <JeepayPaymentConfigDrawer-->
|
||||
<!-- ref="jeepayPaywayRatePanelRef"-->
|
||||
<!-- configMode="agentSelf"-->
|
||||
<!-- infoId="CURRENTAGENT"-->
|
||||
<!-- />-->
|
||||
|
||||
<JeepayPaymentWayConfig type="0" infoId="CURRENTAGENT" configMode="agentSelf" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {reactive} from 'vue'
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
::v-deep .drawer.cur {
|
||||
position: relative;
|
||||
}
|
||||
::v-deep .drawer-btn-center-payfee{
|
||||
position: relative !important;
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,689 @@
|
||||
<template>
|
||||
<div class="content">
|
||||
<a-card style="padding: 30px" class="agent-info">
|
||||
<div class="title">
|
||||
<b>服务商信息</b>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<span class="label">服务商名称</span>
|
||||
<span class="desc">{{ vdata.agentInfo.agentName }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">服务商邀请码</span>
|
||||
<span class="desc">{{ inviteCode ? inviteCode : "" }} <copy-outlined style="color: #2691ff;" @click="getCopy()"/></span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">拓展商户</span>
|
||||
<span class="desc">
|
||||
<QrcodeOutlined style="color: #2691ff;" @click="getVisibleAddQrc(0)" />
|
||||
<copy-outlined style="color: #2691ff;padding-left: 5px" @click="getCopyCode(0)"/>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">拓展代理</span>
|
||||
<span class="desc">
|
||||
<QrcodeOutlined style="color: #2691ff;" @click="getVisibleAddQrc(1)" />
|
||||
<copy-outlined style="color: #2691ff;padding-left: 5px" @click="getCopyCode(1)"/>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">服务商简称</span>
|
||||
<span class="desc">{{ vdata.agentInfo.agentShortName }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">登录名</span>
|
||||
<span class="desc">{{ vdata.agentInfo.loginUsername }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">服务商号</span>
|
||||
<span class="desc">{{ vdata.agentInfo.agentNo }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">渠道商号</span>
|
||||
<span class="desc">{{ vdata.agentInfo.isvNo }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">上级服务商号</span>
|
||||
<span class="desc">{{ vdata.agentInfo.pid }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">是否允许发展下级服务商</span>
|
||||
<span class="desc">{{
|
||||
vdata.agentInfo.addAgentFlag == 1 ? '是' : '否'
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">注册时间</span>
|
||||
<span class="desc">{{ vdata.agentInfo.createdAt }}</span>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<a-card class="statistics-box order-statistics order">
|
||||
<div class="box-flex">
|
||||
<div class="title">
|
||||
<b style="flex-grow: 1">订单/商户统计</b>
|
||||
<a-select
|
||||
v-model:value="vdata.orderStatic"
|
||||
placeholder="订单统计"
|
||||
style="width: 215px; margin-right: 10px"
|
||||
@change="staticChange"
|
||||
>
|
||||
<a-select-option value="1"> 仅统计自己 </a-select-option>
|
||||
<a-select-option value="2"> 全部服务商 </a-select-option>
|
||||
<a-select-option
|
||||
v-for="(item, index) in (vdata.agentList as any)"
|
||||
:key="index"
|
||||
:value="item.agentNo"
|
||||
>
|
||||
{{ item.agentName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<JeepayDateRangePicker
|
||||
v-model:value="orderDate"
|
||||
class="date"
|
||||
customDateRangeType="date"
|
||||
:allTimeIsShow="false"
|
||||
@update:value="getStatisticsData('order')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="other-item" style="margin: 30px 0">
|
||||
<div class="item">
|
||||
<p class="item-title">成交金额(元)</p>
|
||||
<p class="item-text" style="color: #1890ff !important">
|
||||
{{ (vdata.payAmount / 100).toFixed(2) }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">交易笔数(笔)</p>
|
||||
<p class="item-text">{{ vdata.payCount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">退款金额(元)</p>
|
||||
<p class="item-text">{{ (vdata.refundAmount / 100).toFixed(2) }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">退款笔数(笔)</p>
|
||||
<p class="item-text">{{ vdata.refundCount }}</p>
|
||||
</div>
|
||||
<!-- <div class="item">
|
||||
<p class="item-title">利润(元)</p>
|
||||
<p class="item-text">{{ vdata.profit }}</p>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="other-item">
|
||||
<div class="item">
|
||||
<p class="item-title">商户总数</p>
|
||||
<p class="item-text" style="color: #1890ff !important">
|
||||
{{ vdata.mchAllCount }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">新增商户数</p>
|
||||
<p class="item-text">{{ vdata.mchTodayAddCount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">入网商户数</p>
|
||||
<p class="item-text">{{ vdata.mchOnNetCount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">新增入网商户</p>
|
||||
<p class="item-text">{{ vdata.mchOnNetNewCount }}</p>
|
||||
</div>
|
||||
<!-- <div class="item">
|
||||
<p class="item-title">入网失败商户</p>
|
||||
<p class="item-text">{{ vdata.mchOnNetFailCount }}</p>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
<!-- <a-card class="statistics-box order-statistics">
|
||||
<div class="title">
|
||||
<b>商户统计</b>
|
||||
<a-select v-model:value="vdata.mchStatic" placeholder="商户统计" style="width: 200px" @change="staticChange('mch')">
|
||||
<a-select-option value="1">
|
||||
仅统计自己
|
||||
</a-select-option>
|
||||
<a-select-option value="2">
|
||||
全部
|
||||
</a-select-option>
|
||||
<a-select-option v-for="(item, index) in (vdata.agentList as any)" :key="index" :value="item.agentNo">
|
||||
{{ item.agentName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<JeepayDateRangePicker v-model:value="mchDate" class="date" customDateRangeType="date" :allTimeIsShow="false" @update:value="getStatisticsData('merchant')" />
|
||||
</div>
|
||||
</a-card> -->
|
||||
<a-card
|
||||
v-if="vdata.agentInfo.addAgentFlag == 1"
|
||||
class="statistics-box agent"
|
||||
>
|
||||
<div class="agent-statistics">
|
||||
<div class="title">
|
||||
<b>服务商统计</b>
|
||||
<!-- <JeepayDateRangePicker
|
||||
v-model:value="agentDate"
|
||||
class="date"
|
||||
customDateRangeType="date"
|
||||
:allTimeIsShow="false"
|
||||
@update:value="getStatisticsData('agent')"
|
||||
/> -->
|
||||
</div>
|
||||
<div class="main-item">
|
||||
<p class="item-title">服务商总数</p>
|
||||
<p class="item-text">{{ vdata.agentAllCount }}</p>
|
||||
</div>
|
||||
<div class="other-item">
|
||||
<div class="item">
|
||||
<p class="item-title">新增服务商数</p>
|
||||
<p class="item-text">{{ vdata.agentNewCount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">活动服务商数</p>
|
||||
<p class="item-text">{{ vdata.agentOnCount }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
<a-card class="statistics-box hardware-statistics hardware">
|
||||
<div class="title">
|
||||
<b>硬件统计</b>
|
||||
</div>
|
||||
<div class="other-item hardware-item">
|
||||
<div class="item">
|
||||
<p class="item-title">码牌总数</p>
|
||||
<p class="item-text item-text-top">{{ vdata.qrCodeCardAllCount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">云喇叭总数</p>
|
||||
<p class="item-text item-text-top">{{ vdata.speakerAllCount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">云打印总数</p>
|
||||
<p class="item-text item-text-top">{{ vdata.printerAllCount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">POS机总数</p>
|
||||
<p class="item-text item-text-top">{{ vdata.posAllCount }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="other-item hardware-item">
|
||||
<div class="item">
|
||||
<p class="item-title">空码数量</p>
|
||||
<p class="item-text">{{ vdata.qrCodeCardUnCount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">未绑定云喇叭数</p>
|
||||
<p class="item-text">{{ vdata.speakerUnCount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">未绑定云打印数</p>
|
||||
<p class="item-text">{{ vdata.printerUnCount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<p class="item-title">未绑定POS机数</p>
|
||||
<p class="item-text">{{ vdata.posUnCount }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</div>
|
||||
|
||||
|
||||
<a-modal
|
||||
v-model:visible="vdata.visibleAddQrc"
|
||||
:footer="null"
|
||||
@cancel="handleCancel"
|
||||
style="top: 30% !important;"
|
||||
wrap-class-name="full-modal"
|
||||
width="330px"
|
||||
:title="vdata.title"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<div class="modal-body" style="height: 280px !important;">
|
||||
<div style="text-align: center">
|
||||
<img
|
||||
v-if="vdata.inviteUrl"
|
||||
:src='"https://api.pwmqr.com/qrcode/create/?url="+vdata.inviteUrl'
|
||||
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>
|
||||
<a-button
|
||||
type="primary"
|
||||
size="large"
|
||||
block
|
||||
@click="vdata.visibleAddQrc = false"
|
||||
>
|
||||
取消扫码
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, reactive, onMounted, getCurrentInstance} from 'vue'
|
||||
import {
|
||||
$getStatistics,
|
||||
API_URL_AGENT_LIST,
|
||||
req,
|
||||
$getMainUserInfo, $getUserInfo
|
||||
} from '@/api/manage'
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties;
|
||||
const vdata: any = reactive({
|
||||
title:"",
|
||||
inviteUrl:"" as any,
|
||||
visibleAddQrc:false,
|
||||
payAmount: 0, //成交金额
|
||||
payCount: 0, //交易笔数
|
||||
refundAmount: 0, //退款金额
|
||||
refundCount: 0, //退款笔数
|
||||
profit: 0, //利润
|
||||
|
||||
mchAllCount: 0, // 商户总数
|
||||
mchTodayAddCount: 0, // 新增商户数
|
||||
mchOnNetCount: 0, //入网商户数
|
||||
mchOnNetNewCount: 0, // 新增商户入网数量
|
||||
mchOnNetFailCount: 0, //入网失败商户数
|
||||
|
||||
agentAllCount: 0, // 服务商总数
|
||||
agentNewCount: 0, //新增服务商数
|
||||
agentOnCount: 0, //活动服务商数
|
||||
|
||||
orderTodayCount: 0, // 今日订单数量
|
||||
orderTodaySum: 0, // 今日订单金额
|
||||
|
||||
qrCodeCardAllCount: 0, // 码牌总数
|
||||
speakerAllCount: 0, //云喇叭总数
|
||||
printerAllCount: 0, //云打印总数
|
||||
posAllCount: 0, //POS机总数
|
||||
qrCodeCardUnCount: 0, //空码数量
|
||||
speakerUnCount: 0, //未绑定云喇叭数
|
||||
printerUnCount: 0, //未绑定云打印数
|
||||
posUnCount: 0, //未绑定POS机数
|
||||
|
||||
qrCodeCardBindCount: 0, // 已绑定码牌
|
||||
qrCodeCardUnBindCount: 0, // 剩余未绑定码牌
|
||||
|
||||
// 用于下拉框筛选
|
||||
orderStatic: '2', // 订单统计(商户统计)
|
||||
countType: '2', // 自己全部或者子代理
|
||||
agentNo: '', // 服务商编号
|
||||
agentList: [], // 服务商列表
|
||||
|
||||
// 服务商信息
|
||||
agentInfo: {} as any
|
||||
})
|
||||
let statisticsDate = ref('today') // 公共日期
|
||||
let agentDate = ref('today') // 服务商日期
|
||||
let mchDate = ref('today') // 商户日期
|
||||
let orderDate = ref('today') // 订单日期
|
||||
|
||||
const inviteCode = ref(); //服务商邀请码
|
||||
const inviteCodeUrl = ref(); //服务商二维码
|
||||
const agtInviteCodeUrl = ref(); //服务商二维码
|
||||
// 获取服务商列表
|
||||
const getAgentList = () => {
|
||||
req.list(API_URL_AGENT_LIST, vdata.searchData).then((bizData) => {
|
||||
vdata.agentList = bizData.records
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
getAgentList()
|
||||
|
||||
$getUserInfo().then((res) => {
|
||||
inviteCode.value = res.inviteCode;
|
||||
inviteCodeUrl.value = res.inviteCodeUrl;
|
||||
agtInviteCodeUrl.value = res.agtInviteCodeUrl;
|
||||
});
|
||||
})
|
||||
|
||||
// 获取服务商信息
|
||||
$getMainUserInfo().then((res) => {
|
||||
vdata.agentInfo = res
|
||||
})
|
||||
|
||||
// 订单统计切换服务商
|
||||
const staticChange = (e) => {
|
||||
// countType 统计数据类型 1-服务商本身数据 2-全部 3-服务商号搜索 agentNo 3类型时必传
|
||||
let no = e ? e : ''
|
||||
if (['1', '2'].includes(no)) {
|
||||
vdata.countType = no
|
||||
vdata.agentNo = ''
|
||||
} else {
|
||||
vdata.countType = 3
|
||||
vdata.agentNo = no
|
||||
}
|
||||
|
||||
$getStatistics(statisticsDate.value, vdata.countType, vdata.agentNo).then(
|
||||
(bizData) => {
|
||||
const { payAmount, payCount, refundAmount, refundCount } =
|
||||
bizData.orderCount
|
||||
vdata.payAmount = payAmount
|
||||
vdata.payCount = payCount
|
||||
vdata.refundAmount = refundAmount
|
||||
vdata.refundCount = refundCount
|
||||
|
||||
const {
|
||||
mchAllCount,
|
||||
mchTodayAddCount,
|
||||
mchOnNetCount,
|
||||
mchOnNetNewCount,
|
||||
mchOnNetFailCount
|
||||
} = bizData.mchCount
|
||||
vdata.mchAllCount = mchAllCount
|
||||
vdata.mchTodayAddCount = mchTodayAddCount
|
||||
vdata.mchOnNetCount = mchOnNetCount
|
||||
vdata.mchOnNetNewCount = mchOnNetNewCount
|
||||
vdata.mchOnNetFailCount = mchOnNetFailCount
|
||||
|
||||
const {
|
||||
agentAllCount,
|
||||
agentNewCount,
|
||||
agentOnCount
|
||||
} = bizData.agentCount
|
||||
vdata.agentAllCount = agentAllCount
|
||||
vdata.agentNewCount = agentNewCount
|
||||
vdata.agentOnCount = agentOnCount
|
||||
}
|
||||
)
|
||||
}
|
||||
function handleCancel(e) {
|
||||
vdata.visibleAddQrc = false;
|
||||
}
|
||||
// 获取统计数据
|
||||
function getStatisticsData(sign) {
|
||||
if (sign === 'order') {
|
||||
// statisticsDate.value = mchDate.value
|
||||
|
||||
statisticsDate.value = orderDate.value
|
||||
}
|
||||
$getStatistics(statisticsDate.value, vdata.countType, vdata.agentNo)
|
||||
.then((res) => {
|
||||
if (sign === 'order') {
|
||||
vdata.agentAllCount = res.agentCount.agentAllCount
|
||||
vdata.agentNewCount = res.agentCount.agentNewCount
|
||||
vdata.agentOnCount = res.agentCount.agentOnCount
|
||||
|
||||
vdata.mchAllCount = res.mchCount.mchAllCount
|
||||
vdata.mchOnNetNewCount = res.mchCount.mchOnNetNewCount
|
||||
vdata.mchTodayAddCount = res.mchCount.mchTodayAddCount
|
||||
vdata.mchOnNetCount = res.mchCount.mchOnNetCount
|
||||
vdata.mchOnNetFailCount = res.mchCount.mchOnNetFailCount
|
||||
|
||||
vdata.payAmount = res.orderCount.payAmount
|
||||
vdata.payCount = res.orderCount.payCount
|
||||
vdata.refundAmount = res.orderCount.refundAmount
|
||||
vdata.refundCount = res.orderCount.refundCount
|
||||
vdata.profit = res.payProfit
|
||||
} else {
|
||||
// 服务商
|
||||
vdata.agentAllCount = res.agentCount.agentAllCount
|
||||
vdata.agentNewCount = res.agentCount.agentNewCount
|
||||
vdata.agentOnCount = res.agentCount.agentOnCount
|
||||
// 商户
|
||||
vdata.mchAllCount = res.mchCount.mchAllCount
|
||||
vdata.mchOnNetCount = res.mchCount.mchOnNetCount
|
||||
vdata.mchTodayAddCount = res.mchCount.mchTodayAddCount
|
||||
vdata.mchOnNetNewCount = res.mchCount.mchOnNetNewCount
|
||||
vdata.mchOnNetFailCount = res.mchCount.mchOnNetFailCount
|
||||
// 订单
|
||||
vdata.payAmount = res.orderCount.payAmount
|
||||
vdata.payCount = res.orderCount.payCount
|
||||
vdata.refundAmount = res.orderCount.refundAmount
|
||||
vdata.refundCount = res.orderCount.refundCount
|
||||
vdata.profit = res.payProfit
|
||||
|
||||
// 码牌
|
||||
vdata.qrCodeCardAllCount = res.qrCodeCardAllCount
|
||||
vdata.speakerAllCount = res.speakerAllCount
|
||||
vdata.printerAllCount = res.printerAllCount
|
||||
vdata.posAllCount = res.posAllCount
|
||||
vdata.qrCodeCardUnCount = res.qrCodeCardUnBindCount
|
||||
vdata.speakerUnCount = res.speakerUnCount
|
||||
vdata.printerUnCount = res.printerUnCount
|
||||
vdata.posUnCount = res.posUnCount
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
function getCopyCode(type = 0){
|
||||
|
||||
const textarea = document.createElement('textarea');
|
||||
let text = "拓展商户链接复制成功";
|
||||
if(type == 1){
|
||||
text = '拓展服务商链接复制成功'
|
||||
textarea.value = agtInviteCodeUrl.value;
|
||||
}else{
|
||||
textarea.value = inviteCodeUrl.value;
|
||||
}
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(textarea);
|
||||
$infoBox.message.success(text)
|
||||
}
|
||||
|
||||
async function getCopy(){
|
||||
console.log(inviteCode.value)
|
||||
// var textarea= document.createElement("textarea"); // 创建textarea对象
|
||||
// document.body.appendChild(inviteCode.value); // 添加临时实例
|
||||
// textarea.select(); // 选择实例内容
|
||||
// document.execCommand("Copy"); // 执行复制
|
||||
// document.body.removeChild(textarea); // 删除临时实例
|
||||
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = inviteCode.value;
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(textarea);
|
||||
$infoBox.message.success('复制成功')
|
||||
}
|
||||
function getVisibleAddQrc(type = 0){
|
||||
if(type == 1){
|
||||
vdata.title="拓展代理"
|
||||
vdata.inviteUrl = agtInviteCodeUrl.value
|
||||
}else{
|
||||
vdata.title="拓展商户"
|
||||
vdata.inviteUrl = inviteCodeUrl.value
|
||||
}
|
||||
console.log(vdata.inviteUrl,'vdata.inviteUrl')
|
||||
vdata.visibleAddQrc = true
|
||||
}
|
||||
Promise.all([
|
||||
$getStatistics(statisticsDate.value, vdata.countType, vdata.agentNo)
|
||||
])
|
||||
.then((res) => {
|
||||
getStatisticsData('')
|
||||
})
|
||||
.catch((error) => {})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.statistics-box {
|
||||
box-sizing: border-box;
|
||||
padding: 30px;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.main-item,
|
||||
.other-item {
|
||||
width: 100%;
|
||||
.item {
|
||||
width: 25%;
|
||||
}
|
||||
p {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.item-title {
|
||||
white-space: nowrap;
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.05em;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.item-text {
|
||||
font-weight: 400;
|
||||
font-size: 50px;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--ant-primary-color);
|
||||
}
|
||||
}
|
||||
.other-item {
|
||||
display: flex;
|
||||
.item-text {
|
||||
font-weight: 400;
|
||||
font-size: 25px;
|
||||
letter-spacing: 0.05em;
|
||||
color: #000 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hardware-statistics {
|
||||
.hardware-item {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.item {
|
||||
width: 25%;
|
||||
}
|
||||
.item-text-top {
|
||||
margin-bottom: 30px !important;
|
||||
font-weight: 400;
|
||||
font-size: 37px;
|
||||
}
|
||||
}
|
||||
}
|
||||
/deep/ .ant-card-body {
|
||||
height: 100%;
|
||||
}
|
||||
.box-flex {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
height: 100%;
|
||||
align-content: space-between;
|
||||
& > div {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
b {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.date {
|
||||
width: 215px;
|
||||
}
|
||||
}
|
||||
.agent-info {
|
||||
margin-bottom: 30px;
|
||||
.desc {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.05em;
|
||||
color: #262626;
|
||||
}
|
||||
.label {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 10px;
|
||||
&:nth-last-child(1) {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.agent-statistics {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
height: 100%;
|
||||
align-content: space-between;
|
||||
& > div {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式部分
|
||||
.agent-info,
|
||||
.order,
|
||||
.agent,
|
||||
.hardware {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1024px) {
|
||||
.agent-info {
|
||||
order: 1;
|
||||
width: 280px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.agent {
|
||||
order: 0;
|
||||
width: 260px;
|
||||
flex-grow: 1;
|
||||
margin-right: 30px;
|
||||
}
|
||||
.order,
|
||||
.hardware {
|
||||
order: 3;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1430px) {
|
||||
.agent,
|
||||
.agent-info {
|
||||
width: 350px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
.order,
|
||||
.hardware {
|
||||
width: 65%;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.agent-info {
|
||||
order: 0;
|
||||
}
|
||||
.order {
|
||||
order: 1;
|
||||
}
|
||||
.agent {
|
||||
order: 2;
|
||||
}
|
||||
.hardware {
|
||||
order: 3;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<div style="background-color: white; min-height: 100%">
|
||||
<JeepayPayIsvTransferConfigPanel type="0" infoId="CURRENTAGENT" configMode="agentSelf" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {reactive} from 'vue'
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
::v-deep .drawer.cur {
|
||||
position: relative;
|
||||
}
|
||||
::v-deep .drawer-btn-center-payfee{
|
||||
position: relative !important;
|
||||
|
||||
}
|
||||
</style>
|
||||
426
jeepay-ui-agent/src/views/accountCenter/wallet/Wallet.vue
Normal file
426
jeepay-ui-agent/src/views/accountCenter/wallet/Wallet.vue
Normal file
@@ -0,0 +1,426 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-card style="width: 100%; margin-bottom: 20px">
|
||||
<div class="title">
|
||||
<p>佣金钱包</p>
|
||||
</div>
|
||||
<div class="items">
|
||||
<div class="item">
|
||||
<div style="display: flex">
|
||||
<p class="item-title">钱包余额(元)</p>
|
||||
<!-- <a-tooltip class="tooltip">
|
||||
<template #title></template>
|
||||
<i class="bi bi-info-circle" />
|
||||
</a-tooltip> -->
|
||||
</div>
|
||||
<p class="item-detail">{{ vdata.balanceAmountShow }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div style="display: flex">
|
||||
<p class="item-title">在途利润(元)</p>
|
||||
<a-tooltip class="tooltip">
|
||||
<template #title>处于结算周期中的实际利润金额。</template>
|
||||
<i class="bi bi-info-circle" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<p class="item-sub">{{ vdata.auditProfitAmount }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div style="display: flex">
|
||||
<p class="item-title">提现中金额(元)</p>
|
||||
<a-tooltip class="tooltip">
|
||||
<template #title>处于提现中状态下的金额</template>
|
||||
<i class="bi bi-info-circle" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<p class="item-sub">{{ vdata.unAmountShow }}</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div style="display: flex">
|
||||
<p class="item-title">冻结金额(元)</p>
|
||||
<a-tooltip class="tooltip">
|
||||
<template #title>
|
||||
<span>
|
||||
冻结金额为不可提现金额,当前可提现金额为:{{ vdata.allowTakeAmount }} 元。
|
||||
</span>
|
||||
<span v-if="vdata.detailData.freezeDesc"><br>冻结原因:【{{ vdata.detailData.freezeDesc }}】,请尽快处理。</span>
|
||||
</template>
|
||||
<i class="bi bi-info-circle" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<p class="item-sub">{{ vdata.freezeAmount }}</p>
|
||||
</div>
|
||||
<div class="item operate" @click="withdrawFunc">
|
||||
<a-button type="primary">提现</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
<a-card 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="dateTime"
|
||||
/>
|
||||
</a-form-item>
|
||||
<jeepay-text-up
|
||||
v-model:value="vdata.searchData['rid']"
|
||||
: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="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>
|
||||
<!-- 提现弹出框 -->
|
||||
<withdraw-modal ref="withdrawModalInfo" :callbackFunc="refreshTable" />
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="rid"
|
||||
:statisticsIsShow="$access('ENT_CASHOUT_RECORD_COUNT')"
|
||||
@btnLoadClose="vdata.btnLoading = false"
|
||||
>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in tableCount" :key="index" class="item">
|
||||
<div v-if="item.type == 'line'" class="line" />
|
||||
<div class="title-count">{{ 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>
|
||||
<a-button type="primary" @click="withdrawFunc()">
|
||||
<plus-outlined />发起提现
|
||||
</a-button>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key == 'state'">
|
||||
<a-tag v-if="record.state == 1" color="orange">审核中</a-tag>
|
||||
<a-tag v-if="record.state == 2" color="red">审核失败</a-tag>
|
||||
<a-tag v-if="record.state == 3" color="purple">结算中</a-tag>
|
||||
<a-tag v-if="record.state == 4" color="green">结算成功</a-tag>
|
||||
<a-tag v-if="record.state == 5" color="red">结算失败</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key == 'applyAmount'">
|
||||
<span>{{ record.applyAmount / 100 }}</span>
|
||||
</template>
|
||||
<template v-if="column.key == 'settAmount'">
|
||||
<span>{{ record.settAmount / 100 }}</span>
|
||||
</template>
|
||||
<template v-if="column.key == 'settFeeAmount'">
|
||||
<span>{{ record.settFeeAmount / 100 }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'op'">
|
||||
<a-button type="link" @click="detailFunc(record.rid)">详情</a-button>
|
||||
<a-button
|
||||
v-show="record.state === 2"
|
||||
type="link"
|
||||
style="color: red"
|
||||
@click="withdrawAgainFunc(record)"
|
||||
>
|
||||
重新提现
|
||||
</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 详情页面组件 -->
|
||||
<InfoDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { message } from 'ant-design-vue'
|
||||
import withdrawModal from './WithdrawModal.vue' // 提现弹出框
|
||||
import InfoDetail from './WithdrawDetail.vue'
|
||||
import { API_URL_WITHDRAWALS_RECORD_LIST, $getMainUserInfo, req, $getStatistics, $cashoutCount } from '@/api/manage'
|
||||
import { ref, onMounted, reactive, getCurrentInstance } from 'vue'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties // 获取全局函数
|
||||
const infoTable = ref()
|
||||
const vdata = reactive({
|
||||
visible: false,
|
||||
searchData: {} as any,
|
||||
detailData: {} as any,
|
||||
selectedIds: [] as any,
|
||||
auditProfitAmount: '',
|
||||
balanceAmount: 0,
|
||||
balanceAmountShow: '',
|
||||
unAmountShow: '',
|
||||
unAmount: 0,
|
||||
freezeAmount: '', // 冻结金额
|
||||
allowTakeAmount: '', // 当前可提现金额
|
||||
btnLoading: false
|
||||
})
|
||||
let tableCount:any = ref([]) // 数据统计数组
|
||||
const tableColumns = reactive([
|
||||
{
|
||||
key: 'rid',
|
||||
title: '提现单号',
|
||||
fixed: 'left',
|
||||
dataIndex: 'rid',
|
||||
|
||||
},
|
||||
{
|
||||
key: 'applyAmount',
|
||||
title: '申请金额',
|
||||
dataIndex: 'applyAmount',
|
||||
|
||||
},
|
||||
{
|
||||
key: 'settFeeAmount',
|
||||
title: '手续费',
|
||||
dataIndex: 'settFeeAmount',
|
||||
|
||||
},
|
||||
{
|
||||
key: 'settAmount',
|
||||
title: '入账金额',
|
||||
dataIndex: 'settAmount',
|
||||
|
||||
},
|
||||
{
|
||||
key: 'state',
|
||||
title: '提现状态',
|
||||
dataIndex: 'state',
|
||||
|
||||
},
|
||||
{
|
||||
key: 'createdAt',
|
||||
title: '发起时间',
|
||||
dataIndex: 'createdAt',
|
||||
|
||||
},
|
||||
{
|
||||
key: 'op',
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
|
||||
}
|
||||
])
|
||||
const withdrawModalInfo = ref()
|
||||
const infoDetail = ref()
|
||||
const dateRangePicker = ref()
|
||||
// 传递的开始提现对象
|
||||
const sendObject = reactive({
|
||||
amount: 0,
|
||||
agentType: '', // 代理商类型
|
||||
settAccountType: '', //账户类型
|
||||
settAccountNo: '', //结算账户
|
||||
settAccountName: '', //账户姓名
|
||||
settAccountBank: '', //开户行
|
||||
settAccountSubBank: '', //开户行支行名称
|
||||
settCertImg: '', //提现凭证
|
||||
applyRemark: '', //提现备注
|
||||
settFeeAmount: 0, //提现手续费
|
||||
contactTel: '', //联系人手机号
|
||||
contactName: '', //联系人姓名
|
||||
applyAmount: 0, //申请提现金额
|
||||
balanceAmount: 0, // 钱包余额
|
||||
freezeAmount: 0, // 钱包冻结金额
|
||||
isAgain: false
|
||||
})
|
||||
|
||||
// 数据统计
|
||||
const getTableCount = () => {
|
||||
|
||||
if(!$access('ENT_CASHOUT_RECORD_COUNT')){
|
||||
return false
|
||||
}
|
||||
|
||||
$cashoutCount(vdata.searchData).then( res => {
|
||||
tableCount.value = [
|
||||
{title: '申请金额', symbol: 'add', isAmount: true, textColor: '#1A66FF', content: (res.applyAmount / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '手续费', symbol: 'add', isAmount: true, textColor: '#1A66FF', content: (res.settFeeAmount / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '入账金额', symbol: 'add', isAmount: true, textColor: '#1A66FF', content: (res.settAmount / 100).toFixed(2)},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
onMounted( () => {
|
||||
getTableCount()
|
||||
})
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params) {
|
||||
return req.list(API_URL_WITHDRAWALS_RECORD_LIST, params)
|
||||
}
|
||||
|
||||
function detailFunc(recordId) {
|
||||
infoDetail.value.show(recordId)
|
||||
}
|
||||
|
||||
function resetFunc() {
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = {}
|
||||
}
|
||||
// 获取统计数据
|
||||
function getStatisticsData() {
|
||||
$getStatistics('')
|
||||
.then((res) => {
|
||||
vdata.detailData = res
|
||||
vdata.auditProfitAmount = (
|
||||
parseFloat(res.auditProfitAmount) / 100
|
||||
).toFixed(2)
|
||||
vdata.balanceAmount = res.availableBalanceAmount / 100
|
||||
vdata.unAmount = res.unAmount / 100
|
||||
vdata.balanceAmountShow = (
|
||||
parseFloat(res.availableBalanceAmount) / 100
|
||||
).toFixed(2)
|
||||
vdata.unAmountShow = (parseFloat(res.unAmount) / 100).toFixed(2)
|
||||
vdata.freezeAmount = (parseFloat(res.freezeAmount) / 100).toFixed(2)
|
||||
vdata.allowTakeAmount = (parseFloat(res.allowTakeAmount) / 100).toFixed(2)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
function searchFunc() {
|
||||
getTableCount()
|
||||
|
||||
// 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
// 获取账户信息
|
||||
function getAccountInfo() {
|
||||
$getMainUserInfo()
|
||||
.then((res) => {
|
||||
sendObject.agentType = res.agentType
|
||||
sendObject.contactTel = res.contactTel
|
||||
sendObject.contactName = res.contactName
|
||||
sendObject.settAccountName = res.settAccountName
|
||||
sendObject.settAccountNo = res.settAccountNo
|
||||
sendObject.settAccountBank = res.settAccountBank
|
||||
sendObject.settAccountType = res.settAccountType
|
||||
sendObject.settAccountSubBank = res.settAccountSubBank
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
function refreshTable() {
|
||||
infoTable.value.refTable(true)
|
||||
getStatisticsData()
|
||||
}
|
||||
|
||||
// 打开提现弹出框
|
||||
function withdrawFunc() {
|
||||
if (vdata.balanceAmount <= 0) {
|
||||
return message.error('无可提现金额')
|
||||
} else {
|
||||
if (Number(vdata.allowTakeAmount) <= 0) {
|
||||
return message.error('无可提现金额')
|
||||
}
|
||||
getAccountInfo()
|
||||
sendObject.settCertImg = ''
|
||||
sendObject.applyRemark = ''
|
||||
sendObject.amount = Number(vdata.allowTakeAmount)
|
||||
sendObject.balanceAmount = Number(vdata.balanceAmount)
|
||||
sendObject.freezeAmount = Number(vdata.freezeAmount)
|
||||
withdrawModalInfo.value.show(sendObject)
|
||||
}
|
||||
}
|
||||
|
||||
// 重新提现
|
||||
function withdrawAgainFunc(saveObject) {
|
||||
getAccountInfo()
|
||||
sendObject.isAgain = true
|
||||
sendObject.amount = vdata.balanceAmount
|
||||
sendObject.settFeeAmount = saveObject.settFeeAmount / 100
|
||||
sendObject.applyRemark = saveObject.applyRemark
|
||||
sendObject.settCertImg = saveObject.settCertImg
|
||||
sendObject.applyAmount = saveObject.applyAmount
|
||||
withdrawModalInfo.value.show(sendObject)
|
||||
}
|
||||
Promise.all([getStatisticsData()])
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.title {
|
||||
box-sizing: border-box;
|
||||
padding: 16px 0 0px 20px;
|
||||
margin-bottom: 30px;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
p {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.07em;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.items {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
.item {
|
||||
margin-bottom: 20px;
|
||||
p {
|
||||
font-weight: 500;
|
||||
margin: 0;
|
||||
}
|
||||
.item-title {
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.05em;
|
||||
color: #737980;
|
||||
}
|
||||
.item-detail,
|
||||
.item-sub {
|
||||
font-size: 25px;
|
||||
color: var(--ant-primary-color);
|
||||
}
|
||||
.item-sub {
|
||||
color: #000000 !important;
|
||||
}
|
||||
}
|
||||
.operate {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100px;
|
||||
height: 38px;
|
||||
border-radius: 3px;
|
||||
margin-top: 15px;
|
||||
p {
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.02em;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tooltip {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.statistics-list .item .title-count {
|
||||
color: #808080;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:title="true ? '提现详情' : ''"
|
||||
: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['applyAmount'] / 100 }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="提现手续费">{{ vdata.detailData['settFeeAmount'] / 100 }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算账户类型">{{ vdata.detailData['settAccountType'] === "WX_CASH" ? '个人微信':vdata.detailData['settAccountType'] === "ALIPAY_CASH"? '个人支付宝':vdata.detailData['settAccountType'] === "BANK_PUBLIC"? '对公账户':vdata.detailData['settAccountType'] === "BANK_PRIVATE"? '对私账户':'银行卡' }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算账号">{{ vdata.detailData['settAccountNo'] }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="开户行名称">{{ vdata.detailData['settAccountBank'] }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算账户姓名">{{ vdata.detailData['settAccountName'] }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.detailData['auditRemark']" :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="失败原因">{{ vdata.detailData['auditRemark'] }}</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['settAccountTelphone'] }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="提现备注">{{ vdata.detailData['applyRemark'] }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="申请资料">
|
||||
<a-image v-if="vdata.detailData.settCertImg" class="withdraw-img" :src="vdata.detailData.settCertImg" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="打款凭证">
|
||||
<a-image v-if="vdata.detailData['transferCertImg'] && vdata.detailData['state'] == 4" class="withdraw-img" :src="vdata.detailData['transferCertImg']" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_WITHDRAWALS_RECORD_LIST, req } from '@/api/manage'
|
||||
import { defineProps, reactive } from 'vue'
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: null }
|
||||
})
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {
|
||||
settCertImg: ''//提现凭证
|
||||
}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show(recordId) { // 弹层打开事件
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_WITHDRAWALS_RECORD_LIST, recordId, {originData: 0}).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose() {
|
||||
vdata.visible = false
|
||||
}
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
.withdraw-img {
|
||||
width: 200px;
|
||||
}
|
||||
</style>
|
||||
355
jeepay-ui-agent/src/views/accountCenter/wallet/WithdrawModal.vue
Normal file
355
jeepay-ui-agent/src/views/accountCenter/wallet/WithdrawModal.vue
Normal file
@@ -0,0 +1,355 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:mask-closable="false"
|
||||
:title=" vdata.isAgain ? '重新提现' : '发起提现' "
|
||||
width="40%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form v-if="vdata.visible" ref="infoFormModel" :model="vdata.saveObject" layout="vertical" :rules="vdata.rules">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="14">
|
||||
<a-form-item :label="'提现金额(最多可提现:' + vdata.amount + '元)'" name="amount">
|
||||
<a-input-number
|
||||
v-model:value="vdata.saveObject.amount"
|
||||
placeholder="请输入提现金额"
|
||||
style="width:70%;"
|
||||
min="0.01"
|
||||
:max="vdata.amount"
|
||||
addon-after="元"
|
||||
/>
|
||||
<span class="jeepay-tip-text">钱包余额:{{ vdata.detailData.balanceAmount }}元,冻结金额:{{ vdata.detailData.freezeAmount }} 元</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-form-item label=" " name="">
|
||||
<a-button type="dashed" style="color: #1f8cf5; background-color: #e6f2fd;" :loading="vdata.btnLoading" @click="handleTakeAllFunc">
|
||||
<PayCircleOutlined />
|
||||
全部提现
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6" />
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="请输入联系人姓名:" name="contactName">
|
||||
<a-input v-model:value="vdata.saveObject.contactName" placeholder="请输入结算账户姓名" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="结算账户联系人手机号:" name="contactTel">
|
||||
<a-input v-model:value="vdata.saveObject.contactTel" placeholder="结算账户联系人手机号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="提现备注:" name="applyRemark">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['applyRemark']"
|
||||
placeholder="请输入提现备注"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<div class="ant-upload-preview">
|
||||
<div>
|
||||
<a-form-item label="申请资料" name="settCertImg" />
|
||||
<img v-show="vdata.saveObject.settCertImg" :src="vdata.saveObject.settCertImg">
|
||||
</div>
|
||||
<div>
|
||||
<JeepayUpload
|
||||
v-model:src="vdata.saveObject.settCertImg"
|
||||
bizType="avatar"
|
||||
:showUploadList="false"
|
||||
/>
|
||||
<span class="jeepay-tip-text">请上传发票等凭证图片</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="24">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="支付密码:" name="sipwRaw">
|
||||
<a-input-password
|
||||
v-model:value="vdata.saveObject['sipwRaw']"
|
||||
maxlength="6"
|
||||
autocomplete="new-password"
|
||||
placeholder="请输入支付密码"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-col>
|
||||
|
||||
<a-divider orientation="left" />
|
||||
<a-col :span="10">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="提现手续费">
|
||||
{{ vdata.saveObject.settFeeAmount }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="到账金额">
|
||||
{{ vdata.receivedAmount }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商类型">
|
||||
{{ vdata.saveObject.agentType === 1 ? '个人':'企业' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收款账户类型">
|
||||
{{ vdata.saveObject.settAccountType === "WX_CASH" ? '个人微信':vdata.saveObject.settAccountType === "ALIPAY_CASH"? '个人支付宝':vdata.saveObject.settAccountType === "BANK_PUBLIC"? '对公账户':vdata.saveObject.settAccountType === "BANK_PRIVATE"? '对私账户':'银行卡' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="vdata.saveObject.settAccountType === 'WX_CASH' || vdata.saveObject.settAccountType === 'ALIPAY_CASH'" justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="账户姓名">
|
||||
{{ vdata.saveObject.settAccountName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item :label="vdata.saveObject.settAccountType === 'ALIPAY_CASH'?'支付宝账号':'个人微信号'">
|
||||
{{ vdata.saveObject.settAccountNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="vdata.saveObject.settAccountType === 'BANK_PRIVATE'" justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="账户姓名">
|
||||
{{ vdata.saveObject.settAccountName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收款银行卡号">
|
||||
{{ vdata.saveObject.settAccountNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="vdata.saveObject.settAccountType === 'BANK_PUBLIC'" justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="对公账户名称">
|
||||
{{ vdata.saveObject.settAccountName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="对公账号">
|
||||
{{ vdata.saveObject.settAccountNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="开户银行名称">
|
||||
{{ vdata.saveObject.settAccountBank }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="开户行支行名称">
|
||||
{{ vdata.saveObject.settAccountSubBank }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="!vdata.saveObject.settAccountNo" :span="10">
|
||||
<a-form-item label="温馨提示:" name="tips">
|
||||
<a-tag color="red">您还未配置结算信息,请联系运营平台添加</a-tag>
|
||||
</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 { $withdrawalApply, $withdrawalFee } from '@/api/manage'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { defineProps, reactive, ref, watch } from 'vue'
|
||||
import { Base64 } from 'js-base64'
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
const infoFormModel = ref()
|
||||
const vdata : any = reactive({
|
||||
feeType: '',//手续费类型
|
||||
applyLimit: 0,//最低提现金额
|
||||
freeLimit: 0,//免收手续费额度
|
||||
fixFee: 0,//固定费用
|
||||
feeRate: 0,//费率
|
||||
btnLoading: false,
|
||||
amount: 0,//可以提现的金额
|
||||
isAgain: true, // 重新提现 or 提现页面标志
|
||||
saveObject: {}, // 数据对象
|
||||
detailData: {} as any, // 数据对象(详情数据)
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
receivedAmount: 0,//到账金额
|
||||
rules: {
|
||||
amount: [{ required: true, message: '请输入提现金额', trigger: 'blur' }],
|
||||
settFeeAmount: [{ required: true, message: '提现手续费', trigger: 'blur' }],
|
||||
contactName: [{ required: true, message: '请输入联系人姓名', trigger: 'blur' }],
|
||||
contactTel: [{ required: true, message: '请输入联系人手机号', trigger: 'blur' }],
|
||||
sipwRaw: [{ required: true, message: '请输入支付密码', trigger: 'blur' }],
|
||||
}
|
||||
})
|
||||
|
||||
// 计算手续费
|
||||
function calculationFee() {
|
||||
$withdrawalFee().then(res => {
|
||||
vdata.feeType = res.feeType
|
||||
vdata.applyLimit = res.applyLimit / 100
|
||||
vdata.freeLimit = res.freeLimit / 100
|
||||
vdata.fixFee = res.fixFee / 100
|
||||
vdata.feeRate = res.feeRate
|
||||
if(res.freeLimit !== 0){ //如果在额度限度里,手续费为0
|
||||
if(vdata.saveObject.amount <= res.freeLimit / 100){
|
||||
vdata.saveObject.settFeeAmount = 0
|
||||
} else { //如果超过限制额度
|
||||
if(res.feeType === 'FIX'){//若是固定额度
|
||||
vdata.saveObject.settFeeAmount = res.fixFee / 100
|
||||
}else if(res.feeType === 'SINGLE'){//若是费率
|
||||
vdata.saveObject.settFeeAmount = (res.feeRate * vdata.saveObject.amount).toFixed(2)
|
||||
}else if(res.feeType === 'FIXANDRATE'){//若是费率 + 固定
|
||||
vdata.saveObject.settFeeAmount = ((res.fixFee) / 100 + (res.feeRate * vdata.saveObject.amount)).toFixed(2)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//如果额度为0则计算费率
|
||||
if(res.feeType === 'FIX'){
|
||||
vdata.saveObject.settFeeAmount = res.fixFee / 100
|
||||
}else if(res.feeType === 'SINGLE'){ //若是费率
|
||||
vdata.saveObject.settFeeAmount = (res.feeRate * vdata.saveObject.amount).toFixed(2)
|
||||
}else if(res.feeType === 'FIXANDRATE'){//若是费率 + 固定
|
||||
vdata.saveObject.settFeeAmount = ((res.fixFee) / 100 + (res.feeRate * vdata.saveObject.amount)).toFixed(2)
|
||||
}
|
||||
}
|
||||
vdata.receivedAmount = (vdata.saveObject.amount - vdata.saveObject.settFeeAmount).toFixed(2)
|
||||
if(vdata.receivedAmount <0 ){
|
||||
vdata.receivedAmount = 0
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
function show (params) { // 弹层打开事件
|
||||
vdata.isAgain = params.isAgain
|
||||
vdata.amount = params.amount
|
||||
vdata.saveObject = params
|
||||
vdata.detailData = params
|
||||
vdata.btnLoading = false
|
||||
vdata.visible = true
|
||||
calculationFee()
|
||||
if(params.isAgain) {
|
||||
vdata.saveObject.amount = params.applyAmount / 100
|
||||
} else {
|
||||
vdata.saveObject.amount = ''
|
||||
}
|
||||
delete vdata.saveObject.applyAmount
|
||||
delete vdata.saveObject.isAgain
|
||||
delete vdata.saveObject.sipwRaw
|
||||
}
|
||||
// 监听提现金额和手续费的变化
|
||||
watch([() => vdata.saveObject.settFeeAmount, () => vdata.saveObject.amount, () => vdata.receivedAmount], (values) => {
|
||||
calculationFee()
|
||||
})
|
||||
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then(valid =>{
|
||||
vdata.btnLoading = true
|
||||
const phoneReg = /^1\d{10}$/
|
||||
if(!phoneReg.test(vdata.saveObject.contactTel)) {
|
||||
message.error(`请输入合法手机号`)
|
||||
vdata.btnLoading = false
|
||||
}else if(isNaN(vdata.receivedAmount) || vdata.receivedAmount <= 0){
|
||||
message.error(`到账金额计算有误, 请重新填写`)
|
||||
vdata.btnLoading = false
|
||||
}else {
|
||||
if(vdata.amount >= parseFloat(vdata.saveObject.amount)) {
|
||||
if(vdata.applyLimit > parseFloat(vdata.saveObject.amount)) {
|
||||
message.error(`最低提现金额为:${vdata.applyLimit}元`)
|
||||
vdata.btnLoading = false
|
||||
} else {
|
||||
// 请求接口
|
||||
vdata.saveObject.sipw = Base64.encode(vdata.saveObject.sipwRaw) // base 64
|
||||
$withdrawalApply(vdata.saveObject).then(res => {
|
||||
if(vdata.isAgain) {
|
||||
message.success('已重新发起提现')
|
||||
} else {
|
||||
message.success('提现已发起')
|
||||
}
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.btnLoading = false
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
vdata.visible = false
|
||||
}
|
||||
} else {
|
||||
message.error(`请输入不大于${vdata.amount}元的金额`)
|
||||
vdata.btnLoading = false
|
||||
}
|
||||
}
|
||||
}).catch(valid =>{
|
||||
console.log(valid)
|
||||
})
|
||||
}
|
||||
|
||||
function handleTakeAllFunc(){
|
||||
vdata.saveObject.amount = vdata.amount
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.ant-upload-preview {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 1px solid rgba(0,0,0,0.08);
|
||||
}
|
||||
.upload-icon {
|
||||
font-size: 1.4rem;
|
||||
background: rgba(222, 221, 221, 0.7);
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
557
jeepay-ui-agent/src/views/agent/AddOrEdit.vue
Normal file
557
jeepay-ui-agent/src/views/agent/AddOrEdit.vue
Normal file
@@ -0,0 +1,557 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:mask-closable="false"
|
||||
:title=" vdata.isAdd ? '新增服务商' : '修改服务商' "
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="40%"
|
||||
class="drawer-width"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form v-if="vdata.visible" ref="infoFormModel" :model="vdata.saveObject" layout="vertical" :rules="vdata.rules">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="服务商名称" name="agentName">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['agentName']"
|
||||
placeholder="请输入服务商名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="登录名" name="loginUsername">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['loginUsername']"
|
||||
placeholder="请输入服务商登录名"
|
||||
:disabled="!vdata.isAdd"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="服务商简称" name="agentShortName">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['agentShortName']"
|
||||
placeholder="请输入服务商简称"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="联系人姓名" name="contactName">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['contactName']"
|
||||
placeholder="请输入联系人姓名"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="联系人邮箱" name="contactEmail">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['contactEmail']"
|
||||
placeholder="请输入联系人邮箱"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="联系人手机号" name="contactTel">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['contactTel']"
|
||||
placeholder="请输入联系人手机号"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col v-if="!vdata.isAdd" :span="10">
|
||||
<a-form-item label="渠道商号" name="isvNo">
|
||||
<a-select v-model:value="vdata.saveObject['isvNo']" :disabled="!vdata.isAdd" placeholder="请选择渠道商">
|
||||
<a-select-option v-for="d in vdata.isvList" :key="d.isvNo" v-model:value="d.isvNo">
|
||||
{{ d.isvName + " [ ID: " + d.isvNo + " ]" }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="状态" name="state">
|
||||
<a-radio-group v-model:value="vdata.saveObject['state']" :disabled="vdata.saveObject.state == '2' || vdata.saveObject.state == '3'">
|
||||
<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="10">
|
||||
<a-form-item label="是否允许发展下级" name="addAgentFlag">
|
||||
<a-radio-group v-model:value="vdata.saveObject['addAgentFlag']">
|
||||
<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="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="备注" name="remark">
|
||||
<a-input v-model:value="vdata.saveObject['remark']" placeholder="请输入备注" type="textarea" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row> -->
|
||||
|
||||
<!-- 重置密码板块 -->
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
账户安全
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div v-if="vdata.isAdd">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="是否发送开通提醒">
|
||||
<a-radio-group v-model:value="vdata.saveObject['isNotify']">
|
||||
<a-radio :value="0">否</a-radio>
|
||||
<a-radio :value="1">是</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="密码设置">
|
||||
<a-radio-group v-model:value="vdata.saveObject['passwordType']">
|
||||
<a-radio value="default">默认密码</a-radio>
|
||||
<a-radio value="custom">自定义密码</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.saveObject.passwordType == 'custom'" :span="12">
|
||||
<a-form-item label="登录密码" name="loginPassword">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['loginPassword']"
|
||||
placeholder="请输入登录密码"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-button type="primary" ghost @click="randomPassage(false, 6, 0)"><file-sync-outlined />随机生成密码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item v-if="vdata.resetIsShow" label="">
|
||||
重置密码:<a-checkbox v-model:checked="vdata.sysPassword.resetPass" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item v-if="vdata.sysPassword.resetPass" label="">
|
||||
恢复默认密码:<a-checkbox v-model:checked="vdata.sysPassword.defaultPass" @click="isResetPass" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
|
||||
<div v-if="vdata.sysPassword.resetPass">
|
||||
<div v-if="!vdata.sysPassword.defaultPass">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="新密码:" name="newPwd">
|
||||
<a-input-password v-model:value="vdata.newPwd" autocomplete="new-password" :disabled="vdata.sysPassword.defaultPass" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="10">
|
||||
<a-form-item label="确认新密码:" name="confirmPwd">
|
||||
<a-input-password v-model:value="vdata.sysPassword.confirmPwd" autocomplete="new-password" :disabled="vdata.sysPassword.defaultPass" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="vdata.isAudit">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
账户信息
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="服务商类型" name="agentType">
|
||||
<a-select v-model:value="vdata.saveObject['agentType']" :defaultValue="1">
|
||||
<a-select-option :value="1">个人</a-select-option>
|
||||
<a-select-option :value="2">企业</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="收款账户类型" name="settAccountType">
|
||||
<a-select v-model:value="vdata.saveObject['settAccountType']" defaultValue="ALIPAY_CASH">
|
||||
<a-select-option value="ALIPAY_CASH">个人支付宝</a-select-option>
|
||||
<a-select-option value="BANK_PRIVATE">对私账户</a-select-option>
|
||||
<a-select-option v-if="vdata.saveObject['agentType'] !== 1" value="BANK_PUBLIC">对公账户</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="vdata.saveObject['settAccountType'] === 'ALIPAY_CASH'" justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="账户姓名">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['settAccountName']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="支付宝账号">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['settAccountNo']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="vdata.saveObject['settAccountType'] === 'BANK_PRIVATE'" justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="账户姓名">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['settAccountName']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="开户银行名称">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['settAccountBank']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="收款银行卡号">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['settAccountNo']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="vdata.saveObject['settAccountType'] === 'BANK_PUBLIC'" justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="对公账户名称">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['settAccountName']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="对公账号">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['settAccountNo']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="开户银行名称">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['settAccountBank']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="开户行支行名称">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['settAccountSubBank']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
资料信息
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col v-if="vdata.saveObject['agentType'] == 2" :span="10">
|
||||
<a-form-item label="营业执照照片" name="licenseImg">
|
||||
<JeepayUpload v-model:src="vdata.saveObject['licenseImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.saveObject['agentType'] == 2 && vdata.saveObject['settAccountType'] == 'BANK_PUBLIC'" :span="10">
|
||||
<a-form-item label="开户许可证照片" name="permitImg">
|
||||
<JeepayUpload v-model:src="vdata.saveObject['permitImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item :label="vdata.saveObject['agentType'] == 1?'[联系人]身份证人像面照片':'[法人]身份证人像面照片'" name="idcard1Img">
|
||||
<JeepayUpload v-model:src="vdata.saveObject['idcard1Img']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item :label="vdata.saveObject['agentType'] == 1?'[联系人]身份证国徽面照片':'[法人]身份证国徽面照片'" name="idcard2Img">
|
||||
<JeepayUpload v-model:src="vdata.saveObject['idcard2Img']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item :label="vdata.saveObject['agentType'] == 1?'[联系人]手持承诺函照片':'[法人]手持承诺函照片'" name="idcardInHandImg">
|
||||
<JeepayUpload v-model:src="vdata.saveObject['idcardInHandImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.saveObject['settAccountType'] == 'BANK_PRIVATE'" :span="10">
|
||||
<a-form-item label="银行卡照片" name="bankCardImg">
|
||||
<JeepayUpload v-model:src="vdata.saveObject['bankCardImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="手持承诺函照示例:" name="">
|
||||
<a-image style="width: 100px;height: 120px;" src="https://jeepaypublic.oss-cn-beijing.aliyuncs.com/oem/b1cd1646-fdd2-4ea7-8f1f-02a55669f534.svg" />
|
||||
<span><a :href="vdata.promiseFile">模板下载</a></span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</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_AGENT_LIST, API_URL_ISV_LIST, req, $getPasswordRules, $getMainUserInfo } from '@/api/manage'
|
||||
import { Base64 } from 'js-base64'
|
||||
import {message} from 'ant-design-vue'
|
||||
import {defineProps,reactive,ref} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
|
||||
const checkIsvNo = (rule, value) => { // 校验是否选择了渠道商
|
||||
if (!value) {
|
||||
return Promise.reject(new Error('请选择渠道商'))
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
const infoFormModel = ref()
|
||||
const infoTable =ref()
|
||||
const vdata : any = reactive({
|
||||
newPwd: '', // 新密码
|
||||
resetIsShow: false, // 重置密码是否展现
|
||||
passwordRules: /^$/, //密码规则
|
||||
passwordRulesText: '', //密码规则提示文字
|
||||
sysPassword: {
|
||||
resetPass: false, // 重置密码
|
||||
defaultPass: true, // 使用默认密码
|
||||
confirmPwd: '' // 确认密码
|
||||
},
|
||||
btnLoading: false,
|
||||
isAdd: true, // 新增 or 修改页面标志
|
||||
isAudit: false,
|
||||
saveObject: { isNotify: 0 }, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
isvList: [] as any, // 渠道商下拉列表
|
||||
rules: {
|
||||
agentName: [{ required: true, message: '请输入服务商名称', trigger: 'blur' }],
|
||||
loginUsername: [{ required: true, pattern: /^[a-zA-Z][a-zA-Z0-9]{5,17}$/, message: '请输入字母开头,长度为6-18位的登录名', trigger: 'blur' }],
|
||||
agentShortName: [{ required: true, message: '请输入服务商简称', trigger: 'blur' }],
|
||||
contactName: [{ required: true, message: '请输入联系人姓名', trigger: 'blur' }],
|
||||
isvNo: [{ validator: checkIsvNo, trigger: 'blur' }],
|
||||
contactEmail: [{ required: false, pattern: /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/, message: '请输入正确的邮箱地址', trigger: 'blur' }],
|
||||
contactTel: [{ required: true, pattern: /^1\d{10}$/, message: '请输入正确的手机号', trigger: 'blur' }],
|
||||
newPwd: [{ required: false, trigger: 'blur' }, {
|
||||
validator: (rule, value) => {
|
||||
if (!vdata.sysPassword.defaultPass) {
|
||||
if (!vdata.passwordRules.test(vdata.newPwd)) {
|
||||
return Promise.reject(vdata.passwordRulesText)
|
||||
} else if(vdata.newPwd !== vdata.sysPassword.confirmPwd) {
|
||||
return Promise.reject('新密码与确认密码不一致')
|
||||
} else return Promise.resolve()
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
}
|
||||
}], // 新密码
|
||||
confirmPwd: [{ required: false, trigger: 'blur' }, {
|
||||
validator: (rule, value) => {
|
||||
if (!vdata.sysPassword.defaultPass) {
|
||||
// vdata.newPwd === vdata.sysPassword.confirmPwd ? callBack() : callBack('新密码与确认密码不一致')
|
||||
if(!vdata.passwordRules.test(vdata.sysPassword.confirmPwd)){
|
||||
return Promise.reject(vdata.passwordRulesText)
|
||||
} else if(vdata.newPwd !== vdata.sysPassword.confirmPwd) {
|
||||
return Promise.reject('新密码与确认密码不一致')
|
||||
} else return Promise.resolve()
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
}] // 确认新密码
|
||||
}
|
||||
})
|
||||
function getPasswordRules () { // 获取密码规则
|
||||
$getPasswordRules().then(res => {
|
||||
vdata.passwordRules = new RegExp(res.regexpRules)
|
||||
vdata.passwordRulesText = res.errTips
|
||||
if(res.subIsAudit == '1') {
|
||||
vdata.saveObject['settAccountType'] = 'ALIPAY_CASH'
|
||||
vdata.isAudit = true
|
||||
}
|
||||
})
|
||||
}
|
||||
function show (recordId) { // 弹层打开事件
|
||||
getPasswordRules()
|
||||
|
||||
// 查询手持承诺函模板
|
||||
getAgentInfo()
|
||||
|
||||
vdata.isAdd = !recordId
|
||||
vdata.saveObject = { 'state': 1, passwordType: 'default', 'addAgentFlag': 1, isNotify: 0, agentType: 1 } // 数据清空
|
||||
if (infoFormModel.value != undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
req.list(API_URL_ISV_LIST, { 'pageSize': -1, 'state': 1 }).then(res => { // 渠道商下拉选择列表
|
||||
vdata.isvList = res.records
|
||||
})
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.resetIsShow = true // 展示重置密码板块
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_AGENT_LIST, recordId).then(res => {
|
||||
vdata.saveObject = res
|
||||
})
|
||||
vdata.visible = true
|
||||
} else {
|
||||
vdata.visible = true // 立马展示弹层信息
|
||||
}
|
||||
}
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then(valid =>{
|
||||
|
||||
vdata.btnLoading = true
|
||||
|
||||
// 请求接口
|
||||
if (vdata.isAdd) {
|
||||
// 如果新增密码设置为默认密码,登录密码设置为空
|
||||
if(vdata.saveObject.passwordType == 'default' || !vdata.saveObject.loginPassword) {
|
||||
vdata.saveObject.loginPassword = ''
|
||||
}
|
||||
if(vdata.saveObject.passwordType == 'custom' && !vdata.passwordRules.test(vdata.saveObject.loginPassword)) {
|
||||
vdata.btnLoading = false
|
||||
return message.error(vdata.passwordRulesText)
|
||||
}
|
||||
req.add(API_URL_AGENT_LIST, vdata.saveObject).then(res => {
|
||||
message.success('新增成功')
|
||||
vdata.visible = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.btnLoading = false
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
} else {
|
||||
|
||||
vdata.sysPassword.confirmPwd = Base64.encode(vdata.sysPassword.confirmPwd)
|
||||
Object.assign(vdata.saveObject, vdata.sysPassword) // 拼接对象
|
||||
req.updateById(API_URL_AGENT_LIST, vdata.recordId, vdata.saveObject).then(res => {
|
||||
message.success('修改成功')
|
||||
vdata.visible = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.btnLoading = false
|
||||
vdata.resetIsShow = true // 展示重置密码板块
|
||||
vdata.sysPassword.resetPass = false
|
||||
vdata.sysPassword.defaultPass = true // 是否使用默认密码默认为true
|
||||
resetPassEmpty(DataView) // 清空密码
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
vdata.resetIsShow = true // 展示重置密码板块
|
||||
vdata.sysPassword.resetPass = false
|
||||
vdata.sysPassword.defaultPass = true // 是否使用默认密码默认为true
|
||||
resetPassEmpty(vdata) // 清空密码
|
||||
})
|
||||
}
|
||||
|
||||
}).catch(valid =>{
|
||||
})
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
vdata.resetIsShow = false // 取消重置密码板块展示
|
||||
vdata.sysPassword.resetPass = false
|
||||
resetPassEmpty(vdata)
|
||||
vdata.sysPassword.defaultPass = true// 是否使用默认密码默认为true
|
||||
}
|
||||
// 使用默认密码重置是否为true
|
||||
function isResetPass () {
|
||||
if (!vdata.sysPassword.defaultPass) {
|
||||
vdata.newPwd = ''
|
||||
vdata.sysPassword.confirmPwd = ''
|
||||
}
|
||||
}
|
||||
// 保存后清空密码
|
||||
function resetPassEmpty (vdata) {
|
||||
vdata.newPwd = ''
|
||||
vdata.sysPassword.confirmPwd = ''
|
||||
}
|
||||
|
||||
function randomPassage(randomFlag, min, max) { // 生成6位随机密码
|
||||
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['loginPassword'] = str
|
||||
}
|
||||
|
||||
function getAgentInfo() {
|
||||
// 获取服务商信息
|
||||
$getMainUserInfo().then((res) => {
|
||||
vdata.promiseFile = res.promiseFile
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.typePopover {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left:62px;
|
||||
}
|
||||
</style>
|
||||
143
jeepay-ui-agent/src/views/agent/AgentList.vue
Normal file
143
jeepay-ui-agent/src/views/agent/AgentList.vue
Normal file
@@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="() => { searchData= {} }">
|
||||
<jeepay-text-up v-model:value="searchData['agentNo']" :placeholder="'服务商号'" />
|
||||
<jeepay-text-up v-model:value="searchData['agentName']" :placeholder="'服务商名称'" />
|
||||
<jeepay-text-up v-model:value="searchData['loginUsername']" :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>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="searchData"
|
||||
row-key="agentNo"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button v-if="$access('ENT_AGENT_INFO_ADD')" type="primary" @click="addFunc">
|
||||
<plus-outlined />新建
|
||||
</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'agentName'">
|
||||
<a @click="detailFunc(record.agentNo)"><b>{{ record.agentName }}</b></a>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'state'">
|
||||
<a-badge
|
||||
:status="record.state === 0?'error':record.state === 1?'processing':record.state === 2?'warning':record.state === 3?'error':'yellow'"
|
||||
:text="record.state === 0?'禁用':record.state === 1?'启用':record.state === 2?'审核中':record.state === 3?'审核驳回':'未认证'"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_AGENT_INFO_EDIT')" type="link" @click="editFunc(record.agentNo)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_AGENT_INFO_VIEW')" type="link" @click="detailFunc(record.agentNo)">详情</a-button>
|
||||
<a-button v-if="$access('ENT_AGENT_RATE_CONFIG')" type="link" @click="showFeeConfigList(record.agentNo)">费率配置</a-button>
|
||||
<a-button v-if="$access('ENT_AGENT_INFO_DEL')" type="link" style="color: red" @click="delFunc(record.agentNo)">删除</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callback-func="searchFunc" />
|
||||
<!-- 详情页面组件 -->
|
||||
<InfoDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
|
||||
<!-- 费率配置页面 -->
|
||||
|
||||
<JeepayPaymentConfigDrawer ref="JeepayPaymentConfigDrawerRef" configMode="agentSubagent" />
|
||||
<!-- <JeepayPayConfigDrawer ref="JeepayPaymentConfigDrawerRef" configMode="agentSubagent" />-->
|
||||
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import { API_URL_AGENT_LIST, req, reqLoad } from '@/api/manage'
|
||||
import InfoAddOrEdit from './AddOrEdit.vue'
|
||||
import InfoDetail from './Detail.vue'
|
||||
import { ref, reactive, getCurrentInstance } from 'vue'
|
||||
import router from '@/router'
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoDetail = ref()
|
||||
const infoAddOrEdit = ref()
|
||||
const infoTable = ref()
|
||||
|
||||
const JeepayPaymentConfigDrawerRef = ref()
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ key: 'agentName', title: '服务商名称', fixed: 'left', },
|
||||
{ key: 'agentNo', title: '服务商号', dataIndex: 'agentNo' , },
|
||||
{ key: 'mchCount', title: '商户数量', dataIndex: 'mchCount', },
|
||||
{ key: 'state', title: '状态', },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期', },
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let searchData = ref({})
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params: any) {
|
||||
return req.list(API_URL_AGENT_LIST, params)
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function tableExportFunc(){
|
||||
alert('导出!')
|
||||
}
|
||||
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show()
|
||||
}
|
||||
function editFunc (recordId: any) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(recordId)
|
||||
}
|
||||
function rateConfigFunc(recordId: any) {
|
||||
alert('费率配置')
|
||||
}
|
||||
function detailFunc (recordId: any) { // 服务商详情页
|
||||
infoDetail.value.show(recordId)
|
||||
}
|
||||
|
||||
function codeManagementFunc (recordId: any) {
|
||||
alert('码牌管理')
|
||||
}
|
||||
// 删除服务商
|
||||
function delFunc (recordId: any) {
|
||||
$infoBox.confirmDanger('确认删除?', '该操作将删除服务商下所有配置及用户信息', () => {
|
||||
reqLoad.delById(API_URL_AGENT_LIST, recordId).then((res: any) => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('删除成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function showFeeConfigList (recordId) { // 费率配置
|
||||
JeepayPaymentConfigDrawerRef.value.show(recordId)
|
||||
}
|
||||
|
||||
</script>
|
||||
253
jeepay-ui-agent/src/views/agent/Detail.vue
Normal file
253
jeepay-ui-agent/src/views/agent/Detail.vue
Normal file
@@ -0,0 +1,253 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:title=" true ? '服务商详情' : '' "
|
||||
: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['agentNo'] }}
|
||||
</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['loginUsername'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商简称">
|
||||
{{ vdata.detailData['agentShortName'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.detailData['type'] === 2" :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道商号">
|
||||
{{ vdata.detailData['isvNo'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.detailData['type'] === 2" :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道商名称">
|
||||
{{ vdata.isvName }}
|
||||
</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['contactTel'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="状态">
|
||||
<a-tag :color="vdata.detailData['state'] === 1?'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['contactEmail'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="start" type="flex">
|
||||
<a-col :sm="24">
|
||||
<a-form-item label="备注">
|
||||
<a-input
|
||||
v-model:value="vdata.detailData['remark']"
|
||||
type="textarea"
|
||||
disabled="disabled"
|
||||
style="height: 50px"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
账户信息
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商类型">
|
||||
{{ vdata.detailData['agentType'] == "1" ? '个人':'企业' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收款账户类型">
|
||||
{{ vdata.detailData['settAccountType'] === "WX_CASH"? '个人微信':vdata.detailData['settAccountType'] === "ALIPAY_CASH"? '个人支付宝':vdata.detailData['settAccountType'] === "BANK_PUBLIC"? '对公账户':vdata.detailData['settAccountType'] === "BANK_PRIVATE"? '对私账户':'银行卡' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="vdata.detailData['settAccountType'] === 'WX_CASH' || vdata.detailData['settAccountType'] === 'ALIPAY_CASH'" justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item :label="vdata.detailData['settAccountType'] === 'ALIPAY_CASH'?'支付宝账号':'个人微信号'">
|
||||
{{ vdata.detailData['settAccountNo'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="vdata.detailData['settAccountType'] === 'BANK_PRIVATE'" justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收款银行卡号">
|
||||
{{ vdata.detailData['settAccountNo'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="vdata.detailData['settAccountType'] === 'BANK_PUBLIC'" justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="对公账户名称">
|
||||
{{ vdata.detailData['settAccountName'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="对公账号">
|
||||
{{ vdata.detailData['settAccountNo'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="开户银行名称">
|
||||
{{ vdata.detailData['settAccountBank'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="开户行支行名称">
|
||||
{{ vdata.detailData['settAccountSubBank'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-col :sm="24">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
资料信息
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
</a-col>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col v-if="vdata.detailData['agentType'] == 2" :sm="12">
|
||||
<a-form-item label="营业执照照片" name="licenseImg">
|
||||
<JeepayUpload v-if="vdata.detailData['licenseImg']" v-model:src="vdata.detailData['licenseImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.detailData['agentType'] == 2 && vdata.detailData['settAccountType'] == 'BANK_PUBLIC'" :sm="12">
|
||||
<a-form-item label="开户许可证照片" name="permitImg">
|
||||
<JeepayUpload v-if="vdata.detailData['permitImg']" v-model:src="vdata.detailData['permitImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-form-item :label="vdata.detailData['agentType'] == 1?'[联系人]身份证人像面照片':'[法人]身份证人像面照片'" name="idcard1Img">
|
||||
<JeepayUpload v-if="vdata.detailData['idcard1Img']" v-model:src="vdata.detailData['idcard1Img']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-form-item :label="vdata.detailData['agentType'] == 1?'[联系人]身份证国徽面照片':'[法人]身份证国徽面照片'" name="idcard2Img">
|
||||
<JeepayUpload v-if="vdata.detailData['idcard2Img']" v-model:src="vdata.detailData['idcard2Img']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-form-item label="[联系人]手持身份证照片" name="idcardInHandImg">
|
||||
<JeepayUpload v-if="vdata.detailData['idcardInHandImg']" v-model:src="vdata.detailData['idcardInHandImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.detailData['settAccountType'] == 'BANK_PRIVATE'" :sm="12">
|
||||
<a-form-item label="银行卡照片" name="bankCardImg">
|
||||
<JeepayUpload v-if="vdata.detailData['bankCardImg']" v-model:src="vdata.detailData['bankCardImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_AGENT_LIST, API_URL_ISV_LIST, req } from '@/api/manage'
|
||||
import {defineProps,reactive} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
isvList: [], // 渠道商下拉列表
|
||||
isvName: '' // 渠道商名称
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
vdata.detailData = { 'state': 1, 'type': 1 } // 数据清空
|
||||
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_AGENT_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
req.list(API_URL_ISV_LIST, { 'pageSize': null }).then(res => { // 渠道商下拉选择列表
|
||||
vdata.isvList = res.records
|
||||
for (let i = 0; i < vdata.isvList.length; i++) {
|
||||
if (vdata.detailData['isvNo'] === vdata.isvList[i]['isvNo']) {
|
||||
vdata.isvName = vdata.isvList[i]['isvName']
|
||||
}
|
||||
}
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
86
jeepay-ui-agent/src/views/agentconfig/AgentConfig.vue
Normal file
86
jeepay-ui-agent/src/views/agentconfig/AgentConfig.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div style="background: #fff">
|
||||
<a-tabs>
|
||||
<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="flag" 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_AGENT_CONFIG_EDIT')" type="primary" :loading="vdata.btnLoading" @click="confirmUpdateSipw"><check-circle-outlined />确认更改</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
||||
import { $updateAgentSipw, $isSipw } from '@/api/manage'
|
||||
onMounted(()=>{
|
||||
isSipw()
|
||||
})
|
||||
const flag = ref(true)
|
||||
const isSipw = ()=>{
|
||||
$isSipw().then(res=>{
|
||||
flag.value = res
|
||||
})
|
||||
}
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
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()
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
const vdata : any = reactive ({
|
||||
btnLoading: false,
|
||||
groupKey: 'securityConfig',
|
||||
sipwObject:{ } // 支付密码保存对象
|
||||
|
||||
})
|
||||
|
||||
// 更新支付密码
|
||||
function confirmUpdateSipw(){
|
||||
|
||||
sipwFormModel.value.validate().then(() => {
|
||||
return $updateAgentSipw(vdata.sipwObject.originalPwd, vdata.sipwObject.confirmPwd)
|
||||
}).then((res) => {
|
||||
$infoBox.message.success('更新成功')
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.bottom-btn{
|
||||
/deep/ div{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.typePopover {
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
left: 93px;
|
||||
}
|
||||
</style>
|
||||
187
jeepay-ui-agent/src/views/current/AvatarModal.vue
Normal file
187
jeepay-ui-agent/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>
|
||||
741
jeepay-ui-agent/src/views/current/UserinfoPage.vue
Normal file
741
jeepay-ui-agent/src/views/current/UserinfoPage.vue
Normal file
@@ -0,0 +1,741 @@
|
||||
<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 || data.isAudit" 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="安全信息" :disabled="data.isAudit">
|
||||
<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 || data.isAudit">
|
||||
<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="预留信息" :disabled="data.isPwdExpired || data.isAudit">
|
||||
<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-tab-pane key="3" :disabled="data.isPwdExpired" tab="基本资料">
|
||||
<a-row :gutter="16" style="margin-left: 10%;">
|
||||
<a-col :md="16" :lg="16">
|
||||
<a-form ref="auditFormModel" :model="data.agentInfo" layout="vertical" :rules="data.auditRules">
|
||||
<div v-if="data.agentInfo.infoState !== 1">
|
||||
<a-alert v-if="data.agentInfo.state == 4" :message="'请修改默认信息并填写对应资料,提交平台审核。'" type="info" />
|
||||
<a-alert v-if="data.agentInfo.state == 3" :message="!data.agentInfo.auditRemark?'驳回原因:无':'驳回原因:' + data.agentInfo.auditRemark" type="error" />
|
||||
<a-alert v-if="data.agentInfo.state == 2" message="请等待平台审核......" type="warning" />
|
||||
<a-alert v-if="data.agentInfo.state == 1" message="资料已通过审核,请重新登录。" type="success" />
|
||||
</div>
|
||||
|
||||
<a-col :offset="1"><a-divider orientation="left" style="color: #1A66FF;">基本名称</a-divider></a-col>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="服务商类型" name="agentType">
|
||||
<a-select v-model:value="data.agentInfo['agentType']" defaultValue="1">
|
||||
<a-select-option :value="1">个人</a-select-option>
|
||||
<a-select-option :value="2">企业</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item :label="data.agentInfo['agentType'] == 2? '企业全称':'服务商全称'" name="agentName">
|
||||
<a-input v-model:value="data.agentInfo['agentName']" />
|
||||
<span v-if="data.agentInfo['agentType'] == 2" class="jeepay-tip-text">请输入营业执照名称</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item :label="data.agentInfo['agentType'] == 2? '企业简称':'服务商简称'" name="agentShortName">
|
||||
<a-input v-model:value="data.agentInfo['agentShortName']" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="联系人姓名" name="contactName">
|
||||
<a-input v-model:value="data.agentInfo['contactName']" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="联系人邮箱" name="contactEmail">
|
||||
<a-input v-model:value="data.agentInfo['contactEmail']" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-col :offset="1"><a-divider orientation="left" style="color: #1A66FF;">账户资料</a-divider></a-col>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="收款账户类型" name="settAccountType">
|
||||
<a-select v-model:value="data.agentInfo['settAccountType']" placeholder="请选择账户类型">
|
||||
<a-select-option value="ALIPAY_CASH">个人支付宝</a-select-option>
|
||||
<a-select-option value="BANK_PRIVATE">对私账户</a-select-option>
|
||||
<a-select-option v-if="data.agentInfo['agentType'] !== 1" value="BANK_PUBLIC">对公账户</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="data.agentInfo['settAccountType'] === 'ALIPAY_CASH'" justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="账户姓名" name="settAccountName">
|
||||
<a-input
|
||||
v-model:value="data.agentInfo['settAccountName']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="支付宝账号" name="settAccountNo">
|
||||
<a-input
|
||||
v-model:value="data.agentInfo['settAccountNo']"
|
||||
placeholder="请输入账号"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="data.agentInfo['settAccountType'] === 'BANK_PRIVATE'" justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="账户姓名" name="settAccountName">
|
||||
<a-input
|
||||
v-model:value="data.agentInfo['settAccountName']"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="开户银行名称" name="settAccountBank">
|
||||
<a-input
|
||||
v-model:value="data.agentInfo['settAccountBank']"
|
||||
placeholder="请输入银行名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="收款银行卡号" name="settAccountNo">
|
||||
<a-input
|
||||
v-model:value="data.agentInfo['settAccountNo']"
|
||||
placeholder="请输入银行卡号"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row v-if="data.agentInfo['settAccountType'] === 'BANK_PUBLIC'" justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="对公账户名称" name="settAccountName">
|
||||
<a-input
|
||||
v-model:value="data.agentInfo['settAccountName']"
|
||||
placeholder="请输入账户名"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="对公账号" name="settAccountNo">
|
||||
<a-input
|
||||
v-model:value="data.agentInfo['settAccountNo']"
|
||||
placeholder="请输入银行卡号"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="开户银行名称" name="settAccountBank">
|
||||
<a-input
|
||||
v-model:value="data.agentInfo['settAccountBank']"
|
||||
placeholder="请输入银行名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="开户行支行名称" name="settAccountSubBank">
|
||||
<a-input
|
||||
v-model:value="data.agentInfo['settAccountSubBank']"
|
||||
placeholder="请输入开户行支行名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col v-if="data.agentInfo['settAccountType'] === 'BANK_PRIVATE'" :span="10">
|
||||
<a-form-item label="银行卡照片" name="bankCardImg">
|
||||
<JeepayUpload v-model:src="data.agentInfo['bankCardImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="data.agentInfo['agentType'] !== 1 && data.agentInfo['settAccountType'] === 'BANK_PUBLIC'" :span="10">
|
||||
<a-form-item label="开户许可证照片" name="permitImg">
|
||||
<JeepayUpload v-model:src="data.agentInfo['permitImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-col :offset="1"><a-divider orientation="left" style="color: #1A66FF;">照片资料</a-divider></a-col>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item :label="data.agentInfo['agentType'] == 1?'[联系人]身份证人像面照片':'[法人]身份证人像面照片'" name="idcard1Img">
|
||||
<JeepayUpload v-model:src="data.agentInfo['idcard1Img']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item :label="data.agentInfo['agentType'] == 1?'[联系人]身份证国徽面照片':'[法人]身份证国徽面照片'" name="idcard2Img">
|
||||
<JeepayUpload v-model:src="data.agentInfo['idcard2Img']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="[联系人]手持承诺函照片" name="idcardInHandImg">
|
||||
<JeepayUpload v-model:src="data.agentInfo['idcardInHandImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="手持承诺函照示例:" name="">
|
||||
<a-image style="width: 100px;height: 120px;" src="https://jeepaypublic.oss-cn-beijing.aliyuncs.com/oem/b1cd1646-fdd2-4ea7-8f1f-02a55669f534.svg" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<span><a :href="data.promiseFile">模板下载</a></span>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
|
||||
<a-col v-if="data.agentInfo['agentType'] !== 1" :span="10">
|
||||
<a-form-item label="营业执照照片" name="licenseImg">
|
||||
<JeepayUpload v-model:src="data.agentInfo['licenseImg']" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item v-if="data.agentInfo.state != 1 && data.agentInfo.state != 2" class="bottom-btn">
|
||||
<a-button type="primary" :loading="data.btnLoading" @click="auditInfo">
|
||||
<check-circle-outlined />
|
||||
提交审核
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { $getUserInfo, $updateUserInfo, $updateUserPass, $getMFAInfo, $mfaBind, $mfaRelieve, upload, $getPasswordRules, $getMainUserInfo, $auditInfo } from '@/api/manage'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
import ruleGenerator from '@/utils/ruleGenerator'
|
||||
// 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 auditFormModel = ref()
|
||||
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const tabKey = ref()
|
||||
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, //是否强制改密码
|
||||
isAudit: false, // 是否强制审核
|
||||
auditRules: {
|
||||
agentName: [{ required: true, message: '请输入服务商全称', trigger: 'blur' }],
|
||||
agentShortName: [{ required: true, message: '请输入服务商简称', trigger: 'blur' }],
|
||||
contactName: [{ required: true, message: '请输入联系人姓名', trigger: 'blur' }],
|
||||
contactTel: [{ required: true, message: '请输入联系人手机号', trigger: 'blur' }],
|
||||
// contactEmail: [{ required: true, message: '请输入联系人邮箱', trigger: 'blur' }],
|
||||
licenseImg: [ ruleGenerator.requiredUpload('营业执照照片') ],
|
||||
permitImg: [ ruleGenerator.requiredUpload('开户许可证照片') ],
|
||||
idcard1Img: [ ruleGenerator.requiredUpload('身份证人像面照片') ],
|
||||
idcard2Img: [ ruleGenerator.requiredUpload('身份证国徽面照片') ],
|
||||
idcardInHandImg: [ ruleGenerator.requiredUpload('手持身份证照片') ],
|
||||
bankCardImg: [ ruleGenerator.requiredUpload('银行卡照片') ],
|
||||
agentType: [ ruleGenerator.requiredSelect('服务商类型', 'number') ],
|
||||
settAccountType: [ ruleGenerator.requiredSelect('收款账户类型') ],
|
||||
settAccountNo: [{ required: true, message: '请输入个人账号/银行卡号', trigger: 'blur' }],
|
||||
settAccountName: [{ required: true, message: '请输入账户名', trigger: 'blur' }],
|
||||
settAccountBank: [{ required: true, message: '请输入银行名称', trigger: 'blur' }],
|
||||
// settAccountSubBank: [{ required: true, message: '请输入开户行支行名称', trigger: 'blur' }],
|
||||
},
|
||||
agentInfo: {
|
||||
agentName: '',
|
||||
agentShortName: '',
|
||||
contactName: '',
|
||||
contactTel: '',
|
||||
contactEmail: '',
|
||||
licenseImg: '',
|
||||
idcardImg: '',
|
||||
idcardInHandImg: '',
|
||||
bankCardImg: '',
|
||||
auditRemark: '',
|
||||
infoState: '' as any,
|
||||
state: '' as any,
|
||||
},
|
||||
|
||||
previewVisible: false,
|
||||
previewTitle: '',
|
||||
previewImage: '',
|
||||
promiseFile: ''
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
|
||||
if(useRoute().query.isPwdExpired == '1'){
|
||||
data.isPwdExpired = true
|
||||
data.tableKey = '2'
|
||||
}
|
||||
if(useRoute().query.isAudit === '1'){
|
||||
data.isAudit = true
|
||||
data.tableKey = '3'
|
||||
}
|
||||
|
||||
detail()
|
||||
getPasswordRules()
|
||||
})
|
||||
function detail () { // 获取基本信息
|
||||
|
||||
$getUserInfo().then(res => {
|
||||
data.saveObject = res
|
||||
data.safeWord = res.safeWord
|
||||
})
|
||||
|
||||
getAgentInfo()
|
||||
}
|
||||
function getPasswordRules () { // 获取密码规则
|
||||
$getPasswordRules().then(res => {
|
||||
data.passwordRules = new RegExp(res.regexpRules)
|
||||
data.passwordRulesText = res.errTips
|
||||
})
|
||||
}
|
||||
|
||||
function getAgentInfo() {
|
||||
// 获取服务商信息
|
||||
$getMainUserInfo().then((res) => {
|
||||
data.agentInfo = res
|
||||
data.promiseFile = res.promiseFile
|
||||
})
|
||||
}
|
||||
|
||||
function auditInfo () { // 更新基本信息事件
|
||||
auditFormModel.value.validate().then(valid =>{
|
||||
|
||||
$infoBox.confirmPrimary('提交前请仔细核对资料信息,认证通过后将不可更改。', '', () => {
|
||||
data.btnLoading = true // 打开按钮上的 loading
|
||||
// 请求接口
|
||||
$auditInfo(toRaw(data.agentInfo)).then(res => {
|
||||
data.agentInfo.state = '2'
|
||||
data.btnLoading = false // 关闭按钮刷新
|
||||
}).then(bizData => {
|
||||
message.success('提交成功')
|
||||
}).catch(res => {
|
||||
data.btnLoading = false
|
||||
message.error('提交失败')
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function changeInfo () { // 提交审核
|
||||
infoFormModel.value.validate().then(valid =>{
|
||||
$infoBox.confirmPrimary('确认更新信息吗?', '', () => {
|
||||
data.btnLoading = true // 打开按钮上的 loading
|
||||
// that.$store.commit('showLoading') // 关闭全局刷新
|
||||
// 请求接口
|
||||
console.log(toRaw(data.saveObject))
|
||||
$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 = ''
|
||||
}
|
||||
// 上传文件成功回调方法,参数value为文件地址,name是自定义参数
|
||||
function uploadSuccess (value, name) {
|
||||
data.saveObject.avatarUrl = value
|
||||
console.log(data.saveObject.avatarUrl)
|
||||
data.updateKey += 1
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function selectTabsSub (key) { // 清空必填提示
|
||||
console.log(key)
|
||||
if (key) {
|
||||
data.groupKey = key
|
||||
detail()
|
||||
}
|
||||
// 获取MFA信息
|
||||
if(data.groupKey == 'mfaVer') {
|
||||
getMFAInfo()
|
||||
}
|
||||
}
|
||||
|
||||
function getMFAInfo() {
|
||||
$getMFAInfo().then(res => {
|
||||
data.mfaInfo = res
|
||||
})
|
||||
}
|
||||
|
||||
// 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 {
|
||||
display: block !important;
|
||||
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>
|
||||
93
jeepay-ui-agent/src/views/current/postList.vue
Normal file
93
jeepay-ui-agent/src/views/current/postList.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<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:[],
|
||||
noticeDate:{} as any
|
||||
})
|
||||
const noticeViewer = ref()
|
||||
const visible = ref<boolean>(false)
|
||||
onMounted(() =>{
|
||||
reqTableDataFunc({
|
||||
pageSize:10,
|
||||
pageNumber:1
|
||||
}).then(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 = (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>
|
||||
740
jeepay-ui-agent/src/views/dashboard/Analysis.vue
Normal file
740
jeepay-ui-agent/src/views/dashboard/Analysis.vue
Normal file
@@ -0,0 +1,740 @@
|
||||
<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_AGENT_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_AGENT_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="setSafeWord" >{{ safeWord ? safeWord : "未设置" }}</a >
|
||||
<a-tooltip placement="right" title="此信息为你在本站预留的个性信息,用以鉴别假冒、钓鱼网站。如未看到此信息,请立即停止访问并修改密码。如需修改内容请前往个人中心">
|
||||
<question-circle-outlined />
|
||||
</a-tooltip>
|
||||
</p>
|
||||
<p><span>服务商简称:</span ><span>{{ shortName ? shortName : "服务商" }}</span></p>
|
||||
<p><span>服务商邀请码:</span ><span>{{ inviteCode ? inviteCode : "" }} <copy-outlined style="color: #2691ff;" @click="getCopy()"/></span></p>
|
||||
<p><span>拓展商户:</span >
|
||||
<QrcodeOutlined style="color: #2691ff;" @click="getVisibleAdd(0)" />
|
||||
<copy-outlined style="color: #2691ff;padding-left: 5px" @click="getCopyCode(0)"/>
|
||||
</p>
|
||||
<p><span>拓展代理:</span >
|
||||
<QrcodeOutlined style="color: #2691ff;" @click="getVisibleAdd(1)" />
|
||||
<copy-outlined style="color: #2691ff;padding-left: 5px" @click="getCopyCode(1)"/>
|
||||
</p>
|
||||
</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_AGENT_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_AGENT_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>
|
||||
<a-modal
|
||||
v-model:visible="vdata.visibleAdd"
|
||||
:footer="null"
|
||||
@cancel="handleCancel"
|
||||
style="top: 30% !important;"
|
||||
wrap-class-name="full-modal"
|
||||
width="330px"
|
||||
:title="vdata.title"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<div class="modal-body" style="height: 280px !important;">
|
||||
<div style="text-align: center">
|
||||
<img
|
||||
v-if="vdata.inviteUrl"
|
||||
:src='"https://api.pwmqr.com/qrcode/create/?url="+vdata.inviteUrl'
|
||||
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>
|
||||
<a-button
|
||||
type="primary"
|
||||
size="large"
|
||||
block
|
||||
@click="vdata.visibleAdd = false"
|
||||
>
|
||||
取消扫码
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</a-modal>
|
||||
<JeepayNoticeViewer ref="noticeViewer" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
nextTick,
|
||||
ref,
|
||||
computed,
|
||||
watch,
|
||||
getCurrentInstance,
|
||||
onMounted,
|
||||
reactive,
|
||||
} from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import * as echarts from "echarts"; // 引入图标组件
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import {
|
||||
$getPayTrendCount,
|
||||
$getNumCount,
|
||||
$getPayCount,
|
||||
$getPayType,
|
||||
$getUserInfo,
|
||||
API_URL_NOTICELIST,
|
||||
req,
|
||||
} from "@/api/manage";
|
||||
import {
|
||||
pieEcharts,
|
||||
statisticsEcharts,
|
||||
amountEcharts,
|
||||
} from "./echartsConfig.js"; // 图标配置项组件
|
||||
import { Empty } from "ant-design-vue"; // 缺省图
|
||||
const { $infoBox, $access } =
|
||||
getCurrentInstance()!.appContext.config.globalProperties;
|
||||
const userStore = useUserStore();
|
||||
// 获取到路由对象
|
||||
const router = useRouter(); //这是全部路由
|
||||
const safeWord = ref(); //预留信息
|
||||
const shortName = ref(); //服务商简称
|
||||
const inviteCode = ref(); //服务商简称
|
||||
const inviteCodeUrl = ref(); //服务商简称
|
||||
const agtInviteCodeUrl = ref(); //服务商简称
|
||||
|
||||
const vdata = reactive({
|
||||
title:"",
|
||||
inviteUrl:"" as any,
|
||||
visibleAdd: false,
|
||||
qrCodeUrl:"" as any,
|
||||
})
|
||||
//公告列表页
|
||||
const toList = () => {
|
||||
router.push({
|
||||
path: "/notices",
|
||||
});
|
||||
};
|
||||
const notice = reactive({
|
||||
noticeList: [] as any,
|
||||
});
|
||||
const noticeViewer = ref(); //公告详情
|
||||
//设置信息
|
||||
const setSafeWord = () => {
|
||||
router.push({
|
||||
path: "/currentUserinfo",
|
||||
query: { type: "msg" },
|
||||
});
|
||||
};
|
||||
|
||||
// $data['url']='https://api.pwmqr.com/qrcode/create/?url='.urlencode($url);
|
||||
// $data['downUrl']='https://api.pwmqr.com/qrcode/create/?url='.urlencode($url)."&down=1";
|
||||
onMounted(() => {
|
||||
$getUserInfo().then((res) => {
|
||||
safeWord.value = res.safeWord;
|
||||
shortName.value = res.shortName;
|
||||
inviteCode.value = res.inviteCode;
|
||||
agtInviteCodeUrl.value = res.agtInviteCodeUrl;
|
||||
inviteCodeUrl.value = res.inviteCodeUrl;
|
||||
});
|
||||
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 })
|
||||
);
|
||||
}
|
||||
function handleCancel(e) {
|
||||
vdata.visibleAdd = false;
|
||||
}
|
||||
// 切换今日昨日金额数据
|
||||
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);
|
||||
})
|
||||
.then((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
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.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 promise = new Promise((resolve, reject) => {});
|
||||
// 交易统计折线图数据赋值
|
||||
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),
|
||||
$getPayType(payMethodDate.value),
|
||||
$getPayCount(payStatisticsDate.value),
|
||||
])
|
||||
.then((res) => {
|
||||
skeletonIsShow.value = false; // 骨架屏取消
|
||||
payAmountGetDateData(res[0]); // 成交金额
|
||||
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;
|
||||
}
|
||||
};
|
||||
function getCopyCode(type = 0){
|
||||
|
||||
const textarea = document.createElement('textarea');
|
||||
let text = "拓展商户链接复制成功"
|
||||
if(type == 1){
|
||||
text = '拓展服务商链接复制成功'
|
||||
textarea.value = agtInviteCodeUrl.value;
|
||||
}else{
|
||||
textarea.value = inviteCodeUrl.value;
|
||||
}
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(textarea);
|
||||
$infoBox.message.success(text)
|
||||
}
|
||||
function getVisibleAdd(type = 0){
|
||||
if(type == 1){
|
||||
vdata.title="拓展代理"
|
||||
vdata.inviteUrl = agtInviteCodeUrl.value
|
||||
}else{
|
||||
vdata.title="拓展商户"
|
||||
vdata.inviteUrl = inviteCodeUrl.value
|
||||
}
|
||||
console.log(vdata.inviteUrl,'vdata.inviteUrl')
|
||||
vdata.visibleAdd = true
|
||||
}
|
||||
async function getCopy(){
|
||||
console.log(inviteCode.value)
|
||||
// var textarea= document.createElement("textarea"); // 创建textarea对象
|
||||
// document.body.appendChild(inviteCode.value); // 添加临时实例
|
||||
// textarea.select(); // 选择实例内容
|
||||
// document.execCommand("Copy"); // 执行复制
|
||||
// document.body.removeChild(textarea); // 删除临时实例
|
||||
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = inviteCode.value;
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(textarea);
|
||||
$infoBox.message.success('复制成功')
|
||||
}
|
||||
</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;
|
||||
}
|
||||
}
|
||||
|
||||
// 交易统计图表标题
|
||||
.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>
|
||||
206
jeepay-ui-agent/src/views/dashboard/echartsConfig.js
Normal file
206
jeepay-ui-agent/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-agent/src/views/dashboard/index.css
Normal file
194
jeepay-ui-agent/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;
|
||||
}
|
||||
}
|
||||
260
jeepay-ui-agent/src/views/dashboard/index.less
Normal file
260
jeepay-ui-agent/src/views/dashboard/index.less
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
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: 250px;
|
||||
.amount-date {
|
||||
width: auto;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-bottom: 50px;
|
||||
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;
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
span {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.amount-line {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.15);
|
||||
margin: 0 10px 0 20px;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
.personal-line {
|
||||
width: 100%;
|
||||
border-top: 1px solid #ebeff2;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.latest-post {
|
||||
// min-width: 300px;
|
||||
.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 30px;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
.latest-post {
|
||||
.title {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.method {
|
||||
width: 544px;
|
||||
}
|
||||
.pay-statistics {
|
||||
width: calc(100% - 544px);
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
308
jeepay-ui-agent/src/views/device/AutoPosList.vue
Normal file
308
jeepay-ui-agent/src/views/device/AutoPosList.vue
Normal file
@@ -0,0 +1,308 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :placeholder="'服务商号/名称'" />
|
||||
<!-- <JeepaySearchInfoInput v-model:value="vdata.searchData['mchUserName']" placeholder="用户号" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />-->
|
||||
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchUserName']" :placeholder="'用户号/名称/手机号'" />
|
||||
<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['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"
|
||||
:rowSelection="{ type: 'checkbox', selectedRowKeys: vdata.allotDeviceIdList, onChange: infoTableSelectChangeFunc }"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="addFunc"><plus-outlined />申请新设备</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotBatchFunc"><partition-outlined />勾选划拨/收回</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotByBatchIdFunc"><partition-outlined />批次划拨/收回</a-button> -->
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<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 === '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 === 'mchServiceName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.mchServiceName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchServiceName}}</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 === '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 === '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 === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</div>
|
||||
</a-tooltip>
|
||||
</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 === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="($access('ENT_DEVICE_AUTO_POS_EDIT') && record.isSelf)" type="link" @click="bindFunc(record)">绑定</a-button>
|
||||
<a-button v-if="($access('ENT_DEVICE_AUTO_POS_EDIT') && record.bindState == 1 && record.isSelf)" type="link" @click="deBindFunc(record.deviceId)">解绑</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="link" @click="allotFunc(record)">划拨/收回</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 批次号划拨弹窗 -->
|
||||
<a-modal v-model:visible="vdata.allotByBatchIdVisible" title="按批次号划拨设备" @ok="allotOk">
|
||||
<a-form ref="allotFormModel" :model="vdata.allotObject" layout="vertical" :rules="vdata.allotRules">
|
||||
<a-form-item label="批次号:" name="batchId">
|
||||
<a-input v-model:value="vdata.allotObject.batchId" placeholder="请输入批次号" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<!-- 绑定组件 -->
|
||||
<Bind ref="bind" :callbackFunc="searchFunc" />
|
||||
<!-- 选择划拨服务商 -->
|
||||
<JeepayModelAgentList ref="jeepayModelAgentList" showType="AGENT" @selectFinishFunc="searchAgentFinishFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, API_URL_IFDEFINES_LIST, req, reqLoad, $unbindDevice, $allotDevice } from '@/api/manage'
|
||||
import Bind from './Bind.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const bind = ref()
|
||||
const infoTable = ref()
|
||||
const jeepayModelAgentList = ref()
|
||||
const allotFormModel = ref()
|
||||
|
||||
const deviceType = 4
|
||||
|
||||
let tableColumns = reactive([
|
||||
// { title: '设备号', fixed: 'left', dataIndex: 'deviceNo', },
|
||||
// { key: 'provider', title: '所属支付接口', dataIndex: 'provider'},
|
||||
// { title: '服务商号', dataIndex: 'agentNo', agentEntCol: true},
|
||||
// { key: 'bindState', title: '绑定商户信息' },
|
||||
// { key: 'state', title: '状态'},
|
||||
// { dataIndex: 'createdAt', title: '创建日期', },
|
||||
// { key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
|
||||
{ title: '设备号', fixed: 'left', dataIndex: 'deviceNo' },
|
||||
{ key: 'provider', title: '所属支付接口', dataIndex: 'provider', },
|
||||
{ key: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'mchServiceName', title: '服务商名称', dataIndex: 'mchServiceName' },
|
||||
{ title: "商户名称", key: "mchApplyName", dataIndex: "mchApplyName" },
|
||||
{ key: 'storeId',title: '门店名称', dataIndex: 'storeId',},
|
||||
{ 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)
|
||||
const vdata = reactive({
|
||||
ifCodeList: [], // 通道列表
|
||||
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()
|
||||
|
||||
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 () { // 业务通用【新增】 函数
|
||||
$infoBox.message.success('请联系运营平台申请')
|
||||
}
|
||||
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('解绑成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
// 表格多选
|
||||
function infoTableSelectChangeFunc(selectedRowKeys, selectedRows) {
|
||||
vdata.allotDeviceIdList = selectedRowKeys
|
||||
}
|
||||
|
||||
// 按批次号划拨
|
||||
function allotByBatchIdFunc() {
|
||||
vdata.allotObject.allotType = 'batch'
|
||||
vdata.allotObject.batchId = ''
|
||||
|
||||
vdata.allotByBatchIdVisible = true
|
||||
}
|
||||
|
||||
// 按批次号划拨,批次号输入完成
|
||||
function allotOk() {
|
||||
allotFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.allotByBatchIdVisible = false
|
||||
jeepayModelAgentList.value.show()
|
||||
})
|
||||
}
|
||||
|
||||
// 勾选划拨设备
|
||||
function allotBatchFunc() {
|
||||
if (vdata.allotDeviceIdList.length < 1) {
|
||||
$infoBox.message.error('请选择设备')
|
||||
} else {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
}
|
||||
|
||||
// 划拨单个设备
|
||||
function allotFunc(record) {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
vdata.allotDeviceIdList = []
|
||||
vdata.allotDeviceIdList.push(record.deviceId)
|
||||
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
|
||||
// 划拨/收回选择完成
|
||||
function searchAgentFinishFunc(selectObject) {
|
||||
|
||||
vdata.allotObject.agentNo = selectObject[0]
|
||||
vdata.allotObject.allotOrRecover = selectObject[1]
|
||||
|
||||
if (vdata.allotObject.allotOrRecover == 'allot' && !vdata.allotObject.agentNo) {
|
||||
$infoBox.message.error('请选择服务商')
|
||||
return
|
||||
}
|
||||
|
||||
if (vdata.allotDeviceIdList.length > 0) {
|
||||
vdata.allotObject.allotDeviceIds = vdata.allotDeviceIdList.join(',')
|
||||
}
|
||||
|
||||
$allotDevice(vdata.allotObject).then(res => {
|
||||
vdata.allotDeviceIdList = [] // 清空多选
|
||||
$infoBox.message.success('保存成功')
|
||||
jeepayModelAgentList.value.close()
|
||||
searchFunc()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
150
jeepay-ui-agent/src/views/device/Bind.vue
Normal file
150
jeepay-ui-agent/src/views/device/Bind.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.drawerVisible"
|
||||
:mask-closable="false"
|
||||
title="绑定设备"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="40%"
|
||||
class="drawer-width"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" layout="horizontal" :rules="vdata.rules">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="绑定状态:">
|
||||
<a-space>
|
||||
{{ vdata.saveObject.bindState == 1 ? '已绑定' : '未绑定' }}
|
||||
<a-button type="primary" @click="showSelectModal">{{ vdata.saveObject.bindState == 1 ? '重新选择' : '选择商户信息' }}</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.showBindInfo" :span="24">
|
||||
<a-form-item label="用户号:">
|
||||
<span>{{ vdata.saveObject.mchNo }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.showBindInfo && vdata.isSelectMchApp" :span="24">
|
||||
<a-form-item label="应用:">
|
||||
<span>{{ vdata.saveObject.appId }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.showBindInfo" :span="24">
|
||||
<a-form-item label="门店:">
|
||||
<span>{{ vdata.saveObject.storeId }}</span>
|
||||
</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>
|
||||
|
||||
<JeepayModelMchList ref="jeepayModelMchListRef" :showType="vdata.isSelectMchApp ? 'MCH_APP_STORE' : 'MCH_STORE'" :mchNoAndName="true" @selectFinishFunc="selectFinishFunc" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_STORE_DEVICE, req, $bindDevice } from '@/api/manage'
|
||||
import { defineProps, reactive, ref, getCurrentInstance } from 'vue'
|
||||
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const jeepayModelMchListRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
storeList: [] as any, // 门店列表
|
||||
btnLoading: false,
|
||||
showBindInfo: false, // 显示绑定信息
|
||||
saveObject: {} as any, // 数据对象
|
||||
isSelectMchApp: false, // 绑定时 是否选择商户应用
|
||||
recordId: null, // 更新对象ID
|
||||
drawerVisible: false // 是否显示弹层/抽屉
|
||||
}) as any
|
||||
|
||||
function show (record: any) { // 弹层打开事件
|
||||
|
||||
if (infoFormModel.value != undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
vdata.recordId = record.deviceId
|
||||
vdata.isSelectMchApp = record.deviceType != 1
|
||||
|
||||
req.getById(API_URL_STORE_DEVICE, vdata.recordId).then((res: any) => {
|
||||
if(res){
|
||||
vdata.saveObject = res
|
||||
|
||||
if (vdata.saveObject.bindState == 1) {
|
||||
vdata.showBindInfo = true
|
||||
} else {
|
||||
vdata.showBindInfo = false
|
||||
vdata.saveObject.storeId = ''
|
||||
}
|
||||
}
|
||||
vdata.drawerVisible = true
|
||||
})
|
||||
}
|
||||
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.btnLoading = true
|
||||
|
||||
const { deviceId, mchNo, appId, storeId } = vdata.saveObject
|
||||
if (!storeId) {
|
||||
$infoBox.message.error('请选择门店')
|
||||
return
|
||||
}
|
||||
|
||||
$bindDevice(vdata.recordId, { deviceId, mchNo, appId, storeId }).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 showSelectModal(){
|
||||
jeepayModelMchListRef.value.show()
|
||||
}
|
||||
|
||||
// 选择商户、门店完成
|
||||
function selectFinishFunc(selectArray){
|
||||
|
||||
if(!selectArray[0] || !selectArray[2]){
|
||||
return $infoBox.message.error('选择信息不完整!')
|
||||
}
|
||||
if (vdata.isSelectMchApp && !selectArray[1]) {
|
||||
return $infoBox.message.error('选择信息不完整!')
|
||||
}
|
||||
|
||||
vdata.showBindInfo = true
|
||||
|
||||
vdata.saveObject.mchNo = selectArray[0]
|
||||
vdata.saveObject.appId = selectArray[1]
|
||||
vdata.saveObject.storeId = selectArray[2]
|
||||
|
||||
jeepayModelMchListRef.value.close()
|
||||
|
||||
}
|
||||
|
||||
function onClose () { // 关闭抽屉
|
||||
vdata.drawerVisible = false
|
||||
}
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
206
jeepay-ui-agent/src/views/device/BindSpeaker.vue
Normal file
206
jeepay-ui-agent/src/views/device/BindSpeaker.vue
Normal file
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.drawerVisible"
|
||||
:mask-closable="false"
|
||||
title="绑定设备"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="40%"
|
||||
class="drawer-width"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" layout="horizontal" :rules="vdata.rules">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="绑定状态:">
|
||||
<a-space>
|
||||
{{ vdata.saveObject.bindState == 1 ? '已绑定' : '未绑定' }}
|
||||
<a-button type="primary" @click="showSelectModal">{{ vdata.saveObject.bindState == 1 ? '重新选择' : '选择商户信息' }}</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.showBindInfo" :span="24">
|
||||
<a-form-item label="用户号:">
|
||||
<span>{{ vdata.saveObject.mchNo }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.showBindInfo && vdata.deviceType == 3" :span="24">
|
||||
<a-form-item label="应用:">
|
||||
<span>{{ vdata.saveObject.appId }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.showBindInfo" :span="24">
|
||||
<a-form-item label="门店:">
|
||||
<span>{{ vdata.saveObject.storeId }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-form-item label="绑定类型" name="bindType">
|
||||
<a-space>
|
||||
<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-button v-if="vdata.saveObject.bindType == 1" type="primary" @click="showQrcSelectModel">选择码牌</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</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-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>
|
||||
|
||||
<!-- 选择商户信息组件 -->
|
||||
<JeepayModelMchList ref="jeepayModelMchListRef" :showType="vdata.deviceType == 3 ? 'MCH_APP_STORE' : 'MCH_STORE'" :mchNoAndName="true" @selectFinishFunc="selectFinishFunc" />
|
||||
|
||||
<!-- 选择码牌组件 -->
|
||||
<JeepayModelQrcList ref="jeepayModelQrcListRef" @selectFinishFunc="selectQrcFinishFunc" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_STORE_DEVICE, req, $bindDevice } from '@/api/manage'
|
||||
import { defineProps, reactive, ref, getCurrentInstance, watch } from 'vue'
|
||||
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const jeepayModelMchListRef = ref()
|
||||
const jeepayModelQrcListRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
storeList: [] as any, // 门店列表
|
||||
btnLoading: false,
|
||||
showBindInfo: false, // 显示绑定信息
|
||||
saveObject: {} as any, // 数据对象
|
||||
deviceType: 1, // 1-云喇叭 2-云打印 3-扫码POS
|
||||
recordId: null, // 更新对象ID
|
||||
drawerVisible: false // 是否显示弹层/抽屉
|
||||
}) as any
|
||||
|
||||
// 监听属性
|
||||
watch( () => vdata.saveObject.storeId ,(nv, ov)=>{
|
||||
if (ov && nv != ov) {
|
||||
vdata.saveObject.qrcIdList = []
|
||||
}
|
||||
})
|
||||
|
||||
function show (record: any) { // 弹层打开事件
|
||||
|
||||
if (infoFormModel.value != undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
vdata.recordId = record.deviceId
|
||||
vdata.deviceType = record.deviceType
|
||||
|
||||
req.getById(API_URL_STORE_DEVICE, vdata.recordId).then((res: any) => {
|
||||
if(res){
|
||||
vdata.saveObject = res
|
||||
|
||||
if (vdata.saveObject.bindState == 1) {
|
||||
vdata.showBindInfo = true
|
||||
} else {
|
||||
vdata.showBindInfo = false
|
||||
vdata.saveObject.storeId = ''
|
||||
}
|
||||
}
|
||||
vdata.drawerVisible = true
|
||||
})
|
||||
}
|
||||
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.btnLoading = true
|
||||
|
||||
const { deviceId, mchNo, appId, storeId, bindType, qrcIdList } = vdata.saveObject
|
||||
if (!storeId) {
|
||||
vdata.btnLoading = false
|
||||
$infoBox.message.error('请选择门店')
|
||||
return
|
||||
}
|
||||
|
||||
$bindDevice(vdata.recordId, { deviceId, mchNo, appId, storeId, bindType, qrcIdList }).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 showSelectModal(){
|
||||
jeepayModelMchListRef.value.show()
|
||||
}
|
||||
|
||||
// 选择商户、门店完成
|
||||
function selectFinishFunc(selectArray){
|
||||
|
||||
if(!selectArray[0] || !selectArray[2]){
|
||||
return $infoBox.message.error('选择信息不完整!')
|
||||
}
|
||||
if (vdata.deviceType ==3 && !selectArray[1]) {
|
||||
return $infoBox.message.error('选择信息不完整!')
|
||||
}
|
||||
|
||||
vdata.showBindInfo = true
|
||||
|
||||
vdata.saveObject.mchNo = selectArray[0]
|
||||
vdata.saveObject.appId = selectArray[1]
|
||||
vdata.saveObject.storeId = selectArray[2]
|
||||
|
||||
jeepayModelMchListRef.value.close()
|
||||
|
||||
}
|
||||
|
||||
// 选择码牌弹窗
|
||||
function showQrcSelectModel() {
|
||||
|
||||
if (!vdata.saveObject.storeId) {
|
||||
$infoBox.message.error('请选择商户信息')
|
||||
}
|
||||
|
||||
if (vdata.saveObject.storeId && vdata.saveObject.bindType == 1) {
|
||||
jeepayModelQrcListRef.value.show(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
|
||||
}
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
80
jeepay-ui-agent/src/views/device/BizConfig.vue
Normal file
80
jeepay-ui-agent/src/views/device/BizConfig.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<a-form v-if="vdata.deviceType == 2" 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>
|
||||
107
jeepay-ui-agent/src/views/device/CommonAddOrEdit.vue
Normal file
107
jeepay-ui-agent/src/views/device/CommonAddOrEdit.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.drawerVisible"
|
||||
:mask-closable="false"
|
||||
:title="'修改设备'"
|
||||
: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 justify="space-between" type="flex">
|
||||
<a-col :span="11">
|
||||
<a-form-item label="设备号" name="deviceNo">
|
||||
<a-input v-model:value="vdata.saveObject.deviceNo" :disabled="true" 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>
|
||||
|
||||
<!-- 业务参数配置组件 -->
|
||||
<BizConfig ref="bizConfigRef" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_STORE_DEVICE, req } from '@/api/manage'
|
||||
import { defineProps, reactive, ref, getCurrentInstance } from 'vue'
|
||||
import BizConfig from '@/views/device/BizConfig.vue'
|
||||
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const bizConfigRef = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
saveObject: {} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
drawerVisible: false, // 是否显示弹层/抽屉
|
||||
deviceType: 1 // 1-云喇叭 2-云打印 3-扫码POS
|
||||
}) as any
|
||||
|
||||
function show (record: any) { // 弹层打开事件
|
||||
|
||||
vdata.deviceType = record.deviceType
|
||||
vdata.provider = record.provider
|
||||
|
||||
vdata.saveObject = { 'state': 1, 'deviceType': record.deviceType } // 设备类型deviceType: 1-云喇叭, 2-云打印
|
||||
|
||||
if (infoFormModel.value != undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
vdata.recordId = record.deviceId
|
||||
req.getById(API_URL_STORE_DEVICE, vdata.recordId).then((res: any) => {
|
||||
if(res){
|
||||
vdata.saveObject = res
|
||||
|
||||
// 业务参数配置组件
|
||||
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) =>{
|
||||
bizConfigRef.value.getConfigParams().then((bizConfigParams: any) => {
|
||||
vdata.btnLoading = true
|
||||
|
||||
// 赋值
|
||||
vdata.saveObject.bizConfigParams = bizConfigParams || ''
|
||||
|
||||
// 请求接口
|
||||
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 onClose () { // 关闭抽屉
|
||||
vdata.drawerVisible = false
|
||||
}
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
235
jeepay-ui-agent/src/views/device/FaceAppList.vue
Normal file
235
jeepay-ui-agent/src/views/device/FaceAppList.vue
Normal file
@@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :placeholder="'服务商号/名称'" />
|
||||
<JeepaySearchInfoInput v-model:value="vdata.searchData['mchUserName']" placeholder="用户号/名称" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.deviceNo" :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>
|
||||
<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"
|
||||
:rowSelection="{ type: 'checkbox', selectedRowKeys: vdata.allotDeviceIdList, onChange: infoTableSelectChangeFunc }"
|
||||
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>
|
||||
<a-button v-if="$access('ENT_DEVICE_FACE_APP_ALLOT')" type="primary" @click="allotBatchFunc"><partition-outlined />勾选划拨/收回</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotByBatchIdFunc"><partition-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 === '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') && record.isSelf" type="link" @click="bindFunc(record)">绑定</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_FACE_APP_EDIT') && record.bindState == 1 && record.isSelf" type="link" @click="deBindFunc(record.deviceId)">解绑</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_FACE_APP_ALLOT')" type="link" @click="allotFunc(record)">划拨/收回</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 批次号划拨弹窗 -->
|
||||
<a-modal v-model:visible="vdata.allotByBatchIdVisible" title="按批次号划拨设备" @ok="allotOk">
|
||||
<a-form ref="allotFormModel" :model="vdata.allotObject" layout="vertical" :rules="vdata.allotRules">
|
||||
<a-form-item label="批次号:" name="batchId">
|
||||
<a-input v-model:value="vdata.allotObject.batchId" placeholder="请输入批次号" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<!-- 绑定组件 -->
|
||||
<Bind ref="bind" :callbackFunc="searchFunc" />
|
||||
|
||||
<JeepayModelAgentList ref="jeepayModelAgentList" showType="AGENT" @selectFinishFunc="searchAgentFinishFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, req, reqLoad, $allotDevice, $unbindDevice } from '@/api/manage'
|
||||
import Bind from './Bind.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const jeepayModelAgentList = ref()
|
||||
const bind = ref()
|
||||
const infoTable = ref()
|
||||
const allotFormModel = ref()
|
||||
|
||||
const deviceType = 6
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ title: '设备号', fixed: 'left', dataIndex: 'deviceNo', },
|
||||
{ key: 'provider', title: '设备厂商', dataIndex: 'provider'},
|
||||
{ title: '服务商号', dataIndex: 'agentNo', agentEntCol: true},
|
||||
{ key: 'bindState', 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 () { // 业务通用【新增】 函数
|
||||
$infoBox.message.success('请联系运营平台申请')
|
||||
}
|
||||
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 allotByBatchIdFunc() {
|
||||
vdata.allotObject.allotType = 'batch'
|
||||
vdata.allotObject.batchId = ''
|
||||
vdata.allotByBatchIdVisible = true
|
||||
}
|
||||
|
||||
// 按批次号划拨,批次号输入完成
|
||||
function allotOk() {
|
||||
allotFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.allotByBatchIdVisible = false
|
||||
jeepayModelAgentList.value.show()
|
||||
})
|
||||
}
|
||||
|
||||
// 表格多选
|
||||
function infoTableSelectChangeFunc(selectedRowKeys, selectedRows) {
|
||||
vdata.allotDeviceIdList = selectedRowKeys
|
||||
}
|
||||
|
||||
// 勾选划拨设备
|
||||
function allotBatchFunc() {
|
||||
if (vdata.allotDeviceIdList.length < 1) {
|
||||
$infoBox.message.error('请选择设备')
|
||||
} else {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
}
|
||||
|
||||
// 划拨单个设备
|
||||
function allotFunc(record) {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
vdata.allotDeviceIdList = []
|
||||
vdata.allotDeviceIdList.push(record.deviceId)
|
||||
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
|
||||
// 解绑设备
|
||||
function deBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后商户将无法使用该设备!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindDevice(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 服务商选择完成
|
||||
function searchAgentFinishFunc(selectObject) {
|
||||
|
||||
if (vdata.allotDeviceIdList.length > 0) {
|
||||
vdata.allotObject.allotDeviceIds = vdata.allotDeviceIdList.join(',')
|
||||
}
|
||||
vdata.allotObject.agentNo = selectObject[0]
|
||||
vdata.allotObject.allotOrRecover = selectObject[1]
|
||||
|
||||
$allotDevice(vdata.allotObject).then(res => {
|
||||
vdata.allotDeviceIdList = [] // 清空多选
|
||||
$infoBox.message.success('保存成功')
|
||||
jeepayModelAgentList.value.close()
|
||||
searchFunc()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
257
jeepay-ui-agent/src/views/device/PluginCdKeyList.vue
Normal file
257
jeepay-ui-agent/src/views/device/PluginCdKeyList.vue
Normal file
@@ -0,0 +1,257 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchConditionNum="6" :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :placeholder="'服务商号/名称'" />
|
||||
<JeepaySearchInfoInput v-model:value="vdata.searchData['mchUserName']" placeholder="用户号/名称" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.deviceNo" :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="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
:rowSelection="{ type: 'checkbox', selectedRowKeys: vdata.allotDeviceIdList, onChange: infoTableSelectChangeFunc }"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="addFunc"><plus-outlined />申请新激活码</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotBatchFunc"><partition-outlined />勾选划拨/收回</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotByBatchIdFunc"><partition-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 === '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 === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="($access('ENT_DEVICE_PLUGIN_CDKEY_EDIT') && record.isSelf)" type="link" @click="bindFunc(record)">绑定</a-button>
|
||||
<a-button v-if="($access('ENT_DEVICE_PLUGIN_CDKEY_EDIT') && record.bindState == 1 && record.isSelf)" type="link" @click="deBindFunc(record.deviceId)">解绑</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="link" @click="allotFunc(record)">划拨/收回</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 批次号划拨弹窗 -->
|
||||
<a-modal v-model:visible="vdata.allotByBatchIdVisible" title="按批次号划拨设备" @ok="allotOk">
|
||||
<a-form ref="allotFormModel" :model="vdata.allotObject" layout="vertical" :rules="vdata.allotRules">
|
||||
<a-form-item label="批次号:" name="batchId">
|
||||
<a-input v-model:value="vdata.allotObject.batchId" placeholder="请输入批次号" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<!-- 绑定组件 -->
|
||||
<Bind ref="bind" :callbackFunc="searchFunc" />
|
||||
<!-- 选择划拨服务商 -->
|
||||
<JeepayModelAgentList ref="jeepayModelAgentList" showType="AGENT" @selectFinishFunc="searchAgentFinishFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, req, reqLoad, $unbindDevice, $allotDevice } from '@/api/manage'
|
||||
import InfoAddOrEdit from './CommonAddOrEdit.vue'
|
||||
import Bind from './Bind.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import dateUtil from '@/utils/dateUtil.js'
|
||||
import { useRoute } from 'vue-router'
|
||||
import provider from './provider.json'
|
||||
|
||||
const pluginList = provider.plugin
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoAddOrEdit = ref()
|
||||
const bind = ref()
|
||||
const infoTable = ref()
|
||||
const deviceType = 5
|
||||
const jeepayModelAgentList = ref()
|
||||
const allotFormModel = ref()
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ title: '激活码', fixed: 'left', dataIndex: 'deviceNo', },
|
||||
{ key: 'provider', title: '厂商', dataIndex: 'provider', },
|
||||
{ title: '服务商号', dataIndex: 'agentNo', agentEntCol: true, },
|
||||
{ key: 'bindState', 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,
|
||||
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 () { // 业务通用【新增】 函数
|
||||
$infoBox.message.success('请联系运营平台申请')
|
||||
}
|
||||
function bindFunc (record: any) { // 绑定激活码函数
|
||||
bind.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('解绑成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
// 表格多选
|
||||
function infoTableSelectChangeFunc(selectedRowKeys, selectedRows) {
|
||||
vdata.allotDeviceIdList = selectedRowKeys
|
||||
}
|
||||
|
||||
// 按批次号划拨
|
||||
function allotByBatchIdFunc() {
|
||||
vdata.allotObject.allotType = 'batch'
|
||||
vdata.allotObject.batchId = ''
|
||||
|
||||
vdata.allotByBatchIdVisible = true
|
||||
}
|
||||
|
||||
// 按批次号划拨,批次号输入完成
|
||||
function allotOk() {
|
||||
allotFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.allotByBatchIdVisible = false
|
||||
jeepayModelAgentList.value.show()
|
||||
})
|
||||
}
|
||||
|
||||
// 勾选划拨设备
|
||||
function allotBatchFunc() {
|
||||
if (vdata.allotDeviceIdList.length < 1) {
|
||||
$infoBox.message.error('请选择设备')
|
||||
} else {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
}
|
||||
|
||||
// 划拨单个设备
|
||||
function allotFunc(record) {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
vdata.allotDeviceIdList = []
|
||||
vdata.allotDeviceIdList.push(record.deviceId)
|
||||
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
|
||||
// 划拨/收回选择完成
|
||||
function searchAgentFinishFunc(selectObject) {
|
||||
|
||||
vdata.allotObject.agentNo = selectObject[0]
|
||||
vdata.allotObject.allotOrRecover = selectObject[1]
|
||||
|
||||
if (vdata.allotObject.allotOrRecover == 'allot' && !vdata.allotObject.agentNo) {
|
||||
$infoBox.message.error('请选择服务商')
|
||||
return
|
||||
}
|
||||
|
||||
if (vdata.allotDeviceIdList.length > 0) {
|
||||
vdata.allotObject.allotDeviceIds = vdata.allotDeviceIdList.join(',')
|
||||
}
|
||||
|
||||
$allotDevice(vdata.allotObject).then(res => {
|
||||
vdata.allotDeviceIdList = [] // 清空多选
|
||||
$infoBox.message.success('保存成功')
|
||||
jeepayModelAgentList.value.close()
|
||||
searchFunc()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
311
jeepay-ui-agent/src/views/device/PosList.vue
Normal file
311
jeepay-ui-agent/src/views/device/PosList.vue
Normal file
@@ -0,0 +1,311 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchConditionNum="6" :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :placeholder="'服务商号/名称'" />
|
||||
<!-- <JeepaySearchInfoInput v-model:value="vdata.searchData['mchNo']" placeholder="用户号" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />-->
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchUserName']" :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 posList" :key="item.value" :value="item.value">{{ item.text }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['deviceName']" :placeholder="'设备名称/编号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['storeId']" :placeholder="'门店名称/编号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchApplyName']" :placeholder="'商户名称/商户号'" />
|
||||
<!-- <jeepay-text-up v-model:value="searchData['deviceNo']" :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"
|
||||
:init-data="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
:rowSelection="{ type: 'checkbox', selectedRowKeys: vdata.allotDeviceIdList, onChange: infoTableSelectChangeFunc }"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="addFunc"><plus-outlined />申请新设备</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotBatchFunc"><partition-outlined />勾选划拨/收回</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotByBatchIdFunc"><partition-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 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 === '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 === 'agentNo'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.agentName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.agentName}}</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_DEVICE_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 === 'mchServiceName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.mchServiceName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchServiceName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="($access('ENT_DEVICE_POS_DEVICE_EDIT') && record.isSelf)" type="link" @click="bindFunc(record)">绑定</a-button>
|
||||
<a-button v-if="($access('ENT_DEVICE_POS_DEVICE_EDIT') && record.bindState == 1 && record.isSelf)" type="link" @click="deBindFunc(record.deviceId)">解绑</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="link" @click="allotFunc(record)">划拨/收回</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 批次号划拨弹窗 -->
|
||||
<a-modal v-model:visible="vdata.allotByBatchIdVisible" title="按批次号划拨设备" @ok="allotOk">
|
||||
<a-form ref="allotFormModel" :model="vdata.allotObject" layout="vertical" :rules="vdata.allotRules">
|
||||
<a-form-item label="批次号:" name="batchId">
|
||||
<a-input v-model:value="vdata.allotObject.batchId" placeholder="请输入批次号" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<!-- 绑定组件 -->
|
||||
<Bind ref="bind" :callbackFunc="searchFunc" />
|
||||
<!-- 选择划拨服务商 -->
|
||||
<JeepayModelAgentList ref="jeepayModelAgentList" showType="AGENT" @selectFinishFunc="searchAgentFinishFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, req, reqLoad, $unbindDevice, $allotDevice } from '@/api/manage'
|
||||
import InfoAddOrEdit from './CommonAddOrEdit.vue'
|
||||
import Bind from './Bind.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import provider from './provider.json'
|
||||
|
||||
const posList = provider.pos
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoAddOrEdit = ref()
|
||||
const bind = ref()
|
||||
const infoTable = ref()
|
||||
const deviceType = ref(3)
|
||||
const jeepayModelAgentList = ref()
|
||||
const allotFormModel = ref()
|
||||
|
||||
let tableColumns = reactive([
|
||||
// { title: '设备号', fixed: 'left', dataIndex: 'deviceNo', },
|
||||
// { key: 'provider', title: '设备厂商', dataIndex: 'provider',},
|
||||
// { title: '服务商号', dataIndex: 'agentNo', agentEntCol: true, },
|
||||
// { key: 'bindState', title: '绑定商户信息', },
|
||||
// { key: 'state', title: '状态', },
|
||||
// { dataIndex: 'createdAt', title: '创建日期', },
|
||||
// { key: 'operation', title: '操作', fixed: 'right', align: 'center', }
|
||||
|
||||
|
||||
{ key: 'provider', title: '设备厂家', },
|
||||
{ title: '设备号', dataIndex: 'deviceNo' },
|
||||
{ title: '设备名称', dataIndex: 'deviceName', },
|
||||
{ key: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'mchServiceName', title: '服务商名称', dataIndex: 'mchServiceName' },
|
||||
{ title: "商户名称", key: "mchApplyName", dataIndex: "mchApplyName" },
|
||||
{ key: 'storeId',title: '门店名称', dataIndex: 'storeId',},
|
||||
// { key: 'bindState', title: '绑定商户信息', },
|
||||
{ key: 'state', title: '使用状态',},
|
||||
{ dataIndex: 'createdAt', title: '创建日期',},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
const vdata = reactive({
|
||||
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.value }, params))
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
btnLoading.value = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
$infoBox.message.success('请联系运营平台申请')
|
||||
}
|
||||
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('解绑成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
// 表格多选
|
||||
function infoTableSelectChangeFunc(selectedRowKeys, selectedRows) {
|
||||
vdata.allotDeviceIdList = selectedRowKeys
|
||||
}
|
||||
|
||||
// 按批次号划拨
|
||||
function allotByBatchIdFunc() {
|
||||
vdata.allotObject.allotType = 'batch'
|
||||
vdata.allotObject.batchId = ''
|
||||
|
||||
vdata.allotByBatchIdVisible = true
|
||||
}
|
||||
|
||||
// 按批次号划拨,批次号输入完成
|
||||
function allotOk() {
|
||||
allotFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.allotByBatchIdVisible = false
|
||||
jeepayModelAgentList.value.show()
|
||||
})
|
||||
}
|
||||
|
||||
// 勾选划拨设备
|
||||
function allotBatchFunc() {
|
||||
if (vdata.allotDeviceIdList.length < 1) {
|
||||
$infoBox.message.error('请选择设备')
|
||||
} else {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
}
|
||||
|
||||
// 划拨单个设备
|
||||
function allotFunc(record) {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
vdata.allotDeviceIdList = []
|
||||
vdata.allotDeviceIdList.push(record.deviceId)
|
||||
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
|
||||
// 划拨/收回选择完成
|
||||
function searchAgentFinishFunc(selectObject) {
|
||||
|
||||
vdata.allotObject.agentNo = selectObject[0]
|
||||
vdata.allotObject.allotOrRecover = selectObject[1]
|
||||
|
||||
if (vdata.allotObject.allotOrRecover == 'allot' && !vdata.allotObject.agentNo) {
|
||||
$infoBox.message.error('请选择服务商')
|
||||
return
|
||||
}
|
||||
|
||||
if (vdata.allotDeviceIdList.length > 0) {
|
||||
vdata.allotObject.allotDeviceIds = vdata.allotDeviceIdList.join(',')
|
||||
}
|
||||
|
||||
$allotDevice(vdata.allotObject).then(res => {
|
||||
vdata.allotDeviceIdList = [] // 清空多选
|
||||
$infoBox.message.success('保存成功')
|
||||
jeepayModelAgentList.value.close()
|
||||
searchFunc()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
351
jeepay-ui-agent/src/views/device/PrinterList.vue
Normal file
351
jeepay-ui-agent/src/views/device/PrinterList.vue
Normal file
@@ -0,0 +1,351 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchConditionNum="6" :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :placeholder="'服务商号'" />
|
||||
<!-- <JeepaySearchInfoInput v-model:value="vdata.searchData['mchUserName']" placeholder="用户号" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />-->
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchUserName']" :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 printerList" :key="item.value" :value="item.value">{{ item.text }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['deviceName']" :placeholder="'设备名称/编号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['storeId']" :placeholder="'门店名称/编号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchApplyName']" :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="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['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>
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
:rowSelection="{ type: 'checkbox', selectedRowKeys: vdata.allotDeviceIdList, onChange: infoTableSelectChangeFunc }"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="addFunc"><plus-outlined />申请新设备</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotBatchFunc"><partition-outlined />勾选划拨/收回</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotByBatchIdFunc"><partition-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 === 'state'">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="$access('ENT_DEVICE_PRINTER_DEVICE_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 === 'jsonBizConfigParams'">
|
||||
<div v-if="record.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>
|
||||
</div>
|
||||
<div v-else>
|
||||
<a-tag >未知</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'bizConfigParams'">
|
||||
{{record.jsonBizConfigParams?record.jsonBizConfigParams.printNum:"--"}}
|
||||
</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 === '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 === 'mchServiceName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.mchServiceName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchServiceName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</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_DEVICE_EDIT')" type="link" @click="editFunc(record)">修改</a-button>
|
||||
<a-button v-if="($access('ENT_DEVICE_PRINTER_DEVICE_EDIT') && record.isSelf)" type="link" @click="bindFunc(record)">绑定</a-button>
|
||||
<a-button v-if="($access('ENT_DEVICE_PRINTER_DEVICE_EDIT') && record.bindState == 1 && record.isSelf)" type="link" @click="deBindFunc(record.deviceId)">解绑</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="link" @click="allotFunc(record)">划拨/收回</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_PRINTER_DEVICE_TEST')" type="link" @click="test(record.deviceId)">打印测试</a-button>
|
||||
<a-button v-if="record.provider === 'fe' && $access('ENT_DEVICE_PRINTER_DEVICE_CLEAR')" type="link" @click="clear(record.deviceId)">清空打印队列</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 批次号划拨弹窗 -->
|
||||
<a-modal v-model:visible="vdata.allotByBatchIdVisible" title="按批次号划拨设备" @ok="allotOk">
|
||||
<a-form ref="allotFormModel" :model="vdata.allotObject" layout="vertical" :rules="vdata.allotRules">
|
||||
<a-form-item label="批次号:" name="batchId">
|
||||
<a-input v-model:value="vdata.allotObject.batchId" placeholder="请输入批次号" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<!-- 测试设备组件 -->
|
||||
<TestDevice ref="testDevice" :callbackFunc="searchFunc" />
|
||||
<!-- 绑定组件 -->
|
||||
<Bind ref="bind" :callbackFunc="searchFunc" />
|
||||
<!-- 选择划拨服务商 -->
|
||||
<JeepayModelAgentList ref="jeepayModelAgentList" showType="AGENT" @selectFinishFunc="searchAgentFinishFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, req, reqLoad, $clearPrint, $unbindDevice, $allotDevice } from '@/api/manage'
|
||||
import InfoAddOrEdit from './CommonAddOrEdit.vue'
|
||||
import TestDevice from './TestDevice.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import Bind from './Bind.vue'
|
||||
import provider from './provider.json'
|
||||
|
||||
const printerList = provider.printer
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoAddOrEdit = ref()
|
||||
const testDevice = ref()
|
||||
const infoTable = ref()
|
||||
const bind = ref()
|
||||
const deviceType = ref(2)
|
||||
const jeepayModelAgentList = ref()
|
||||
const allotFormModel = ref()
|
||||
|
||||
let tableColumns = reactive([
|
||||
// { title: '设备号', fixed: 'left', dataIndex: 'deviceNo', },
|
||||
// { key: 'provider', title: '设备厂商', dataIndex: 'provider', },
|
||||
// { title: '服务商号', dataIndex: 'agentNo', agentEntCol: true, },
|
||||
// { key: 'bindState', title: '绑定商户信息', },
|
||||
// { key: 'state', title: '状态', },
|
||||
// { dataIndex: 'createdAt', title: '创建日期', },
|
||||
// { key: 'operation', title: '操作', fixed: 'right', align: 'center',}
|
||||
|
||||
|
||||
{ key: 'provider', title: '设备厂商', },
|
||||
{ title: '设备号', fixed: 'left', dataIndex: 'deviceNo' },
|
||||
{ title: '设备名称', dataIndex: 'deviceName', },
|
||||
{ key: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'mchServiceName', title: '服务商名称', dataIndex: 'mchServiceName' },
|
||||
{ title: "商户名称", key: "mchApplyName", dataIndex: "mchApplyName" },
|
||||
{ key: 'storeId',title: '门店名称', dataIndex: 'storeId',},
|
||||
{ title: '服务商号', dataIndex: 'agentNo', agentEntCol: true, },
|
||||
// { 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)
|
||||
const vdata = reactive({
|
||||
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.value }, 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 test(recordId){ //打印测试
|
||||
testDevice.value.show(recordId, deviceType.value)
|
||||
}
|
||||
function bindFunc (record: any) { // 绑定设备函数
|
||||
bind.value.show(record)
|
||||
}
|
||||
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('解绑成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
// 表格多选
|
||||
function infoTableSelectChangeFunc(selectedRowKeys, selectedRows) {
|
||||
vdata.allotDeviceIdList = selectedRowKeys
|
||||
}
|
||||
|
||||
// 按批次号划拨
|
||||
function allotByBatchIdFunc() {
|
||||
vdata.allotObject.allotType = 'batch'
|
||||
vdata.allotObject.batchId = ''
|
||||
|
||||
vdata.allotByBatchIdVisible = true
|
||||
}
|
||||
|
||||
// 按批次号划拨,批次号输入完成
|
||||
function allotOk() {
|
||||
allotFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.allotByBatchIdVisible = false
|
||||
jeepayModelAgentList.value.show()
|
||||
})
|
||||
}
|
||||
|
||||
// 勾选划拨设备
|
||||
function allotBatchFunc() {
|
||||
if (vdata.allotDeviceIdList.length < 1) {
|
||||
$infoBox.message.error('请选择设备')
|
||||
} else {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
}
|
||||
|
||||
// 划拨单个设备
|
||||
function allotFunc(record) {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
vdata.allotDeviceIdList = []
|
||||
vdata.allotDeviceIdList.push(record.deviceId)
|
||||
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
|
||||
// 划拨/收回选择完成
|
||||
function searchAgentFinishFunc(selectObject) {
|
||||
|
||||
vdata.allotObject.agentNo = selectObject[0]
|
||||
vdata.allotObject.allotOrRecover = selectObject[1]
|
||||
|
||||
if (vdata.allotObject.allotOrRecover == 'allot' && !vdata.allotObject.agentNo) {
|
||||
$infoBox.message.error('请选择服务商')
|
||||
return
|
||||
}
|
||||
|
||||
if (vdata.allotDeviceIdList.length > 0) {
|
||||
vdata.allotObject.allotDeviceIds = vdata.allotDeviceIdList.join(',')
|
||||
}
|
||||
|
||||
$allotDevice(vdata.allotObject).then(res => {
|
||||
vdata.allotDeviceIdList = [] // 清空多选
|
||||
$infoBox.message.success('保存成功')
|
||||
jeepayModelAgentList.value.close()
|
||||
searchFunc()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
229
jeepay-ui-agent/src/views/device/RuyiList.vue
Normal file
229
jeepay-ui-agent/src/views/device/RuyiList.vue
Normal file
@@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :placeholder="'服务商号/名称'" />
|
||||
<JeepaySearchInfoInput v-model:value="vdata.searchData['mchUserName']" placeholder="用户号/名称" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.deviceNo" :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>
|
||||
<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"
|
||||
:rowSelection="{ type: 'checkbox', selectedRowKeys: vdata.allotDeviceIdList, onChange: infoTableSelectChangeFunc }"
|
||||
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>
|
||||
<a-button v-if="$access('ENT_DEVICE_FACE_APP_ALLOT')" type="primary" @click="allotBatchFunc"><partition-outlined />勾选划拨/收回</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotByBatchIdFunc"><partition-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 === '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="blue">
|
||||
支付宝如意Lite
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_DEVICE_RUYI_EDIT') && record.isSelf" type="link" @click="bindFunc(record)">绑定</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_RUYI_EDIT') && record.bindState == 1 && record.isSelf" type="link" @click="deBindFunc(record.deviceId)">解绑</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_RUYI_ALLOT')" type="link" @click="allotFunc(record)">划拨/收回</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 批次号划拨弹窗 -->
|
||||
<a-modal v-model:visible="vdata.allotByBatchIdVisible" title="按批次号划拨设备" @ok="allotOk">
|
||||
<a-form ref="allotFormModel" :model="vdata.allotObject" layout="vertical" :rules="vdata.allotRules">
|
||||
<a-form-item label="批次号:" name="batchId">
|
||||
<a-input v-model:value="vdata.allotObject.batchId" placeholder="请输入批次号" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<!-- 绑定组件 -->
|
||||
<Bind ref="bind" :callbackFunc="searchFunc" />
|
||||
|
||||
<JeepayModelAgentList ref="jeepayModelAgentList" showType="AGENT" @selectFinishFunc="searchAgentFinishFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, req, reqLoad, $allotDevice, $unbindDevice } from '@/api/manage'
|
||||
import Bind from './Bind.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const jeepayModelAgentList = ref()
|
||||
const bind = ref()
|
||||
const infoTable = ref()
|
||||
const allotFormModel = ref()
|
||||
|
||||
const deviceType = 7
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ title: '设备号', fixed: 'left', dataIndex: 'deviceNo', },
|
||||
{ key: 'provider', title: '设备厂商', dataIndex: 'provider'},
|
||||
{ title: '服务商号', dataIndex: 'agentNo', agentEntCol: true},
|
||||
{ key: 'bindState', 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 () { // 业务通用【新增】 函数
|
||||
$infoBox.message.success('请联系运营平台申请')
|
||||
}
|
||||
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 allotByBatchIdFunc() {
|
||||
vdata.allotObject.allotType = 'batch'
|
||||
vdata.allotObject.batchId = ''
|
||||
vdata.allotByBatchIdVisible = true
|
||||
}
|
||||
|
||||
// 按批次号划拨,批次号输入完成
|
||||
function allotOk() {
|
||||
allotFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.allotByBatchIdVisible = false
|
||||
jeepayModelAgentList.value.show()
|
||||
})
|
||||
}
|
||||
|
||||
// 表格多选
|
||||
function infoTableSelectChangeFunc(selectedRowKeys, selectedRows) {
|
||||
vdata.allotDeviceIdList = selectedRowKeys
|
||||
}
|
||||
|
||||
// 勾选划拨设备
|
||||
function allotBatchFunc() {
|
||||
if (vdata.allotDeviceIdList.length < 1) {
|
||||
$infoBox.message.error('请选择设备')
|
||||
} else {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
}
|
||||
|
||||
// 划拨单个设备
|
||||
function allotFunc(record) {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
vdata.allotDeviceIdList = []
|
||||
vdata.allotDeviceIdList.push(record.deviceId)
|
||||
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
|
||||
// 解绑设备
|
||||
function deBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后商户将无法使用该设备!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindDevice(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 服务商选择完成
|
||||
function searchAgentFinishFunc(selectObject) {
|
||||
|
||||
if (vdata.allotDeviceIdList.length > 0) {
|
||||
vdata.allotObject.allotDeviceIds = vdata.allotDeviceIdList.join(',')
|
||||
}
|
||||
vdata.allotObject.agentNo = selectObject[0]
|
||||
vdata.allotObject.allotOrRecover = selectObject[1]
|
||||
|
||||
$allotDevice(vdata.allotObject).then(res => {
|
||||
vdata.allotDeviceIdList = [] // 清空多选
|
||||
$infoBox.message.success('保存成功')
|
||||
jeepayModelAgentList.value.close()
|
||||
searchFunc()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
359
jeepay-ui-agent/src/views/device/SpeakerList.vue
Normal file
359
jeepay-ui-agent/src/views/device/SpeakerList.vue
Normal file
@@ -0,0 +1,359 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="onReset">
|
||||
<!-- <jeepay-text-up v-model:value="vdata.searchData.agentNo" :placeholder="'服务商号/名称'" />-->
|
||||
<!-- <JeepaySearchInfoInput v-model:value="vdata.searchData['mchNo']" placeholder="用户号" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />-->
|
||||
<!-- <jeepay-text-up v-model:value="vdata.searchData['mchNo']" :placeholder="'用户号/名称/手机号'" />-->
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.qrcType" 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>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.entryPage" placeholder="页面类型">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="default">默认</a-select-option>
|
||||
<a-select-option value="h5">H5</a-select-option>
|
||||
<a-select-option value="lite">小程序</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :placeholder="'服务商号'" />
|
||||
<JeepaySearchInfoInput v-model:value="vdata.searchData['mchUserName']" placeholder="用户号/名称" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.qrcAlias" placeholder="二维码名称/编号" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchApplyName']" :placeholder="'商户名称/商户号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.storeId" 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.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"
|
||||
:rowSelection="{ type: 'checkbox', selectedRowKeys: vdata.allotDeviceIdList, onChange: infoTableSelectChangeFunc }"
|
||||
row-key="deviceId"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="addFunc"><plus-outlined />申请新设备</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotBatchFunc"><partition-outlined />勾选划拨/收回</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="primary" @click="allotByBatchIdFunc"><partition-outlined />批次划拨/收回</a-button> -->
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
|
||||
<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 === '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 === 'agentNo'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.agentName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.agentName}}</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 === 'qrcType'">
|
||||
<a-tag v-if="record.qrcType == 0" color="blue">电子码牌</a-tag>
|
||||
<a-tag v-if="record.qrcType == 1" color="orange">实体码牌</a-tag>
|
||||
<a-tag v-if="record.qrcType == 2" color="green">实体立牌</a-tag>
|
||||
</template>
|
||||
<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.storeId }} ({{ record.storeName }})</template>
|
||||
</template>
|
||||
|
||||
<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 === 'state'">
|
||||
<JeepayTableColState :state="record.state" :showSwitchType="$access('ENT_DEVICE_SPEAKER_DEVICE_EDIT')" :onChange="(state) => { return updateState(record.deviceId, state)}" />
|
||||
</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 === 'mchServiceName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.mchServiceName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchServiceName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</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_DEVICE_EDIT') && record.isSelf" type="link" @click="bindFunc(record)">绑定</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_EDIT') && record.bindState == 1 && record.isSelf" type="link" @click="unBindFunc(record.deviceId)">解绑</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_ALLOT')" type="link" @click="allotFunc(record)">划拨/收回</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE_TEST')" type="link" @click="test(record.deviceId)">播报测试</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 批次号划拨弹窗 -->
|
||||
<a-modal v-model:visible="vdata.allotByBatchIdVisible" title="按批次号划拨设备" @ok="allotOk">
|
||||
<a-form ref="allotFormModel" :model="vdata.allotObject" layout="vertical" :rules="vdata.allotRules">
|
||||
<a-form-item label="批次号:" name="batchId">
|
||||
<a-input v-model:value="vdata.allotObject.batchId" placeholder="请输入批次号" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
|
||||
<!-- 绑定组件 -->
|
||||
<Bind ref="bind" :callbackFunc="searchFunc" />
|
||||
|
||||
<!-- 测试设备组件 -->
|
||||
<TestDevice ref="testDevice" :callbackFunc="searchFunc" />
|
||||
|
||||
<!-- 选择划拨代理商 -->
|
||||
<JeepayModelAgentList ref="jeepayModelAgentList" showType="AGENT" @selectFinishFunc="searchAgentFinishFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_STORE_DEVICE, req, reqLoad, $unbindDevice, $allotDevice } from '@/api/manage'
|
||||
import InfoAddOrEdit from './CommonAddOrEdit.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import Bind from './BindSpeaker.vue'
|
||||
import TestDevice from './TestDevice.vue'
|
||||
import provider from './provider.json'
|
||||
|
||||
const speakerList = provider.speaker
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoAddOrEdit = ref()
|
||||
const infoTable = ref()
|
||||
const bind = ref()
|
||||
const testDevice = ref()
|
||||
const deviceType = ref(1)
|
||||
const jeepayModelAgentList = ref()
|
||||
const allotFormModel = ref()
|
||||
|
||||
let tableColumns = reactive([
|
||||
// // { title: '设备ID', fixed: 'left', dataIndex: 'deviceId' },
|
||||
// { title: '设备号', dataIndex: 'deviceNo'},
|
||||
// // { title: '批次号', dataIndex: 'batchId' },
|
||||
// { title: '绑定码牌ID', dataIndex: 'bindQrcId' },
|
||||
// { key: 'provider', title: '设备厂商', dataIndex: 'provider'},
|
||||
// { title: '代理商号', dataIndex: 'agentNo', agentEntCol: true, },
|
||||
// { key: 'bindState', title: '绑定商户信息', },
|
||||
// { key: 'bindType', title: '绑定类型'},
|
||||
// { key: 'state', title: '状态' },
|
||||
// { dataIndex: 'createdAt', title: '创建日期', },
|
||||
// { key: 'operation', title: '操作', fixed: 'right', align: 'center', }
|
||||
|
||||
{ key: 'provider', title: '设备厂商', },
|
||||
{ key: 'deviceNo',title: '设备号', dataIndex: 'deviceNo' },
|
||||
{ key: 'deviceName',title: '设备名称', dataIndex: 'deviceName', },
|
||||
{ key: 'bindQrcId', title: '二维码编号', },
|
||||
{ key: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'mchServiceName', title: '服务商名称', dataIndex: 'mchServiceName' },
|
||||
{ title: "商户名称", key: "mchApplyName", dataIndex: "mchApplyName" },
|
||||
{ key: 'storeId', title: '门店名称', dataIndex: 'storeId', },
|
||||
// { key: 'bindState', title: '绑定商户信息', },
|
||||
{ key: 'bindType', title: '绑定类型',},
|
||||
{ key: 'state', title: '使用状态', },
|
||||
{ key: 'fixedFlag', title: '固定金额', },
|
||||
{ dataIndex: 'createdAt', title: '创建日期',},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
const vdata = reactive({
|
||||
searchData: {} as any,
|
||||
isSupportAgentAllot: false, // 是否支持代理商划拨设备
|
||||
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
|
||||
vdata.searchData.deviceId = useRoute().query.deviceId
|
||||
searchFunc()
|
||||
})
|
||||
|
||||
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 () { // 业务通用【新增】 函数
|
||||
$infoBox.message.success('请联系运营平台申请')
|
||||
}
|
||||
function bindFunc (record: any) { // 绑定设备函数
|
||||
bind.value.show(record)
|
||||
}
|
||||
function test(recordId){ // 测试
|
||||
testDevice.value.show(recordId, deviceType.value)
|
||||
}
|
||||
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 unBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后商户将无法使用该设备!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindDevice(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 表格多选
|
||||
function infoTableSelectChangeFunc(selectedRowKeys, selectedRows) {
|
||||
vdata.allotDeviceIdList = selectedRowKeys
|
||||
}
|
||||
|
||||
// 按批次号划拨
|
||||
function allotByBatchIdFunc() {
|
||||
vdata.allotObject.allotType = 'batch'
|
||||
vdata.allotObject.batchId = ''
|
||||
|
||||
vdata.allotByBatchIdVisible = true
|
||||
}
|
||||
|
||||
// 按批次号划拨,批次号输入完成
|
||||
function allotOk() {
|
||||
allotFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.allotByBatchIdVisible = false
|
||||
jeepayModelAgentList.value.show()
|
||||
})
|
||||
}
|
||||
|
||||
// 勾选划拨设备
|
||||
function allotBatchFunc() {
|
||||
if (vdata.allotDeviceIdList.length < 1) {
|
||||
$infoBox.message.error('请选择设备')
|
||||
} else {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
}
|
||||
|
||||
// 划拨单个设备
|
||||
function allotFunc(record) {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
vdata.allotDeviceIdList = []
|
||||
vdata.allotDeviceIdList.push(record.deviceId)
|
||||
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
|
||||
// 划拨/收回选择完成
|
||||
function searchAgentFinishFunc(selectObject) {
|
||||
|
||||
vdata.allotObject.agentNo = selectObject[0]
|
||||
vdata.allotObject.allotOrRecover = selectObject[1]
|
||||
|
||||
if (vdata.allotObject.allotOrRecover == 'allot' && !vdata.allotObject.agentNo) {
|
||||
$infoBox.message.error('请选择服务商')
|
||||
return
|
||||
}
|
||||
|
||||
if (vdata.allotDeviceIdList.length > 0) {
|
||||
vdata.allotObject.allotDeviceIds = vdata.allotDeviceIdList.join(',')
|
||||
}
|
||||
|
||||
$allotDevice(vdata.allotObject).then(res => {
|
||||
vdata.allotDeviceIdList = [] // 清空多选
|
||||
$infoBox.message.success('保存成功')
|
||||
jeepayModelAgentList.value.close()
|
||||
searchFunc()
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
58
jeepay-ui-agent/src/views/device/TestDevice.vue
Normal file
58
jeepay-ui-agent/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>
|
||||
1
jeepay-ui-agent/src/views/device/provider.json
Normal file
1
jeepay-ui-agent/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"}]}
|
||||
21
jeepay-ui-agent/src/views/exception/403.vue
Normal file
21
jeepay-ui-agent/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-agent/src/views/exception/404.vue
Normal file
21
jeepay-ui-agent/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-agent/src/views/exception/500.vue
Normal file
21
jeepay-ui-agent/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>
|
||||
76
jeepay-ui-agent/src/views/info/AgentInfo.vue
Normal file
76
jeepay-ui-agent/src/views/info/AgentInfo.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-card style="width: 500px;padding:30px">
|
||||
<div>
|
||||
<p>服务商信息</p>
|
||||
</div>
|
||||
<a-divider style="margin: 20px 0 10px 0;" />
|
||||
<div class="item">
|
||||
<span class="label">服务商名称</span>
|
||||
<span class="desc">{{ vdata.agentInfo.agentName }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">服务商简称</span>
|
||||
<span class="desc">{{ vdata.agentInfo.agentShortName }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">登录名</span>
|
||||
<span class="desc">{{ vdata.agentInfo.loginUsername }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">服务商号</span>
|
||||
<span class="desc">{{ vdata.agentInfo.agentNo }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">渠道商号</span>
|
||||
<span class="desc">{{ vdata.agentInfo.isvNo }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">上级服务商号</span>
|
||||
<span class="desc">{{ vdata.agentInfo.pid }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">注册时间</span>
|
||||
<span class="desc">{{ vdata.agentInfo.createdAt }}</span>
|
||||
</div>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { $getMainUserInfo } from '@/api/manage' // 接口
|
||||
import {reactive} from 'vue'
|
||||
|
||||
const vdata = reactive ({
|
||||
agentInfo: {} as any
|
||||
})
|
||||
|
||||
$getMainUserInfo().then(res => {
|
||||
vdata.agentInfo = res
|
||||
console.log(vdata.agentInfo)
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
p {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin:0 5px;
|
||||
}
|
||||
.desc {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.05em;
|
||||
color: #262626;
|
||||
}
|
||||
.label {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.05em;
|
||||
color: #999;
|
||||
}
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 8px;
|
||||
}
|
||||
</style>
|
||||
88
jeepay-ui-agent/src/views/info/MchInfoPage.vue
Normal file
88
jeepay-ui-agent/src/views/info/MchInfoPage.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-card style="width: 500px;padding:30px">
|
||||
<div>
|
||||
<p>商户中心</p>
|
||||
</div>
|
||||
<a-divider style="margin: 20px 0 10px 0;" />
|
||||
<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.type==1?'普通商户':'特约商户' }}</span>
|
||||
</div>
|
||||
<div 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 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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { $getMainUserInfo } from '@/api/manage' // 接口
|
||||
import {reactive} from 'vue'
|
||||
|
||||
const vdata = reactive ({
|
||||
mchInfo: {} as any
|
||||
})
|
||||
|
||||
$getMainUserInfo().then(res => {
|
||||
vdata.mchInfo = res
|
||||
console.log(vdata.mchInfo)
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
p {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin:0 5px;
|
||||
}
|
||||
.desc {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.05em;
|
||||
color: #262626;
|
||||
}
|
||||
.label {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.05em;
|
||||
color: #999;
|
||||
}
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 8px;
|
||||
}
|
||||
</style>
|
||||
387
jeepay-ui-agent/src/views/mch/AddOrEdit.vue
Normal file
387
jeepay-ui-agent/src/views/mch/AddOrEdit.vue
Normal file
@@ -0,0 +1,387 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:mask-closable="false"
|
||||
:title=" vdata.isAdd ? '新增商户' : '修改商户' "
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="40%"
|
||||
class="drawer-width"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form v-if="vdata.visible" ref="infoFormModel" :model="vdata.saveObject" layout="vertical" :rules="vdata.rules">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="用户名称" name="mchName">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['mchName']"
|
||||
placeholder="请输入商户名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="登录名" name="loginUsername">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['loginUsername']"
|
||||
placeholder="请输入商户登录名"
|
||||
:disabled="!vdata.isAdd"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="商户简称" name="mchShortName">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['mchShortName']"
|
||||
placeholder="请输入商户简称"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="联系人姓名" name="contactName">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['contactName']"
|
||||
placeholder="请输入联系人姓名"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="联系人邮箱" name="contactEmail">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['contactEmail']"
|
||||
placeholder="请输入联系人邮箱"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="联系人手机号" name="contactTel">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['contactTel']"
|
||||
placeholder="请输入联系人手机号"
|
||||
/>
|
||||
<span v-if="!vdata.isAdd" class="jeepay-tip-text">同步更改登录手机号</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<!-- <a-col :span="10" style="position:relative">-->
|
||||
<!-- <a-form-item label="商户级别" name="mchLevel">-->
|
||||
<!-- <!– 商户级别 气泡弹窗 –>-->
|
||||
<!-- <a-radio-group v-model:value="vdata.saveObject['mchLevel']">-->
|
||||
<!-- <a-radio :value="'M0'" :disabled="true">M0</a-radio>-->
|
||||
<!-- <a-radio :value="'M1'">M1</a-radio>-->
|
||||
<!-- </a-radio-group>-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- <div id="components-popover-demo-placement">-->
|
||||
<!-- <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>-->
|
||||
<!-- </div>-->
|
||||
<!-- </a-col>-->
|
||||
<a-col :span="10">
|
||||
<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-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="备注" name="remark">
|
||||
<a-input v-model:value="vdata.saveObject['remark']" placeholder="请输入备注" type="textarea" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<!-- 重置密码板块 -->
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
账户安全
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div v-if="vdata.isAdd">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="是否发送开通提醒">
|
||||
<a-radio-group v-model:value="vdata.saveObject['isNotify']">
|
||||
<a-radio :value="0">否</a-radio>
|
||||
<a-radio :value="1">是</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="密码设置">
|
||||
<a-radio-group v-model:value="vdata.saveObject['passwordType']">
|
||||
<a-radio value="default">默认密码</a-radio>
|
||||
<a-radio value="custom">自定义密码</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.saveObject.passwordType == 'custom'" :span="12">
|
||||
<a-form-item label="登录密码" name="loginPassword">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['loginPassword']"
|
||||
placeholder="请输入登录密码"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-button type="primary" ghost @click="randomPassage(false, 6, 0)"><file-sync-outlined />随机生成密码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item v-if="vdata.resetIsShow" label="">
|
||||
重置密码:<a-checkbox v-model:checked="vdata.sysPassword.resetPass" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item v-if="vdata.sysPassword.resetPass" label="">
|
||||
恢复默认密码:<a-checkbox v-model:checked="vdata.sysPassword.defaultPass" @click="isResetPass" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
|
||||
<div v-if="vdata.sysPassword.resetPass">
|
||||
<div v-if="!vdata.sysPassword.defaultPass">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="新密码:" name="newPwd">
|
||||
<a-input-password v-model:value="vdata.newPwd" autocomplete="new-password" :disabled="vdata.sysPassword.defaultPass" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="10">
|
||||
<a-form-item label="确认新密码:" name="confirmPwd">
|
||||
<a-input-password v-model:value="vdata.sysPassword.confirmPwd" autocomplete="new-password" :disabled="vdata.sysPassword.defaultPass" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</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_MCH_LIST, req, $getPasswordRules } from '@/api/manage'
|
||||
import { Base64 } from 'js-base64'
|
||||
import {message} from 'ant-design-vue'
|
||||
import {defineProps,reactive,ref} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const infoTable =ref()
|
||||
const vdata : any = reactive({
|
||||
newPwd: '', // 新密码
|
||||
resetIsShow: false, // 重置密码是否展现
|
||||
passwordRules: /^$/, //密码规则
|
||||
passwordRulesText: '', //密码规则提示文字
|
||||
sysPassword: {
|
||||
resetPass: false, // 重置密码
|
||||
defaultPass: true, // 使用默认密码
|
||||
confirmPwd: '' // 确认密码
|
||||
},
|
||||
btnLoading: false,
|
||||
isAdd: true, // 新增 or 修改页面标志
|
||||
saveObject: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
rules: {
|
||||
mchName: [{ required: true, message: '请输入商户名称', trigger: 'blur' }],
|
||||
loginUsername: [{ required: true, pattern: /^[a-zA-Z][a-zA-Z0-9]{5,17}$/, message: '请输入字母开头,长度为6-18位的登录名', trigger: 'blur' }],
|
||||
mchShortName: [{ required: true, message: '请输入商户简称', trigger: 'blur' }],
|
||||
contactName: [{ required: true, message: '请输入联系人姓名', trigger: 'blur' }],
|
||||
contactEmail: [{ required: false, pattern: /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/, message: '请输入正确的邮箱地址', trigger: 'blur' }],
|
||||
contactTel: [{ required: true, pattern: /^1\d{10}$/, message: '请输入正确的手机号', trigger: 'blur' }],
|
||||
newPwd: [{ required: false, trigger: 'blur' }, {
|
||||
validator: (rule, value) => {
|
||||
if (!vdata.sysPassword.defaultPass) {
|
||||
if (!vdata.passwordRules.test(vdata.newPwd)) {
|
||||
return Promise.reject(vdata.passwordRulesText)
|
||||
} else if(vdata.newPwd !== vdata.sysPassword.confirmPwd) {
|
||||
return Promise.reject('新密码与确认密码不一致')
|
||||
} else return Promise.resolve()
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
}
|
||||
}], // 新密码
|
||||
confirmPwd: [{ required: false, trigger: 'blur' }, {
|
||||
validator: (rule, value) => {
|
||||
if (!vdata.sysPassword.defaultPass) {
|
||||
// vdata.newPwd === vdata.sysPassword.confirmPwd ? callBack() : callBack('新密码与确认密码不一致')
|
||||
if(!vdata.passwordRules.test(vdata.sysPassword.confirmPwd)){
|
||||
return Promise.reject(vdata.passwordRulesText)
|
||||
} else if(vdata.newPwd !== vdata.sysPassword.confirmPwd) {
|
||||
return Promise.reject('新密码与确认密码不一致')
|
||||
} else return Promise.resolve()
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
}] // 确认新密码
|
||||
}
|
||||
})
|
||||
function getPasswordRules () { // 获取密码规则
|
||||
$getPasswordRules().then(res => {
|
||||
vdata.passwordRules = new RegExp(res.regexpRules)
|
||||
vdata.passwordRulesText = res.errTips
|
||||
})
|
||||
}
|
||||
function show (recordId) { // 弹层打开事件
|
||||
getPasswordRules()
|
||||
vdata.isAdd = !recordId
|
||||
vdata.saveObject = { 'state': 1, 'type': 1, mchLevel: 'M1', passwordType: 'default', isNotify: 0, refundMode: ['plat', 'api'] } // 数据清空
|
||||
if (infoFormModel.value != undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.resetIsShow = true // 展示重置密码板块
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_MCH_LIST, recordId).then(res => {
|
||||
vdata.saveObject = res
|
||||
})
|
||||
vdata.visible = true
|
||||
} else {
|
||||
vdata.visible = true // 立马展示弹层信息
|
||||
}
|
||||
}
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then(valid =>{
|
||||
|
||||
vdata.btnLoading = true
|
||||
|
||||
// 请求接口
|
||||
if (vdata.isAdd) {
|
||||
// 如果新增密码设置为默认密码,登录密码设置为空
|
||||
if(vdata.saveObject.passwordType == 'default' || !vdata.saveObject.loginPassword) {
|
||||
vdata.saveObject.loginPassword = ''
|
||||
}
|
||||
if(vdata.saveObject.passwordType == 'custom' && !vdata.passwordRules.test(vdata.saveObject.loginPassword)) {
|
||||
vdata.btnLoading = false
|
||||
return message.error(vdata.passwordRulesText)
|
||||
}
|
||||
vdata.saveObject.mchLevel = 'M1';
|
||||
req.add(API_URL_MCH_LIST, vdata.saveObject).then(res => {
|
||||
message.success('新增成功')
|
||||
vdata.visible = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.btnLoading = false
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
} else {
|
||||
|
||||
vdata.sysPassword.confirmPwd = Base64.encode(vdata.sysPassword.confirmPwd)
|
||||
Object.assign(vdata.saveObject, vdata.sysPassword) // 拼接对象
|
||||
req.updateById(API_URL_MCH_LIST, vdata.recordId, vdata.saveObject).then(res => {
|
||||
message.success('修改成功')
|
||||
vdata.visible = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.btnLoading = false
|
||||
vdata.resetIsShow = true // 展示重置密码板块
|
||||
vdata.sysPassword.resetPass = false
|
||||
vdata.sysPassword.defaultPass = true // 是否使用默认密码默认为true
|
||||
resetPassEmpty(DataView) // 清空密码
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
vdata.resetIsShow = true // 展示重置密码板块
|
||||
vdata.sysPassword.resetPass = false
|
||||
vdata.sysPassword.defaultPass = true // 是否使用默认密码默认为true
|
||||
resetPassEmpty(vdata) // 清空密码
|
||||
})
|
||||
}
|
||||
|
||||
}).catch(valid =>{
|
||||
})
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
vdata.resetIsShow = false // 取消重置密码板块展示
|
||||
vdata.sysPassword.resetPass = false
|
||||
resetPassEmpty(vdata)
|
||||
vdata.sysPassword.defaultPass = true// 是否使用默认密码默认为true
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
// 使用默认密码重置是否为true
|
||||
function isResetPass () {
|
||||
if (!vdata.sysPassword.defaultPass) {
|
||||
vdata.newPwd = ''
|
||||
vdata.sysPassword.confirmPwd = ''
|
||||
}
|
||||
}
|
||||
// 保存后清空密码
|
||||
function resetPassEmpty (vdata) {
|
||||
vdata.newPwd = ''
|
||||
vdata.sysPassword.confirmPwd = ''
|
||||
}
|
||||
|
||||
function randomPassage(randomFlag, min, max) { // 生成6位随机密码
|
||||
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['loginPassword'] = str
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.typePopover {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left:62px;
|
||||
}
|
||||
</style>
|
||||
148
jeepay-ui-agent/src/views/mch/Detail.vue
Normal file
148
jeepay-ui-agent/src/views/mch/Detail.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:title=" true ? '商户详情' : '' "
|
||||
: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['mchName'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="登录名">
|
||||
{{ vdata.detailData['loginUsername'] }}
|
||||
</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 v-if="vdata.detailData['type'] === 2" :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商号">
|
||||
{{ vdata.detailData['isvNo'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.detailData['type'] === 2" :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商名称">
|
||||
{{ vdata.isvName }}
|
||||
</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['type'] === 1 ? '普通商户': '特约商户' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="联系人手机号">
|
||||
{{ vdata.detailData['contactTel'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="状态">
|
||||
<a-tag :color="vdata.detailData['state'] === 1?'green':'volcano'">
|
||||
{{ vdata.detailData['state'] === 1?'启用':'禁用' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="联系人邮箱">
|
||||
{{ vdata.detailData['contactEmail'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="start" type="flex">
|
||||
<a-col :sm="24">
|
||||
<a-form-item label="备注">
|
||||
<a-input
|
||||
v-model:value="vdata.detailData['remark']"
|
||||
type="textarea"
|
||||
disabled="disabled"
|
||||
style="height: 50px"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MCH_LIST, API_URL_ISV_LIST, req } from '@/api/manage'
|
||||
import {defineProps,reactive} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
isvList: [], // 服务商下拉列表
|
||||
isvName: '' // 服务商名称
|
||||
})
|
||||
|
||||
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_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
req.list(API_URL_ISV_LIST, { 'pageSize': null }).then(res => { // 服务商下拉选择列表
|
||||
vdata.isvList = res.records
|
||||
for (let i = 0; i < vdata.isvList.length; i++) {
|
||||
if (vdata.detailData['isvNo'] === vdata.isvList[i]['isvNo']) {
|
||||
vdata.isvName = vdata.isvList[i]['isvName']
|
||||
}
|
||||
}
|
||||
})
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
690
jeepay-ui-agent/src/views/mch/MchConfig.vue
Normal file
690
jeepay-ui-agent/src/views/mch/MchConfig.vue
Normal file
@@ -0,0 +1,690 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:mask-closable="false"
|
||||
title="商户高级配置"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="60%"
|
||||
class="drawer-width"
|
||||
@close="vdata.visible = false"
|
||||
>
|
||||
<div style="background: #fff">
|
||||
<a-tabs v-if="vdata.visible" @change="selectTabs">
|
||||
<a-tab-pane key="mchApiEnt" tab="接口权限">
|
||||
<a-table :dataSource="vdata.mchApiEntTableData" :columns="vdata.mchApiEntTableColumns" :pagination="false" size="small">
|
||||
<!-- header 标题 插槽 -->
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'batch'">
|
||||
<a-checkbox @change="(e) => mchApiEntAllCehcked(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>
|
||||
|
||||
<template #title>商户可自调用接口</template>
|
||||
</a-table>
|
||||
|
||||
|
||||
<a-form-item class="bottom-btn">
|
||||
<a-button type="primary" :loading="vdata.btnLoading" @click="confirmByApiEnt"><check-circle-outlined />确认更新</a-button>
|
||||
</a-form-item>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_CONFIG, API_URL_MCH_LIST, req, API_URL_MCH_APP, API_URL_MCH_STORE_LIST, } from '@/api/manage'
|
||||
import { ref, reactive, getCurrentInstance } from 'vue'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const configFormModel = ref()
|
||||
const payTestBarCode =ref()
|
||||
|
||||
|
||||
const vdata : any = reactive ({
|
||||
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
|
||||
mchAppList: [] as any, // app列表
|
||||
mchStoreList: [] as any, // 门店列表
|
||||
appId: '', // 已选择的appId
|
||||
storeId: '', // 已选择的门店ID
|
||||
cashierUrl: '', // 收银台地址
|
||||
isShowCashier: true as any,
|
||||
|
||||
btnLoading: false,
|
||||
groupKey: 'orderConfig',
|
||||
mchConfigData: [] as any, // 配置保存对象
|
||||
defaultConfig: [{
|
||||
configKey: 'appVoice',
|
||||
configName: '是否启用app订单语音播报',
|
||||
configVal: '1',
|
||||
type: 'radio'
|
||||
},
|
||||
{
|
||||
configKey: 'qrcEscaping',
|
||||
configName: '是否启用码牌防逃单功能',
|
||||
configVal: '1',
|
||||
type: 'radio'
|
||||
},
|
||||
{
|
||||
configKey: 'weChatVoice',
|
||||
configName: '小程序语音推送',
|
||||
configVal: '0',
|
||||
type: 'radio'
|
||||
}
|
||||
], // 默认配置项
|
||||
|
||||
mchPayNotifyUrl: '', // 商户支付回调地址
|
||||
mchRefundNotifyUrl: '', // 商户退款回调地址
|
||||
|
||||
mchNotifyFlag: {
|
||||
payNotifyFlag: '1',
|
||||
refundNotifyFlag: '1'
|
||||
}, // 商户回调开关
|
||||
|
||||
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 },
|
||||
{key: 'platformOrderNo', name: '支付凭证交易单号', desc: '', checked: false, disabled: false },
|
||||
{key: 'platformMchOrderNo', name: '支付凭证商户单号', desc: '', checked: false, disabled: false },
|
||||
],
|
||||
|
||||
mchApiEntTableColumns: [
|
||||
{key: 'batch', title: '批量选择' },
|
||||
{key: 'title', dataIndex: 'title', title: '名称' },
|
||||
{key: 'key', dataIndex: 'key', title: 'KEY' },
|
||||
{key: 'apiPath', dataIndex: 'apiPath', title: '路径' },
|
||||
],
|
||||
|
||||
mchApiEntTableData: [
|
||||
{key: 'API_PAY_ORDER', title: '统一下单', apiPath: '/api/pay/unifiedOrder', checked: false },
|
||||
{key: 'API_PAY_ORDER_QUERY', title: '查询支付订单', apiPath: '/api/pay/query', checked: false },
|
||||
{key: 'API_PAY_ORDER_CLOSE', title: '支付订单关闭', apiPath: '/api/pay/close', checked: false },
|
||||
{key: 'API_CHANNEL_USER', title: '获取渠道用户ID', apiPath: '/api/channelUserId/jump', checked: false },
|
||||
{key: 'API_REFUND_ORDER', title: '发起支付退款', apiPath: '/api/refund/refundOrder', checked: false },
|
||||
{key: 'API_REFUND_ORDER_QUERY', title: '查询退款订单', apiPath: '/api/refund/query', checked: false },
|
||||
{key: 'API_TRANS_ORDER', title: '发起转账订单', apiPath: '/api/transferOrder', checked: false },
|
||||
{key: 'API_TRANS_ORDER_QUERY', title: '查询转账订单', apiPath: '/api/transfer/query', checked: false },
|
||||
{key: 'API_TRANS_BALANCE_QUERY', title: '查询转账可用余额', apiPath: '/api/transfer/balance/query', checked: false },
|
||||
{key: 'API_DIVISION_BIND', title: '绑定分账用户', apiPath: '/api/division/receiver/bind', checked: false },
|
||||
{key: 'API_DIVISION_EXEC', title: '发起订单分账', apiPath: '/api/division/exec', checked: false },
|
||||
{key: 'API_DIVISION_CHANNEL_BALANCE', title: '查询分账用户可用余额', apiPath: '/api/division/receiver/channelBalanceQuery', checked: false },
|
||||
{key: 'API_DIVISION_CHANNEL_CASHOUT', title: '对分账用户的渠道余额发起提现', apiPath: '/api/division/receiver/channelBalanceCashout', checked: false },
|
||||
],
|
||||
|
||||
cashierWxH5Data: [
|
||||
{ label: '微信H5', value: 'WX_H5', },
|
||||
{ label: '微信小程序', value: 'WX_LITE', },
|
||||
],
|
||||
cashierAliWebData: [
|
||||
{ label: '支付宝WAP', value: 'ALI_WAP', },
|
||||
{ label: '支付宝生活号', value: 'ALI_JSAPI', },
|
||||
{ label: '支付宝小程序', value: 'ALI_LITE', },
|
||||
],
|
||||
|
||||
|
||||
// 分账管理菜单
|
||||
divisionConfig: { overrideAutoFlag: 0, autoDivisionRules: { amountLimit: 0, delayTime: 120 }, mchDivisionEntFlag: 1, calBaseAmountType: 'INCOME_AMOUNT' },
|
||||
|
||||
// 广告配置
|
||||
advertConfig: { advertFlag: 0 },
|
||||
|
||||
// 便捷收银台配置
|
||||
selfCashierState : { configKey: 'selfCashierState', configName: '便捷收银台权限开关', configVal: '0', type: 'radio' },
|
||||
selfCashierSiteInfoType: { configKey: 'selfCashierSiteInfoType', configName: '便捷收银台logo/底部显示配置', configVal: 'DEFAULT', type: 'text' },
|
||||
selfCashierWxH5Config: { configKey: 'selfCashierWxH5Config', configName: '便捷收银台微信H5配置', configVal: ['WX_H5'], type: 'text' },
|
||||
selfCashierAliWapConfig: { configKey: 'selfCashierAliWapConfig', configName: '便捷收银台支付宝WAP配置', configVal: ['ALI_WAP'], type: 'text'},
|
||||
|
||||
// 商户web收银台配置
|
||||
wabCashierState: { configKey: 'wabCashierState', configName: 'WEB收银台权限开关', configVal: '0', type: 'radio' },
|
||||
wabCashierSiteInfoType: { configKey: 'wabCashierSiteInfoType', configName: 'WEB收银台logo/底部显示配置', configVal: 'DEFAULT', type: 'text' },
|
||||
wabCashierWxH5Config: { configKey: 'wabCashierWxH5Config', configName: 'WEB收银台微信H5配置', configVal: ['WX_H5'], type: 'text' },
|
||||
wabCashierAliWapConfig: { configKey: 'wabCashierAliWapConfig', configName: 'WEB收银台支付宝WAP配置', configVal: ['ALI_WAP'], type: 'text' },
|
||||
|
||||
// 会员配置
|
||||
memberConfigData: [
|
||||
{ configKey: 'memberModelState', configName: '会员模块状态开关', configVal: '1', type: 'radio' },
|
||||
{ configKey: 'memberPayState', configName: '会员支付开关', configVal: '0', type: 'radio' },
|
||||
{ configKey: 'memberCustomAmountState', configName: '充值自定义金额', configVal: '1', type: 'radio' },
|
||||
{ configKey: 'mbrMaxBalance', configName: '会员最大储值余额(元), 0表示依据系统配置', configVal: '0', type: 'text' },
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
|
||||
vdata.recordId = recordId
|
||||
selectTabs('mchApiEnt') //初始化数据
|
||||
vdata.visible = true
|
||||
}
|
||||
|
||||
|
||||
function selectTabs (key) { // 清空必填提示
|
||||
|
||||
if (key) {
|
||||
vdata.groupKey = key
|
||||
|
||||
if(key == 'orderConfig'){
|
||||
|
||||
req.list(API_URL_MCH_CONFIG, {groupKey: vdata.groupKey, mchNo: vdata.recordId}).then(res => {
|
||||
if (res != null && res.length > 0) {
|
||||
vdata.mchConfigData = res
|
||||
// 遍历总配置列表;如果configKey不存在则push进该条记录
|
||||
for (var key in vdata.defaultConfig) {
|
||||
// configKey是否存在 默认为不存在
|
||||
var isdefault = true
|
||||
vdata.mchConfigData.forEach((item) => {
|
||||
// 遍历到相同key时,key存在,赋值false
|
||||
if (item.configKey == vdata.defaultConfig[key].configKey) {
|
||||
isdefault = false
|
||||
}
|
||||
})
|
||||
// 如果不存在 true 添加该条默认记录
|
||||
if(isdefault) {
|
||||
vdata.mchConfigData.push(vdata.defaultConfig[key])
|
||||
}
|
||||
}
|
||||
|
||||
}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, mchNo: vdata.recordId}).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 (item.configKey == 'mchNotifyFlag') {
|
||||
if (item.configVal) {
|
||||
vdata.mchNotifyFlag = JSON.parse(item.configVal)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
}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))
|
||||
}
|
||||
})
|
||||
}else if(key == 'mchApiEnt'){ // 接口权限
|
||||
|
||||
|
||||
// 恢复初始值
|
||||
vdata.mchApiEntTableData.forEach(r => {
|
||||
r. checked = false
|
||||
})
|
||||
|
||||
req.list(API_URL_MCH_CONFIG, {groupKey: vdata.groupKey, mchNo: vdata.recordId}).then(res => {
|
||||
if (res != null && res.length > 0) {
|
||||
res.forEach(item => {
|
||||
if (item.configKey == 'mchApiEntList') { // 商户接口权限集合
|
||||
let arr = JSON.parse(item.configVal)
|
||||
vdata.mchApiEntTableData.forEach(r => {
|
||||
r.checked = arr.indexOf(r.key) >= 0
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}else if(key == 'advertConfig'){ // 广告权限
|
||||
|
||||
|
||||
// 恢复初始值
|
||||
vdata.mchApiEntTableData.forEach(r => {
|
||||
r. checked = false
|
||||
})
|
||||
|
||||
req.getById(API_URL_MCH_LIST, vdata.recordId).then(res => {
|
||||
vdata.advertConfig = res
|
||||
})
|
||||
|
||||
}else if(key == 'selfCashier'){ // 便捷收银台配置
|
||||
|
||||
// 初始化配置
|
||||
vdata.selfCashierState = { configKey: 'selfCashierState', configName: '便捷收银台权限开关', configVal: '0', type: 'radio' },
|
||||
vdata.selfCashierSiteInfoType = { configKey: 'selfCashierSiteInfoType', configName: '便捷收银台logo/底部显示配置', configVal: 'DEFAULT', type: 'text' },
|
||||
vdata.selfCashierWxH5Config = { configKey: 'selfCashierWxH5Config', configName: '便捷收银台微信H5配置', configVal: ['WX_H5'], type: 'text' },
|
||||
vdata.selfCashierAliWapConfig = { configKey: 'selfCashierAliWapConfig', configName: '便捷收银台支付宝WAP配置', configVal: ['ALI_WAP'], type: 'text'},
|
||||
|
||||
|
||||
req.list(API_URL_MCH_CONFIG, {groupKey: vdata.groupKey, mchNo: vdata.recordId}).then(res => {
|
||||
if (res != null && res.length > 0) {
|
||||
res.forEach(value => {
|
||||
|
||||
if(value.configKey == 'selfCashierState') {
|
||||
vdata.selfCashierState = value
|
||||
}else if (value.configKey == 'selfCashierSiteInfoType') {
|
||||
vdata.selfCashierSiteInfoType = value
|
||||
}else if (value.configKey == 'selfCashierWxH5Config') {
|
||||
vdata.selfCashierWxH5Config = value
|
||||
if (vdata.selfCashierWxH5Config.configVal) {
|
||||
vdata.selfCashierWxH5Config.configVal = JSON.parse(vdata.selfCashierWxH5Config.configVal)
|
||||
}
|
||||
}else if (value.configKey == 'selfCashierAliWapConfig') {
|
||||
vdata.selfCashierAliWapConfig = value
|
||||
if (vdata.selfCashierAliWapConfig.configVal) {
|
||||
vdata.selfCashierAliWapConfig.configVal = JSON.parse(vdata.selfCashierAliWapConfig.configVal)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
vdata.appId = ''
|
||||
vdata.storeId = ''
|
||||
// 请求接口,获取所有的appid,只有此处进行pageSize=-1传参
|
||||
req.list(API_URL_MCH_APP, { pageSize: -1, mchNo: vdata.recordId, 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, mchNo: vdata.recordId }).then(res => {
|
||||
vdata.mchStoreList = res.records
|
||||
if (vdata.mchStoreList.length > 0) {
|
||||
// 赋予默认值
|
||||
if(vdata.storeId == '') vdata.storeId = vdata.mchStoreList[0].storeId
|
||||
// two()
|
||||
}
|
||||
})
|
||||
}
|
||||
// function two (){
|
||||
// $mchConfigCreateCashier({
|
||||
// appId: vdata.appId, // appId
|
||||
// storeId: vdata.storeId, // storeId
|
||||
// mchNo: vdata.recordId
|
||||
// }).then(res => {
|
||||
// vdata.cashierUrl = res
|
||||
// }).catch(() => {
|
||||
// payTestBarCode.value.processCatch()
|
||||
// })
|
||||
// }
|
||||
|
||||
}else if(key == 'webCashier'){ // web收银台配置
|
||||
|
||||
// 初始化配置
|
||||
vdata.webCashierState = { configKey: 'webCashierState', configName: 'WEB收银台权限开关', configVal: '0', type: 'radio' },
|
||||
vdata.webCashierSiteInfoType = { configKey: 'webCashierSiteInfoType', configName: 'WEB收银台logo/底部显示配置', configVal: 'DEFAULT', type: 'text' },
|
||||
vdata.webCashierWxH5Config = { configKey: 'webCashierWxH5Config', configName: 'WEB收银台微信H5配置', configVal: ['WX_H5'], type: 'text' },
|
||||
vdata.webCashierAliWapConfig = { configKey: 'webCashierAliWapConfig', configName: 'WEB收银台支付宝WAP配置', configVal: ['ALI_WAP'], type: 'text'},
|
||||
|
||||
|
||||
req.list(API_URL_MCH_CONFIG, {groupKey: vdata.groupKey, mchNo: vdata.recordId}).then(res => {
|
||||
if (res != null && res.length > 0) {
|
||||
res.forEach(value => {
|
||||
|
||||
if(value.configKey == 'webCashierState') {
|
||||
vdata.webCashierState = value
|
||||
}else if (value.configKey == 'webCashierSiteInfoType') {
|
||||
vdata.webCashierSiteInfoType = value
|
||||
}else if (value.configKey == 'webCashierWxH5Config') {
|
||||
vdata.webCashierWxH5Config = value
|
||||
if (vdata.webCashierWxH5Config.configVal) {
|
||||
vdata.webCashierWxH5Config.configVal = JSON.parse(vdata.webCashierWxH5Config.configVal)
|
||||
}
|
||||
}else if (value.configKey == 'webCashierAliWapConfig') {
|
||||
vdata.webCashierAliWapConfig = value
|
||||
if (vdata.webCashierAliWapConfig.configVal) {
|
||||
vdata.webCashierAliWapConfig.configVal = JSON.parse(vdata.webCashierAliWapConfig.configVal)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}else if(key == 'memberConfig'){
|
||||
req.list(API_URL_MCH_CONFIG, {groupKey: vdata.groupKey, mchNo: vdata.recordId}).then(res => {
|
||||
|
||||
if (res != null && res.length > 0) {
|
||||
vdata.memberConfigData.forEach(item =>{
|
||||
res.forEach(res => {
|
||||
if (item.configKey == res.configKey) {
|
||||
item.configVal = res.configVal
|
||||
|
||||
if (item.configKey == 'mbrMaxBalance' && res.configVal) {
|
||||
item.configVal = Number.parseFloat((res.configVal / 100).toFixed(2))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 确认更新
|
||||
function confirm (e) {
|
||||
configFormModel.value.validate().then(valid => {
|
||||
$infoBox.confirmPrimary('确认修改支付配置吗?', '', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {mchNo: vdata.recordId, configData: JSON.stringify(vdata.mchConfigData)}).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: 'mchNotifyFlag', configVal : vdata.mchNotifyFlag },
|
||||
{ groupKey: vdata.groupKey, configName: '商户接收通知方式', configKey: 'mchNotifyPostType', configVal : vdata.mchNotifyPostType }
|
||||
]
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {mchNo: vdata.recordId, configData: JSON.stringify(configItem)}).then(res => {
|
||||
$infoBox.message.success('修改成功')
|
||||
vdata.btnLoading = false
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
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
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
function confirmByAdvertManage(){
|
||||
|
||||
$infoBox.confirmPrimary('确认修改广告设置?', '', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
let reqObject : any = JSON.parse(JSON.stringify(vdata.advertConfig))
|
||||
|
||||
req.updateById(API_URL_MCH_LIST, vdata.recordId, reqObject).then(res => {
|
||||
$infoBox.message.success('修改成功')
|
||||
vdata.btnLoading = false
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function confirmBySelfCashierManage(){
|
||||
|
||||
$infoBox.confirmPrimary('确认修改便捷收银台设置?', '', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
let arr : any = []
|
||||
arr.push(vdata.selfCashierState)
|
||||
arr.push(vdata.selfCashierSiteInfoType)
|
||||
arr.push(vdata.selfCashierWxH5Config)
|
||||
arr.push(vdata.selfCashierAliWapConfig)
|
||||
|
||||
let reqObject : any = JSON.stringify(arr)
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {mchNo: vdata.recordId, configData: reqObject}).then(res => {
|
||||
vdata.btnLoading = false
|
||||
$infoBox.message.success('修改成功')
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function confirmByWebCashierManage(){
|
||||
|
||||
$infoBox.confirmPrimary('确认修改WEB收银台设置?', '', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
let arr : any = []
|
||||
arr.push(vdata.webCashierState)
|
||||
arr.push(vdata.webCashierSiteInfoType)
|
||||
arr.push(vdata.webCashierWxH5Config)
|
||||
arr.push(vdata.webCashierAliWapConfig)
|
||||
|
||||
let reqObject : any = JSON.stringify(arr)
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {mchNo: vdata.recordId, configData: reqObject}).then(res => {
|
||||
vdata.btnLoading = false
|
||||
$infoBox.message.success('修改成功')
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 更新会员配置
|
||||
function confirmUpdateMemberConfig(){
|
||||
$infoBox.confirmPrimary('确认修改会员配置吗?', '', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
let reqObject : any = JSON.parse(JSON.stringify(vdata.memberConfigData))
|
||||
|
||||
// 最大储值金额
|
||||
reqObject.forEach(item => {
|
||||
if (item.configKey == 'mbrMaxBalance') {
|
||||
const mbrMaxBalance = item.configVal ? item.configVal : 0
|
||||
item.configVal = Number.parseInt((mbrMaxBalance * 100).toFixed(0)).toString()
|
||||
}
|
||||
})
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {mchNo: vdata.recordId, configData: reqObject}).then(res => {
|
||||
$infoBox.message.success('修改成功')
|
||||
vdata.btnLoading = false
|
||||
|
||||
selectTabs('memberConfig')
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 确认更新
|
||||
function confirmByApiEnt (e) {
|
||||
|
||||
$infoBox.confirmPrimary('确认修改商户的接口权限?', '', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
let arr : any = []
|
||||
vdata.mchApiEntTableData.forEach(r => {
|
||||
if(r.checked){
|
||||
arr.push(r.key)
|
||||
}
|
||||
})
|
||||
|
||||
let configItem = [{ groupKey: vdata.groupKey, configName: '商户接口权限集合', configKey: 'mchApiEntList', configVal : JSON.stringify(arr) }]
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {mchNo: vdata.recordId, configData: JSON.stringify(configItem)}).then(res => {
|
||||
$infoBox.message.success('修改成功')
|
||||
vdata.btnLoading = false
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 全选,反选
|
||||
function notifyAllCehcked(isChekced){
|
||||
vdata.notifyTableData.filter(r => !r.disabled).forEach(r => {
|
||||
r.checked = isChekced
|
||||
})
|
||||
}
|
||||
|
||||
// 全选,反选
|
||||
function mchApiEntAllCehcked(isChekced){
|
||||
vdata.mchApiEntTableData.filter(r => !r.disabled).forEach(r => {
|
||||
r.checked = isChekced
|
||||
})
|
||||
}
|
||||
|
||||
// 变更 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
|
||||
// $mchConfigCreateCashier({
|
||||
// appId: vdata.appId, // appId
|
||||
// storeId: vdata.storeId, // storeId
|
||||
// mchNo: vdata.recordId
|
||||
// }).then(res => {
|
||||
// vdata.cashierUrl = res
|
||||
// }).catch(() => {
|
||||
// payTestBarCode.value.processCatch()
|
||||
// })
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.bottom-btn{
|
||||
/deep/ div{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.typePopover {
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
left: 93px;
|
||||
}
|
||||
</style>
|
||||
240
jeepay-ui-agent/src/views/mch/MchList.vue
Normal file
240
jeepay-ui-agent/src/views/mch/MchList.vue
Normal file
@@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="() => { vdata.searchData= {} }">
|
||||
<JeepaySearchInfoInput v-model:value="vdata.searchData['mchName']" placeholder="用户号/名称/手机号" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :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>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData['type']" 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>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="mchNo"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button v-if="$access('ENT_MCH_INFO_ADD')" type="primary" @click="addFunc">
|
||||
<plus-outlined />新建
|
||||
</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'mchName'">
|
||||
<a @click="detailFunc(record.mchNo)"><b>{{ record.mchName }}</b></a>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'state'">
|
||||
<a-badge :status="record.state === 1?'processing':'error'" :text="record.state === 1?'启用':'禁用'" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'mchServiceName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.mchServiceName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchServiceName}}</div>
|
||||
</a-tooltip>
|
||||
</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 === 'operation'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_MCH_INFO_EDIT')" type="link" @click="editFunc(record.mchNo)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_APP_CONFIG')" type="link" @click="mchAppConfig(record.mchNo)">应用配置</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_APP_CONFIG')" type="link" @click="showPayIfConfigList(record.mchNo)">支付配置</a-button>
|
||||
<a-button v-if="vdata.configPageIsShow" type="link" @click="mchConfigFunc(record.mchNo)">高级功能配置</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_QRC_LIST')" type="link" @click="mchQrCodeConfig(record.mchNo)">码牌管理</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_SPEAKER_DEVICE')" type="link" @click="speakerConfig(record.mchNo)">云喇叭设备</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_PRINTER_DEVICE')" type="link" @click="printerConfig(record.mchNo)">云打印设备</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_APPLYMENT_LIST') && record.type == 2" type="link" @click="toMchApplymentPage(record.mchNo)">进件管理</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_STORE_LIST')" type="link" @click="mchStoreConfig(record.mchNo)">门店管理</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_MCH_INFO_DEL')" type="link" style="color: red" @click="delFunc(record.mchNo)">删除</a-button>-->
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callback-func="searchFunc" />
|
||||
<!-- 详情页面组件 -->
|
||||
<InfoDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
<!--商户配置 -->
|
||||
<MchConfig ref="mchConfigRef" />
|
||||
|
||||
<JeepayPayConfigUserDrawer ref="jeepayPayConfigUserDrawerRef" configMode="agentMch" />
|
||||
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import { API_URL_MCH_LIST, req, reqLoad, $getAgentConfig } from '@/api/manage'
|
||||
import InfoAddOrEdit from './AddOrEdit.vue'
|
||||
import InfoDetail from './Detail.vue'
|
||||
import MchConfig from './MchConfig.vue'
|
||||
import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
|
||||
import router from '@/router'
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoDetail = ref()
|
||||
const infoAddOrEdit = ref()
|
||||
const infoTable = ref()
|
||||
const mchConfigRef = ref()
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ key: 'mchName', title: '用户名称', fixed: 'left',},
|
||||
{ key: 'mchNo', title: '用户号', dataIndex: 'mchNo' , },
|
||||
{ key: 'contactTel', title: '手机号', dataIndex: 'contactTel' ,},
|
||||
{ key: 'mchServiceName', title: '服务商', dataIndex: 'mchServiceName', },
|
||||
{ key: 'state', title: '状态', },
|
||||
{ key: 'type', title: '商户类型',},
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期',},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
const vdata = reactive({
|
||||
searchData: {} as any,
|
||||
configPageIsShow: false, // 商户高级配置页面是否展示
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
// 高级配置页权限
|
||||
getAgentConfig()
|
||||
})
|
||||
|
||||
function queryFunc () {
|
||||
btnLoading.value = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params: any) {
|
||||
return req.list(API_URL_MCH_LIST, params)
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show()
|
||||
}
|
||||
function editFunc (recordId: any) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(recordId)
|
||||
}
|
||||
function detailFunc (recordId: any) { // 商户详情页
|
||||
infoDetail.value.show(recordId)
|
||||
}
|
||||
// 删除商户
|
||||
function delFunc (recordId: any) {
|
||||
$infoBox.confirmDanger('确认删除?', '该操作将删除商户下所有配置及用户信息', () => {
|
||||
reqLoad.delById(API_URL_MCH_LIST, recordId).then((res: any) => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('删除成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
function mchAppConfig (recordId: any) { // 应用配置
|
||||
router.push({
|
||||
path: '/apps',
|
||||
query: { mchNo: recordId }
|
||||
})
|
||||
}
|
||||
function mchStoreConfig (recordId: any) { // 门店管理
|
||||
router.push({
|
||||
path: '/store',
|
||||
query: { mchNo: recordId }
|
||||
})
|
||||
}
|
||||
function mchReceiverGroupConfig (recordId: any) { // 账号分组管理
|
||||
router.push({
|
||||
path: '/divisionReceiverGroup',
|
||||
query: { mchNo: recordId }
|
||||
})
|
||||
}
|
||||
function mchReceiverConfig (recordId: any) { // 账号管理
|
||||
router.push({
|
||||
path: '/divisionReceiver',
|
||||
query: { mchNo: recordId }
|
||||
})
|
||||
}
|
||||
function mchQrCodeConfig (recordId: any) { // 静态码管理
|
||||
router.push({
|
||||
path: '/qrc',
|
||||
query: { mchNo: recordId }
|
||||
})
|
||||
}
|
||||
|
||||
function speakerConfig(recordId: any) {// 云喇叭管理
|
||||
router.push({
|
||||
path: '/speaker/device',
|
||||
query: { mchNo: recordId }
|
||||
})
|
||||
}
|
||||
|
||||
function printerConfig(recordId: any) {// 云打印管理
|
||||
router.push({
|
||||
path: '/printer/device',
|
||||
query: { mchNo: recordId }
|
||||
})
|
||||
}
|
||||
|
||||
function toMchApplymentPage(recordId){
|
||||
router.push({
|
||||
path: '/applyments',
|
||||
query: { mchNo: recordId }
|
||||
})
|
||||
}
|
||||
|
||||
function mchConfigFunc (recordId: any) { // 配置 函数
|
||||
mchConfigRef.value.show(recordId)
|
||||
}
|
||||
|
||||
function getAgentConfig() {
|
||||
$getAgentConfig('subMchPayInterfaceConfigIsUsable').then(config => {
|
||||
if (config && config.configVal) {
|
||||
vdata.configPageIsShow = config.configVal=='true'?true:false
|
||||
}
|
||||
})
|
||||
}
|
||||
const jeepayPayConfigUserDrawerRef = ref()
|
||||
const showPayIfConfigList = function (recordId) { // 支付参数配置
|
||||
|
||||
|
||||
jeepayPayConfigUserDrawerRef.value.show(recordId)
|
||||
}
|
||||
</script>
|
||||
38
jeepay-ui-agent/src/views/mch/applyment/AppConfigDrawer.vue
Normal file
38
jeepay-ui-agent/src/views/mch/applyment/AppConfigDrawer.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
<!-- 参数配置, 弹层模式 -->
|
||||
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="参数配置"
|
||||
width="70%"
|
||||
@close="vdata.visible = false"
|
||||
>
|
||||
<JeepayApplymentAppConfig v-if="vdata.visible" ref="jeepayApplymentAppConfig" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref, reactive, nextTick} from 'vue'
|
||||
|
||||
const jeepayApplymentAppConfig = ref()
|
||||
|
||||
const vdata : any = reactive({
|
||||
|
||||
applyId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (applyId) { // 弹层打开事件
|
||||
|
||||
vdata.applyId = applyId
|
||||
vdata.visible = true
|
||||
|
||||
nextTick(() => {
|
||||
jeepayApplymentAppConfig.value.pageRender(applyId)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
36
jeepay-ui-agent/src/views/mch/applyment/ChangeConfig.vue
Normal file
36
jeepay-ui-agent/src/views/mch/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="'agentApplyment'" 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-agent/src/views/mch/applyment/ChangeDetail.vue
Normal file
325
jeepay-ui-agent/src/views/mch/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-agent/src/views/mch/applyment/Detail.vue
Normal file
224
jeepay-ui-agent/src/views/mch/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>
|
||||
589
jeepay-ui-agent/src/views/mch/applyment/MchApplymentList.vue
Normal file
589
jeepay-ui-agent/src/views/mch/applyment/MchApplymentList.vue
Normal file
@@ -0,0 +1,589 @@
|
||||
<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="'系统/渠道申请单号'" />-->
|
||||
<!-- <JeepaySearchInfoInput v-model:value="vdata.searchData['mchUserName']" placeholder="用户号/名称/手机号" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />-->
|
||||
|
||||
<!-- <jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :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['mchUserName']" :placeholder="'用户号/名称/手机号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :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="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="false"
|
||||
: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="getVisibleAdd()"><plus-outlined />发起进件</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APPLYMENT_ADD')" type="primary" @click="addFunc('')"><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 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="error" text="已风控" />
|
||||
<a-badge v-if="record.state == 21" status="error" text="已冻结" />
|
||||
<a-badge v-if="record.state == 100" status="warning" text="进件请求中" />
|
||||
|
||||
<!-- <a-tooltip v-if="record.applyErrorInfo && record.state != 2" :title="record.applyErrorInfo">-->
|
||||
<!-- <info-circle-outlined />-->
|
||||
<!-- </a-tooltip>-->
|
||||
<!-- <QrcodeOutlined v-if="record.state == 5 && record.ifCode === 'alipay'" style="font-size: 16px;margin-left: 10px;" @click="showQrImgFunc(record)" />-->
|
||||
<!-- <QrcodeOutlined-->
|
||||
<!-- v-if="(record.state == 4 || record.state == 5) && (record.ifCode === 'wxpay' || record.ifCode === 'sftpay')"-->
|
||||
<!-- style="font-size: 16px;margin-left: 10px;"-->
|
||||
<!-- @click="showQrImgFunc(record)"-->
|
||||
<!-- />-->
|
||||
|
||||
<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 === 'applyId'">
|
||||
<a @click="detailFunc(record.applyId)"><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 == '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 === 'mchServiceName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.mchServiceName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchServiceName}}</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 === '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 === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'applyPageType'">
|
||||
<span v-if="record.applyPageType == 'PLATFORM_WEB'">运营平台系统</span>
|
||||
<span v-else-if="record.applyPageType == 'AGENT_WEB'">服务商系统</span>
|
||||
<span v-else-if="record.applyPageType == 'AGENT_APP'">{{ $SYS_NAME_MAP.AGENT_APP }}APP</span>
|
||||
<span v-else-if="record.applyPageType == 'AGENT_LITE'">{{ $SYS_NAME_MAP.AGENT_APP }}小程序</span>
|
||||
<span v-else-if="record.applyPageType == 'MCH_WEB'">商户系统</span>
|
||||
<span v-else-if="record.applyPageType == 'MCH_APP'">{{ $SYS_NAME_MAP.MCH_APP }}APP</span>
|
||||
<span v-else-if="record.applyPageType == 'MCH_LITE'">{{ $SYS_NAME_MAP.MCH_APP }}小程序</span>
|
||||
<span v-else>{{ record.applyPageType || '' }}</span>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 以下为: 运营, 服务商通用按钮 -->
|
||||
<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" 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_VIEW')" type="link" @click="detailFunc(record.applyId)">进件信息</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_APPLYMENT_ADD')" type="link" @click="toCopySelectIfCodePage(record.applyId, record.mchNo,record.range)">复用信息</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>
|
||||
|
||||
<!-- 进件成功后可发起 参数配置 -->
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APPLYMENT_PAY_CONFIG') && record.state == 2" type="link" @click="appConfigDrawerRef.show(record.applyId)">参数配置</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>-->
|
||||
<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" ref="applyPageComponentRef" :listPageSearchMchNo="vdata.searchData.mchNo" @switchApplyPage="switchApplyPage" />
|
||||
</a-card>
|
||||
|
||||
<JeepayModelMchList ref="jeepayModelMchList" showType="MCH" @selectFinishFunc="searchMchFinishFunc" />
|
||||
|
||||
<!-- 参数配置 弹层 -->
|
||||
<AppConfigDrawer ref="appConfigDrawerRef" />
|
||||
|
||||
<JeepayMchOauth2 v-show="vdata.visibleOauth2" ref="jeepayMchOauth2Ref" />
|
||||
|
||||
<!-- 后续流程 弹层 -->
|
||||
<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>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_APPLYMENT_LIST, req, $getMchApplymentChannelState, $getPayConfigIfcodes } from '@/api/manage'
|
||||
import {ref, reactive, getCurrentInstance, nextTick, provide, computed, onMounted } 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 AppConfigDrawer from './AppConfigDrawer.vue'
|
||||
import NextBizsDrawer from './NextBizsDrawer.vue'
|
||||
import InfoDetail from './NewDetail.vue'
|
||||
import { useRoute,useRouter } from 'vue-router'
|
||||
const { $infoBox, $access, $SYS_NAME_MAP } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
/** 定义全部组件 **/
|
||||
const allApplyPage = {
|
||||
'list': { name: '列表', component: null },
|
||||
'applySelectMchAndIfcode': { name: '选择商户及进件渠道', component: ApplySelectMchAndIfcode },
|
||||
'applyMchDetailInfoEntry': { name: '填写进件资料', component: ApplyMchDetailInfoEntry }
|
||||
}
|
||||
|
||||
// 动态组件
|
||||
const applyPageComponentRef = ref()
|
||||
|
||||
const jeepayModelMchList = ref()
|
||||
const jeepayMchOauth2Ref = ref();
|
||||
|
||||
const appConfigDrawerRef = ref()
|
||||
const nextBizsDrawerRef = ref()
|
||||
const infoDetail = ref()
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = 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: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'mchServiceName', title: '服务商名称', dataIndex: 'mchServiceName' },
|
||||
{ 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({
|
||||
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, // 是否预览模式
|
||||
|
||||
ifCodeList: [],
|
||||
|
||||
copyInfoSourceApplyId: '', // 副本资料
|
||||
|
||||
})
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
vdata.searchData['mchNo'] = useRoute().query.mchNo
|
||||
if($access('ENT_MCH_APPLYMENT')){
|
||||
$getPayConfigIfcodes('CURRENT', 'agentApplyment', '').then((res) => {
|
||||
vdata.ifCodeList = res
|
||||
})
|
||||
}
|
||||
searchFunc()
|
||||
})
|
||||
|
||||
|
||||
// 向所有子组件注入参数 (子组件可直接更改此值)
|
||||
provide('mchApplymentData', computed( ()=> vdata.mchApplymentData) )
|
||||
provide('isView', computed( ()=> vdata.isView) )
|
||||
|
||||
// 向所有子组件注入参数: 配置模式: mgrApplyment / agentApplyment / mchApplyment
|
||||
provide('configMode', 'agentApplyment')
|
||||
|
||||
// 向所有子组件注入参数 副本资料来源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)
|
||||
}
|
||||
|
||||
const router = useRouter(); //这是全部路由
|
||||
// 切换步骤: 不清空数据
|
||||
function switchApplyPage(page){
|
||||
if (page == "applyAddApps") {
|
||||
router.push({
|
||||
path: "/apps",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (page == "applyMch") {
|
||||
router.push({
|
||||
path: "/mch",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
vdata.backupApplyPage = vdata.currentApplyPage
|
||||
vdata.currentApplyPage = allApplyPage[page]
|
||||
|
||||
if(vdata.currentApplyPage && vdata.currentApplyPage.component){
|
||||
nextTick(() => { applyPageComponentRef.value.pageRender(vdata.sceneType) })
|
||||
}else{
|
||||
|
||||
delete vdata.searchData.mchNo
|
||||
//列表页
|
||||
searchFunc() // 刷新
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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,sceneType:sceneType}
|
||||
}
|
||||
|
||||
//进件数据重置
|
||||
vdata.isView = false
|
||||
switchApplyPage('applySelectMchAndIfcode')
|
||||
})
|
||||
// vdata.isView = false
|
||||
// switchApplyPage('applySelectMchAndIfcode')
|
||||
}
|
||||
|
||||
// 修改资料 然后重新发起进件操作
|
||||
function editOrViewFunc(applyId, isView){
|
||||
console.log(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, isvNo, state ,range,autoConfigMchAppId} = res
|
||||
vdata.mchApplymentData = {applyId, channelApplyNo, mchNo, ifCode, applyDetailInfo, applyErrorInfo,isvNo, state,range,autoConfigMchAppId}
|
||||
switchApplyPage('applyMchDetailInfoEntry')
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 查询最新状态
|
||||
function queryChannelState(applyId, currState){
|
||||
$getMchApplymentChannelState(applyId).then(res => {
|
||||
if(currState != res.state){
|
||||
$infoBox.message.success('状态已更新')
|
||||
searchFunc() // 更新列表
|
||||
}else{
|
||||
$infoBox.message.info('状态无变化')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 恢复上一次步骤
|
||||
function recoveryApplyPage(){
|
||||
vdata.currentApplyPage = vdata.backupApplyPage
|
||||
}
|
||||
|
||||
// 获取下拉框组件
|
||||
const ifCodeRef = ref()
|
||||
const stateRef = ref()
|
||||
let isReset = ref(0) // 下拉搜索框是否重置
|
||||
|
||||
// 清空搜索项
|
||||
const resetFunc = () => {
|
||||
isReset.value++ // 下拉搜索框重置
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData= {}
|
||||
}
|
||||
|
||||
// 选择商户 / 应用 完成后的操作
|
||||
function searchMchFinishFunc(selectVal){
|
||||
|
||||
if(selectVal[0]){
|
||||
vdata.searchData.mchNo = selectVal[0]
|
||||
}
|
||||
|
||||
jeepayModelMchList.value.close()
|
||||
|
||||
}
|
||||
|
||||
// 显示二维码图片
|
||||
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
|
||||
}
|
||||
function oauthFunc(applyId) {
|
||||
vdata.visibleOauth2 = true;
|
||||
jeepayMchOauth2Ref.value.show(applyId);
|
||||
}
|
||||
|
||||
// 副本 copySourceApplyId : 需要copy的资料来源。
|
||||
function toCopySelectIfCodePage(copySourceApplyId, mchNo,range){
|
||||
const sceneType = parseInt(range) + 1;
|
||||
|
||||
vdata.searchData.mchNo = mchNo
|
||||
addFunc(copySourceApplyId,sceneType)
|
||||
|
||||
}
|
||||
function oauthFuncButton(applyId,state){
|
||||
if(state == 2){
|
||||
oauthFunc(applyId)
|
||||
}else{
|
||||
nextBizsDrawerRef.value.show(applyId)
|
||||
}
|
||||
}
|
||||
function getVisibleAdd(){
|
||||
vdata.visibleAdd = true
|
||||
}
|
||||
function handleCancel (e) {
|
||||
vdata.visibleAdd = false
|
||||
}
|
||||
</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>
|
||||
262
jeepay-ui-agent/src/views/mch/applyment/MchApplymentListOne.vue
Normal file
262
jeepay-ui-agent/src/views/mch/applyment/MchApplymentListOne.vue
Normal file
@@ -0,0 +1,262 @@
|
||||
<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 == 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 == 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" @click="oauthFuncButton(record.applyId)" style="font-size: 16px; padding-left: 5px;color: #1965FF" />
|
||||
<reload-outlined @click="queryChannelState(record.modifyApplyId, 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>
|
||||
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'agentName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.agentName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.agentName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</div>
|
||||
</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="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_URL_MCH_MODIFY_APPLYMENT_LIST,$getMchApplymentsModifyApplyId,$getMerchantChangeModifyApply
|
||||
} 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: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'agentName', title: '服务商名称', dataIndex: 'agentName' },
|
||||
{ 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);
|
||||
}
|
||||
function searchFunc() {
|
||||
// 点击【查询】按钮点击事件
|
||||
vdata.btnLoading = true; // 打开查询按钮的loading
|
||||
infoTable.value.refTable(true);
|
||||
}
|
||||
const resetFunc = () => {
|
||||
vdata.searchData = {};
|
||||
};
|
||||
//变更详情
|
||||
function getChanageConfigFunc(applyId){
|
||||
vdata.visibleMchChange = true
|
||||
jeepayMchChangeConfigRef.value.show(applyId)
|
||||
}
|
||||
//详情
|
||||
function getChanageDetailFunc(recordId : any) { // 进件详情页
|
||||
|
||||
vdata.copyInfoSourceApplyId = '' // 副本清空。
|
||||
|
||||
infoDetail.value.show(recordId)
|
||||
}
|
||||
//签约
|
||||
function oauthFuncButton(applyId){
|
||||
vdata.visibleChangeConfig = true;
|
||||
signingConfigRef.value.show({applyId:applyId});
|
||||
}
|
||||
|
||||
// 查询最新状态
|
||||
|
||||
// 查询最新状态
|
||||
function queryChannelState(applyId, currState) {
|
||||
$getMchApplymentsModifyApplyId(applyId).then((res) => {
|
||||
$getMerchantChangeModifyApply(applyId).then((resData) => {
|
||||
if (currState != resData.state) {
|
||||
$infoBox.message.success("状态已更新");
|
||||
searchFunc(); // 更新列表
|
||||
} else {
|
||||
$infoBox.message.info("状态无变化");
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
</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>
|
||||
888
jeepay-ui-agent/src/views/mch/applyment/MchBusinessList.vue
Normal file
888
jeepay-ui-agent/src/views/mch/applyment/MchBusinessList.vue
Normal file
@@ -0,0 +1,888 @@
|
||||
<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>
|
||||
|
||||
<!-- <JeepaySearchInfoInput v-model:value="vdata.searchData['mchUserName']" placeholder="用户号/名称/手机号" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />-->
|
||||
|
||||
|
||||
<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['mchUserName']" :placeholder="'用户号/名称/手机号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :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="false"
|
||||
: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="getVisibleAdd()"><plus-outlined />发起进件</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APPLYMENT_ADD')" type="primary" @click="addFunc('')"><plus-outlined />发起进件</a-button>-->
|
||||
</template>
|
||||
|
||||
<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>
|
||||
<!-- 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" >
|
||||
<b>{{ record.remark ?? "--" }}</b>
|
||||
<EditOutlined @click="remarkFunc(record)" />
|
||||
</span>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'mchServiceName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.mchServiceName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchServiceName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchNo'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchName}}</span><br>
|
||||
<span>用户号:{{record.mchNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchName}}</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 === 'settlementType'">
|
||||
<!-- <a @click="getChangeConfigRef(record)"><b>{{ record.settlementType }}</b>-->
|
||||
{{ record.settlementType }}
|
||||
|
||||
<!-- <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 === '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)" ><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 == 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="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="record.ifCode == 'zftpay'">--</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'applyPageType'">
|
||||
<span v-if="record.applyPageType == 'PLATFORM_WEB'">运营平台系统</span>
|
||||
<span v-else-if="record.applyPageType == 'AGENT_WEB'">服务商系统</span>
|
||||
<span v-else-if="record.applyPageType == 'AGENT_APP'">{{ $SYS_NAME_MAP.AGENT_APP }}APP</span>
|
||||
<span v-else-if="record.applyPageType == 'AGENT_LITE'">{{ $SYS_NAME_MAP.AGENT_APP }}小程序</span>
|
||||
<span v-else-if="record.applyPageType == 'MCH_WEB'">商户系统</span>
|
||||
<span v-else-if="record.applyPageType == 'MCH_APP'">{{ $SYS_NAME_MAP.MCH_APP }}APP</span>
|
||||
<span v-else-if="record.applyPageType == 'MCH_LITE'">{{ $SYS_NAME_MAP.MCH_APP }}小程序</span>
|
||||
<span v-else>{{ record.applyPageType || '' }}</span>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operation'">
|
||||
<!-- 以下为: 运营, 服务商通用按钮 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" @click="getStore(record.applyId)" >门店管理</a-button>
|
||||
<a-button type="link" @click="deviceFunc(record.applyId)">设备管理</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_APPLYMENT_VIEW')" type="link" @click="getChangeConfigRef(record)" >变更修改</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_APPLYMENT_VIEW') && record.ifCode != 'zftpay'" type="link" @click="oauthFunc(record.applyId)" >实名认证</a-button>
|
||||
|
||||
<a-button v-if="$access('ENT_MCH_APPLYMENT_VIEW')" type="link" @click="oauthDeployFunc(record.applyId)" >参数配置</a-button >
|
||||
<a-button v-if="$access('ENT_MCH_APPLYMENT_VIEW')" type="link" @click="getOperator()">添加管理员</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_APPLYMENT_VIEW')" type="link" @click="editOrViewFunc(record.applyId, true)">详情</a-button>
|
||||
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APPLYMENT_VIEW')" type="link" @click="detailFunc(record.applyId)">详细数据</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_EDIT') && record.state == 3" type="link" @click="editOrViewFunc(record.applyId, false)">修改</a-button>-->
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APPLYMENT_ADD')" type="link" @click="toCopySelectIfCodePage(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>-->
|
||||
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APPLYMENT_SIGN')" type="link" @click="oauthFunc(record.applyId)" >实名认证</a-button>-->
|
||||
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APPLYMENT_PAY_CONFIG')" type="link" @click="oauthDeployFunc(record.applyId)" >参数配置</a-button >-->
|
||||
<!-- 进件成功后可发起 参数配置 -->
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APPLYMENT_PAY_CONFIG') && record.state == 2" type="link" @click="appConfigDrawerRef.show(record.applyId)">参数配置</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-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" ref="applyPageComponentRef" :listPageSearchMchNo="vdata.searchData.mchNo" @switchApplyPage="switchApplyPage" />
|
||||
</a-card>
|
||||
|
||||
<JeepayModelMchList ref="jeepayModelMchList" showType="MCH" @selectFinishFunc="searchMchFinishFunc" />
|
||||
|
||||
<!-- 参数配置 弹层 -->
|
||||
<AppConfigDrawer ref="appConfigDrawerRef" />
|
||||
|
||||
<!-- 后续流程 弹层 -->
|
||||
<NextBizsDrawer ref="nextBizsDrawerRef" />
|
||||
<ChangeConfig ref="changeConfigRef" v-show="vdata.visibleChangeConfig" />
|
||||
|
||||
<!-- 详情页面组件 -->
|
||||
<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>
|
||||
|
||||
<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>
|
||||
<JeepayOauth2DeployConfig v-show="vdata.visibleOauth2Deploy" configMode="mchApplyment" ref="jeepayOauth2DeployConfigRef"/>
|
||||
<JeepayMchOauth2 v-show="vdata.visibleOauth2" ref="jeepayMchOauth2Ref" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_APPLYMENT_LIST,API_MCH_APPLYMENT_REMARK, req, $getMchApplymentChannelState, $getPayConfigIfcodes } from '@/api/manage'
|
||||
import {ref, reactive, getCurrentInstance, nextTick, provide, computed, onMounted } 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 AppConfigDrawer from './AppConfigDrawer.vue'
|
||||
import NextBizsDrawer from './NextBizsDrawer.vue'
|
||||
import ChangeConfig from "./ChangeConfig.vue";
|
||||
import InfoDetail from './NewDetail.vue'
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
const { $infoBox, $access, $SYS_NAME_MAP } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
const router = useRouter(); //这是全部路由
|
||||
/** 定义全部组件 **/
|
||||
const allApplyPage = {
|
||||
'list': { name: '列表', component: null },
|
||||
'applySelectMchAndIfcode': { name: '选择商户及进件渠道', component: ApplySelectMchAndIfcode },
|
||||
'applyMchDetailInfoEntry': { name: '填写进件资料', component: ApplyMchDetailInfoEntry }
|
||||
}
|
||||
|
||||
// 动态组件
|
||||
const applyPageComponentRef = ref()
|
||||
|
||||
const jeepayModelMchList = ref()
|
||||
|
||||
const appConfigDrawerRef = ref()
|
||||
const nextBizsDrawerRef = ref()
|
||||
const infoDetail = ref()
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
const changeConfigRef = ref()
|
||||
|
||||
const jeepayMchOauth2Ref = ref();
|
||||
const jeepayOauth2DeployConfigRef = ref();
|
||||
let tableColumns = reactive([
|
||||
// { key: 'applyId', title: '申请单号', dataIndex: 'applyId', },
|
||||
// { key: 'ifName', title: '渠道', dataIndex: 'ifName' , },
|
||||
// { key: 'merchantType', title: '商户类型', dataIndex: 'merchantType' , },
|
||||
// { key: 'mchNo', title: '用户号', dataIndex: 'mchNo' , },
|
||||
// { key: 'mchFullName', title: '进件商户名', dataIndex: 'mchFullName', },
|
||||
// // { key: 'isvNo', title: '服务商号', dataIndex: 'isvNo', width: 140, minWidth: 140, maxWidth: 170},
|
||||
// { key: 'state', title: '进件状态', },
|
||||
// // { key: 'applyPageType', title: '来源', width: 150, minWidth: 150, maxWidth: 150},
|
||||
// { key: 'createdAt', dataIndex: 'createdAt', title: '创建日期', },
|
||||
// { key: 'lastApplyAt', dataIndex: 'lastApplyAt', title: '最后提交', },
|
||||
// { key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
|
||||
{ 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: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'mchServiceName', title: '服务商名称', dataIndex: 'mchServiceName' },
|
||||
{ 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({
|
||||
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: '' }, // 搜索条件
|
||||
|
||||
notes: {
|
||||
appid: "",
|
||||
value: "",
|
||||
},
|
||||
currentApplyPage: allApplyPage.list, // 当前的步骤组件 null表示列表页
|
||||
backupApplyPage: null, // 备份: 用作快速恢复
|
||||
|
||||
mchApplymentData: { }, //商户进件资料
|
||||
isView: false, // 是否预览模式
|
||||
|
||||
ifCodeList: [],
|
||||
|
||||
copyInfoSourceApplyId: '', // 副本资料
|
||||
|
||||
})
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
vdata.searchData['mchNo'] = useRoute().query.mchNo
|
||||
if($access('ENT_MCH_APPLYMENT')){
|
||||
$getPayConfigIfcodes('CURRENT', 'agentApplyment', '').then((res) => {
|
||||
vdata.ifCodeList = res
|
||||
})
|
||||
}
|
||||
searchFunc()
|
||||
})
|
||||
|
||||
|
||||
// 向所有子组件注入参数 (子组件可直接更改此值)
|
||||
provide('mchApplymentData', computed( ()=> vdata.mchApplymentData) )
|
||||
provide('isView', computed( ()=> vdata.isView) )
|
||||
|
||||
// 向所有子组件注入参数: 配置模式: mgrApplyment / agentApplyment / mchApplyment
|
||||
provide('configMode', 'agentApplyment')
|
||||
|
||||
// 向所有子组件注入参数 副本资料来源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 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 maskedName(fullName) {
|
||||
if (fullName.length >= 2) {
|
||||
const firstName = fullName.charAt(0);
|
||||
const maskedPart = "*".repeat(fullName.length - 1);
|
||||
return firstName + maskedPart;
|
||||
}
|
||||
return fullName;
|
||||
}
|
||||
function getStore(applyId) {
|
||||
router.push({
|
||||
path: "/store",
|
||||
query: { applyId: applyId },
|
||||
});
|
||||
}
|
||||
|
||||
function deviceFunc(mchApplyId){
|
||||
router.push({
|
||||
path: "/qrc",
|
||||
query:{mchApplyId:mchApplyId}
|
||||
});
|
||||
}
|
||||
function getOperator() {
|
||||
router.push({
|
||||
path: "/users",
|
||||
});
|
||||
}
|
||||
// 点击【查询】按钮点击事件
|
||||
function searchFunc () {
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
// 切换步骤: 不清空数据
|
||||
function switchApplyPage(page){
|
||||
if (page == "applyAddApps") {
|
||||
router.push({
|
||||
path: "/apps",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (page == "applyMch") {
|
||||
router.push({
|
||||
path: "/mch",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
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 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,sceneType:sceneType}
|
||||
}
|
||||
|
||||
//进件数据重置
|
||||
vdata.isView = false
|
||||
switchApplyPage('applySelectMchAndIfcode')
|
||||
})
|
||||
// vdata.isView = false
|
||||
// switchApplyPage('applySelectMchAndIfcode')
|
||||
}
|
||||
|
||||
// 修改资料 然后重新发起进件操作
|
||||
function editOrViewFunc(applyId, isView){
|
||||
console.log(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, isvNo, state ,range} = res
|
||||
vdata.mchApplymentData = {applyId, channelApplyNo, mchNo, ifCode, applyDetailInfo, applyErrorInfo,isvNo, state,range}
|
||||
switchApplyPage('applyMchDetailInfoEntry')
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 查询最新状态
|
||||
function queryChannelState(applyId, currState){
|
||||
$getMchApplymentChannelState(applyId).then(res => {
|
||||
if(currState != res.state){
|
||||
$infoBox.message.success('状态已更新')
|
||||
searchFunc() // 更新列表
|
||||
}else{
|
||||
$infoBox.message.info('状态无变化')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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 recoveryApplyPage(){
|
||||
vdata.currentApplyPage = vdata.backupApplyPage
|
||||
}
|
||||
|
||||
// 获取下拉框组件
|
||||
const ifCodeRef = ref()
|
||||
const stateRef = ref()
|
||||
let isReset = ref(0) // 下拉搜索框是否重置
|
||||
|
||||
// 清空搜索项
|
||||
const resetFunc = () => {
|
||||
isReset.value++ // 下拉搜索框重置
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData= {}
|
||||
}
|
||||
|
||||
// 选择商户 / 应用 完成后的操作
|
||||
function searchMchFinishFunc(selectVal){
|
||||
|
||||
if(selectVal[0]){
|
||||
vdata.searchData.mchNo = selectVal[0]
|
||||
}
|
||||
|
||||
jeepayModelMchList.value.close()
|
||||
|
||||
}
|
||||
|
||||
// 显示二维码图片
|
||||
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 getVisibleAdd(){
|
||||
vdata.visibleAdd = true
|
||||
}
|
||||
function handleCancel (e) {
|
||||
vdata.visibleAdd = 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);
|
||||
}
|
||||
function remarkFunc(data) {
|
||||
vdata.notes.appid = data.applyId;
|
||||
vdata.notes.value = data.remark ?? "";
|
||||
vdata.visibleNotes = true;
|
||||
}
|
||||
</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>
|
||||
|
||||
<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>
|
||||
235
jeepay-ui-agent/src/views/mch/applyment/MchSign.vue
Normal file
235
jeepay-ui-agent/src/views/mch/applyment/MchSign.vue
Normal file
@@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="自主签约"
|
||||
width="50%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form>
|
||||
<template
|
||||
v-if="
|
||||
vdata.bizSignInfo &&
|
||||
(vdata.bizSignInfo.state || vdata.bizSignInfo.signUrl)
|
||||
"
|
||||
>
|
||||
<a-divider orientation="left" style="color: #1a66ff"
|
||||
>电子合同签约</a-divider
|
||||
>
|
||||
|
||||
<a-form-item label="签约状态">
|
||||
{{
|
||||
vdata.bizSignInfo.state || "异常[" + vdata.bizSignInfo.errInfo + "]"
|
||||
}}
|
||||
<a-button
|
||||
:loading="vdata.bizSignInfoBtnLoading"
|
||||
size="small"
|
||||
style="margin-left: 20px"
|
||||
type="primary"
|
||||
@click="getMchApplymentChannelSignInfoFunc"
|
||||
><reload-outlined />刷新</a-button
|
||||
>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="vdata.bizSignInfo.signUrl" label="合同地址">
|
||||
<p style="margin-top: 5px">
|
||||
<a :href="vdata.bizSignInfo.signUrl" target="_blank">{{
|
||||
vdata.bizSignInfo.signUrl
|
||||
}}</a>
|
||||
</p>
|
||||
|
||||
<p style="margin-top: 20px">合同地址快捷访问二维码:</p>
|
||||
<QrcodeVue
|
||||
:value="vdata.bizSignInfo.signUrl"
|
||||
:size="150"
|
||||
class="qrcode"
|
||||
/>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<template
|
||||
v-if="
|
||||
vdata.wxOpenInfo &&
|
||||
(vdata.wxOpenInfo.state || vdata.wxOpenInfo.signUrl)
|
||||
"
|
||||
>
|
||||
<a-divider orientation="left" style="color: #1a66ff"
|
||||
>微信开户意愿确认</a-divider
|
||||
>
|
||||
|
||||
<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.signUrl" label="">
|
||||
<p>商户联系人使用已绑定银行卡的微信扫下面的二维码:</p>
|
||||
<QrcodeVue
|
||||
v-if="vdata.wxOpenInfo.imgType == 'qrContent'"
|
||||
:value="vdata.wxOpenInfo.signUrl"
|
||||
:size="150"
|
||||
class="qrcode"
|
||||
/>
|
||||
<img
|
||||
v-else
|
||||
:src="'data:image/jpg;base64,' + vdata.wxOpenInfo.signUrl"
|
||||
class="qrcode"
|
||||
style="width: 200px"
|
||||
/>
|
||||
<br />
|
||||
<p class="jeepay-tip-text">
|
||||
(温馨提示:自助认证不限制谁来操作认证,但建议是商户联系人进行认证,以免后期需要扫码找不到微信认证管理员)
|
||||
</p>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<template
|
||||
v-if="vdata.alipayOpenInfo.state || vdata.alipayOpenInfo.signUrl"
|
||||
>
|
||||
<a-divider orientation="left" style="color: #1a66ff"
|
||||
>支付宝实名审核</a-divider
|
||||
>
|
||||
|
||||
<a-form-item label="商户确认状态">
|
||||
{{ vdata.alipayOpenInfo.state }}
|
||||
<a-button
|
||||
:loading="vdata.alipayOpenInfoBtnLoading"
|
||||
size="small"
|
||||
style="margin-left: 20px"
|
||||
type="primary"
|
||||
@click="getMchApplymentAlipayOpenInfoFunc"
|
||||
><reload-outlined />刷新</a-button
|
||||
>
|
||||
</a-form-item>
|
||||
<br />
|
||||
<span v-if="vdata.alipayOpenInfo.errInfo">{{
|
||||
"异常[" + vdata.alipayOpenInfo.errInfo + "]"
|
||||
}}</span>
|
||||
|
||||
<a-form-item v-if="vdata.alipayOpenInfo.signUrl" label="">
|
||||
<p>商户联系人使用已绑定银行卡的支付宝扫下面的二维码:</p>
|
||||
<QrcodeVue
|
||||
v-if="vdata.alipayOpenInfo.imgType == 'qrContent'"
|
||||
:value="vdata.alipayOpenInfo.signUrl"
|
||||
:size="150"
|
||||
class="qrcode"
|
||||
/>
|
||||
<template v-else>
|
||||
<img
|
||||
v-if="
|
||||
vdata.alipayOpenInfo.signUrl &&
|
||||
vdata.alipayOpenInfo.signUrl.indexOf('http') == 0
|
||||
"
|
||||
:src="vdata.alipayOpenInfo.signUrl"
|
||||
class="qrcode"
|
||||
style="width: 200px"
|
||||
/>
|
||||
<img
|
||||
v-else
|
||||
:src="'data:image/jpg;base64,' + vdata.alipayOpenInfo.signUrl"
|
||||
class="qrcode"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</template>
|
||||
<br />
|
||||
<!-- <p class="jeepay-tip-text">(温馨提示:自助认证不限制谁来操作认证,但建议是商户联系人进行认证,以免后期需要扫码找不到微信认证管理员)</p> -->
|
||||
</a-form-item>
|
||||
</template>
|
||||
</a-form>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
$getMchApplymentChannelSignInfo,
|
||||
$getMchApplymentWxOpenInfo,
|
||||
$getMchApplymentAlipayOpenInfo,
|
||||
} from "@/api/manage";
|
||||
import { reactive, getCurrentInstance } from "vue";
|
||||
import QrcodeVue from "qrcode.vue";
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties;
|
||||
|
||||
const vdata: any = reactive({
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
|
||||
bizSignInfo: {}, // 电子合同信息
|
||||
|
||||
wxOpenInfo: {}, // 微信开户意愿信息
|
||||
alipayOpenInfo: {}, // 支付宝开户意愿信息
|
||||
|
||||
bizSignInfoBtnLoading: false,
|
||||
wxOpenInfoBtnLoading: false,
|
||||
alipayOpenInfoBtnLoading: false,
|
||||
});
|
||||
|
||||
function show(recordId) {
|
||||
// 弹层打开事件
|
||||
|
||||
// 数据的清空
|
||||
vdata.bizSignInfo = {};
|
||||
vdata.wxOpenInfo = {};
|
||||
vdata.alipayOpenInfo = {};
|
||||
|
||||
vdata.recordId = recordId;
|
||||
getMchApplymentChannelSignInfoFunc();
|
||||
getMchApplymentWxOpenInfoFunc();
|
||||
getMchApplymentAlipayOpenInfoFunc();
|
||||
vdata.visible = true;
|
||||
}
|
||||
|
||||
// 电子合同状态查询
|
||||
function getMchApplymentChannelSignInfoFunc() {
|
||||
vdata.bizSignInfoBtnLoading = true;
|
||||
$getMchApplymentChannelSignInfo(vdata.recordId)
|
||||
.then((res) => {
|
||||
vdata.bizSignInfo = res;
|
||||
})
|
||||
.finally(() => {
|
||||
vdata.bizSignInfoBtnLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 电子合同状态查询
|
||||
function getMchApplymentWxOpenInfoFunc() {
|
||||
vdata.wxOpenInfoBtnLoading = true;
|
||||
$getMchApplymentWxOpenInfo(vdata.recordId)
|
||||
.then((res) => {
|
||||
vdata.wxOpenInfo = res;
|
||||
})
|
||||
.finally(() => {
|
||||
vdata.wxOpenInfoBtnLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 电子合同状态查询
|
||||
function getMchApplymentAlipayOpenInfoFunc() {
|
||||
vdata.alipayOpenInfoBtnLoading = true;
|
||||
$getMchApplymentAlipayOpenInfo(vdata.recordId)
|
||||
.then((res) => {
|
||||
vdata.alipayOpenInfo = res || {};
|
||||
})
|
||||
.finally(() => {
|
||||
vdata.alipayOpenInfoBtnLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
vdata.visible = false;
|
||||
}
|
||||
|
||||
defineExpose({ show });
|
||||
</script>
|
||||
<style scoped>
|
||||
.form-item-content {
|
||||
width: 70%;
|
||||
}
|
||||
</style>
|
||||
164
jeepay-ui-agent/src/views/mch/applyment/NewDetail.vue
Normal file
164
jeepay-ui-agent/src/views/mch/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>
|
||||
38
jeepay-ui-agent/src/views/mch/applyment/NextBizsDrawer.vue
Normal file
38
jeepay-ui-agent/src/views/mch/applyment/NextBizsDrawer.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
<!-- 签约开通 弹层模式 -->
|
||||
|
||||
<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({
|
||||
|
||||
applyId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
})
|
||||
|
||||
function show (applyId) { // 弹层打开事件
|
||||
|
||||
vdata.applyId = applyId
|
||||
vdata.visible = true
|
||||
|
||||
nextTick(() => {
|
||||
jeepayApplymentNextBizsRef.value.pageRender(applyId)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
36
jeepay-ui-agent/src/views/mch/applyment/SigningConfig.vue
Normal file
36
jeepay-ui-agent/src/views/mch/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>
|
||||
114
jeepay-ui-agent/src/views/mch/applyment/WxAppConfig.vue
Normal file
114
jeepay-ui-agent/src/views/mch/applyment/WxAppConfig.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
title="参数配置"
|
||||
width="50%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form>
|
||||
<a-form-item label="用户号:">
|
||||
<a-tag color="blue">{{ vdata.detailData.mchNo }}</a-tag>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="支付参数:">
|
||||
<a-textarea
|
||||
v-model:value="vdata.detailData.succResParameter"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-divider orientation="left"><a-tag color="black">应用配置</a-tag></a-divider>
|
||||
|
||||
<a-form-item label="参数配置到应用:">
|
||||
<a-select v-model:value="vdata.configAppId" class="form-item-content" placeholder="选择应用">
|
||||
<a-select-option key="">请选择商户应用</a-select-option>
|
||||
<a-select-option v-for="(item) in vdata.mchAppList" :key="item.appId">{{ item.appName }} [{{ item.appId }}]</a-select-option>
|
||||
</a-select>
|
||||
<a-button size="small" style="margin-left: 20px;" type="primary" :disabled="!vdata.configAppId" @click="configMchAppIdFunc"><save-outlined />配置到应用</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MCH_APPLYMENT_LIST, API_URL_MCH_APP, req, $applymentAppConfig, $saveRateConfig } from '@/api/manage'
|
||||
import {reactive, getCurrentInstance} from 'vue'
|
||||
const { $infoBox } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
const vdata : any = reactive({
|
||||
detailData: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
mchAppList: [], // 商户app列表
|
||||
configAppId: ''
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
|
||||
//重置配置
|
||||
vdata.configAppId = ''
|
||||
vdata.mchAppList = []
|
||||
|
||||
vdata.recordId = recordId
|
||||
|
||||
req.getById(API_URL_MCH_APPLYMENT_LIST, recordId).then( (res) => {
|
||||
vdata.detailData = res
|
||||
req.list(API_URL_MCH_APP, { pageSize: -1, mchNo: vdata.detailData.mchNo }).then(res2 => {
|
||||
vdata.mchAppList = res2.records
|
||||
if(vdata.mchAppList.length > 0){
|
||||
vdata.configAppId = vdata.mchAppList[0].appId
|
||||
}
|
||||
})
|
||||
|
||||
vdata.visible = true
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 配置本系统的app应用配置项
|
||||
function configMchAppIdFunc(){
|
||||
|
||||
if(!vdata.configAppId){
|
||||
$infoBox.message.error('请选择商户应用')
|
||||
return Promise.reject()
|
||||
}
|
||||
|
||||
return $applymentAppConfig(vdata.recordId, vdata.configAppId).then((res) => {
|
||||
$infoBox.message.success('商户应用配置完成, 如商户支付方式未配置,请进行方式配置。 ')
|
||||
return Promise.resolve()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
// 配置费率到应用
|
||||
function configMchRateAppIdFunc(){
|
||||
|
||||
if(!vdata.configAppId){
|
||||
$infoBox.message.error('请选择商户应用')
|
||||
return Promise.reject()
|
||||
}
|
||||
|
||||
// 请求对象
|
||||
let configMode = 'agentMch' // 服务商配置商户费率
|
||||
let reqObject = {infoId: vdata.configAppId, ifCode: vdata.detailData.ifCode, configMode: configMode, MCHRATE: JSON.parse(vdata.detailData.applyDetailInfo).paywayFeeList}
|
||||
return $saveRateConfig(reqObject).then((res) => {
|
||||
$infoBox.message.success('费率保存成功')
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
.form-item-content{
|
||||
width: 70%
|
||||
}
|
||||
|
||||
</style>
|
||||
231
jeepay-ui-agent/src/views/mchApp/AddOrEdit.vue
Normal file
231
jeepay-ui-agent/src/views/mchApp/AddOrEdit.vue
Normal file
@@ -0,0 +1,231 @@
|
||||
<!-- 复制自: 运营平台(无改动) -->
|
||||
<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 v-if="!vdata.isAdd" :span="12">
|
||||
<a-form-item label="应用 AppId" name="appId">
|
||||
<a-input v-model:value="vdata.saveObject['appId']" placeholder="请输入" :disabled="!vdata.isAdd" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="用户号" name="mchNo">
|
||||
<JeepaySearchInfoInput v-model:value="vdata.saveObject['mchNo']" placeholder="请输入" :disabled="!vdata.isAdd" :mchNoAndName="true" :onlyMchName="true" />
|
||||
</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="appName">
|
||||
<a-input v-model:value="vdata.saveObject['appName']" placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<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 :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['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
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
|
||||
197
jeepay-ui-agent/src/views/mchApp/List.vue
Normal file
197
jeepay-ui-agent/src/views/mchApp/List.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card v-show="vdata.tableType == 'table'">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="() => { vdata.searchData= {} }">
|
||||
<JeepaySearchInfoInput v-model:value="vdata.searchData.mchNo" placeholder="用户号" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appId" :placeholder="'应用AppId'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.appName" :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>
|
||||
<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="false"
|
||||
: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 == 'state'">
|
||||
<a-badge :status="record.state === 0?'error':'processing'" :text="record.state === 0?'禁用':'启用'" />
|
||||
</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 == '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 === 'mchServiceName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.mchServiceName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchServiceName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_MCH_APP_EDIT')" type="link" @click="editFunc(record.appId)">修改</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_MCH_APP_PAY_CONFIG')" type="link" @click="showFeeConfigList(record.appId)">支付配置</a-button>-->
|
||||
<a-button v-if="$access('ENT_MCH_PAY_TEST')" 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')" 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')" type="link" style="color: red" @click="delFunc(record.appId)">删除</a-button>-->
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 新增应用 -->
|
||||
<MchAppAddOrEdit ref="mchAppAddOrEdit" :callbackFunc="searchFunc" />
|
||||
|
||||
<!-- 费率配置页面 -->
|
||||
<JeepayPayConfigDrawer ref="jeepayPayWayFeeConfigDrawer" configMode="agentMch" />
|
||||
|
||||
<a-card v-show="vdata.tableType == 'appSaveEdit'" style="background: #f0f2f5; ">
|
||||
<JeepayApplicationSave ref="jeepayApplicationSave" :configMode="'agent'" @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 {ref, reactive, onMounted, 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: 'appName',fixed: 'left', title: '应用名称', dataIndex: 'appName' },
|
||||
{ key: 'appId', title: '应用ID', },
|
||||
{ key: 'range', title: '应用类型',},
|
||||
{ key: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'mchServiceName', title: '服务商名称', dataIndex: 'mchServiceName' },
|
||||
{ key: 'state', title: '应用状态',},
|
||||
// { key: 'defaultFlag', title: '默认',},
|
||||
{ key: 'createdAt', title: '创建日期', dataIndex: 'createdAt',},
|
||||
{ key: 'op', title: '操作', fixed: 'right', align: 'center' }
|
||||
])
|
||||
|
||||
onMounted(() => {
|
||||
vdata.searchData.mchNo = useRoute().query.mchNo
|
||||
searchFunc()
|
||||
})
|
||||
|
||||
const mchAppAddOrEdit =ref()
|
||||
const infoTable = ref()
|
||||
|
||||
const jeepayApplicationSave = ref()
|
||||
const jeepayPayWayFeeConfigDrawer = ref()
|
||||
|
||||
const vdata = reactive({
|
||||
tableType:'table',
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {} as any
|
||||
})
|
||||
function getMchAppSave(e){
|
||||
if(e.type == 1){
|
||||
vdata.tableType = e.tableType
|
||||
queryFunc()
|
||||
}
|
||||
|
||||
}
|
||||
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(vdata.searchData['mchNo'])
|
||||
}
|
||||
|
||||
function editFunc (recordId) { // 业务通用【修改】 函数
|
||||
mchAppAddOrEdit.value.show(vdata.searchData['mchNo'], recordId)
|
||||
}
|
||||
|
||||
function delFunc (appId) {
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
req.delById(API_URL_MCH_APP, appId).then(res => {
|
||||
$infoBox.message.success('删除成功!')
|
||||
searchFunc()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const showFeeConfigList = function (recordId) { // 支付费率配置
|
||||
jeepayPayWayFeeConfigDrawer.value.show(recordId)
|
||||
}
|
||||
|
||||
function getAddFunc(type){
|
||||
vdata.tableType = type
|
||||
jeepayApplicationSave.value.show()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
150
jeepay-ui-agent/src/views/mchconfig/MchConfig.vue
Normal file
150
jeepay-ui-agent/src/views/mchconfig/MchConfig.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div style="background: #fff">
|
||||
<a-tabs>
|
||||
<a-tab-pane key="mchConfig" tab="系统配置">
|
||||
<div 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-col :span="7" :offset="1">
|
||||
<a-form-item label="是否启用码牌防逃单功能" name="qrcEscaping">
|
||||
<a-radio-group v-model:value="vdata.mchConfigData.qrcEscaping">
|
||||
<a-radio :value="1">启用</a-radio>
|
||||
<a-radio :value="0">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="7" :offset="1">
|
||||
<a-form-item label="是否启用app订单语音播报" name="appVoice">
|
||||
<a-radio-group v-model:value="vdata.mchConfigData.appVoice">
|
||||
<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="mchConfig2" tab="功能配置">
|
||||
<div 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-tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_MCH_CONFIG, req, $getMainUserInfo, $updateMchLevel } from '@/api/manage'
|
||||
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
||||
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const configFormModel = ref()
|
||||
|
||||
const vdata = reactive ({
|
||||
btnLoading: false,
|
||||
groupKey: 'orderConfig',
|
||||
mchConfigData: [] as any, // 配置保存对象
|
||||
defaultConfig: [{
|
||||
configKey: 'appVoice',
|
||||
configName: '是否启用app订单语音播报',
|
||||
configVal: '1',
|
||||
type: 'radio'
|
||||
}, {
|
||||
configKey: 'qrcEscaping',
|
||||
configName: '是否启用码牌防逃单功能',
|
||||
configVal: '1',
|
||||
type: 'radio'
|
||||
}], // 默认配置项
|
||||
|
||||
mchLevel: '',
|
||||
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
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
|
||||
}
|
||||
})
|
||||
|
||||
$getMainUserInfo().then((res) => {
|
||||
vdata.mchLevel = res.mchLevel
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
// 确认更新
|
||||
function confirm (e) {
|
||||
configFormModel.value.validate().then(valid => {
|
||||
$infoBox.confirmPrimary('确认修改系统配置吗?', '', () => {
|
||||
vdata.btnLoading = true // 打开按钮上的 loading
|
||||
|
||||
req.updateById(API_URL_MCH_CONFIG, vdata.groupKey, {configData: JSON.stringify(vdata.mchConfigData)}).then(res => {
|
||||
$infoBox.message.success('修改成功')
|
||||
vdata.btnLoading = false
|
||||
}).catch(res => {
|
||||
vdata.btnLoading = false
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 更新商户等级
|
||||
function confirmUpdateLevel(){
|
||||
$updateMchLevel(vdata.mchLevel).then(() => {
|
||||
$infoBox.modalWarning('提示', '更新成功,重新登录后将切换功能模式!')
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.bottom-btn{
|
||||
/deep/ div{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.typePopover {
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
left: 93px;
|
||||
}
|
||||
</style>
|
||||
59
jeepay-ui-agent/src/views/notice/AddOrEdit.vue
Normal file
59
jeepay-ui-agent/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>
|
||||
94
jeepay-ui-agent/src/views/notice/NoticePage.vue
Normal file
94
jeepay-ui-agent/src/views/notice/NoticePage.vue
Normal file
@@ -0,0 +1,94 @@
|
||||
<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_DELET')" 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: 'nickname', fixed: 'left', 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('删除成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
function onReset(){ //重置搜索内容
|
||||
searchData.value = {}
|
||||
}
|
||||
</script>
|
||||
98
jeepay-ui-agent/src/views/order/pay/PayDetail.vue
Normal file
98
jeepay-ui-agent/src/views/order/pay/PayDetail.vue
Normal file
@@ -0,0 +1,98 @@
|
||||
<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="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{
|
||||
//width: 30%;
|
||||
}
|
||||
.item-box-title-border{
|
||||
//border-right: 1px solid #EFEFEF !important;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
447
jeepay-ui-agent/src/views/order/pay/PayLogDetail.vue
Normal file
447
jeepay-ui-agent/src/views/order/pay/PayLogDetail.vue
Normal file
@@ -0,0 +1,447 @@
|
||||
<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.mchUserName}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="用户ID">
|
||||
{{ vdata.detailData.mchNo }} [ {{vdata.detailData.mchUserPhone}} ]
|
||||
</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>
|
||||
1004
jeepay-ui-agent/src/views/order/pay/PayOrderList.vue
Normal file
1004
jeepay-ui-agent/src/views/order/pay/PayOrderList.vue
Normal file
File diff suppressed because it is too large
Load Diff
66
jeepay-ui-agent/src/views/order/pay/PaySucDetail.vue
Normal file
66
jeepay-ui-agent/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>
|
||||
170
jeepay-ui-agent/src/views/order/pay/RefundModal.vue
Normal file
170
jeepay-ui-agent/src/views/order/pay/RefundModal.vue
Normal file
@@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-modal
|
||||
v-model:visible="vdata.visible"
|
||||
title="退款"
|
||||
:confirm-loading="vdata.confirmLoading"
|
||||
:closable="false"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :sm="24">
|
||||
<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="24">
|
||||
<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="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="可退金额">
|
||||
<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="refundAmount">
|
||||
<a-input-number v-model:value="vdata.refund.refundAmount" :precision="2" style="width:100%" />
|
||||
</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-item label="支付密码" name="refundPassword">
|
||||
<a-input v-model:value="vdata.refund.refundPassword" maxlength="6" type="password" autocomplete="off" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="tsx">
|
||||
import { API_URL_PAY_ORDER_LIST, req, $payOrderRefund } from '@/api/manage'
|
||||
import {ref, onMounted, reactive, getCurrentInstance,computed} from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// 获取全局函数
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const props = defineProps ({
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
})
|
||||
|
||||
const refundInfo = ref()
|
||||
const vdata : any = reactive({
|
||||
refundErrorModal: null, // 退款错误信息的modal对象
|
||||
recordId: '',
|
||||
labelCol: { span: 4 },
|
||||
wrapperCol: { span: 16 },
|
||||
visible: false,
|
||||
confirmLoading: false,
|
||||
detailData: {} as any,
|
||||
refund: {
|
||||
refundReason: '', // 退款原因
|
||||
refundAmount: '' // 退款金额
|
||||
} as any,
|
||||
|
||||
})
|
||||
|
||||
const rules = {
|
||||
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
|
||||
})
|
||||
|
||||
defineExpose({show})
|
||||
function show (recordId) {
|
||||
if (refundInfo.value !== undefined) {
|
||||
refundInfo.value.resetFields()
|
||||
}
|
||||
vdata.recordId = recordId
|
||||
vdata.visible = true
|
||||
vdata.refund = {}
|
||||
|
||||
req.getById(API_URL_PAY_ORDER_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
}
|
||||
function handleOk () {
|
||||
refundInfo.value.validate().then(valid =>{
|
||||
vdata.confirmLoading = true
|
||||
|
||||
// 退款接口
|
||||
$payOrderRefund(vdata.recordId, vdata.refund.refundAmount, vdata.refund.refundReason, vdata.refund.refundPassword).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>
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
368
jeepay-ui-agent/src/views/order/refund/RefundDetail.vue
Normal file
368
jeepay-ui-agent/src/views/order/refund/RefundDetail.vue
Normal file
@@ -0,0 +1,368 @@
|
||||
<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.mchUserName}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="用户ID">
|
||||
{{ vdata.detailData.mchNo }} [ {{vdata.detailData.mchUserPhone}} ]
|
||||
</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>
|
||||
675
jeepay-ui-agent/src/views/order/refund/RefundOrderList.vue
Normal file
675
jeepay-ui-agent/src/views/order/refund/RefundOrderList.vue
Normal file
@@ -0,0 +1,675 @@
|
||||
<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>
|
||||
<a-form-item class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData['agentName']" placeholder="请选择服务商" @change="handleChange">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="onlyOne">仅自己</a-select-option>
|
||||
<a-select-option v-for="d in vdata.agentList" :key="d.agentNo" v-model:value="d.agentNo">
|
||||
{{ d.agentName + " [ ID: " + d.agentNo + " ]" }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<JeepaySearchInfoInput v-model:value="vdata.searchData['mchUserName']" placeholder="用户号/名称" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />
|
||||
|
||||
<!-- <jeepay-text-up v-model:value="vdata.searchData.unionOrderId" :placeholder="'退款/支付/渠道/商户退款号'" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'退款订单号'" :msg="searchData.refundOrderId" v-model="searchData.refundOrderId" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'商户退款单号'" :msg="searchData.mchRefundNo" v-model="searchData.mchRefundNo" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'支付订单号'" :msg="searchData.payOrderId" v-model="searchData.payOrderId" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'渠道订单号'" :msg="searchData.channelPayOrderNo" v-model="searchData.channelPayOrderNo" />-->
|
||||
<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>
|
||||
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:closable="true"
|
||||
:searchData="vdata.searchData"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
rowKey="refundOrderId"
|
||||
:tableRowCrossColor="true"
|
||||
:statisticsIsShow="$access('ENT_REFUND_ORDER_COUNT')"
|
||||
: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'"><b>¥{{ record.refundAmount/100 }}</b></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>-->
|
||||
<!-- </div>-->
|
||||
<!-- </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>-->
|
||||
<!-- </template>-->
|
||||
<!-- <template v-if="column.key == 'pay'">-->
|
||||
<!-- <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 === 'ifCode'">-->
|
||||
<!-- <span>{{ record.ifName }} ({{ record.ifCode }})</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- <template v-if="column.key == 'op'">-->
|
||||
<!-- <!– 操作列插槽 –>-->
|
||||
<!-- <a-button v-if="$access('ENT_REFUND_ORDER_VIEW')" type="link" @click="detailFunc(record.refundOrderId)">详情</a-button>-->
|
||||
<!-- </template>-->
|
||||
<!-- </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 === 'agentName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.agentName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.agentName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</div>
|
||||
</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'">
|
||||
<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-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>
|
||||
|
||||
</template>
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<a-button v-if="$access('ENT_REFUND_ORDER_VIEW')" type="link" @click="detailFunc(record)">详情</a-button>
|
||||
|
||||
<!-- <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="支付金额">-->
|
||||
<!-- <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>-->
|
||||
<RefundDetail ref="refundDetail" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_REFUND_ORDER_LIST, API_URL_AGENT_LIST, req, $exportExcel, exportExcelUrl, $getPayConfigIfcodes, $refundOrderCount } from '@/api/manage'
|
||||
import moment from 'moment'
|
||||
import fileDownload from 'js-file-download'
|
||||
import {ref, onMounted, reactive, getCurrentInstance} from 'vue'
|
||||
import RefundDetail from "./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' }, width: '260px' },
|
||||
// { key: 'refund', title: '支付订单号', scopedSlots: { customRender: 'payOrderSlot' }, width: '260px' },
|
||||
// { key: 'storeName', title: '门店名称', dataIndex: 'storeName', defaultHidden: true },
|
||||
// { key: 'storeId', title: '门店ID', dataIndex: 'storeId', defaultHidden: true },
|
||||
// { key: 'payAmount', title: '支付金额' },
|
||||
// { key: 'refundAmount', title: '退款金额' },
|
||||
// { key: 'refundFeeAmount', title: '手续费退还金额' },
|
||||
// { key: 'mchName', title: '用户名称', dataIndex: 'mchName', ellipsis: true, },
|
||||
// { key: 'ifCode', title: '支付接口'},
|
||||
// { key: 'state', title: '支付状态', scopedSlots: { customRender: 'stateSlot' } },
|
||||
// { key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
|
||||
// { key: 'op', title: '操作', width: '100px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
// ])
|
||||
|
||||
const tableColumns = reactive([
|
||||
// { key: 'pay', title: '退款订单号', scopedSlots: { customRender: 'refundOrderSlot' } },
|
||||
{ key: 'pay', title: '退款订单号' },
|
||||
{ key: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'agentName', title: '服务商名称', dataIndex: 'agentName' },
|
||||
{ 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: 'appId', title: '所属应用', dataIndex: 'appId' },
|
||||
// { 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: '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 ifCodeRef = ref()
|
||||
const dateRangePicker = ref()
|
||||
const infoTable = ref()
|
||||
const vdata :any = reactive({
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {queryDateRange: 'today'} as any,
|
||||
createdStart: '', // 选择开始时间
|
||||
createdEnd: '', // 选择结束时间
|
||||
visible: false,
|
||||
detailData: {} as any,
|
||||
agentList: [] as any, // 服务商下拉列表
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
if($access('ENT_AGENT_RATE_CONFIG')){
|
||||
$getPayConfigIfcodes('AGENT', 'agentApplyment', '').then((res) => {
|
||||
vdata.ifCodeList = res
|
||||
})
|
||||
}
|
||||
getOrderCount()
|
||||
})
|
||||
|
||||
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.totalAmount / 100).toFixed(2), num:res.allCount },
|
||||
{type: 'line'},
|
||||
{title: '退款成功金额',symbol: 'add', textColor: '#389e0d',content: (res.totalRefundAmount / 100).toFixed(2), num:res.succesCount },
|
||||
{type: 'line'},
|
||||
{title: '手续费退款金额',symbol: 'add',textColor: '#FF0000', content: (res.totalRefundFeeAmt / 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(recordId) {
|
||||
refundDetail.value.show(recordId)
|
||||
// req.getById(API_URL_REFUND_ORDER_LIST, recordId).then(res => {
|
||||
// vdata.detailData = res
|
||||
// console.log(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 handleChange (value) {
|
||||
for (let i = 0; i < vdata.agentList.length; i++) {
|
||||
if (value === vdata.agentList[i]['agentNo']) {
|
||||
vdata.searchData['isvNo'] = vdata.agentList[i]['isvNo']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req.list(API_URL_AGENT_LIST, { 'pageSize': -1, 'state': 1 }).then(res => { // 服务商下拉选择列表
|
||||
vdata.agentList = res.records
|
||||
})
|
||||
|
||||
let isReset = ref(0) // 下拉搜索框是否重置
|
||||
function onReset(){
|
||||
isReset.value++ // 下拉搜索框重置
|
||||
//重置搜索内容
|
||||
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>
|
||||
399
jeepay-ui-agent/src/views/order/settle/settleList.vue
Normal file
399
jeepay-ui-agent/src/views/order/settle/settleList.vue
Normal file
@@ -0,0 +1,399 @@
|
||||
<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 === 'agentName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.agentName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.agentName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</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: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'agentName', title: '服务商名称', dataIndex: 'agentName' },
|
||||
{ key: 'mchName', title: '商户名称', dataIndex: 'mchName' },
|
||||
{ key: 'ifName', title: '支付通道', dataIndex: 'ifName',},
|
||||
{ key: 'isvNo', title: '所属渠道', dataIndex: 'isvNo',},
|
||||
{ key: 'appid', title: '应用名称', dataIndex: 'appid' },
|
||||
{ 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: '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 as any, 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>
|
||||
475
jeepay-ui-agent/src/views/payTest/PayTest.vue
Normal file
475
jeepay-ui-agent/src/views/payTest/PayTest.vue
Normal file
@@ -0,0 +1,475 @@
|
||||
<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('UPACP_QR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'UPACP_QR')}"
|
||||
@click="changeCurrentWayCode('UPACP_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('UPACP_BAR') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'UPACP_BAR')}"
|
||||
@click="changeCurrentWayCode('UPACP_BAR', '')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/upacp_bar.svg" class="paydemo-type-img"><span class="color-change">银联条码</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="vdata.appPaywayList.indexOf('UPACP_WAP') >= 0"
|
||||
class="paydemo-type-h5"
|
||||
:class="{this:(vdata.currentWayCode === 'UPACP_WAP')}"
|
||||
@click="changeCurrentWayCode('UPACP_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('UPACP_PC') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'UPACP_PC')}"
|
||||
@click="changeCurrentWayCode('UPACP_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('UPACP_B2B') >= 0"
|
||||
class="paydemo-type color-change"
|
||||
:class="{this:(vdata.currentWayCode === 'UPACP_B2B')}"
|
||||
@click="changeCurrentWayCode('UPACP_B2B', 'payurl')"
|
||||
>
|
||||
<img src="@/assets/payTestImg/upacp_b2b.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('WX_JSAPI') >= 0 || vdata.appPaywayList.indexOf('ALI_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('UPACP_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('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>
|
||||
</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="payTestBarCode.value.visible = false" />
|
||||
|
||||
<!-- 条码弹框 -->
|
||||
<pay-test-bar-code ref="payTestBarCode" @barCodeValue="barCodeChange" @CodeAgainChange="testCodeChange" />
|
||||
</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 {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: '', // 条码的值
|
||||
paytestAmount: 0.01, // 支付金额,默认为0.01
|
||||
amountInput: false, // 自定金额输入框是否展示
|
||||
noConfigText: false, // 尚无任何配置分割线提示文字
|
||||
divisionMode: 0, // 订单分账模式
|
||||
orderTitle: '接口调试', // 订单标题
|
||||
divisionMode1:0.01 //默认支付金额绑定
|
||||
|
||||
})
|
||||
const payTestBarCode =ref()
|
||||
const payTestModal = 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()
|
||||
}
|
||||
|
||||
// 根据不同的appId展示不同的支付方式(在下拉框切换时和在携带参数进入页面时调用)
|
||||
function appPaywayListHandle (value) {
|
||||
if (!value) {
|
||||
vdata.appPaywayList = []
|
||||
return false
|
||||
}
|
||||
|
||||
$payTest(value).then(res => {
|
||||
vdata.appPaywayList = res
|
||||
if (res.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 === 'UPACP_BAR' || vdata.currentWayCode === 'AUTO_BAR')) {
|
||||
payTestBarCode.value.showModal()
|
||||
return
|
||||
}
|
||||
|
||||
$payTestOrder({
|
||||
// jsapi 默认使用聚合二维码支付
|
||||
wayCode: (vdata.currentWayCode === 'WX_JSAPI' || vdata.currentWayCode === 'ALI_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
|
||||
}).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
|
||||
}
|
||||
|
||||
// 条码弹窗点击x或者蒙版关闭
|
||||
function testCodeChange () {
|
||||
randomOrderNo() // 刷新订单号
|
||||
}
|
||||
|
||||
// handleCloseBarCode () {
|
||||
// this.$refs.payTestBarCode.visible = false
|
||||
// }
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="css">
|
||||
@import './payTest.css';
|
||||
</style>
|
||||
67
jeepay-ui-agent/src/views/payTest/PayTestBarCode.vue
Normal file
67
jeepay-ui-agent/src/views/payTest/PayTestBarCode.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-modal
|
||||
v-model:visible="vdata.visible"
|
||||
title="条码支付"
|
||||
:footer="null"
|
||||
:width="350"
|
||||
@cancel="handleChose"
|
||||
>
|
||||
<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})
|
||||
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 handleChose () {
|
||||
// 点击×关闭,或者点击蒙版关闭时,设置父组件barCodeAgain的值为false
|
||||
emit('CodeAgainChange')
|
||||
}
|
||||
function getVisible () {
|
||||
return vdata.visible
|
||||
}
|
||||
function processCatch () {
|
||||
vdata.loading = false
|
||||
}
|
||||
</script>
|
||||
159
jeepay-ui-agent/src/views/payTest/PayTestModal.vue
Normal file
159
jeepay-ui-agent/src/views/payTest/PayTestModal.vue
Normal file
@@ -0,0 +1,159 @@
|
||||
<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 === '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()
|
||||
console.log(1111111)
|
||||
Modal.error({
|
||||
title:'支付失败',
|
||||
content:`错误码:${apiRes.errCode}`
|
||||
})
|
||||
// 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)
|
||||
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}`
|
||||
})
|
||||
// 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-agent/src/views/payTest/payTest.css
Normal file
128
jeepay-ui-agent/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
|
||||
}
|
||||
405
jeepay-ui-agent/src/views/product/CheckList.vue
Normal file
405
jeepay-ui-agent/src/views/product/CheckList.vue
Normal file
@@ -0,0 +1,405 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="resetFunc">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker v-if="vdata.showDateTimeRage" ref="dateRangePicker" v-model:value="vdata.searchData['queryDateRange']" customDateRangeType="date" />
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['id']" :placeholder="'申请单号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['productOrPackageName']" :placeholder="'产品名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['contactsName']" :placeholder="'联系人'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.state" 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-option value="4">已取消</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="id"
|
||||
:expandedRowShow="true"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
@handleTableChange="handleChange"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<span v-if="column.tooltipTitle">
|
||||
{{ column.title }}
|
||||
<a-tooltip :title="column.tooltipTitle"><info-circle-outlined /></a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #expandedRowRender="{record}">
|
||||
<a-table :columns="vdata.innerColumns" :data-source="record.specialCertificationText" :pagination="false" style="margin-top: 5px">
|
||||
<template #certificationUrl="{ record }">
|
||||
<a-image :src="record.certificationUrl" style="width: 100px;height: 100px" />
|
||||
</template>
|
||||
<template #UserUrl="{ record }">
|
||||
<a-image v-if="record.UserUrl" :src="record.UserUrl" style="width: 100px;height: 100px" />
|
||||
<span v-else style="color:#ff4949" >未上传</span>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'costRule'">
|
||||
<div v-for="item in record.costRule" :key="item">
|
||||
{{item.versionName}}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'actualPrice'">
|
||||
<div v-for="item in record.costRule" :key="item">
|
||||
{{item.sellingPrice}}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<template v-if="column.key === 'state'">
|
||||
<a-badge status="warning" v-if="record.state == 1" text="审核中" />
|
||||
<!-- <a-badge status="processing" text="审核失败" />-->
|
||||
<!-- <a-badge status="processing" text="待签约" />-->
|
||||
<a-badge status="success" v-if="record.state == 3" text="审核通过" />
|
||||
<a-badge status="error" v-if="record.state == 2" text="审核失败" />
|
||||
<a-badge status="default" v-if="record.state == 4" text="已失效" />
|
||||
<!-- <a-tooltip :title="record.errMsg" v-if="record.state == 3">-->
|
||||
<!-- <info-circle-outlined style="color: #FFD080;margin-left: 10px"/>-->
|
||||
<!-- </a-tooltip>-->
|
||||
<a-tooltip v-if="record.state == 2" :title="record.stateDesc" >
|
||||
<info-circle-outlined style="color: #FFD080;margin-left: 10px"/>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key == 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<!-- <a-button type="link" >付款</a-button>-->
|
||||
<!-- <a-button type="link" >签约</a-button>-->
|
||||
<a-button v-if="record.state == 2" type="link" @click="edit(record)" >修改</a-button>
|
||||
<!-- <a-button type="link" >查看详情</a-button>-->
|
||||
<!-- <a-button type="link" >续约</a-button>-->
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<a-drawer
|
||||
v-if="vdata.visible"
|
||||
title="修改"
|
||||
placement="right"
|
||||
:closable="false"
|
||||
width="700px"
|
||||
v-model:visible="vdata.visible"
|
||||
:after-visible-change="afterVisibleChange"
|
||||
>
|
||||
<a-form :model="vdata.editForm" :label-col="{ span: 4 }">
|
||||
<a-form-item label="关联应用">
|
||||
<a-select v-model:value="vdata.orderFormState.appId" placeholder="选择应用" show-search
|
||||
:filter-option="false">
|
||||
<a-select-option v-for="(item) in vdata.filteredAppInfoList" :key="item.appId">{{ item.appName }}
|
||||
[{{ item.appId as any }}]
|
||||
<span v-if="vdata.productDetail.bindingAppList">{{
|
||||
vdata.productDetail.bindingAppList.indexOf(item.appId as any) === -1 ? '未关联' : '已关联' }}</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="订购信息">
|
||||
<a-col :span="24" style="margin:10px 0px;">
|
||||
<a-table :columns="vdata.columns" ref="tableRef" :data-source="vdata.costRule" :pagination="false" style="margin-left: -1px;"
|
||||
:row-selection="{selectedRowKeys:vdata.selectedRowKeys,type: 'radio', onChange: onSelectionChange }" rowKey="key" >
|
||||
<template #customTitle>
|
||||
<span>
|
||||
产品名称
|
||||
</span>
|
||||
</template>
|
||||
<template #versionName="{ text }">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<span>{{ text }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #validTime="{ text }">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<span>{{ text === -1 ? '长期' : text }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #sellingPrice="{ text }">
|
||||
<span>
|
||||
{{ text }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #lineationPrice="{ text }">
|
||||
<span>
|
||||
{{ text }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #countPrice="{ record }">
|
||||
<span style="color: #f00;">{{ record.sellingPrice == '免费' ? '免费' : record.count * record.sellingPrice
|
||||
+ '元' }}</span>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-col>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="备注(可选)" name="remark">
|
||||
<a-textarea v-model:value="vdata.orderFormState.remark" :rows="1" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="姓名" required>
|
||||
<a-input v-model:value="vdata.orderFormState.contactsName" />
|
||||
</a-form-item>
|
||||
<a-form-item label="手机号" required>
|
||||
<a-input v-model:value="vdata.orderFormState.contactsTel" maxlength="11"
|
||||
onkeyup="value=value.replace(/\D+/,'')" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="特殊资质">
|
||||
<a-col :span="24" style="margin:10px 0px;">
|
||||
<div style="display: flex;flex-wrap: wrap;">
|
||||
<div class="upload-box" v-for="(item,index) in vdata.specialCertificationText" :key="index" style="margin-right: 20px;text-align: center;">
|
||||
<div>{{item.certificationName}}</div>
|
||||
<JeepayUpload v-model:src="item.UserUrl" bizType="applyment" :imgSize="1" class="upload-box-img"/>
|
||||
<a class="color-box-span" @click="getImg(item)">查看示例</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-form-item>
|
||||
|
||||
<!-- <a-form-item label="特殊资质名称" required>-->
|
||||
<!-- <a-input v-model:value="vdata.orderFormState.specialCertificationText[0].certificationName" />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- <a-form-item label="特殊资质图片" required>-->
|
||||
<!-- <JeepayUpload :src="vdata.orderFormState.specialCertificationText[0].certificationUrl" @update:src="updateSrc" bizType="oem" />-->
|
||||
<!-- <span class="jeepay-tip-text">建议最小尺寸:220*220px,不超过2.9M</span>-->
|
||||
<!-- </a-form-item>-->
|
||||
|
||||
|
||||
</a-form>
|
||||
|
||||
<div
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
width: '100%',
|
||||
borderTop: '1px solid #e9e9e9',
|
||||
padding: '10px 16px',
|
||||
background: '#fff',
|
||||
textAlign: 'right',
|
||||
zIndex: 1,
|
||||
}"
|
||||
>
|
||||
<a-button style="margin-right: 8px" @click="vdata.visible=false">取消</a-button>
|
||||
<a-button type="primary" @click="onSubmit">确认修改</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
|
||||
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup >
|
||||
import {req, $exportExcel, exportExcelUrl, API_URL_PACKAGE_ORDER, API_URL_MCH_APP} from '@/api/manage'
|
||||
import {ref, reactive, onMounted, nextTick, getCurrentInstance} from 'vue'
|
||||
import fileDownload from 'js-file-download'
|
||||
import { useRoute } from 'vue-router'
|
||||
import dateUtil from '@/utils/dateUtil.js'
|
||||
import $infoBox from "@/utils/infoBox";
|
||||
const { $viewerApi } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoTable = ref()
|
||||
const dateRangePicker = ref()
|
||||
|
||||
let tableColumns = reactive([
|
||||
{ key: 'id', title: '申请单号', dataIndex: 'id', },
|
||||
{ key: 'productOrPackageName', title: '产品名称', dataIndex: 'productOrPackageName', },
|
||||
// { key: 'kafaizhe', title: '开发者', dataIndex: 'kafaizhe', },
|
||||
{ key: 'costRule', title: '订购信息', dataIndex: 'costRule', },
|
||||
// { key: 'specialCertificationText', title: '特殊资质', dataIndex: 'specialCertificationText', },
|
||||
{ key: 'actualPrice', title: '总价', dataIndex: 'originPrice', },
|
||||
{ key: 'state', title: '开通状态', dataIndex: 'state', },
|
||||
{ key: 'createdAt', title: '创建时间', dataIndex: 'createdAt', },
|
||||
{ key: 'op', title: '操作', dataIndex: 'op', },
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let count:any = ref([]) // 数据统计数组
|
||||
|
||||
const vdata: any = reactive({
|
||||
visible:false, //抽屉标识
|
||||
orderFormState:{} as any,
|
||||
showDateTimeRage: false,
|
||||
searchData: { queryDateRange: 'today',method : 'store', sortField: 'payAmount', sortOrder: 'descend' },
|
||||
columns: [
|
||||
{
|
||||
dataIndex: 'versionName',
|
||||
key: 'versionName',
|
||||
slots: { title: 'customTitle', customRender: 'versionName' },
|
||||
},
|
||||
{
|
||||
title: '周期',
|
||||
dataIndex: 'validTime',
|
||||
key: 'validTime',
|
||||
slots: {customRender: 'validTime' },
|
||||
},
|
||||
{
|
||||
title: '单价',
|
||||
key: 'sellingPrice',
|
||||
dataIndex: 'sellingPrice',
|
||||
},
|
||||
{
|
||||
title: '划线价',
|
||||
key: 'lineationPrice',
|
||||
dataIndex: 'lineationPrice',
|
||||
},
|
||||
],
|
||||
costRule:[],
|
||||
selectedRowKeys:[],
|
||||
filteredAppInfoList:[],
|
||||
mchAppList:[],
|
||||
productDetail: {
|
||||
bindingApp: 1,
|
||||
bindingAppList: [] as any
|
||||
} as any,
|
||||
appId:'' as any,
|
||||
specialCertificationText:[],
|
||||
certificationColumns:[
|
||||
{
|
||||
title: '名称',
|
||||
key: 'certificationName',
|
||||
dataIndex: 'certificationName',
|
||||
},
|
||||
{
|
||||
key: 'certificationUrl',
|
||||
dataIndex: 'certificationUrl',
|
||||
title: '图片',
|
||||
slots: { customRender: "certificationUrl" },
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
key: 'inputType',
|
||||
dataIndex: 'inputType',
|
||||
},
|
||||
],
|
||||
ZZselectedRowKeys:[],
|
||||
innerColumns:[
|
||||
{
|
||||
title: '特殊资质名称',
|
||||
key: 'certificationName',
|
||||
dataIndex: 'certificationName',
|
||||
},
|
||||
{
|
||||
title: '图片',
|
||||
key: 'UserUrl',
|
||||
dataIndex: 'UserUrl',
|
||||
slots: { customRender: "UserUrl" },
|
||||
}, {
|
||||
title: '示例图',
|
||||
key: 'certificationUrl',
|
||||
dataIndex: 'certificationUrl',
|
||||
slots: { customRender: "certificationUrl" },
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
function getMchApp() {
|
||||
req.list(API_URL_MCH_APP, { pageSize: -1, state: 1 }).then(res => {
|
||||
vdata.mchAppList = res.records
|
||||
vdata.filteredAppInfoList = res.records
|
||||
})
|
||||
|
||||
console.log(vdata.filteredAppInfoList)
|
||||
}
|
||||
|
||||
|
||||
function updateSrc(data){
|
||||
vdata.orderFormState.specialCertificationText[0].certificationUrl=data
|
||||
}
|
||||
|
||||
getMchApp()
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
searchFunc()
|
||||
vdata.showDateTimeRage = true
|
||||
})
|
||||
|
||||
function handleChange(sorter) {
|
||||
vdata.searchData['sortField'] = sorter.columnKey
|
||||
vdata.searchData['sortOrder'] = sorter.order
|
||||
}
|
||||
|
||||
function afterVisibleChange(){}
|
||||
|
||||
const onSelectionChange = (selectedRowKeys, selectedRows) => {
|
||||
vdata.selectedRowKeys = selectedRowKeys;
|
||||
vdata.orderFormState.costRule = selectedRows
|
||||
}
|
||||
|
||||
|
||||
let tableRef=ref()
|
||||
function edit(record){
|
||||
vdata.orderFormState=record
|
||||
vdata.selectedRowKeys[0]=record.costRule[0].key
|
||||
vdata.ZZselectedRowKeys[0]=record.specialCertificationText[0].key
|
||||
|
||||
if(record.packageOrProduct===0){
|
||||
req.list('/api/product/getProductById',{productId:record.productId}).then((res)=>{
|
||||
vdata.specialCertificationText=res.specialCertificationText
|
||||
vdata.costRule=res.productText
|
||||
})
|
||||
}else{
|
||||
req.list('/api/packageInfo/getPackageById',{packageId:record.packageId}).then((res)=>{
|
||||
vdata.specialCertificationText=res.specialCertificationText
|
||||
vdata.costRule=res.productText
|
||||
})
|
||||
}
|
||||
vdata.visible=true
|
||||
}
|
||||
function resetFunc() {
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { method : 'store', queryDateRange: 'today', sortField: 'payAmount', sortOrder: 'descend' }
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params: any) {
|
||||
// params.method = 'store'
|
||||
|
||||
if (!params.sortField) {
|
||||
// params.sortField = 'payAmount'
|
||||
// params.sortOrder = 'descend'
|
||||
}
|
||||
|
||||
return req.list(API_URL_PACKAGE_ORDER, params)
|
||||
}
|
||||
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function onSubmit(){
|
||||
vdata.orderFormState.specialCertificationText=vdata.specialCertificationText
|
||||
req.updateById('/api/packageInfo',vdata.orderFormState.id,vdata.orderFormState).then((res)=>{
|
||||
$infoBox.message.success('更新成功')
|
||||
searchFunc()
|
||||
vdata.visible=false
|
||||
})
|
||||
}
|
||||
|
||||
const onSelectioncertificationChange = (selectedRowKeys, selectedRows) => {
|
||||
vdata.ZZselectedRowKeys = selectedRowKeys;
|
||||
vdata.orderFormState.specialCertificationText = selectedRows
|
||||
}
|
||||
|
||||
function getImg(item){
|
||||
$viewerApi({images: [item.certificationUrl]})
|
||||
}
|
||||
</script>
|
||||
161
jeepay-ui-agent/src/views/product/MarketsList.vue
Normal file
161
jeepay-ui-agent/src/views/product/MarketsList.vue
Normal file
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<SybMarketsList configMode="agent" 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
|
||||
|
||||
const sybProductListRef = ref()
|
||||
const vdata = reactive({
|
||||
tableType: 'table',
|
||||
productList: [] as any, // 产品列表
|
||||
filteredProductList: [] as any, // 产品列表
|
||||
tab_index: -1,
|
||||
tabList: [] as any, // 分类列表
|
||||
filteredTabList: [] as any, // 分类列表
|
||||
state_index: -1,
|
||||
stateList: ['未开通', '审核中', '审核驳回', '已开通', '已关联应用'] as any, // 状态
|
||||
})
|
||||
|
||||
</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>
|
||||
161
jeepay-ui-agent/src/views/product/ProductList.vue
Normal file
161
jeepay-ui-agent/src/views/product/ProductList.vue
Normal file
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<SybProductList configMode="agent" 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
|
||||
|
||||
const sybProductListRef = ref()
|
||||
const vdata = reactive({
|
||||
tableType: 'table',
|
||||
productList: [] as any, // 产品列表
|
||||
filteredProductList: [] as any, // 产品列表
|
||||
tab_index: -1,
|
||||
tabList: [] as any, // 分类列表
|
||||
filteredTabList: [] as any, // 分类列表
|
||||
state_index: -1,
|
||||
stateList: ['未开通', '审核中', '审核驳回', '已开通', '已关联应用'] as any, // 状态
|
||||
})
|
||||
|
||||
</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>
|
||||
190
jeepay-ui-agent/src/views/qrcode/AddOrEdit.vue
Normal file
190
jeepay-ui-agent/src/views/qrcode/AddOrEdit.vue
Normal file
@@ -0,0 +1,190 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:mask-closable="false"
|
||||
:title="vdata.isAdd ? '新增二维码' : '修改二维码' "
|
||||
width="40%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form v-if="vdata.visible" ref="infoFormModel" :model="vdata.saveObject" :rules="saveRule">
|
||||
<a-row v-if="vdata.isAdd">
|
||||
<a-form-item label="批次号" name="batchId">
|
||||
<a-input-number v-model:value="vdata.saveObject.batchId" style="width:70%; margin-right: 20px;" />
|
||||
<a-button type="primary" size="small" @click="resetBatchId">今天</a-button>
|
||||
<p class="jeepay-tip-text">( 数字格式, 二维码编号的前缀, 建议采用: YYMMDD+次数表示 )</p>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
|
||||
<a-row v-if="vdata.isAdd">
|
||||
<a-form-item label="创建数量" name="addNum">
|
||||
<a-input-number v-model:value="vdata.saveObject.addNum" />
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
|
||||
<a-row v-if="vdata.isAdd">
|
||||
<a-form-item label="选择模板" name="qrcShellId">
|
||||
<a-select v-model:value="vdata.saveObject.qrcShellId" placeholder="选择模板" style="width: 200px;">
|
||||
<a-select-option value="">无</a-select-option>
|
||||
<template v-for="item in vdata.qrcShellList" :key="item.sid">
|
||||
<a-select-option :value="item.sid">{{ item.shellAlias }} <img :src="item.shellImgViewUrl" style="width: 20px"> </a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<a-form-item label="状态" name="qrcState">
|
||||
<a-radio-group v-model:value="vdata.saveObject.qrcState">
|
||||
<a-radio :value="1">启用</a-radio>
|
||||
<a-radio :value="0">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<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" /> 元
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<a-form-item v-if="vdata.isAdd" label="选择页面类型" name="entryPage">
|
||||
谨慎选择, 一经填写不可变更。
|
||||
<a-radio-group v-model:value="vdata.saveObject.entryPage">
|
||||
<a-radio :value="'default'">默认(未指定,取决于二维码是否绑定到微信侧)</a-radio>
|
||||
<a-radio :value="'h5'">固定H5页面</a-radio>
|
||||
<a-radio :value="'lite'">固定小程序页面</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<a-form-item label="支付宝支付方式(仅H5呈现时生效)" name="alipayWayCode">
|
||||
<a-radio-group v-model:value="vdata.saveObject.alipayWayCode">
|
||||
<a-radio :value="'ALI_JSAPI'">ALI_JSAPI</a-radio>
|
||||
<a-radio :value="'ALI_WAP'">ALI_WAP</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</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_MCH_QR_CODE_LIST, API_URL_QRC_SHELL_LIST, req} from '@/api/manage'
|
||||
import {defineProps, reactive, ref, getCurrentInstance} from 'vue'
|
||||
import ruleGenerator from '@/utils/ruleGenerator'
|
||||
import {formatDate} from '@/utils/util'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
// 定义组件参数
|
||||
const props = defineProps({
|
||||
callbackFunc: {type: Function, default: () => {}}
|
||||
})
|
||||
|
||||
// 定义ref对象
|
||||
const infoFormModel = ref()
|
||||
|
||||
const saveRule = {
|
||||
addNum: [ruleGenerator.requiredInput('创建数量', 'number'), { type: 'number', max: 500, min: 1, message: '数量请介于1-100之间' }],
|
||||
batchId:[ruleGenerator.requiredInput('批次号', 'number'), { type: 'number', min: 1, message: '请输入正确的批次号' }],
|
||||
appId: [{ required: true, message: '请选择应用', trigger: 'blur' }],
|
||||
fixedPayAmount: [{ required: true, message: '请输入固定金额', trigger: 'blur', type: 'number', min: 0.01 }],
|
||||
}
|
||||
|
||||
|
||||
const vdata : any = reactive({
|
||||
|
||||
btnLoading: false,
|
||||
isAdd: true, // 新增 or 修改页面标志
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
saveObject: {}, // 数据对象
|
||||
qrcShellList: []
|
||||
|
||||
})
|
||||
|
||||
|
||||
// 弹层打开事件
|
||||
function show(recordId, mchNo) {
|
||||
|
||||
// 查询全部模板信息
|
||||
req.list(API_URL_QRC_SHELL_LIST, {pageSize: -1}).then((res) => {
|
||||
vdata.qrcShellList = res.records
|
||||
})
|
||||
|
||||
|
||||
vdata.isAdd = !recordId
|
||||
vdata.saveObject = {addNum: 1, qrcState: 1, fixedFlag: 0, entryPage: 'default', alipayWayCode: 'ALI_JSAPI' } // 重置清空
|
||||
resetBatchId()
|
||||
|
||||
// 重置表单验证规则
|
||||
if (infoFormModel.value) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
// 修改弹层
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_MCH_QR_CODE_LIST, recordId).then(res => {
|
||||
vdata.saveObject = res
|
||||
vdata.saveObject.fixedPayAmount = vdata.saveObject.fixedPayAmount / 100
|
||||
vdata.visible = true
|
||||
})
|
||||
} else {
|
||||
vdata.visible = true // 立马展示弹层信息
|
||||
}
|
||||
}
|
||||
|
||||
// 点击 【保存】按钮的事件
|
||||
function handleOkFunc(){
|
||||
|
||||
vdata.btnLoading = true
|
||||
infoFormModel.value.validate().then(() => {
|
||||
|
||||
if(vdata.isAdd){
|
||||
|
||||
req.add(API_URL_MCH_QR_CODE_LIST, vdata.saveObject).then( res => reqSuccessFunc() ).finally(() => vdata.btnLoading = false)
|
||||
|
||||
}else{
|
||||
|
||||
req.updateById(API_URL_MCH_QR_CODE_LIST, vdata.recordId, vdata.saveObject).then( res => reqSuccessFunc() ).finally(() => vdata.btnLoading = false)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 接口请求成功的处理函数
|
||||
function reqSuccessFunc(){
|
||||
$infoBox.message.success( vdata.isAdd ? '新增成功' : '更新成功')
|
||||
vdata.visible = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}
|
||||
|
||||
|
||||
function onClose() {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
function resetBatchId(){
|
||||
vdata.saveObject.batchId = parseInt(formatDate('YYMMDD00'))
|
||||
}
|
||||
|
||||
|
||||
defineExpose({show})
|
||||
</script>
|
||||
128
jeepay-ui-agent/src/views/qrcode/Bind.vue
Normal file
128
jeepay-ui-agent/src/views/qrcode/Bind.vue
Normal file
@@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:mask-closable="false"
|
||||
title="绑定管理"
|
||||
width="40%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form ref="infoFormModel" :model="vdata.record" layout="horizontal" :rules="vdata.rules">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="绑定状态:">
|
||||
<a-space>
|
||||
{{ vdata.record.bindState == 1 ? '已绑定' : '未绑定' }}
|
||||
<a-button type="primary" @click="showSelectModal">{{ vdata.record.bindState == 1 ? '重新选择' : '选择商户信息' }}</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.showBindInfo" :span="24">
|
||||
<a-form-item label="用户号:">
|
||||
<span>{{ vdata.record.mchNo }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.showBindInfo" :span="24">
|
||||
<a-form-item label="商户应用:">
|
||||
<span>{{ vdata.record.appId }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.showBindInfo" :span="24">
|
||||
<a-form-item label="门店:">
|
||||
<span>{{ vdata.record.storeId }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
||||
<JeepayModelMchList ref="jeepayModelMchListRef" showType="MCH_APP_STORE" :mchNoAndName="true" @selectFinishFunc="selectFinishFunc" />
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" style="margin-right:8px" @click="onClose"><close-outlined />取消</a-button>
|
||||
<a-button type="primary" @click="handleOkFunc"><check-outlined />保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import {API_URL_MCH_QR_CODE_LIST, $bindQrc, req} from '@/api/manage'
|
||||
import {defineProps, reactive, ref, getCurrentInstance, inject} from 'vue'
|
||||
import ruleGenerator from '@/utils/ruleGenerator'
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
|
||||
// 定义组件参数
|
||||
const props = defineProps({
|
||||
callbackFunc: {type: Function, default: () => {}}
|
||||
})
|
||||
|
||||
const listPageSearchFunc : any = inject('listPageSearchFunc')
|
||||
|
||||
|
||||
// 定义ref对象
|
||||
const infoFormModel = ref()
|
||||
|
||||
const jeepayModelMchListRef = ref()
|
||||
|
||||
const vdata : any = reactive({
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
record: {}, //当前对象数据
|
||||
showBindInfo: false // 显示绑定信息
|
||||
|
||||
})
|
||||
|
||||
|
||||
// 弹层打开事件
|
||||
function show(recordId) {
|
||||
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_MCH_QR_CODE_LIST, recordId).then(res => {
|
||||
vdata.record = res
|
||||
if (vdata.record.bindState == 1) {
|
||||
vdata.showBindInfo = true
|
||||
} else {
|
||||
vdata.showBindInfo = false
|
||||
}
|
||||
vdata.visible = true
|
||||
})
|
||||
}
|
||||
|
||||
function showSelectModal(){
|
||||
jeepayModelMchListRef.value.show()
|
||||
}
|
||||
|
||||
function selectFinishFunc(selectArray){
|
||||
|
||||
if(!selectArray[0] || !selectArray[1] || !selectArray[2]){
|
||||
return $infoBox.message.error('选择信息不完整!')
|
||||
}
|
||||
|
||||
vdata.record.mchNo = selectArray[0]
|
||||
vdata.record.appId = selectArray[1]
|
||||
vdata.record.storeId = selectArray[2]
|
||||
vdata.showBindInfo = true
|
||||
|
||||
jeepayModelMchListRef.value.close()
|
||||
|
||||
}
|
||||
|
||||
// 点击 【保存】按钮的事件
|
||||
function handleOkFunc(){
|
||||
|
||||
$bindQrc(vdata.recordId, vdata.record).then((res) => {
|
||||
$infoBox.message.success('更新成功')
|
||||
onClose()
|
||||
listPageSearchFunc()
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
|
||||
defineExpose({show})
|
||||
</script>
|
||||
459
jeepay-ui-agent/src/views/qrcode/List.vue
Normal file
459
jeepay-ui-agent/src/views/qrcode/List.vue
Normal file
@@ -0,0 +1,459 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchConditionNum="4" :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>
|
||||
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.qrcType" 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>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData.entryPage" placeholder="页面类型">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="default">默认</a-select-option>
|
||||
<a-select-option value="h5">H5</a-select-option>
|
||||
<a-select-option value="lite">小程序</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchUserName']" :placeholder="'用户号/名称/手机号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :placeholder="'服务商号'" />
|
||||
<!-- <JeepaySearchInfoInput v-model:value="vdata.searchData['mchNo']" placeholder="用户号" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />-->
|
||||
<jeepay-text-up v-model:value="vdata.searchData.qrcAlias" placeholder="二维码名称/编号" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchApplyId']" :placeholder="'商户名称/商户号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.storeId" 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.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"
|
||||
:initData="false"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
:tableExportFunc="$access('ENT_DEVICE_QRC_EXPORT') ? tableExportFunc : null"
|
||||
:rowSelection="{ type: 'checkbox', onChange: infoTableSelectChangeFunc }"
|
||||
rowKey="qrcId"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="addOrEditFunc()"><PlusOutlined /> 申请新码</a-button>
|
||||
|
||||
<!-- <a-button @click="batchChecked(true)">全选</a-button>
|
||||
<a-button @click="batchChecked(false)">反选</a-button> -->
|
||||
<a-button v-if="$access('ENT_DEVICE_QRC_ALLOT')" type="primary" @click="allotBatchFunc"><partition-outlined />勾选划拨/收回</a-button>
|
||||
<!-- <a-button v-if="$access('ENT_DEVICE_QRC_ALLOT')" type="primary" @click="allotByBatchIdFunc">批次划拨</a-button> -->
|
||||
<a-button v-if="$access('ENT_DEVICE_QRC_EXPORT')" @click="tableExportByBatchSelectFunc">导出选择项</a-button>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'qrcId'">
|
||||
{{ record.qrcId }}
|
||||
<QrcodeOutlined style="font-size: 16px" @click="showQrImgFunc(record.qrcId)" />
|
||||
</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 === 'mchServiceName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.mchServiceName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchServiceName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'qrcType'">
|
||||
<a-tag v-if="record.qrcType == 0" color="blue">电子码牌</a-tag>
|
||||
<a-tag v-if="record.qrcType == 1" color="orange">实体码牌</a-tag>
|
||||
<a-tag v-if="record.qrcType == 2" color="green">实体立牌</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'bindState'">
|
||||
<JeepayTableColState :state="record.bindState" :showSwitchType="$access('ENT_MCH_QR_CODE_EDIT')" :onChange="(state) => { return updateState(record.qrcId, state)}" />
|
||||
</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 === 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_DEVICE_QRC_VIEW')" type="link" @click="showQrImgFunc(record.qrcId)">详情</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_QRC_EDIT') && record.isSelf" type="link" @click="showBind(record.qrcId)">绑定</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_QRC_RELIEVE') && record.bindState == 1 && record.isSelf" type="link" @click="unBindFunc(record.qrcId)">解绑</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_QRC_ALLOT')" type="link" @click="allotFunc(record)">划拨/收回</a-button>
|
||||
<a-button v-if="$access('ENT_DEVICE_QRC_EDIT') && record.bindState == 1" type="link" @click="getBindDeviceFunc(record.qrcId)">受支持设备</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
|
||||
<!-- <AddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" /> -->
|
||||
|
||||
<Bind ref="bindRef" :callbackFunc="searchFunc" />
|
||||
|
||||
<JeepayQrcDeviceList ref="jeepayQrcDeviceListRef" sysType="AGENT" />
|
||||
|
||||
<JeepayModelAgentList ref="jeepayModelAgentList" showType="AGENT" @selectFinishFunc="searchAgentFinishFunc" />
|
||||
|
||||
<!-- 批次号划拨弹窗 -->
|
||||
<a-modal v-model:visible="vdata.allotByBatchIdVisible" title="按批次号划拨" @ok="allotOk">
|
||||
<a-form ref="allotFormModel" :model="vdata.allotObject" layout="vertical" :rules="vdata.allotRules">
|
||||
<a-form-item label="批次号:" name="batchId">
|
||||
<a-input v-model:value="vdata.allotObject.batchId" placeholder="请输入批次号" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<a-modal v-model:visible="vdata.exportVisible" title="导出选项" :width="500" @ok="tableExportDowonloadFunc">
|
||||
<a-radio-group v-model:value="vdata.exportModel">
|
||||
<a-radio value="infoAndUrl" style="margin-bottom: 10px;">Excel: 二维码信息并且包含二维码解析URL</a-radio><br>
|
||||
<a-radio value="templateImg" style="margin-bottom: 10px;">压缩包: 模板图片(如果有)</a-radio> <br>
|
||||
<a-radio value="qrcode" style="margin-bottom: 10px;">压缩包: 二维码图片(不含编号)</a-radio><br>
|
||||
<a-radio value="qrcodeAndQrcId" style="margin-bottom: 10px;">压缩包: 二维码图片(含编号) </a-radio><br>
|
||||
</a-radio-group>
|
||||
</a-modal>
|
||||
</a-card>
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Bind from './Bind.vue'
|
||||
import {API_URL_MCH_QR_CODE_LIST, req, reqLoad, $qrcShellViewByQrc, $exportExcel, exportExcelUrl, $unbindQrc, $allotQrc } from '@/api/manage'
|
||||
import { ref, reactive, provide, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import fileDownload from 'js-file-download'
|
||||
import {getCurrentDatetime} from '@/utils/util'
|
||||
|
||||
// 导入全局函数
|
||||
const { $infoBox, $access, $viewerApi } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
// infoTable组件
|
||||
const infoTable = ref()
|
||||
|
||||
const bindRef = ref()
|
||||
|
||||
const jeepayQrcDeviceListRef = ref()
|
||||
|
||||
const allotFormModel = ref()
|
||||
|
||||
const jeepayModelAgentList = ref()
|
||||
|
||||
const dateRangePicker = ref()
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = ref([
|
||||
// { key: 'qrcId', title: '二维码', },
|
||||
// { key: 'agentNo', title: '服务商', dataIndex: 'agentNo', agentEntCol: true },
|
||||
// { key: 'mchNo', title: '绑定商户信息' },
|
||||
// { key: 'entryPage', title: '扫码页面', customRender: ({ record }) => {return record.entryPage == 'default' ? '默认' : record.entryPage == 'h5' ? 'H5' : '小程序'} , },
|
||||
// { key: 'qrcState', title: '状态', },
|
||||
// { key: 'fixedFlag', title: '固定金额', },
|
||||
// { key: 'createdAt', dataIndex: 'createdAt', title: '创建日期', },
|
||||
// { key: 'op', title: '操作', fixed: 'right', align: 'center',}
|
||||
|
||||
{ key: 'qrcType', title: '码牌类型', },
|
||||
{ key: 'entryPage', title: '页面类型', customRender: ({ record }) => {return record.entryPage == 'default' ? '默认' : record.entryPage == 'h5' ? 'H5' : '小程序'} ,},
|
||||
{ key: 'qrcId', title: '二维码编号', },
|
||||
{ key: 'qrcAlias', dataIndex: 'qrcAlias', title: '二维码名称'},
|
||||
{ key: 'mchUserName', title: '用户名称', dataIndex: 'mchUserName'},
|
||||
{ key: 'mchServiceName', title: '服务商名称', dataIndex: 'mchServiceName' },
|
||||
{ title: "商户名称", key: "mchApplyName", dataIndex: "mchApplyName" },
|
||||
{ key: 'storeId', title: '门店名称', dataIndex: 'storeId', },
|
||||
{ key: 'bindAppIdName', dataIndex: 'bindAppIdName', title: '所属应用', },
|
||||
// { key: 'qrcState', title: '使用状态(无字段)', },
|
||||
{ key: 'bindState', title: '使用状态', },
|
||||
{ key: 'fixedFlag', title: '固定金额', },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期', },
|
||||
{ key: 'op', title: '操作', fixed: 'right', align: 'center', }
|
||||
])
|
||||
|
||||
|
||||
const vdata : any = reactive({
|
||||
searchData: {},
|
||||
exportVisible: false, // 显示导出弹层
|
||||
exportModel: '', //二维码导出模式
|
||||
|
||||
listRecords: [], //当前列表页的缓存数据
|
||||
|
||||
listExportIds: null, //列表的批量导出选择项目
|
||||
|
||||
allotByBatchIdVisible: false, // 批次划拨设备弹窗
|
||||
allotObject: {
|
||||
agentNo: null, // 划拨服务商号
|
||||
allotType: null, // 划拨类型:select-勾选划拨 batch-批次划拨
|
||||
batchId: null, // 批次号,划拨类型为 batch-批次划拨 时必填
|
||||
allotIds: [] as any, // 要划拨的码ID,划拨类型为 select-勾选划拨 时必填
|
||||
} as any, // 划拨设备对象
|
||||
allotRules: {
|
||||
batchId: [{ required: true, message: '请输入批次号', trigger: 'blur' }]
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
vdata.searchData['mchNo'] = useRoute().query.mchNo
|
||||
vdata.searchData['storeId'] = useRoute().query.storeId
|
||||
vdata.searchData['mchApplyId'] = useRoute().query.mchApplyId
|
||||
searchFunc()
|
||||
})
|
||||
|
||||
|
||||
// 向所有子组件注入刷新事件
|
||||
provide('listPageSearchFunc', searchFunc)
|
||||
|
||||
function searchFunc () {
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc (params) {
|
||||
return req.list(API_URL_MCH_QR_CODE_LIST, params).then((res) => {
|
||||
vdata.listRecords = (res && res.records) || []
|
||||
return Promise.resolve(res)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 新增 or 修改函数
|
||||
function addOrEditFunc(){
|
||||
$infoBox.message.success('请联系运营平台申请')
|
||||
}
|
||||
|
||||
// 显示二维码图片
|
||||
function showQrImgFunc(recordId){
|
||||
$qrcShellViewByQrc(recordId).then((res) => {
|
||||
$viewerApi({images: [res]})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 显示绑定管理
|
||||
function showBind(recordId){
|
||||
bindRef.value.show(recordId)
|
||||
}
|
||||
|
||||
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
|
||||
const title = state === 1 ? '确认[启用]?' : '确认[停用]?'
|
||||
return $infoBox.confirmDangerPromise(title, '').then(() => {
|
||||
return reqLoad.updateById(API_URL_MCH_QR_CODE_LIST, recordId, { qrcState: state })
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 解绑设备
|
||||
function unBindFunc(recordId) {
|
||||
const title = '确认解绑?'
|
||||
const content = '解绑后商户将无法使用该码牌!'
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return $unbindQrc(recordId).then(res => {
|
||||
infoTable.value.refTable(true)
|
||||
$infoBox.message.success('解绑成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 受支持的设备
|
||||
function getBindDeviceFunc(recordId) {
|
||||
jeepayQrcDeviceListRef.value.show(recordId)
|
||||
}
|
||||
|
||||
|
||||
// function batchChecked(checked){
|
||||
// vdata.listRecords.forEach(element => {
|
||||
// element.checked = checked
|
||||
// })
|
||||
// }
|
||||
|
||||
function infoTableSelectChangeFunc(selectedRowKeys){
|
||||
|
||||
// 获取真实的qrcId
|
||||
let qrcIdList : any = []
|
||||
selectedRowKeys.forEach(el => qrcIdList.push(el) )
|
||||
|
||||
// 遍历 vdata.listRecords 如果selectedRowKeys数组中存在对应的id,则将其checked改为true,反之false
|
||||
vdata.listRecords.forEach(element => {
|
||||
qrcIdList.includes(element.qrcId) ? element.checked = true : element.checked = false
|
||||
})
|
||||
}
|
||||
|
||||
// 第一次点击导出的事件( 筛选条件的导出 )
|
||||
function tableExportFunc(){
|
||||
vdata.exportVisible = true
|
||||
vdata.exportModel = 'infoAndUrl' //默认excel
|
||||
|
||||
vdata.listExportIds = null //批量选择清空
|
||||
}
|
||||
|
||||
|
||||
// 第一次点击导出的事件( 批量选择的导出 )
|
||||
function tableExportByBatchSelectFunc(){
|
||||
|
||||
vdata.listExportIds = []
|
||||
vdata.listRecords.forEach(element => {
|
||||
if(element.checked){
|
||||
vdata.listExportIds.push(element.qrcId)
|
||||
}
|
||||
})
|
||||
|
||||
if(vdata.listExportIds.length <= 0){
|
||||
return $infoBox.message.error('请选择数据')
|
||||
}
|
||||
|
||||
vdata.exportVisible = true
|
||||
vdata.exportModel = 'infoAndUrl' //默认excel
|
||||
}
|
||||
|
||||
|
||||
// 弹层点击确认按钮的事件
|
||||
function tableExportDowonloadFunc(){
|
||||
|
||||
vdata.exportVisible = false
|
||||
|
||||
let queryCond :any = { 'exportModel': vdata.exportModel, 'pageSize': -1 } //搜索条件
|
||||
|
||||
if(typeof vdata.listExportIds == 'object' && vdata.listExportIds != null){
|
||||
queryCond.idsStr = ''
|
||||
vdata.listExportIds.forEach(r => {
|
||||
queryCond.idsStr += (r + '_')
|
||||
})
|
||||
queryCond.idsStr = queryCond.idsStr.substring(0, queryCond.idsStr.length - 1)
|
||||
|
||||
}else{
|
||||
queryCond = Object.assign(queryCond, vdata.searchData)
|
||||
}
|
||||
|
||||
return $exportExcel(exportExcelUrl.qrCodes, queryCond).then(res => {
|
||||
|
||||
if(vdata.exportModel == 'infoAndUrl'){
|
||||
fileDownload(res.data, '码牌信息导出_'+ getCurrentDatetime() +'.xlsx')
|
||||
}else{
|
||||
fileDownload(res.data, '码牌图片导出_'+ getCurrentDatetime() +'.zip')
|
||||
}
|
||||
|
||||
}).catch ((error) =>{console.log(error)} )
|
||||
|
||||
}
|
||||
|
||||
// 按批次号划拨
|
||||
function allotByBatchIdFunc() {
|
||||
vdata.allotObject.allotType = 'batch'
|
||||
vdata.allotObject.batchId = ''
|
||||
vdata.allotByBatchIdVisible = true
|
||||
}
|
||||
|
||||
// 按批次号划拨,批次号输入完成
|
||||
function allotOk() {
|
||||
allotFormModel.value.validate().then((valid: any) =>{
|
||||
vdata.allotByBatchIdVisible = false
|
||||
jeepayModelAgentList.value.show()
|
||||
})
|
||||
}
|
||||
|
||||
// 勾选划拨设备
|
||||
function allotBatchFunc() {
|
||||
|
||||
vdata.listExportIds = []
|
||||
vdata.listRecords.forEach(element => {
|
||||
if(element.checked){
|
||||
vdata.listExportIds.push(element.qrcId)
|
||||
}
|
||||
})
|
||||
|
||||
if(vdata.listExportIds.length <= 0){
|
||||
return $infoBox.message.error('请选择数据')
|
||||
}
|
||||
|
||||
vdata.allotObject.allotType = 'select'
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
|
||||
// 划拨单个设备
|
||||
function allotFunc(record) {
|
||||
vdata.allotObject.allotType = 'select'
|
||||
vdata.listExportIds = []
|
||||
vdata.listExportIds.push(record.qrcId)
|
||||
|
||||
jeepayModelAgentList.value.show()
|
||||
}
|
||||
|
||||
// 划拨/收回选择完成
|
||||
function searchAgentFinishFunc(selectObject) {
|
||||
|
||||
vdata.allotObject.agentNo = selectObject[0]
|
||||
vdata.allotObject.allotOrRecover = selectObject[1]
|
||||
|
||||
if (vdata.allotObject.allotOrRecover == 'allot' && !vdata.allotObject.agentNo) {
|
||||
$infoBox.message.error('请选择服务商')
|
||||
return
|
||||
}
|
||||
|
||||
if (vdata.listExportIds.length > 0) {
|
||||
vdata.allotObject.allotIds = vdata.listExportIds.join(',')
|
||||
}
|
||||
|
||||
$allotQrc(vdata.allotObject).then(res => {
|
||||
vdata.listExportIds = [] // 清空多选
|
||||
$infoBox.message.success('保存成功')
|
||||
jeepayModelAgentList.value.close()
|
||||
searchFunc()
|
||||
})
|
||||
}
|
||||
|
||||
function onReset(){
|
||||
//重置搜索内容
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { queryDateRange: '' }
|
||||
}
|
||||
</script>
|
||||
651
jeepay-ui-agent/src/views/quickCollection/QuickCollection.vue
Normal file
651
jeepay-ui-agent/src/views/quickCollection/QuickCollection.vue
Normal file
@@ -0,0 +1,651 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="vdata.visible"
|
||||
title="快捷收银"
|
||||
:footer="null"
|
||||
:maskClosable="false"
|
||||
@cancel="clear"
|
||||
>
|
||||
<div class="select-id">
|
||||
<!-- <div v-if="$access('ENT_MCH_APP_LIST')">-->
|
||||
<!-- <p>应用:</p>-->
|
||||
<!-- <a-select v-model:value="vdata.appId" style="margin-right: 10px">-->
|
||||
<!-- <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>-->
|
||||
<!-- </div>-->
|
||||
<div style="display: ruby">
|
||||
<div>门店:</div>
|
||||
<div style="min-width: 300px !important;">
|
||||
<a-select v-model:value="vdata.storeId" dropdownMatchSelectWidth="true" style="width: 90% !important;">
|
||||
<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>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="mode">选择收款方式</p>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<div class="boxs">
|
||||
<div
|
||||
v-for="(item, index) in vdata.imgList"
|
||||
:key="item.key"
|
||||
class="mode-box"
|
||||
:style="{
|
||||
borderColor: vdata.imgIndex == index ? item.color : '#e6e6e6'
|
||||
}"
|
||||
@click="chooseType(index, item.key)"
|
||||
>
|
||||
<img :src="item.imgSrc" alt="">
|
||||
<span>{{ item.text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 金额 备注 -->
|
||||
<div class="input">
|
||||
<span>订单金额:</span>
|
||||
<a-input v-model:value="vdata.params.amount" style="width: 100%" />
|
||||
|
||||
<span>备注:</span>
|
||||
<a-input v-model:value="vdata.params.remark" />
|
||||
</div>
|
||||
|
||||
<!-- 软键盘 -->
|
||||
<div class="keyboard display" style="margin-top: 40px">
|
||||
<div class="keyboard-num noSelect">
|
||||
<div
|
||||
v-for="(item, index) in vdata.numList"
|
||||
:key="index"
|
||||
@click="keyNumber(item)"
|
||||
>
|
||||
{{ item }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="operate">
|
||||
<div class="noSelect" @click="delet">
|
||||
<img src="/src/assets/svg/shcnhu.svg" alt="">
|
||||
</div>
|
||||
<div
|
||||
class="reallybutton noSelect"
|
||||
style="position: relative"
|
||||
@click="openSmallVisible"
|
||||
>
|
||||
确认支付
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 小弹窗 -->
|
||||
<a-modal
|
||||
v-model:visible="vdata.SmallVisible"
|
||||
:footer="null"
|
||||
wrap-class-name="full-modal"
|
||||
width="330px"
|
||||
:maskClosable="false"
|
||||
@cancel="clearSmallModal"
|
||||
>
|
||||
<div class="modal-body">
|
||||
<!-- 扫条码与刷脸 -->
|
||||
<div v-if="[1, 2].includes(vdata.imgIndex)" class="code">
|
||||
<img
|
||||
:src="
|
||||
vdata.imgIndex === 1
|
||||
? vdata.imgList[1].imgSrc
|
||||
: vdata.imgList[2].imgSrc
|
||||
"
|
||||
alt=""
|
||||
>
|
||||
<div
|
||||
style="
|
||||
margin: 30px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
"
|
||||
>
|
||||
<a-input
|
||||
ref="barCodeInput"
|
||||
v-model:value="vdata.authCode"
|
||||
style="margin-bottom: 10px"
|
||||
@keyup.enter="handleOk"
|
||||
/>
|
||||
<a-button
|
||||
type="primary"
|
||||
:loading="vdata.loading"
|
||||
@click="handleOk"
|
||||
>
|
||||
确认支付
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 用户扫聚合码 -->
|
||||
<div v-if="vdata.imgIndex === 0">
|
||||
<img
|
||||
v-if="vdata.apiRes.payData"
|
||||
:src="vdata.apiRes.payData"
|
||||
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">
|
||||
{{ modeText(vdata.imgIndex) }}
|
||||
</p>
|
||||
<a-button
|
||||
type="primary"
|
||||
class="cancel"
|
||||
size="large"
|
||||
block
|
||||
@click="vdata.SmallVisible = false"
|
||||
>
|
||||
取消收款
|
||||
</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, getCurrentInstance, nextTick } from 'vue'
|
||||
import {
|
||||
API_URL_MCH_APP,
|
||||
API_URL_MCH_STORE_LIST,
|
||||
req,
|
||||
$payTestOrder
|
||||
} from '@/api/manage' // 接口
|
||||
import { $getWebSocketPrefix } from '@/api/manage'
|
||||
import ReconnectingWebSocket from 'reconnectingwebsocket'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
// @ts-ignore
|
||||
import smSvg from '@/assets/svg/sm.svg'
|
||||
// @ts-ignore
|
||||
import fkSvg from '@/assets/svg/fk.svg'
|
||||
// @ts-ignore
|
||||
import slSvg from '@/assets/svg/sl.svg'
|
||||
|
||||
// 获取全局函数
|
||||
const { $infoBox, $access } =
|
||||
getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const vdata: any = reactive({
|
||||
currentWayCode: 'QR_CASHIER', // 支付方式
|
||||
mchAppList: [] as any, // app列表
|
||||
appId: '', // 已选择的appId
|
||||
mchStoreList: [] as any, // 门店列表
|
||||
storeId: '', // 已选择的门店ID
|
||||
loading: false, // 确认收款按钮loading
|
||||
visible: false, // 弹出框标识
|
||||
SmallVisible: false, // 小弹窗标识
|
||||
orderTitle: '快捷收款', // 用于下单传参,写死即可
|
||||
payOrderWebSocket: null as any, // 支付订单webSocket对象
|
||||
numList: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '0', '00'], //键盘数字集合
|
||||
imgIndex: 0, // 付款方式框高亮索引
|
||||
authCode: '', // 条码值
|
||||
apiRes: '', // 支付信息
|
||||
params: {
|
||||
// 传参对象
|
||||
amount: '',
|
||||
remark: ''
|
||||
},
|
||||
imgList: [
|
||||
// 支付方式列表
|
||||
{
|
||||
imgSrc: smSvg,
|
||||
text: '付款主扫',
|
||||
color: '#000000',
|
||||
key: 'QR_CASHIER'
|
||||
},
|
||||
{
|
||||
imgSrc: fkSvg,
|
||||
text: '付款被扫',
|
||||
color: '#17c2b2',
|
||||
key: 'AUTO_BAR'
|
||||
},
|
||||
{
|
||||
imgSrc: slSvg,
|
||||
text: '刷脸支付',
|
||||
color: '#4784ff ',
|
||||
key: 'AUTO_BAR'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 获取条码输入框
|
||||
const barCodeInput = ref()
|
||||
|
||||
// 关闭外层弹窗,则清空输入框
|
||||
const clear = () => (vdata.params.amount = vdata.params.remark = '') // 清空输入框
|
||||
// 关闭内层
|
||||
const clearSmallModal = () => {
|
||||
vdata.authCode = '' // 清空输入框
|
||||
randomOrderNo() // 刷新订单号
|
||||
}
|
||||
|
||||
// 同时关闭内外层弹窗并清空输入框
|
||||
const closeAllModal = () => {
|
||||
vdata.visible = false // 关闭大小弹窗
|
||||
vdata.SmallVisible = false // 关闭大小弹窗
|
||||
clear()
|
||||
clearSmallModal()
|
||||
}
|
||||
|
||||
// 小弹窗提示文字
|
||||
const modeText = (index) => {
|
||||
let text
|
||||
switch (index) {
|
||||
case 0:
|
||||
text = '请扫描付款码收款'
|
||||
break
|
||||
case 1:
|
||||
text = '请扫描二维码收款'
|
||||
break
|
||||
default:
|
||||
text = '请对准摄像头刷脸支付'
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
// 选择付款方式
|
||||
const chooseType = (index, key) => {
|
||||
vdata.imgIndex = index
|
||||
vdata.currentWayCode = key
|
||||
randomOrderNo() // 刷新单号
|
||||
}
|
||||
|
||||
// 软键盘点击事件
|
||||
const keyNumber = (item) => {
|
||||
let currentVal = vdata.params.amount
|
||||
currentVal == '0' && item != '.' ? (currentVal = item) : (currentVal += item)
|
||||
if (!/^(([1-9]{1}\d{0,5})|(0{1}))(\.\d{0,2})?$/.test(currentVal)) return
|
||||
vdata.params.amount = currentVal
|
||||
}
|
||||
|
||||
// 删除按钮
|
||||
const delet = () => {
|
||||
let currentVal = vdata.params.amount
|
||||
!currentVal || currentVal.length <= 1
|
||||
? (vdata.params.amount = '')
|
||||
: (vdata.params.amount = vdata.params.amount.substring(
|
||||
0,
|
||||
currentVal.length - 1
|
||||
))
|
||||
}
|
||||
|
||||
// 订单号
|
||||
const randomOrderNo = () => {
|
||||
vdata.mchOrderNo =
|
||||
'M' +
|
||||
new Date().getTime() +
|
||||
Math.floor(Math.random() * (9999 - 1000) + 1000)
|
||||
}
|
||||
|
||||
// 开启小弹窗 包含前置校验
|
||||
const openSmallVisible = () => {
|
||||
// 判断支付金额是否为0
|
||||
if (!vdata.params.amount || vdata.params.amount == 0.0)
|
||||
return $infoBox.message.error('请输入支付金额')
|
||||
|
||||
// 判断是否选择应用
|
||||
if (vdata.appId === '' && $access('ENT_MCH_APP_LIST'))
|
||||
return $infoBox.message.error('请选择一个应用')
|
||||
|
||||
// 判断是否选择门店
|
||||
if (vdata.storeId === '') return $infoBox.message.error('请选择一个门店')
|
||||
|
||||
// 验证金额是否合法
|
||||
if (!/^(([1-9]{1}\d{0,5})|(0{1}))(\.\d{0,2})?$/.test(vdata.params.amount))
|
||||
return $infoBox.message.error('请输入合法金额')
|
||||
|
||||
vdata.SmallVisible = true // 开启弹窗
|
||||
|
||||
nextTick(() => {
|
||||
// 弹窗展示后,输入框默认展示焦点
|
||||
if (barCodeInput.value) barCodeInput.value.focus()
|
||||
})
|
||||
|
||||
// 如果是聚合码支付 则直接吊起下单
|
||||
if (vdata.currentWayCode == 'QR_CASHIER') reallyPay()
|
||||
}
|
||||
|
||||
// 确认收款 下单
|
||||
const reallyPay = () => {
|
||||
vdata.loading = true
|
||||
$payTestOrder({
|
||||
wayCode: vdata.currentWayCode, // 支付方式
|
||||
amount: vdata.params.amount, // 支付金额
|
||||
appId: vdata.appId, // appId
|
||||
storeId: vdata.storeId, // storeId
|
||||
mchOrderNo: vdata.mchOrderNo, // 订单编号
|
||||
payDataType: 'codeImgUrl', // 支付参数(二维码,条码)快捷收银都是走聚合支付
|
||||
authCode: vdata.authCode, // 条码值
|
||||
divisionMode: 0, // 分账模式 0代表不分账 快捷收银写死即可
|
||||
orderTitle: vdata.orderTitle // 订单标题
|
||||
})
|
||||
.then((res) => {
|
||||
vdata.apiRes = res
|
||||
if (vdata.payOrderWebSocket) vdata.payOrderWebSocket.close() // 关闭上一个webSocket监听
|
||||
|
||||
// 此处判断接口中返回的orderState,值为0,1 代表支付中,直接放行无需处理,2 成功 3 失败
|
||||
if (res.orderState === 2 || res.orderState === 3) {
|
||||
if (res.orderState === 2) {
|
||||
handleClose()
|
||||
const succModal = Modal.success({
|
||||
title: '支付成功',
|
||||
content: '2秒后自动关闭'
|
||||
})
|
||||
closeAllModal()
|
||||
setTimeout(() => {
|
||||
succModal.destroy()
|
||||
}, 2000)
|
||||
} else if (res.orderState === 3) {
|
||||
handleClose()
|
||||
Modal.error({
|
||||
title: '支付失败',
|
||||
content: `错误码:${res.errCode}`
|
||||
})
|
||||
}
|
||||
vdata.loading = false
|
||||
return
|
||||
}
|
||||
|
||||
// 监听响应结果
|
||||
// @ts-ignore
|
||||
vdata.payOrderWebSocket = new ReconnectingWebSocket(
|
||||
$getWebSocketPrefix() +
|
||||
'/api/anon/ws/payOrder/' +
|
||||
res.payOrderId +
|
||||
'/' +
|
||||
new Date().getTime()
|
||||
)
|
||||
vdata.payOrderWebSocket.onopen = () => {}
|
||||
vdata.payOrderWebSocket.onmessage = (msgObject) => {
|
||||
console.log(msgObject,'msgObjectmsgObject')
|
||||
const resMsgObject = JSON.parse(msgObject.data)
|
||||
if (resMsgObject.state === 2) {
|
||||
handleClose()
|
||||
const succModal = Modal.success({
|
||||
title: '支付成功',
|
||||
content: '2秒后自动关闭'
|
||||
})
|
||||
closeAllModal()
|
||||
setTimeout(() => {
|
||||
succModal.destroy()
|
||||
}, 2000)
|
||||
} else {
|
||||
handleClose()
|
||||
Modal.error({
|
||||
title: '支付失败',
|
||||
content: `错误码:${res.errCode}`
|
||||
})
|
||||
}
|
||||
}
|
||||
vdata.loading = false
|
||||
randomOrderNo() // 刷新订单号
|
||||
})
|
||||
.catch(() => {
|
||||
vdata.loading = false
|
||||
randomOrderNo() // 刷新订单号
|
||||
})
|
||||
}
|
||||
|
||||
// 打开弹窗时请求应用列表与门店列表
|
||||
const getList = () => {
|
||||
// 是否有应用的权限
|
||||
if ($access('ENT_MCH_APP_LIST')) {
|
||||
// 请求接口,获取所有的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
|
||||
}
|
||||
})
|
||||
} else {
|
||||
vdata.appId = '' // 没有权限就传空
|
||||
}
|
||||
|
||||
// 请求接口,获取商户所有门店,只有次数进行pageSize=-1传参
|
||||
req.list(API_URL_MCH_STORE_LIST, { pageSize: -1 }).then((res) => {
|
||||
vdata.mchStoreList = res.records
|
||||
if (vdata.mchStoreList.length > 0) {
|
||||
vdata.storeId = vdata.mchStoreList[0].storeId // 赋予默认值
|
||||
}
|
||||
})
|
||||
|
||||
// 在进入页面时刷新订单号
|
||||
randomOrderNo()
|
||||
}
|
||||
|
||||
// 扫条码与刷脸确认按钮, 输入框输入内容后自动调用
|
||||
function handleOk() {
|
||||
if (!vdata.authCode) return
|
||||
reallyPay() // 调起下单接口
|
||||
}
|
||||
|
||||
// 清除WebSocket
|
||||
function handleClose() {
|
||||
if (vdata.payOrderWebSocket) {
|
||||
vdata.payOrderWebSocket.close()
|
||||
}
|
||||
}
|
||||
|
||||
// 开启弹窗,供父组件调用
|
||||
const showModal = () => {
|
||||
vdata.visible = true
|
||||
getList()
|
||||
}
|
||||
|
||||
defineExpose({ showModal })
|
||||
|
||||
// 监听键盘事件
|
||||
document.addEventListener('keydown', (e) => {
|
||||
// 大弹窗开启,并且小弹窗未开启的情况下,回车掉起支付按钮
|
||||
if (vdata.visible && !vdata.SmallVisible && e.keyCode === 13)
|
||||
openSmallVisible()
|
||||
// f1 f2 f3 快捷切换支付方式 (112 113 114)
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.mode {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
margin: 16px 0;
|
||||
}
|
||||
.boxs {
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.mode-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2px solid #e6e6e6;
|
||||
border-radius: 10px;
|
||||
box-sizing: border-box;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
span {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.input {
|
||||
span {
|
||||
display: inline-block;
|
||||
margin: 20px 0 10px 0;
|
||||
}
|
||||
}
|
||||
// 键盘
|
||||
.keyboard {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
// background: #0b6159;
|
||||
// margin-top: 11px;
|
||||
box-sizing: border-box;
|
||||
// padding: 3PX;
|
||||
.keyboard-num {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
flex-grow: 1;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
div {
|
||||
width: 33%;
|
||||
height: 60px;
|
||||
background: var(--ant-primary-color);
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
line-height: 60px;
|
||||
border: 2px solid #fff;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
border-radius: 5px;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operate {
|
||||
width: 25%;
|
||||
margin-right: 1px;
|
||||
user-select: none;
|
||||
div:nth-child(1) {
|
||||
width: 100%;
|
||||
height: 61px;
|
||||
background: var(--ant-primary-color);
|
||||
border: 2px solid #fff;
|
||||
box-sizing: border-box;
|
||||
border-radius: 5px;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
img {
|
||||
width: 20px;
|
||||
height: 14px;
|
||||
margin: 23px 65px;
|
||||
}
|
||||
}
|
||||
div:nth-child(2) {
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
height: 182px;
|
||||
background: #ffb22d;
|
||||
border-radius: 0px 0px 5px 0px;
|
||||
line-height: 184px;
|
||||
font-size: 22px;
|
||||
font-family: PingFang SC, PingFang SC-Bold;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
border: 2px solid #fff;
|
||||
box-sizing: border-box;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.noSelect {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
// 小弹窗样式
|
||||
.full-modal {
|
||||
.ant-modal {
|
||||
top: 50%;
|
||||
padding-bottom: 0;
|
||||
margin: 0 auto;
|
||||
margin-top: -200px;
|
||||
}
|
||||
.ant-modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 400px;
|
||||
}
|
||||
}
|
||||
.modal-body {
|
||||
width: 282px;
|
||||
height: 352px;
|
||||
display: flex;
|
||||
position: relative;
|
||||
padding: 24px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.code {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.auth-code {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cancel {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
// left: 50%;
|
||||
// margin-left: -50px;
|
||||
}
|
||||
.select-id {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 45%;
|
||||
flex-grow: 1;
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
115
jeepay-ui-agent/src/views/role/AddOrEdit.vue
Normal file
115
jeepay-ui-agent/src/views/role/AddOrEdit.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="data.isShow"
|
||||
:title=" data.isAdd ? '新增角色' : '修改角色' "
|
||||
width="600"
|
||||
:mask-closable="false"
|
||||
@close="data.isShow = false"
|
||||
>
|
||||
<a-form
|
||||
ref="infoFormModel"
|
||||
:model="data.saveObject"
|
||||
:label-col="{span: 4}"
|
||||
:rules="data.rules"
|
||||
>
|
||||
<a-form-item label="角色名称:" name="roleName">
|
||||
<a-input :disabled="!$access('ENT_UR_ROLE_EDIT')" v-model:value="data.saveObject['roleName']" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<!-- 角色权限分配 -->
|
||||
<RoleDist ref="roleDist" />
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button
|
||||
:style="{ marginRight: '8px' }"
|
||||
|
||||
@click="data.isShow = false"
|
||||
>
|
||||
<close-outlined />
|
||||
取消
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
:loading="data.confirmLoading"
|
||||
|
||||
@click="handleOkFunc"
|
||||
>
|
||||
<check-outlined />
|
||||
保存
|
||||
</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { API_URL_ROLE_LIST, req } from '@/api/manage'
|
||||
import RoleDist from './RoleDist.vue'
|
||||
import {ref,reactive,nextTick,getCurrentInstance} from 'vue'
|
||||
import {message} from 'ant-design-vue'
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const props= defineProps ({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
const roleDist = ref()
|
||||
const infoFormModel = ref()
|
||||
const data = reactive({
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isAdd: true, // 新增 or 修改页面标识
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
rules: {
|
||||
roleName: [
|
||||
{ required: true, message: '请输入角色名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
defineExpose({show})
|
||||
function show(recordId) { // 弹层打开事件
|
||||
data.isAdd = !recordId
|
||||
data.saveObject = {} // 数据清空
|
||||
data.confirmLoading = false // 关闭loading
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
if (!data.isAdd) { // 修改信息 延迟展示弹层
|
||||
data.recordId = recordId
|
||||
req.getById(API_URL_ROLE_LIST, recordId).then(res => { data.saveObject = res })
|
||||
data.isShow = true
|
||||
} else {
|
||||
data.isShow = true // 立马展示弹层信息
|
||||
}
|
||||
// 初始化角色权限分配功能
|
||||
nextTick(()=>{
|
||||
roleDist.value.initTree(recordId)
|
||||
})
|
||||
}
|
||||
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then(valid =>{
|
||||
data.confirmLoading = true // 显示loading
|
||||
|
||||
// 保存选择的权限信息
|
||||
const selectedEntIdList = roleDist.value.getSelectedEntIdList()
|
||||
data.saveObject['entIdListStr'] = selectedEntIdList ? JSON.stringify(selectedEntIdList) : ''
|
||||
|
||||
if (data.isAdd) {
|
||||
req.add(API_URL_ROLE_LIST, data.saveObject).then(res => {
|
||||
message.success('新增成功')
|
||||
data.isShow = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(res => { data.confirmLoading = false })
|
||||
} else {
|
||||
req.updateById(API_URL_ROLE_LIST, data.recordId, data.saveObject).then(res => {
|
||||
message.success('修改成功')
|
||||
data.isShow = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(res => { data.confirmLoading = false })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
88
jeepay-ui-agent/src/views/role/RoleDist.vue
Normal file
88
jeepay-ui-agent/src/views/role/RoleDist.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div style="padding-bottom:50px;">
|
||||
<p v-if="vdata.hasEnt">请选择权限: </p>
|
||||
<!-- 树状结构 -->
|
||||
<a-tree v-if="vdata.hasEnt" v-model:checkedKeys="vdata.checkedKeys" :tree-data="vdata.treeData" :fieldNames="vdata.replaceFields" :checkable="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { $getEntTree, API_URL_ROLE_ENT_RELA_LIST, req } from '@/api/manage'
|
||||
import { reactive, getCurrentInstance } from 'vue'
|
||||
// 获取全局函数
|
||||
const { $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const vdata = reactive({
|
||||
hasEnt: $access('ENT_UR_ROLE_DIST'),
|
||||
recordId: null, // 更新对象ID
|
||||
treeData: [],
|
||||
replaceFields: { key: 'entId', title: 'entName' }, // 配置替换字段
|
||||
checkedKeys: [], // 已选中的节点
|
||||
allEntList: {} // 由于antd vue关联操作,无法直接获取到父ID, 需要内部自行维护一套数据结构 {entId: {pid, children}}
|
||||
})
|
||||
defineExpose({initTree,getSelectedEntIdList})
|
||||
function initTree(recordId) { // 弹层打开事件
|
||||
// 判断是否有权限访问
|
||||
if (!vdata.hasEnt) {
|
||||
return false
|
||||
}
|
||||
// 重置数据
|
||||
vdata.checkedKeys = []
|
||||
vdata.treeData = []
|
||||
vdata.allEntList = {}
|
||||
vdata.recordId = recordId
|
||||
// 获取全部权限的树状结构
|
||||
$getEntTree().then(res => {
|
||||
vdata.treeData = res
|
||||
// 存储所有的菜单权限集合
|
||||
recursionTreeData(res, (item) => {
|
||||
vdata.allEntList[item.entId] = { pid: item.pid, children: item.children || [] }
|
||||
})
|
||||
// 查询所有的已分配的权限集合 (默认为 0 , 无数据)
|
||||
req.list(API_URL_ROLE_ENT_RELA_LIST, { roleId: recordId || 'NONE', pageSize: -1 }).then(res2 => {
|
||||
const checkedEntIdList:any = [] // 所有已分配的权限集合(兼容antd vue 仅保留子节点)
|
||||
res2.records.map(item => {
|
||||
if (vdata.allEntList[item.entId] && vdata.allEntList[item.entId].children.length <= 0) { // 说明是子节点
|
||||
checkedEntIdList.push(item.entId)
|
||||
}
|
||||
})
|
||||
vdata.checkedKeys = checkedEntIdList
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getSelectedEntIdList() { // 获取已选择的列表集合
|
||||
// 判断是否有权限访问
|
||||
if (!vdata.hasEnt) {
|
||||
return false
|
||||
}
|
||||
const reqData:any = []
|
||||
vdata.checkedKeys.map(item => {
|
||||
const pidList:any = [] // 当前权限的所有的父节点IDList
|
||||
getAllPid(item, pidList)
|
||||
pidList.map(pid => {
|
||||
if (reqData.indexOf(pid) < 0) {
|
||||
reqData.push(pid)
|
||||
}
|
||||
})
|
||||
})
|
||||
return reqData
|
||||
}
|
||||
|
||||
// 递归遍历树状结构数据
|
||||
function recursionTreeData (entTreeData, func) {
|
||||
for (let i = 0; i < entTreeData.length; i++) {
|
||||
const thisEnt = entTreeData[i]
|
||||
if (thisEnt.children && thisEnt.children.length > 0) {
|
||||
recursionTreeData(thisEnt.children, func)
|
||||
}
|
||||
func(thisEnt)
|
||||
}
|
||||
}
|
||||
|
||||
function getAllPid (entId, array) { // 获取所有的PID
|
||||
if (vdata.allEntList[entId] && entId !== 'ROOT') {
|
||||
array.push(entId)
|
||||
getAllPid(vdata.allEntList[entId].pid, array)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
116
jeepay-ui-agent/src/views/role/RolePage.vue
Normal file
116
jeepay-ui-agent/src/views/role/RolePage.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="() => { data.searchData= {} }" v-if = "$access('ENT_UR_ROLE_SEARCH')">
|
||||
<jeepay-text-up v-model:value="data.searchData['roleId']" :placeholder="'角色ID'" />
|
||||
<jeepay-text-up v-model:value="data.searchData['roleName']" :placeholder="'角色名称'" />
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="data.searchData"
|
||||
row-key="roleName"
|
||||
@btnLoadClose="data.btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<div>
|
||||
<a-button
|
||||
v-if="$access('ENT_UR_ROLE_ADD')"
|
||||
type="primary"
|
||||
class="mg-b-30"
|
||||
@click="addFunc"
|
||||
>
|
||||
<plus-outlined />
|
||||
新建
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<!-- {{ record }} -->
|
||||
<template v-if="column.key === 'roleId'">
|
||||
<b>{{ record.roleId }}</b>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'op'">
|
||||
<a v-if="$access('ENT_UR_ROLE_EDIT')" style="padding-left: 15px; padding-right: 15px;" @click="editFunc(record.roleId)">修改</a>
|
||||
<a v-if="$access('ENT_UR_ROLE_DEL')" style="color: red" @click="delFunc(record.roleId)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 新增 / 修改 页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callback-func="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_ROLE_LIST, req } from '@/api/manage'
|
||||
import InfoAddOrEdit from './AddOrEdit.vue'
|
||||
import {ref,reactive,getCurrentInstance} from 'vue'
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import {message} from 'ant-design-vue'
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const tableColumns =reactive([
|
||||
{
|
||||
key: 'roleId', // key为必填项,用于标志该列的唯一
|
||||
title: '角色ID',
|
||||
sorter: true,
|
||||
fixed: 'left',
|
||||
},
|
||||
{
|
||||
key: 'roleName',
|
||||
title: '角色名称',
|
||||
dataIndex: 'roleName',
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'op',
|
||||
title: '操作',
|
||||
width: '200px',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
}
|
||||
])
|
||||
const infoTable = ref()
|
||||
const infoAddOrEdit = ref()
|
||||
const data = reactive ({
|
||||
tableColumns: tableColumns,
|
||||
searchData: {},
|
||||
btnLoading: false
|
||||
})
|
||||
|
||||
|
||||
// 请求table接口数据
|
||||
const reqTableDataFunc =(params) => {
|
||||
return req.list(API_URL_ROLE_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
data.btnLoading = true // 打开查询按钮上的loading
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show()
|
||||
}
|
||||
|
||||
function editFunc (recordId) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(recordId)
|
||||
}
|
||||
|
||||
function delFunc (recordId) { // 业务通用【删除】 函数
|
||||
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
// 需要【按钮】loading 请返回 promise对象, 不需要请直接返回null
|
||||
return req.delById(API_URL_ROLE_LIST, recordId).then(res => {
|
||||
message.success('删除成功!')
|
||||
infoTable.value.refTable(false)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
208
jeepay-ui-agent/src/views/statistic/agent/List.vue
Normal file
208
jeepay-ui-agent/src/views/statistic/agent/List.vue
Normal file
@@ -0,0 +1,208 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="resetFunc">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker
|
||||
v-if="vdata.showDateTimeRage"
|
||||
ref="dateRangePicker"
|
||||
v-model:value="vdata.searchData['queryDateRange']"
|
||||
customDateRangeType="date"
|
||||
/>
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['agentNo']" :placeholder="'服务商号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['agentName']" :placeholder="'服务商名称'" />
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="agentNo"
|
||||
:statisticsIsShow="true"
|
||||
:tableExportFunc="tableExportFunc"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
@handleTableChange="handleChange"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<span v-if="column.tooltipTitle">
|
||||
{{ column.title }}
|
||||
<a-tooltip :title="column.tooltipTitle"><info-circle-outlined /></a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="tableExportFunc">
|
||||
<plus-outlined />导出表格
|
||||
</a-button>
|
||||
</template>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in count" :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 #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'agentName'">
|
||||
<a>
|
||||
<b>{{ record.agentName }}</b>
|
||||
</a>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalSuccAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalSuccAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalFinalAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalFinalAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalEntryAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalEntryAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalRefundAmt / 100).toFixed(2)}}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundNum'">
|
||||
<b style="color: #FF6848;">{{ record.totalRefundNum }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalSuccNum'">
|
||||
<b style="color: #15B86C;">{{ record.totalSuccNum }}/{{ record.totalNum }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalFeeAmt'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>收单手续费:¥{{ (record.totalFeeAmt / 100).toFixed(2) }}</span><br>
|
||||
<span>垫资手续费:¥{{ ( record.totalCashFee / 100).toFixed(2) }}</span>
|
||||
</template>
|
||||
<b style="color: #FF6848;">¥{{ ((record.totalFeeAmt + record.totalCashFee) / 100).toFixed(2) }}</b>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'succRate'">
|
||||
<b style="color: #FF8800;">{{ record.succRate }}%</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'operation'">
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_STATISTIC_MCH')" type="link" @click="toPage(record.agentNo, vdata.parameterDate)">商户统计</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import { API_URL_STATISTIC, req, $exportExcel, exportExcelUrl } from '@/api/manage'
|
||||
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
||||
import router from '@/router'
|
||||
import { useRoute } from 'vue-router'
|
||||
import fileDownload from 'js-file-download'
|
||||
import dateUtil from '@/utils/dateUtil.js'
|
||||
const { $infoBox, $access, $hasAgentEnt } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoDetail = ref()
|
||||
const infoTable = ref()
|
||||
let tableColumns = reactive([
|
||||
{ key: 'agentName', title: '服务商名称', dataIndex: 'agentName', },
|
||||
{ key: 'agentNo', title: '服务商号', dataIndex: 'agentNo', agentEntCol: true, },
|
||||
{ key: 'totalSuccAmt', title: '成交金额', tooltipTitle: '支付成功的订单金额,包含部分退款及全额退款的订单', dataIndex: 'totalSuccAmt', },
|
||||
{ key: 'totalRefundAmt', title: '退款金额', dataIndex: 'totalRefundAmt'},
|
||||
{ key: 'totalRefundNum', title: '退款笔数', tooltipTitle: '实际退款订单笔数,若一笔已成交订单退款多次,则计多次', dataIndex: 'totalRefundNum'},
|
||||
{ key: 'totalFeeAmt', title: '手续费', tooltipTitle: '成交订单产生的手续费金额', dataIndex: 'totalFeeAmt'},
|
||||
{ key: 'totalEntryAmt', title: '入账金额', tooltipTitle: '扣除已退款金额及手续费,入账金额为商户实际到账金额', dataIndex: 'totalEntryAmt'},
|
||||
{ key: 'totalSuccNum', title: '成交笔数/总交易笔数', dataIndex: 'totalSuccNum', },
|
||||
{ key: 'succRate', title: '成功率', tooltipTitle: '成交笔数与总订单笔数除得的百分比', dataIndex: 'round',},
|
||||
// { key: 'operation', title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let count:any = ref([]) // 数据统计数组
|
||||
|
||||
const dateRangePicker = ref()
|
||||
const vdata : any = reactive({
|
||||
searchData: { method : 'agent', queryDateRange: 'today', sortField: 'totalSuccAmt', sortOrder: 'descend' },
|
||||
showDateTimeRage: false,
|
||||
parameterDate: 'today'
|
||||
})
|
||||
|
||||
vdata.searchData['isvNo'] = useRoute().query.isvNo
|
||||
|
||||
onMounted(() => {
|
||||
if(useRoute().query.queryDate) {
|
||||
vdata.searchData['queryDateRange'] = dateUtil.parseQueryStringByRange(useRoute().query.queryDate)
|
||||
}
|
||||
searchFunc()
|
||||
vdata.showDateTimeRage = true
|
||||
})
|
||||
|
||||
function handleChange(sorter) {
|
||||
vdata.searchData['sortField'] = sorter.columnKey
|
||||
vdata.searchData['sortOrder'] = sorter.order
|
||||
}
|
||||
|
||||
function resetFunc() {
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { method : 'agent', queryDateRange: 'today', sortField: 'totalSuccAmt', sortOrder: 'descend' }
|
||||
}
|
||||
|
||||
function searchFunc() { // 点击【查询】按钮点击事件
|
||||
vdata.parameterDate = vdata.searchData.queryDateRange
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params: any) {
|
||||
params.method = 'agent'
|
||||
|
||||
if (!params.sortField) {
|
||||
params.sortField = 'totalSuccAmt'
|
||||
params.sortOrder = 'descend'
|
||||
}
|
||||
|
||||
reqTableCountFunc(params)
|
||||
return req.list(API_URL_STATISTIC, params)
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableCountFunc(params: any) {
|
||||
req.list(API_URL_STATISTIC + '/total', params).then(res => {
|
||||
count.value = [
|
||||
{title: '总成交金额', symbol: 'add', textColor: '#1A66FF', content: ((res.totalSuccAmt) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总成交笔数', content: (res.totalSuccNum)},
|
||||
{type: 'line'},
|
||||
{title: '总退款金额', symbol: 'sub', content: ((res.totalRefundAmt) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总退款笔数', content: (res.totalRefundNum)},
|
||||
// {type: 'line'},
|
||||
// {title: '支付成功率', content: (res.round) + '%'},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
function tableExportFunc(){
|
||||
return $exportExcel(exportExcelUrl.statistic, Object.assign({}, vdata.searchData, {})).then(res => {
|
||||
fileDownload(res.data, '服务商统计.xlsx')
|
||||
}).catch ((error) =>{console.log(error)} )
|
||||
}
|
||||
|
||||
function toPage(recordId, date) {
|
||||
if (date.indexOf('_7') > -1) {
|
||||
date = 7
|
||||
} else if (date.indexOf('_30') > -1) {
|
||||
date = 30
|
||||
} else if (date.indexOf('customDateTime') > -1) {
|
||||
date = dateUtil.getCustomDateTime(date)
|
||||
}
|
||||
router.push({
|
||||
path: '/statistic/mch',
|
||||
query: { agentNo: recordId, queryDateRange: date }
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
206
jeepay-ui-agent/src/views/statistic/device/List.vue
Normal file
206
jeepay-ui-agent/src/views/statistic/device/List.vue
Normal file
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="resetFunc">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker
|
||||
v-if="vdata.showDateTimeRage"
|
||||
ref="dateRangePicker"
|
||||
v-model:value="vdata.searchData['queryDateRange']"
|
||||
customDateRangeType="date"
|
||||
/>
|
||||
</a-form-item>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.deviceNo" :placeholder="'设备号'" />
|
||||
<JeepaySelect ref="deviceTypeRef" placeholder="设备类型" :reset="isReset">
|
||||
<a-select v-model:value="vdata.searchData.deviceType" @change="deviceTypeRef.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="scan_pos">扫码POS</a-select-option>
|
||||
<a-select-option value="auto_pos">智能POS</a-select-option>
|
||||
<a-select-option value="cash_plugin">收银插件</a-select-option>
|
||||
</a-select>
|
||||
</JeepaySelect>
|
||||
<jeepay-text-up v-model:value="vdata.searchData.agentNo" :placeholder="'服务商号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData.mchNo" :placeholder="'用户号'" />
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="ifCode"
|
||||
:statisticsIsShow="true"
|
||||
:tableExportFunc="tableExportFunc"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
@handleTableChange="handleChange"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<span v-if="column.tooltipTitle">
|
||||
{{ column.title }}
|
||||
<a-tooltip :title="column.tooltipTitle"><info-circle-outlined /></a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="tableExportFunc">
|
||||
<plus-outlined />导出表格
|
||||
</a-button>
|
||||
</template>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in count" :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 #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'totalSuccAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalSuccAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalFinalAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalFinalAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalEntryAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalEntryAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalRefundAmt / 100).toFixed(2)}}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundNum'">
|
||||
<b style="color: #FF6848;">{{ record.totalRefundNum }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalSuccNum'">
|
||||
<b style="color: #15B86C;">{{ record.totalSuccNum }}/{{ record.totalNum }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'succRate'">
|
||||
<b style="color: #FF8800;">{{ record.succRate }}%</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalFeeAmt'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>收单手续费:¥{{ (record.totalFeeAmt / 100).toFixed(2) }}</span><br>
|
||||
<span>垫资手续费:¥{{ ( record.totalCashFee / 100).toFixed(2) }}</span>
|
||||
</template>
|
||||
<b style="color: #FF6848;">¥{{ ((record.totalFeeAmt + record.totalCashFee) / 100).toFixed(2) }}</b>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'deviceType'">
|
||||
<a-tag v-if="record.deviceType != 'qr_code'" :color="record.deviceType == 'qr_code' ? '#2db7f5' : record.deviceType == 'scan_pos' ? '#87d068' : record.deviceType == 'auto_pos' ? '#531dab' : record.deviceType == 'cash_plugin' ? '#f50' : ''">
|
||||
{{ record.deviceType == 'qr_code' ? '码牌' : record.deviceType == 'scan_pos' ? '扫码POS' : record.deviceType == 'auto_pos' ? '智能POS' : record.deviceType == 'cash_plugin' ? '收银插件' : '其他' }}
|
||||
</a-tag>
|
||||
<a-tag v-else :color="record.deviceType == 'qr_code' ? '#2db7f5' : record.deviceType == 'scan_pos' ? '#87d068' : record.deviceType == 'auto_pos' ? '#531dab' : record.deviceType == 'cash_plugin' ? '#f50' : ''">
|
||||
{{ record.qrcType == 0 ? '电子码牌' : record.qrcType == 1 ? '实体码牌' : record.qrcType == 2 ? '实体立牌' : record.qrcType == 3 ? '云音响码牌' : '其他' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import { API_URL_STATISTIC, req, $exportExcel, exportExcelUrl } from '@/api/manage'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import fileDownload from 'js-file-download'
|
||||
import dateUtil from '@/utils/dateUtil.js'
|
||||
|
||||
const deviceTypeRef = ref()
|
||||
const infoTable = ref()
|
||||
let tableColumns = reactive([
|
||||
{ key: 'deviceType', title: '设备类型', dataIndex: 'deviceType', },
|
||||
{ key: 'deviceNo', title: '设备号', dataIndex: 'deviceNo', },
|
||||
{ key: 'deviceName', title: '设备名称', dataIndex: 'deviceName', },
|
||||
{ key: 'totalSuccAmt', title: '成交金额', tooltipTitle: '支付成功的订单金额,包含部分退款及全额退款的订单', dataIndex: 'totalSuccAmt', },
|
||||
{ key: 'totalRefundAmt', title: '退款金额', dataIndex: 'totalRefundAmt'},
|
||||
{ key: 'totalRefundNum', title: '退款笔数', tooltipTitle: '实际退款订单笔数,若一笔已成交订单退款多次,则计多次', dataIndex: 'totalRefundNum'},
|
||||
{ key: 'totalFeeAmt', title: '手续费', tooltipTitle: '成交订单产生的手续费金额', dataIndex: 'totalFeeAmt'},
|
||||
{ key: 'totalEntryAmt', title: '入账金额', tooltipTitle: '扣除已退款金额及手续费,入账金额为商户实际到账金额', dataIndex: 'totalEntryAmt'},
|
||||
{ key: 'totalSuccNum', title: '成交笔数/总交易笔数', dataIndex: 'totalSuccNum', },
|
||||
{ key: 'succRate', title: '成功率', tooltipTitle: '成交笔数与总订单笔数除得的百分比', dataIndex: 'succRate', },
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let count:any = ref([]) // 数据统计数组
|
||||
const dateRangePicker = ref()
|
||||
|
||||
const vdata : any = reactive({
|
||||
searchData: { method : 'device', queryDateRange: 'today', sortField: 'totalSuccAmt', sortOrder: 'descend' },
|
||||
showDateTimeRage: false
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if(useRoute().query.queryDate) {
|
||||
vdata.searchData['queryDateRange'] = dateUtil.parseQueryStringByRange(useRoute().query.queryDate)
|
||||
}
|
||||
searchFunc()
|
||||
vdata.showDateTimeRage = true
|
||||
})
|
||||
|
||||
function handleChange(sorter) {
|
||||
vdata.searchData['sortField'] = sorter.columnKey
|
||||
vdata.searchData['sortOrder'] = sorter.order
|
||||
}
|
||||
|
||||
function resetFunc() {
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { method : 'device', queryDateRange: 'today', sortField: 'totalSuccAmt', sortOrder: 'descend' }
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params: any) {
|
||||
params.method = 'device'
|
||||
|
||||
if (!params.sortField) {
|
||||
params.sortField = 'totalSuccAmt'
|
||||
params.sortOrder = 'descend'
|
||||
}
|
||||
|
||||
reqTableCountFunc(params)
|
||||
return req.list(API_URL_STATISTIC, params)
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableCountFunc(params: any) {
|
||||
req.list(API_URL_STATISTIC + '/total', params).then(res => {
|
||||
count.value = [
|
||||
{title: '总成交金额', symbol: 'add', textColor: '#1A66FF', content: ((res.totalSuccAmt) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总成交笔数', content: (res.totalSuccNum)},
|
||||
{type: 'line'},
|
||||
{title: '总退款金额', symbol: 'sub', content: ((res.totalRefundAmt) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总退款笔数', content: (res.totalRefundNum)},
|
||||
// {type: 'line'},
|
||||
// {title: '支付成功率', content: (res.round) + '%'},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
function tableExportFunc(){
|
||||
return $exportExcel(exportExcelUrl.statistic, Object.assign({}, vdata.searchData, {})).then(res => {
|
||||
fileDownload(res.data, '设备统计.xlsx')
|
||||
}).catch ((error) =>{console.log(error)} )
|
||||
}
|
||||
|
||||
let isReset = ref(0) // 下拉搜索框是否重置
|
||||
|
||||
function onReset(){
|
||||
isReset.value++ // 下拉搜索框重置
|
||||
//重置搜索内容
|
||||
vdata.searchData = {}
|
||||
}
|
||||
|
||||
</script>
|
||||
228
jeepay-ui-agent/src/views/statistic/mch/List.vue
Normal file
228
jeepay-ui-agent/src/views/statistic/mch/List.vue
Normal file
@@ -0,0 +1,228 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="resetFunc">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker
|
||||
v-if="vdata.showDateTimeRage"
|
||||
ref="dateRangePicker"
|
||||
v-model:value="vdata.searchData['queryDateRange']"
|
||||
customDateRangeType="date"
|
||||
/>
|
||||
</a-form-item>
|
||||
<JeepaySearchInfoInput
|
||||
v-model:value="vdata.searchData.mchNo"
|
||||
placeholder="用户号"
|
||||
:textUpStyle="true"
|
||||
:mchNoAndName="true"
|
||||
showType="MCH"
|
||||
/>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchName']" :placeholder="'用户名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['agentNo']" :placeholder="'代理商号'" />
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="false"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:statisticsIsShow="true"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="mchNo"
|
||||
:tableExportFunc="tableExportFunc"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
@handleTableChange="handleChange"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<span v-if="column.tooltipTitle">
|
||||
{{ column.title }}
|
||||
<a-tooltip :title="column.tooltipTitle"><info-circle-outlined /></a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="tableExportFunc">
|
||||
<plus-outlined />导出表格
|
||||
</a-button>
|
||||
</template>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in count" :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 #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'mchName'">
|
||||
<a>
|
||||
<b>{{ record.mchName }}</b>
|
||||
</a>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalSuccAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalSuccAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalFinalAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalFinalAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalEntryAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalEntryAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalFeeAmt'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>收单手续费:¥{{ (record.totalFeeAmt / 100).toFixed(2) }}</span><br>
|
||||
<span>垫资手续费:¥{{ ( record.totalCashFee / 100).toFixed(2) }}</span>
|
||||
</template>
|
||||
<b style="color: #FF6848;">¥{{ ((record.totalFeeAmt + record.totalCashFee) / 100).toFixed(2) }}</b>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalRefundAmt / 100).toFixed(2)}}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundFeeAmt'">
|
||||
<b style="color: #FF6848;">¥{{ (record.totalRefundFeeAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundNum'">
|
||||
<b style="color: #FF6848;">{{ record.totalRefundNum }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalSuccNum'">
|
||||
<b style="color: #15B86C;">{{ record.totalSuccNum }}/{{ record.totalNum }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'succRate'">
|
||||
<b style="color: #FF8800;">{{ record.succRate }}%</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'operation'">
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" @click="detailFunc(record.mchNo, vdata.parameterDate)">明细</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 明细页面组件 -->
|
||||
<billDetail ref="accountDetail" :callback-func="searchFunc" />
|
||||
<!-- 商户详情页面组件 -->
|
||||
<InfoDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import { API_URL_STATISTIC, req, $exportExcel, exportExcelUrl } from '@/api/manage'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import billDetail from './accountDetail.vue'
|
||||
import fileDownload from 'js-file-download'
|
||||
import dateUtil from '@/utils/dateUtil.js'
|
||||
|
||||
const accountDetail = ref()
|
||||
const infoTable = ref()
|
||||
let tableColumns = reactive([
|
||||
{ key: 'mchName', title: '用户名称', dataIndex: 'mchName', },
|
||||
{ key: 'mchNo', title: '用户号', dataIndex: 'mchNo',},
|
||||
{ key: 'totalSuccAmt', title: '成交金额', tooltipTitle: '支付成功的订单金额,包含部分退款及全额退款的订单', dataIndex: 'totalSuccAmt', },
|
||||
{ key: 'totalRefundAmt', title: '退款金额', dataIndex: 'totalRefundAmt'},
|
||||
{ key: 'totalRefundNum', title: '退款笔数', tooltipTitle: '实际退款订单笔数,若一笔已成交订单退款多次,则计多次', dataIndex: 'totalRefundNum'},
|
||||
{ key: 'totalFeeAmt', title: '手续费', tooltipTitle: '成交订单所产生的交易手续费和垫资手续费', dataIndex: 'totalFeeAmt'},
|
||||
{ key: 'totalEntryAmt', title: '入账金额', tooltipTitle: '扣除已退款金额及手续费,入账金额为商户实际到账金额', dataIndex: 'totalEntryAmt'},
|
||||
{ key: 'totalSuccNum', title: '成交笔数/总交易笔数', dataIndex: 'totalSuccNum', },
|
||||
{ key: 'succRate', title: '成功率', tooltipTitle: '成交笔数与总订单笔数除得的百分比', dataIndex: 'succRate', },
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center', }
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let count:any = ref([]) // 数据统计数组
|
||||
const dateRangePicker = ref()
|
||||
const vdata : any = reactive({
|
||||
searchData: { method : 'mch', queryDateRange: 'today', sortField: 'totalSuccAmt', sortOrder: 'descend' },
|
||||
showDateTimeRage: false, //是否显示时间搜索组件
|
||||
parameterDate: 'today'
|
||||
})
|
||||
|
||||
vdata.searchData['agentNo'] = useRoute().query.agentNo
|
||||
vdata.searchData['isvNo'] = useRoute().query.isvNo
|
||||
onMounted(() => {
|
||||
if (useRoute().query.queryDate) {
|
||||
vdata.searchData['queryDateRange'] = dateUtil.parseQueryStringByRange(useRoute().query.queryDate)
|
||||
} else if (useRoute().query.queryDateRange) {
|
||||
let date = useRoute().query.queryDateRange as any
|
||||
if (date == 7) {
|
||||
date = 'near2now_7'
|
||||
} else if (date == 30) {
|
||||
date = 'near2now_30'
|
||||
} else if (date.indexOf('_') > -1) {
|
||||
date = dateUtil.parseQueryStringByRange(date)
|
||||
}
|
||||
vdata.searchData['queryDateRange'] = date
|
||||
}
|
||||
searchFunc()
|
||||
vdata.showDateTimeRage = true
|
||||
})
|
||||
|
||||
function handleChange(sorter) {
|
||||
vdata.searchData['sortField'] = sorter.columnKey
|
||||
vdata.searchData['sortOrder'] = sorter.order
|
||||
}
|
||||
|
||||
function resetFunc() {
|
||||
dateRangePicker.value.returnSelectModel()
|
||||
vdata.searchData = { method : 'mch', queryDateRange: 'today', sortField: 'totalSuccAmt', sortOrder: 'descend' }
|
||||
}
|
||||
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params: any) {
|
||||
params.method = 'mch'
|
||||
|
||||
if (!params.sortField) {
|
||||
params.sortField = 'totalSuccAmt'
|
||||
params.sortOrder = 'descend'
|
||||
}
|
||||
|
||||
reqTableCountFunc(params)
|
||||
return req.list(API_URL_STATISTIC, params)
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableCountFunc(params: any) {
|
||||
req.list(API_URL_STATISTIC + '/total', params).then(res => {
|
||||
count.value = [
|
||||
{title: '总成交金额', symbol: 'add', textColor: '#1A66FF', content: ((res.totalSuccAmt) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总成交笔数', content: (res.totalSuccNum)},
|
||||
{type: 'line'},
|
||||
{title: '总退款金额', symbol: 'sub', content: ((res.totalRefundAmt) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总退款笔数', content: (res.totalRefundNum)},
|
||||
// {type: 'line'},
|
||||
// {title: '支付成功率', content: (res.round) + '%'},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
function searchFunc() { // 点击【查询】按钮点击事件
|
||||
vdata.parameterDate = vdata.searchData.queryDateRange
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function detailFunc(recordId, date) {
|
||||
accountDetail.value.show(recordId, date)
|
||||
}
|
||||
|
||||
function tableExportFunc(){
|
||||
return $exportExcel(exportExcelUrl.statistic, Object.assign({}, vdata.searchData, {})).then(res => {
|
||||
fileDownload(res.data, '商户统计.xlsx')
|
||||
}).catch ((error) =>{console.log(error)} )
|
||||
}
|
||||
|
||||
// function infoTableSelectChangeFunc(selectedRowKeys){
|
||||
// // 遍历 vdata.listRecords 如果selectedRowKeys数组中存在对应的id,则将其checked改为true,反之false
|
||||
// vdata.listRecords.forEach(element => {
|
||||
// selectedRowKeys.includes(element.qrcId) ? element.checked = true : element.checked = false
|
||||
// })
|
||||
// }
|
||||
|
||||
</script>
|
||||
85
jeepay-ui-agent/src/views/statistic/mch/accountDetail.vue
Normal file
85
jeepay-ui-agent/src/views/statistic/mch/accountDetail.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:destroyOnClose="true"
|
||||
:title="'统计明细'"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="80%"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-tabs v-model:activeKey="vdata.activeKey" :size="'large'">
|
||||
<a-tab-pane key="1" tab="门店统计">
|
||||
<accountDetailPane :method="'store'" :tableColumns="tableStoreColumns" :mchNo="vdata.mchNo" :date="vdata.date" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" tab="支付方式统计">
|
||||
<accountDetailPane :method="'wayCode'" :tableColumns="tableWayCodeColumns" :mchNo="vdata.mchNo" :date="vdata.date" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="3" tab="通道统计">
|
||||
<accountDetailPane :method="'wayCodeType'" :tableColumns="tableChannelColumns" :mchNo="vdata.mchNo" :date="vdata.date" />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import accountDetailPane from './accountDetailPane.vue'
|
||||
const vdata: any = reactive({
|
||||
visible: false,
|
||||
mchNo: '',
|
||||
activeKey: '1',
|
||||
date: ''
|
||||
})
|
||||
// 门店表头
|
||||
let tableStoreColumns = reactive([
|
||||
{ key: 'storeName', title: '门店名称', dataIndex: 'storeName', },
|
||||
{ key: 'storeId', title: '门店编号', dataIndex: 'storeId', },
|
||||
{ key: 'totalSuccAmt', title: '成交金额', tooltipTitle: '支付成功的订单金额,包含部分退款及全额退款的订单', dataIndex: 'totalSuccAmt', },
|
||||
{ key: 'totalRefundAmt', title: '退款金额', dataIndex: 'totalRefundAmt'},
|
||||
{ key: 'totalRefundNum', title: '退款笔数', tooltipTitle: '实际退款订单笔数,若一笔已成交订单退款多次,则计多次', dataIndex: 'totalRefundNum'},
|
||||
{ key: 'totalFeeAmt', title: '手续费', tooltipTitle: '成交订单所产生的交易手续费和垫资手续费', dataIndex: 'totalFeeAmt'},
|
||||
{ key: 'totalEntryAmt', title: '入账金额', tooltipTitle: '扣除已退款金额及手续费,入账金额为商户实际到账金额', dataIndex: 'totalEntryAmt'},
|
||||
// { key: 'totalFeeAmt', title: '手续费', tooltipTitle: '成交订单产生的手续费金额' , dataIndex: 'totalFeeAmt', },
|
||||
// { key: 'totalRefundAmt', title: '退款金额', dataIndex: 'totalRefundAmt', },
|
||||
// { key: 'totalRefundFeeAmt', title: '手续费回退', tooltipTitle: '退款订单产生的手续费退费金额' , dataIndex: 'totalRefundFeeAmt', },
|
||||
// { key: 'totalRefundNum', title: '退款笔数', tooltipTitle: '实际退款订单笔数,若一笔已成交订单退款多次,则计多次', dataIndex: 'totalRefundNum', },
|
||||
{ key: 'totalSuccNum', title: '成交笔数/总交易笔数', dataIndex: 'totalSuccNum', },
|
||||
{ key: 'succRate', title: '成功率', tooltipTitle: '成交笔数与总订单笔数除得的百分比', dataIndex: 'succRate', },
|
||||
])
|
||||
// 支付方式表头
|
||||
let tableWayCodeColumns = reactive([
|
||||
{ key: 'name', title: '支付类型',},
|
||||
{ key: 'totalSuccAmt', title: '成交金额', tooltipTitle: '支付成功的订单金额,包含部分退款及全额退款的订单', dataIndex: 'totalSuccAmt', },
|
||||
{ key: 'totalRefundAmt', title: '退款金额', dataIndex: 'totalRefundAmt'},
|
||||
{ key: 'totalRefundNum', title: '退款笔数', tooltipTitle: '实际退款订单笔数,若一笔已成交订单退款多次,则计多次', dataIndex: 'totalRefundNum'},
|
||||
{ key: 'totalEntryAmt', title: '入账金额', tooltipTitle: '扣除已退款金额及手续费,入账金额为商户实际到账金额', dataIndex: 'totalEntryAmt'},
|
||||
{ key: 'totalSuccNum', title: '成交笔数/总交易笔数', dataIndex: 'totalSuccNum', },
|
||||
{ key: 'succRate', title: '成功率', tooltipTitle: '成交笔数与总订单笔数除得的百分比', dataIndex: 'succRate', },
|
||||
])
|
||||
// 支付类型(渠道)表头
|
||||
let tableChannelColumns = reactive([
|
||||
// { key: 'wayType', title: '支付渠道', dataIndex: 'wayType', },
|
||||
{ key: 'name', title: '渠道名称',},
|
||||
{ key: 'totalSuccAmt', title: '成交金额', tooltipTitle: '支付成功的订单金额,包含部分退款及全额退款的订单', dataIndex: 'totalSuccAmt', },
|
||||
{ key: 'totalRefundAmt', title: '退款金额', dataIndex: 'totalRefundAmt'},
|
||||
{ key: 'totalRefundNum', title: '退款笔数', tooltipTitle: '实际退款订单笔数,若一笔已成交订单退款多次,则计多次', dataIndex: 'totalRefundNum'},
|
||||
{ key: 'totalEntryAmt', title: '入账金额', tooltipTitle: '扣除已退款金额及手续费,入账金额为商户实际到账金额', dataIndex: 'totalFinalAmt'},
|
||||
{ key: 'totalSuccNum', title: '成交笔数/总交易笔数', dataIndex: 'totalSuccNum', },
|
||||
{ key: 'succRate', title: '成功率', tooltipTitle: '成交笔数与总订单笔数除得的百分比', dataIndex: 'succRate', },
|
||||
])
|
||||
|
||||
function show(recordId, date) { // 弹层打开事件
|
||||
vdata.activeKey = '1'
|
||||
vdata.visible = true
|
||||
vdata.mchNo = recordId
|
||||
vdata.date = date
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
167
jeepay-ui-agent/src/views/statistic/mch/accountDetailPane.vue
Normal file
167
jeepay-ui-agent/src/views/statistic/mch/accountDetailPane.vue
Normal file
@@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="() => { vdata.searchData = {} }">
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<JeepayDateRangePicker
|
||||
ref="dateRangePicker"
|
||||
v-model:value="vdata.searchData['queryDateRange']"
|
||||
customDateRangeType="date"
|
||||
/>
|
||||
</a-form-item>
|
||||
<JeepaySearchInfoInput v-if="props.method == 'store'" v-model:value="vdata.searchData['storeId']" placeholder="门店ID" :textUpStyle="true" showType="MCH_STORE" />
|
||||
<jeepay-text-up v-if="props.method == 'wayCode'" v-model:value="vdata.searchData['wayCode']" :placeholder="'支付代码'" />
|
||||
<JeepaySelect>
|
||||
<a-select v-if="props.method == 'wayCodeType'" v-model:value="vdata.searchData['wayType']" :placeholder="'支付渠道'" defaultValue="">
|
||||
<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>
|
||||
</JeepaySelect>
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="props.tableColumns"
|
||||
:statisticsIsShow="true"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="mchNo"
|
||||
:tableExportFunc="tableExportFunc"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<span v-if="column.tooltipTitle">
|
||||
{{ column.title }}
|
||||
<a-tooltip :title="column.tooltipTitle"><info-circle-outlined /></a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="tableExportFunc">
|
||||
<plus-outlined />导出表格
|
||||
</a-button>
|
||||
</template>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in count" :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 #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'storeName'">
|
||||
<a>
|
||||
<b>{{ record.storeName }}</b>
|
||||
</a>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalSuccAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalSuccAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalEntryAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalEntryAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalFeeAmt'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>收单手续费:¥{{ (record.totalFeeAmt / 100).toFixed(2) }}</span><br>
|
||||
<span>垫资手续费:¥{{ ( record.totalCashFee / 100).toFixed(2) }}</span>
|
||||
</template>
|
||||
<b style="color: #FF6848;">¥{{ ((record.totalFeeAmt + record.totalCashFee) / 100).toFixed(2) }}</b>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalRefundAmt / 100).toFixed(2)}}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundFeeAmt'">
|
||||
<b style="color: #FF6848;">¥{{ (record.totalRefundFeeAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundNum'">
|
||||
<b style="color: #FF6848;">{{ record.totalRefundNum }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalSuccNum'">
|
||||
<b style="color: #15B86C;">{{ record.totalSuccNum }}/{{ record.totalNum }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'succRate'">
|
||||
<b style="color: #FF8800;">{{ record.succRate }}%</b>
|
||||
</template>
|
||||
<!-- <template v-if="column.key === 'wayTypeName'">-->
|
||||
<!-- {{ record.wayType == 'WECHAT'?'微信':record.wayType == 'ALIPAY'?'支付宝':record.wayType == 'YSFPAY'?'云闪付':record.wayType == 'UNIONPAY'?'银联':record.wayType == 'DCEPPAY'?'数字人民币':'其他' }}-->
|
||||
<!-- </template>-->
|
||||
<template v-if="column.key === 'name'">
|
||||
{{ record.name }}
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_STATISTIC, $exportExcel, exportExcelUrl, req } from '@/api/manage'
|
||||
import { defineProps, reactive, ref } from 'vue'
|
||||
import fileDownload from 'js-file-download'
|
||||
|
||||
const infoTable = ref()
|
||||
|
||||
const props = defineProps({
|
||||
method: { type: String, default: 'store' },
|
||||
tableColumns: { type: Array, default: [] },
|
||||
mchNo: { type: String, default: '' },
|
||||
date: { type: String, default: '' }
|
||||
})
|
||||
const vdata: any = reactive({
|
||||
searchData: { method: 'store', mchNo: '', queryDateRange: props.date },
|
||||
tableColumns: []
|
||||
})
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let count: any = ref([]) // 数据统计数组
|
||||
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params: any) {
|
||||
params.mchNo = props.mchNo
|
||||
params.method = props.method
|
||||
params.queryDateRange = props.date
|
||||
vdata.tableIsShow = true
|
||||
reqTableCountFunc(params)
|
||||
return req.list(API_URL_STATISTIC, params)
|
||||
}
|
||||
|
||||
function searchFunc() { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableCountFunc(params: any) {
|
||||
req.list(API_URL_STATISTIC + '/total', params).then(res => {
|
||||
count.value = [
|
||||
{title: '总成交金额', symbol: 'add', textColor: '#1A66FF', content: ((res.totalSuccAmt) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总成交笔数', content: (res.totalSuccNum)},
|
||||
{type: 'line'},
|
||||
{title: '总退款金额', symbol: 'sub', content: ((res.totalRefundAmt) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总退款笔数', content: (res.totalRefundNum)},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
function tableExportFunc() {
|
||||
return $exportExcel(exportExcelUrl.statistic, Object.assign({}, vdata.searchData, {mchNo: props.mchNo, method: props.method})).then(res => {
|
||||
fileDownload(res.data, props.method == 'store'?'门店统计.xlsx':props.method == 'wayCode'?'支付方式统计.xlsx':props.method == 'wayCodeType'?'通道统计.xlsx':'商户统计.xlsx')
|
||||
}).catch((error) => { console.log(error) })
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.table-layer .table-search-item {
|
||||
width: calc(100% / 6);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select :value="props.cycleType" @change="changeType">
|
||||
<a-select-option value="date">日报</a-select-option>
|
||||
<a-select-option value="month">月报</a-select-option>
|
||||
<a-select-option value="year">年报</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-space direction="vertical" :size="12">
|
||||
<a-range-picker v-if="props.cycleType === 'date'" v-model:value="vdata.date" :disabled-date="disabledDate" @change="changeDate" />
|
||||
<a-range-picker v-else-if="props.cycleType === 'month'" v-model:value="vdata.date" picker="month" @change="changeDate" />
|
||||
<a-range-picker v-else-if="props.cycleType === 'year'" v-model:value="vdata.date" picker="year" @change="changeDate" />
|
||||
</a-space>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, watch } from 'vue'
|
||||
import dayjs, { Dayjs } from 'dayjs'
|
||||
const emit = defineEmits(['changeDate', 'changeDateType'])
|
||||
|
||||
const disabledDate = (current: Dayjs) => {
|
||||
return current && current > dayjs().subtract(1).startOf('day')
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
cycleType: { type: String, default:'date' },
|
||||
date: { type: String, default: '' }
|
||||
})
|
||||
|
||||
const vdata = reactive({
|
||||
type: '日报',
|
||||
cycleType: 'date',//周期类型
|
||||
date: [] as any,
|
||||
startDate: dayjs().subtract(30, 'day'),
|
||||
endDate: dayjs().subtract(1, 'day')
|
||||
})
|
||||
onMounted(() => {
|
||||
if (!props.date) {
|
||||
vdata.date = [dayjs(vdata.startDate, 'YYYY-MM-DD'), dayjs(vdata.endDate, 'YYYY-MM-DD')]
|
||||
}
|
||||
})
|
||||
|
||||
// 重置按钮,不能直接重置时间选择,需要通过watch监听,进行重置
|
||||
watch( () => props.date ,(newVal,oldVal)=>{
|
||||
if (!props.date) {
|
||||
vdata.date = []
|
||||
}
|
||||
})
|
||||
|
||||
function changeType(e) {
|
||||
vdata.cycleType = e
|
||||
vdata.date = []
|
||||
emit('changeDateType', vdata.cycleType)
|
||||
// 清空时间具体值,保留时间类型
|
||||
emit('changeDate', { timeParams: '' })
|
||||
}
|
||||
|
||||
function changeDate(e) {
|
||||
let unit = vdata.cycleType
|
||||
if (vdata.cycleType == 'date') {
|
||||
unit = 'day'
|
||||
}
|
||||
|
||||
let start = e[0].startOf(unit).format('YYYY-MM-DD HH:mm:ss')
|
||||
let end = e[1].endOf(unit).format('YYYY-MM-DD HH:mm:ss')
|
||||
|
||||
let timeParameter = 'customDateTime_' + start + '_' + end
|
||||
let dateObject = reactive({
|
||||
startDate: start,
|
||||
endDate: end,
|
||||
timeParams: timeParameter
|
||||
})
|
||||
emit('changeDate', dateObject)
|
||||
}
|
||||
</script>
|
||||
239
jeepay-ui-agent/src/views/statistic/transaction/List.vue
Normal file
239
jeepay-ui-agent/src/views/statistic/transaction/List.vue
Normal file
@@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card class="table-card">
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="resetFunc">
|
||||
<JeepayDateCascadeSelection
|
||||
:date="vdata.searchData.queryDateRange"
|
||||
:cycleType="vdata.cycleType"
|
||||
@changeDate="changeDateHandle"
|
||||
@changeDateType="changeDateTypeHandle"
|
||||
/>
|
||||
<JeepaySearchInfoInput
|
||||
v-if="$access('ENT_STATISTIC_MCH')"
|
||||
v-model:value="vdata.searchData.mchNo"
|
||||
placeholder="用户号"
|
||||
:textUpStyle="true"
|
||||
:mchNoAndName="true"
|
||||
showType="MCH"
|
||||
/>
|
||||
<jeepay-text-up v-model:value="vdata.searchData['agentNo']" :placeholder="'代理商号'" />
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="vdata.searchData"
|
||||
row-key="groupDate"
|
||||
:statisticsIsShow="true"
|
||||
:tableExportFunc="tableExportFunc"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<span v-if="column.tooltipTitle">
|
||||
{{ column.title }}
|
||||
<a-tooltip :title="column.tooltipTitle"><info-circle-outlined /></a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<template #topBtnSlot>
|
||||
<a-button type="primary" @click="tableExportFunc">
|
||||
<plus-outlined />导出表格
|
||||
</a-button>
|
||||
</template>
|
||||
<template #statistics>
|
||||
<div class="statistics-list">
|
||||
<div v-for="(item, index) in count" :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 #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'totalSuccAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalSuccAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalFinalAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalFinalAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalEntryAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalEntryAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalFeeAmt'">
|
||||
<a-tooltip overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>收单手续费:¥{{ (record.totalFeeAmt / 100).toFixed(2) }}</span><br>
|
||||
<span>垫资手续费:¥{{ ( record.totalCashFee / 100).toFixed(2) }}</span>
|
||||
</template>
|
||||
<b style="color: #FF6848;">¥{{ ((record.totalFeeAmt + record.totalCashFee) / 100).toFixed(2) }}</b>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundAmt'">
|
||||
<b style="color: #15B86C;">¥{{ (record.totalRefundAmt / 100).toFixed(2)}}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundFeeAmt'">
|
||||
<b style="color: #FF6848;">¥{{ (record.totalRefundFeeAmt / 100).toFixed(2) }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalRefundNum'">
|
||||
<b style="color: #FF6848;">{{ record.totalRefundNum }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalSuccNum'">
|
||||
<b style="color: #15B86C;">{{ record.totalSuccNum }}/{{ record.totalNum }}</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'succRate'">
|
||||
<b style="color: #FF8800;">{{ record.succRate }}%</b>
|
||||
</template>
|
||||
<template v-if="column.key === 'operation'">
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_STATISTIC_MCH')" type="link" @click="toPage('/statistic/mch', record.groupDate)">商户详情</a-button>
|
||||
<a-button type="link" @click="toPage('/statistic/agent', record.groupDate)">代理商详情</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import { API_URL_STATISTIC, req, $exportExcel, exportExcelUrl } from '@/api/manage'
|
||||
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
||||
import JeepayDateCascadeSelection from './JeepayDateCascadeSelection.vue'
|
||||
import router from '@/router'
|
||||
import dateUtil from '@/utils/dateUtil.js'
|
||||
import { message } from 'ant-design-vue'
|
||||
import fileDownload from 'js-file-download'
|
||||
const { $infoBox, $access, $hasAgentEnt } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoDetail = ref()
|
||||
const infoTable = ref()
|
||||
let tableColumns = reactive([
|
||||
{ key: 'groupDate', title: '日期', dataIndex: 'groupDate', agentEntCol: true, },
|
||||
{ key: 'totalSuccAmt', title: '成交金额', tooltipTitle: '支付成功的订单金额,包含部分退款及全额退款的订单', dataIndex: 'totalSuccAmt', },
|
||||
{ key: 'totalRefundAmt', title: '退款金额', dataIndex: 'totalRefundAmt'},
|
||||
{ key: 'totalRefundNum', title: '退款笔数', tooltipTitle: '实际退款订单笔数,若一笔已成交订单退款多次,则计多次', dataIndex: 'totalRefundNum'},
|
||||
{ key: 'totalFeeAmt', title: '手续费', tooltipTitle: '成交订单所产生的交易手续费和垫资手续费', dataIndex: 'totalFeeAmt'},
|
||||
{ key: 'totalEntryAmt', title: '入账金额', tooltipTitle: '扣除已退款金额及手续费,入账金额为商户实际到账金额', dataIndex: 'totalEntryAmt'},
|
||||
{ key: 'totalSuccNum', title: '成交笔数/总交易笔数', dataIndex: 'totalSuccNum', },
|
||||
{ key: 'succRate', title: '成功率', tooltipTitle: '成交笔数与总订单笔数除得的百分比', dataIndex: 'succRate'},
|
||||
{ key: 'operation', title: '操作', fixed: 'right', align: 'center', }
|
||||
])
|
||||
|
||||
let btnLoading = ref(false)
|
||||
let count:any = ref([]) // 数据统计数组
|
||||
|
||||
const vdata : any = reactive({
|
||||
searchData: { method : 'transaction', queryDateType: 'day' }
|
||||
})
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params: any) {
|
||||
params.method = 'transaction'
|
||||
reqTableCountFunc(params)
|
||||
return req.list(API_URL_STATISTIC, params)
|
||||
}
|
||||
function searchFunc () { // 点击【查询】按钮点击事件
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableCountFunc(params: any) {
|
||||
req.list(API_URL_STATISTIC + '/total', params).then(res => {
|
||||
count.value = [
|
||||
{title: '总成交金额', symbol: 'add', textColor: '#1A66FF', content: ((res.totalSuccAmt) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总成交笔数', content: (res.totalSuccNum)},
|
||||
{type: 'line'},
|
||||
{title: '总退款金额', symbol: 'sub', content: ((res.totalRefundAmt) / 100).toFixed(2)},
|
||||
{type: 'line'},
|
||||
{title: '总退款笔数', content: (res.totalRefundNum)},
|
||||
// {type: 'line'},
|
||||
// {title: '支付成功率', content: (res.round) + '%'},
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
function resetFunc(){
|
||||
vdata.searchData = {}
|
||||
vdata.cycleType = 'date'
|
||||
}
|
||||
|
||||
function tableExportFunc(){
|
||||
return $exportExcel(exportExcelUrl.statistic, Object.assign({}, vdata.searchData, {})).then(res => {
|
||||
fileDownload(res.data, '交易报表.xlsx')
|
||||
}).catch ((error) =>{console.log(error)} )
|
||||
}
|
||||
|
||||
function toPage(path, groupDate) {
|
||||
let queryString = dateUtil.getMonthRangeQueryString(groupDate)
|
||||
if (vdata.searchData.queryDateType === 'day') {
|
||||
console.log('day')
|
||||
queryString = dateUtil.getDayRangeQueryString(groupDate)
|
||||
} else if(vdata.searchData.queryDateType === 'month') {
|
||||
queryString = dateUtil.getMonthRangeQueryString(groupDate)
|
||||
} else {
|
||||
queryString = dateUtil.getYearRangeQueryString(groupDate)
|
||||
}
|
||||
router.push({
|
||||
path: path,
|
||||
query: { queryDate: queryString }
|
||||
})
|
||||
}
|
||||
function dateDiff(startDate, endDate) {
|
||||
let flag = [1, 3, 5, 7, 8, 10, 12, 4, 6, 9, 11, 2]
|
||||
let start = new Date(startDate)
|
||||
let end = new Date(endDate)
|
||||
let year = end.getFullYear() - start.getFullYear()
|
||||
let month = end.getMonth() - start.getMonth()
|
||||
let day = end.getDate() - start.getDate()
|
||||
|
||||
if (month < 0) {
|
||||
year--
|
||||
month = end.getMonth() + (12 - start.getMonth())
|
||||
}
|
||||
|
||||
if (day < 0) {
|
||||
month--
|
||||
let index = flag.findIndex((temp) => { return temp === start.getMonth() + 1 })
|
||||
let monthLength = 0
|
||||
if (index <= 6) {
|
||||
monthLength = 31
|
||||
} else if (index > 6 && index <= 10) {
|
||||
monthLength = 30
|
||||
} else {
|
||||
monthLength = 28
|
||||
}
|
||||
day = end.getDate() + (monthLength - start.getDate())
|
||||
}
|
||||
let result = { years: year, months: month, days: day }
|
||||
return result
|
||||
}
|
||||
// 时间选择
|
||||
function changeDateHandle(e) {
|
||||
vdata.dateSpan = dateDiff(e.startDate, e.endDate)
|
||||
vdata.dateObject = { startDate: e.startDate, endDate: e.endDate }
|
||||
|
||||
if(vdata.searchData['queryDateType'] === 'day') {
|
||||
if(vdata.dateSpan.days > 30 || vdata.dateSpan.months > 0) {
|
||||
message.error('相隔天数最多为30天!')
|
||||
}
|
||||
} else if(vdata.searchData['queryDateType'] === 'month') {
|
||||
if(vdata.dateSpan.months > 12 || vdata.dateSpan.years > 0) {
|
||||
message.error('相隔月数最多为12个月!')
|
||||
}
|
||||
}
|
||||
vdata.searchData['queryDateRange'] = e.timeParams
|
||||
}
|
||||
// 周期选择
|
||||
function changeDateTypeHandle(e) {
|
||||
if(e === 'date') {
|
||||
vdata.searchData['queryDateType'] = 'day'
|
||||
} else {
|
||||
vdata.searchData['queryDateType'] = e
|
||||
}
|
||||
vdata['cycleType'] = e
|
||||
}
|
||||
</script>
|
||||
210
jeepay-ui-agent/src/views/store/AddOrEdit.vue
Normal file
210
jeepay-ui-agent/src/views/store/AddOrEdit.vue
Normal file
@@ -0,0 +1,210 @@
|
||||
|
||||
<!--
|
||||
复制自 运营平台
|
||||
差异: 无
|
||||
-->
|
||||
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.isShow"
|
||||
:title=" vdata.isAdd ? '新增门店' : '修改门店' "
|
||||
width="60%"
|
||||
:mask-closable="false"
|
||||
@close="vdata.isShow = false"
|
||||
>
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" :label-col="{span: 6}" :wrapper-col="{span: 15}" :rules="rules">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col v-if="vdata.isAdd" :span="12">
|
||||
<a-form-item label="用户:" name="mchNo">
|
||||
<JeepaySearchInfoInput v-model:value="vdata.saveObject.mchName" placeholder="用户号" @itemRender="getUserMchNo" :textUpStyle="false" showType="MCH" :onlyMchName="true" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="选择商户" name="mchApplyId" >
|
||||
<a-select :disabled="vdata.isAdd?false : true" v-model:value="vdata.saveObject.mchApplyId" placeholder="请选择商户号" show-search @search="handleBankChange" :filter-option="false">
|
||||
<a-select-option v-for="(d, index) in vdata.filteredAppInfoList" :key="index" v-model:value="d.applyId"> {{ d.mchShortName }} - {{ d.applyId }} - {{ d.ifName }} </a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="门店名称:" name="storeName">
|
||||
<a-input v-model:value="vdata.saveObject.storeName" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="联系人电话" name="contactPhone">
|
||||
<a-input v-model:value="vdata.saveObject.contactPhone" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="门店LOGO" name="storeLogo">
|
||||
<JeepayUpload v-model:src="vdata.saveObject.storeLogo" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="门头照" name="storeOuterImg">
|
||||
<JeepayUpload v-model:src="vdata.saveObject.storeOuterImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="门店内景照" name="storeInnerImg">
|
||||
<JeepayUpload v-model:src="vdata.saveObject.storeInnerImg" bizType="applyment" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="备注:" name="remark">
|
||||
<a-input v-model:value="vdata.saveObject.remark" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-divider />
|
||||
|
||||
<!-- 引入地图组件 -->
|
||||
<JeepayAmap ref="jeepayAmapRef" />
|
||||
</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 lang="ts" setup>
|
||||
import { req, API_URL_MCH_STORE_LIST,API_URL_MCH_APPLYMENT_LIST }from '@/api/manage'
|
||||
import { reactive, ref, getCurrentInstance, nextTick } from 'vue'
|
||||
import {message} from "ant-design-vue";
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const jeepayAmapRef = ref()
|
||||
const infoFormModel = ref()
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: {type: Function, default: () => {} }
|
||||
})
|
||||
|
||||
const vdata = reactive({
|
||||
appList:[] as any,
|
||||
filteredAppInfoList:[] as any,
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isAdd: true, // 新增 or 修改页面标识
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: {} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
})
|
||||
|
||||
const rules = {
|
||||
mchNo: [{ required: true, message: '请输入用户名称', trigger: 'blur' }],
|
||||
storeName: [{ required: true, message: '请输入门店名称', trigger: 'blur' }],
|
||||
mchApplyId: [{ required: true, message: '请输入商户号', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
|
||||
function show (mchNo, recordId) { // 弹层打开事件
|
||||
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
vdata.isAdd = !recordId
|
||||
|
||||
// 数据恢复为默认数据
|
||||
vdata.saveObject = {mchNo: mchNo, lng: '', lat: ''}
|
||||
|
||||
vdata.confirmLoading = false // 关闭loading
|
||||
|
||||
let initMapData : any = {}
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_MCH_STORE_LIST, recordId).then(res => {
|
||||
vdata.saveObject = res
|
||||
|
||||
// 门店包含了区域编码
|
||||
if(res.areaCode && res.areaCode.length){
|
||||
initMapData.areacode = res.areaCode
|
||||
initMapData.lnglat = res.lng + ',' + res.lat
|
||||
initMapData.address = res.address
|
||||
}
|
||||
|
||||
// 显示地图信息
|
||||
nextTick(() => jeepayAmapRef.value.init(initMapData))
|
||||
|
||||
})
|
||||
vdata.isShow = true
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
vdata.isShow = true // 立马展示弹层信息
|
||||
|
||||
// 显示地图信息
|
||||
nextTick(() => jeepayAmapRef.value.init(initMapData))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 设置地图标点
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
|
||||
|
||||
let mapData = jeepayAmapRef.value.getMapData()
|
||||
// if(!mapData || mapData.areacode.length == 0 || !mapData.address || !mapData.lnglat){
|
||||
// return $infoBox.message.error('请选择地理位置')
|
||||
// }
|
||||
|
||||
// if(mapData.lnglat.indexOf(',') < 0){
|
||||
// return $infoBox.message.error('请输入正确的经纬度')
|
||||
// }
|
||||
|
||||
|
||||
infoFormModel.value.validate().then(valid =>{
|
||||
|
||||
vdata.confirmLoading = true // 显示loading
|
||||
|
||||
vdata.saveObject.lng = mapData.lnglat.split(',')[0]
|
||||
vdata.saveObject.lat = mapData.lnglat.split(',')[1]
|
||||
vdata.saveObject.address = mapData.address
|
||||
vdata.saveObject.areaCode = JSON.stringify(mapData.areacode)
|
||||
|
||||
// 请求HTTP
|
||||
req.addOrUpdate(vdata.isAdd ? null: vdata.recordId, API_URL_MCH_STORE_LIST, vdata.saveObject).then(res => {
|
||||
vdata.isShow = false
|
||||
vdata.confirmLoading = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(valid =>{
|
||||
vdata.confirmLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
async function businessList(){
|
||||
let res = await req.list(API_URL_MCH_APPLYMENT_LIST, {pageNumber:1,pageSize:-1,state:99,mchNo:vdata.saveObject.mchNo});
|
||||
|
||||
vdata.filteredAppInfoList = res.records
|
||||
console.log(vdata.filteredAppInfoList,'vdatafilteredAppInfoList')
|
||||
vdata.appList = res.records
|
||||
}
|
||||
const handleBankChange = (value) => {
|
||||
if(!vdata.saveObject.mchNo){
|
||||
return message.error('请先选择用户')
|
||||
}
|
||||
vdata.filteredAppInfoList = [];
|
||||
vdata.appList.forEach((item,index) => {
|
||||
if (item.mchShortName.includes(value) || item.applyId.includes(value)) {
|
||||
vdata.filteredAppInfoList.push(vdata.appList[index]);
|
||||
}
|
||||
});
|
||||
};
|
||||
function getUserMchNo(e){
|
||||
console.log(e,'--------')
|
||||
vdata.saveObject.mchNo = e.mchNo
|
||||
vdata.saveObject.mchName = e.mchName
|
||||
businessList()
|
||||
|
||||
|
||||
}
|
||||
defineExpose({show})
|
||||
</script>
|
||||
189
jeepay-ui-agent/src/views/store/Detail.vue
Normal file
189
jeepay-ui-agent/src/views/store/Detail.vue
Normal file
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:title=" true ? '门店详情' : '' "
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
width="40%"
|
||||
@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.mchDetail.mchFullName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户简称">
|
||||
{{ vdata.mchDetail.mchShortName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户类型">
|
||||
{{ vdata.mchDetail.merchantType == 1?'小微':vdata.mchDetail.merchantType == 2?'个体':vdata.mchDetail.merchantType == 1?'企业':'其他' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="结算状态">
|
||||
{{vdata.mchDetail.settlementType??"无"}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="联系人姓名">
|
||||
{{ vdata.mchDetail.contactName }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="联系人手机号">
|
||||
{{ vdata.mchDetail.contactPhone }}
|
||||
</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['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="门店logo">
|
||||
<a-image v-if="vdata.detailData['storeLogo']" class="img" :src="vdata.detailData['storeLogo']" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="门店内景照">
|
||||
<a-image v-if="vdata.detailData['storeInnerImg']" class="img" :src="vdata.detailData['storeInnerImg']" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="门头照">
|
||||
<a-image v-if="vdata.detailData['storeOuterImg']" class="img" :src="vdata.detailData['storeOuterImg']" />
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="门店地址">
|
||||
{{ vdata.detailData['address'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<!-- <a-col :sm="12">-->
|
||||
<!-- <a-descriptions>-->
|
||||
<!-- <a-descriptions-item label="代理商号">-->
|
||||
<!-- {{ vdata.detailData['agentNo'] }}-->
|
||||
<!-- </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['contactPhone'] }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row justify="start" type="flex">
|
||||
<a-col :sm="24">
|
||||
<a-form-item label="备注">
|
||||
<a-input
|
||||
v-model:value="vdata.detailData['remark']"
|
||||
type="textarea"
|
||||
disabled="disabled"
|
||||
style="height: 50px"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {API_URL_MCH_APPLYMENT_LIST, API_URL_MCH_STORE_LIST, req} from '@/api/manage'
|
||||
import { reactive } from 'vue'
|
||||
const vdata:any = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {}, // 数据对象
|
||||
mchDetail:{},// 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
isvList: [], // 服务商下拉列表
|
||||
isvName: '' // 服务商名称
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
vdata.detailData = {} // 数据清空
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_MCH_STORE_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
mchDetail()
|
||||
})
|
||||
|
||||
|
||||
|
||||
vdata.visible = true
|
||||
}
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
function mchDetail(){
|
||||
req.getById(API_URL_MCH_APPLYMENT_LIST, vdata.detailData.mchApplyId).then(res => {
|
||||
if(res.succResParameter){
|
||||
const succResParameter = JSON.parse(res.succResParameter)
|
||||
vdata.termNo = succResParameter.termNo
|
||||
}else{
|
||||
vdata.termNo = "无"
|
||||
}
|
||||
vdata.mchDetail = res
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
.img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
215
jeepay-ui-agent/src/views/store/StorePage.vue
Normal file
215
jeepay-ui-agent/src/views/store/StorePage.vue
Normal file
@@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="() => { vdata.searchData = {} }">
|
||||
<JeepaySearchInfoInput v-model:value="vdata.searchData['mchNo']" placeholder="用户号" :textUpStyle="true" :mchNoAndName="true" showType="MCH" />
|
||||
|
||||
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchApplyName']" :placeholder="'商户名称/商户号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['storeId']" :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['mchUserName']" :placeholder="'用户号/名称/手机号'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchServiceName']" :placeholder="'服务商号/服务商名称'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['bindAppIdName']" :placeholder="'应用名称/应用ID'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['contactPhone']" :placeholder="'联系人电话'" />
|
||||
</JeepaySearchForm>
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="false"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="storeId"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<div>
|
||||
<a-button v-if="$access('ENT_MCH_STORE_ADD')" type="primary" class="mg-b-30" @click="addFunc"><plus-outlined />新建</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'storeName'">
|
||||
<a @click="detailFunc(record.storeId)"><b>{{ record.storeName }}</b></a >
|
||||
</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.bindAppId}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.bindAppIdName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
|
||||
<template v-if="column.key === 'mchUserName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>用户名称:{{record.mchUserName}}</span><br>
|
||||
<span>用户手机号:{{record.mchUserPhone}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchUserName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchServiceName'">
|
||||
<a-tooltip class="my-tooltip" overlayClassName="tooltip-box-name">
|
||||
<template #title>
|
||||
<span>服务商名称:{{record.mchServiceName}}</span><br>
|
||||
<span>服务商号:{{record.agentNo}}</span>
|
||||
</template>
|
||||
<div class="my-tooltip-title-box"> {{record.mchServiceName}}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchShortName'">
|
||||
<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 === 'defaultFlag'">
|
||||
<a-tag v-if="record.defaultFlag===1" color="green">是</a-tag>
|
||||
<a-switch v-else :checked="record.defaultFlag===1?true:false" @change="(defaultFlag) => { return updateState(record.mchNo, record.storeId, defaultFlag)}" />
|
||||
</template>
|
||||
<template v-if="column.key === 'deviceNumber'">
|
||||
<a href="javascript:void(0)" @click="deviceFunc(record.storeId)">{{ record.deviceNumber ? record.deviceNumber : 0 }}</a>
|
||||
</template>
|
||||
<template v-if="column.key === 'remark'">
|
||||
<!-- <span @click="editFunc(record.storeId)" class="two-lines"-->
|
||||
<!-- ><b></b>-->
|
||||
<!-- <EditOutlined @click="editFunc(record.storeId)" />-->
|
||||
<!-- </span>-->
|
||||
<div class="my-tooltip-title-box"> {{record.remark != "" ? record.remark : "--" }}</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_MCH_STORE_EDIT')" type="link" style="padding-right: 10px;padding-left: 10px;" @click="deviceFunc(record.storeId)">设备管理</a-button>
|
||||
<a-button v-if="$access('ENT_MCH_STORE_EDIT')" type="link" style="padding-right: 10px; padding-left: 10px;text-align: center" @click="editFunc(record.storeId)" >修改</a-button >
|
||||
<a-button v-if="$access('ENT_MCH_STORE_DELETE')" type="link" style="color: red" @click="delFunc(record.storeId)">删除</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 新增 / 修改 页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
<!-- 详情页面组件 -->
|
||||
<InfoDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_MCH_STORE_LIST, req, reqLoad } from '@/api/manage'
|
||||
import InfoAddOrEdit from './AddOrEdit.vue'
|
||||
import InfoDetail from './Detail.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ref, onMounted, reactive, getCurrentInstance } from 'vue'
|
||||
import router from '@/router'
|
||||
// 获取全局函数
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const tableColumns = reactive([
|
||||
{ title: "商户名称", key: "mchShortName", dataIndex: "mchShortName" },
|
||||
{ title: "门店名称", key: "storeName", dataIndex: "storeName"},
|
||||
{ title: "门店编号", dataIndex: "storeId"},
|
||||
{ title: '用户名称', key: 'mchUserName', dataIndex: 'mchUserName' },
|
||||
{ title: '服务商名称', key: 'mchServiceName', dataIndex: 'mchServiceName' },
|
||||
// { title: "是否默认", key: "defaultFlag", align: "center" },
|
||||
{ title: "所属应用",key: "bindAppIdName", dataIndex: "bindAppIdName" },
|
||||
{ title: "联系电话", dataIndex: "contactPhone" },
|
||||
{ title: "备注", key: "remark", dataIndex: "remark"},
|
||||
{ title: "设备总数", key: "deviceNumber", dataIndex: "deviceNumber", align: "center" },
|
||||
// { title: '蚂蚁店铺状态', key: 'alipayShopStatus', dataIndex: 'alipayShopStatus' },
|
||||
{ title: "创建时间", dataIndex: "createdAt" },
|
||||
{ key: "op", title: "操作", fixed: "right", align: "center" },
|
||||
])
|
||||
const infoDetail = ref()
|
||||
const infoAddOrEdit = ref()
|
||||
const infoTable = ref()
|
||||
const vdata = reactive({
|
||||
tableColumns: tableColumns,
|
||||
searchData: {} as any,
|
||||
btnLoading: false
|
||||
})
|
||||
|
||||
const queryFunc = () => {
|
||||
|
||||
vdata.btnLoading = true
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
vdata.searchData['mchNo'] = useRoute().query.mchNo
|
||||
queryFunc()
|
||||
})
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc (params) {
|
||||
return req.list(API_URL_MCH_STORE_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc() { // 点击【查询】按钮点击事件
|
||||
vdata.btnLoading = true // 打开查询按钮的loading
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show(vdata.searchData['mchNo'])
|
||||
}
|
||||
function delFunc (recordId) { // 业务通用【删除】 函数
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
return req.delById(API_URL_MCH_STORE_LIST, recordId).then(res => {
|
||||
$infoBox.message.success('删除成功!')
|
||||
infoTable.value.refTable(false)
|
||||
}).catch(err => {})
|
||||
})
|
||||
}
|
||||
function editFunc (recordId) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(vdata.searchData['mchNo'], recordId)
|
||||
}
|
||||
function detailFunc (recordId: any) { // 门店详情页
|
||||
infoDetail.value.show(recordId)
|
||||
}
|
||||
function updateState (mchNo, recordId, state) { // 【更新状态】
|
||||
const title = state === 1 ? '确认[默认]该门店?' : '确认[取消默认]该门店?'
|
||||
const content = '开启默认后则默认使用该门店配置,有且只能有一个默认门店。'
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return reqLoad.updateById(API_URL_MCH_STORE_LIST, recordId, { mchNo: mchNo, defaultFlag: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 云喇叭配置
|
||||
function speakerConfig (recordId: any) {
|
||||
router.push({
|
||||
path: '/store/speaker',
|
||||
query: { storeId: recordId }
|
||||
})
|
||||
}
|
||||
function deviceFunc(storeId){
|
||||
router.push({
|
||||
path: "/qrc",
|
||||
query:{storeId:storeId}
|
||||
});
|
||||
}
|
||||
|
||||
// 云打印配置
|
||||
function printerConfig (recordId: any) {
|
||||
router.push({
|
||||
path: '/store/printer',
|
||||
query: { storeId: recordId }
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
239
jeepay-ui-agent/src/views/sys/advert/AddOrEdit.vue
Normal file
239
jeepay-ui-agent/src/views/sys/advert/AddOrEdit.vue
Normal file
@@ -0,0 +1,239 @@
|
||||
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.isShow"
|
||||
:title="vdata.isAdd ? '新增广告' : '编辑广告'"
|
||||
width="50%"
|
||||
:mask-closable="false"
|
||||
@close="vdata.isShow = false"
|
||||
>
|
||||
<a-form ref="infoFormModel" :model="vdata.saveObject" :label-col="{ span: 6 }" :wrapper-col="{ span: 15 }" :rules="rules">
|
||||
<a-row justify="center" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="标题" name="title">
|
||||
<a-input v-model:value="vdata.saveObject.title" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="状态" name="releaseState">
|
||||
<a-radio-group v-model:value="vdata.saveObject['releaseState']">
|
||||
<a-radio :value="1">
|
||||
立即发布
|
||||
</a-radio>
|
||||
<a-radio :value="0">
|
||||
手动发布
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider orientation="left">轮播设置</a-divider>
|
||||
<a-col :span="24">
|
||||
<a-button
|
||||
class="editable-add-btn"
|
||||
style="margin-bottom: 8px;margin-left: 30px;"
|
||||
type="dashed"
|
||||
@click="handleAdd"
|
||||
>
|
||||
<PlusOutlined />新增
|
||||
</a-button>
|
||||
<a-table bordered :data-source="vdata.saveObject.infoList" :columns="columns">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'imgUrl'">
|
||||
<div class="editable-cell">
|
||||
<div class="editable-cell-input-wrapper">
|
||||
<JeepayUpload v-model:src="record.imgUrl" bizType="notice" listType="picture-card" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'sort'">
|
||||
<div class="editable-cell-input-wrapper">
|
||||
<a-input-number v-model:value="record.sort" :min="0" :max="10" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'linkUrl' && vdata.groupKey != 'faceAdvert'">
|
||||
<div class="editable-cell-input-wrapper">
|
||||
<a-input v-model:value="record.linkUrl" placeholder="请以http://或https://开头" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'operation'">
|
||||
<a style="color: red" @click="onDelete(record)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-col>
|
||||
|
||||
<div v-if="vdata.isAdd">
|
||||
<a-row v-if="vdata.groupKey == 'faceAdvert'" justify="center" type="flex">
|
||||
<a-divider orientation="left">所属商户配置</a-divider>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="发布商户" name="bindType">
|
||||
<a-space>
|
||||
<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-button v-if="vdata.saveObject.bindType == 1" type="primary" @click="showQrcSelectModel">选择商户</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.saveObject.bindType == 1" :span="24">
|
||||
<a-form-item label="所属商户" name="infoIds">
|
||||
<a-textarea v-model:value="vdata.saveObject.infoIds" disabled />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</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>
|
||||
<!-- 选择商户组件 -->
|
||||
<JeepayModelSelectMchList ref="jeepayModelSelectMchRef" @selectFinishFunc="selectQrcFinishFunc" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { req, API_URL_ADVERT } from '@/api/manage'
|
||||
import { reactive, ref, getCurrentInstance, computed } from 'vue'
|
||||
|
||||
const { $infoBox, $access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const infoFormModel = ref()
|
||||
const jeepayModelSelectMchRef = ref()
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function, default: () => { } }
|
||||
})
|
||||
|
||||
const columns = [
|
||||
{ title: '广告图片(建议尺寸800x1280px)', dataIndex: 'imgUrl', width: '35%', },
|
||||
{ title: '轮播排序', dataIndex: 'sort', },
|
||||
{ title: '操作', dataIndex: 'operation', },
|
||||
]
|
||||
|
||||
const vdata = reactive({
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isAdd: true, // 新增 or 修改页面标识
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: {infoList: [{ imgUrl: '', linkUrl: '', sort: '' }]} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
groupKey: '',
|
||||
})
|
||||
|
||||
const rules = {
|
||||
title: [{ required: true, message: '请输入广告标题', trigger: 'blur' }],
|
||||
releaseState: [{ required: true, message: '请选择发布状态', trigger: 'blur' }],
|
||||
imgUrl: [{ required: true, message: '请上传广告图片', trigger: 'blur' }],
|
||||
linkUrl: [{ required: true, message: '请输入广告链接', trigger: 'blur' }],
|
||||
content: [{ required: true, message: '请输入广告内容', trigger: 'blur' }],
|
||||
bindType: [{ required: true, message: '请选择发布商户类型', trigger: 'blur' }],
|
||||
infoIds: [{ required: true, message: '请选择要发布的商户', trigger: 'blur' }],
|
||||
advertSort: [{ required: true, message: '请输入广告排序', trigger: 'blur' }],
|
||||
changeTime: [{ required: true, message: '请输入轮播时间', trigger: 'blur' }],
|
||||
}
|
||||
|
||||
|
||||
function show(groupKey, recordId) { // 弹层打开事件
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
vdata.groupKey = groupKey
|
||||
vdata.isAdd = !recordId
|
||||
|
||||
// 数据恢复为默认数据
|
||||
vdata.saveObject = { bindType: 0, releaseState: 1 }
|
||||
vdata.saveObject.infoList = [{ imgUrl: '', linkUrl: '', sort: '' }]
|
||||
vdata.saveObject.infoIds = ''
|
||||
|
||||
vdata.confirmLoading = false // 关闭loading
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_ADVERT, recordId).then(res => {
|
||||
vdata.saveObject = res
|
||||
if (vdata.saveObject.appContent) {
|
||||
vdata.saveObject.infoList = JSON.parse(vdata.saveObject.appContent)
|
||||
}
|
||||
})
|
||||
}
|
||||
vdata.isShow = true // 立马展示弹层信息
|
||||
}
|
||||
|
||||
function handleOkFunc() { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then(valid => {
|
||||
|
||||
vdata.confirmLoading = true // 显示loading
|
||||
if (vdata.saveObject.infoList.length < 1) {
|
||||
vdata.confirmLoading = false
|
||||
return $infoBox.message.error('轮播配置不可为空')
|
||||
}
|
||||
vdata.saveObject.advertType = '1'
|
||||
if (vdata.saveObject.infoList) {
|
||||
var firstInfo = vdata.saveObject.infoList[0]
|
||||
if (!firstInfo.imgUrl) {
|
||||
vdata.confirmLoading = false
|
||||
return $infoBox.message.error('轮播图不可为空')
|
||||
}
|
||||
vdata.saveObject.imgUrl = firstInfo.imgUrl
|
||||
vdata.saveObject.linkUrl = firstInfo.linkUrl
|
||||
}
|
||||
vdata.saveObject.appContent = JSON.stringify(vdata.saveObject.infoList)
|
||||
|
||||
// 请求HTTP
|
||||
req.addOrUpdate(vdata.isAdd ? null : vdata.recordId, API_URL_ADVERT, vdata.saveObject).then(res => {
|
||||
vdata.isShow = false
|
||||
vdata.confirmLoading = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(valid => {
|
||||
vdata.confirmLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 选择商户弹窗
|
||||
function showQrcSelectModel() {
|
||||
jeepayModelSelectMchRef.value.show(vdata.saveObject.infoIds, { advertFlag: '1' })
|
||||
}
|
||||
|
||||
// 选择商户完成
|
||||
function selectQrcFinishFunc(e) {
|
||||
|
||||
if (!e || e.length <= 0) {
|
||||
return $infoBox.message.error('请选中要发布广告的商户!')
|
||||
}
|
||||
|
||||
vdata.saveObject.infoIds = e.toString()
|
||||
jeepayModelSelectMchRef.value.close()
|
||||
}
|
||||
|
||||
const count = computed(() => vdata.saveObject.infoList.length + 1)
|
||||
|
||||
const onDelete = (item) => {
|
||||
// vdata.saveObject.infoList = vdata.saveObject.infoList.filter(item => item.key !== key)
|
||||
const index = vdata.saveObject.infoList.indexOf(item)
|
||||
if (index != -1) {
|
||||
vdata.saveObject.infoList.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
if (vdata.saveObject.appPlaceType == '1' && vdata.saveObject.infoList.length > 1) {
|
||||
return $infoBox.message.error('卡片广告最多添加两条记录!')
|
||||
}
|
||||
const newData = { key: `${count.value}`, imgUrl: ``, sort: '', linkUrl: ``, }
|
||||
vdata.saveObject.infoList.push(newData)
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.ant-btn-dangerous {
|
||||
position: absolute;
|
||||
right: 50px;
|
||||
}
|
||||
.ant-row-space-between {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
193
jeepay-ui-agent/src/views/sys/advert/Advert.vue
Normal file
193
jeepay-ui-agent/src/views/sys/advert/Advert.vue
Normal file
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div style="background: #fff">
|
||||
<a-tabs @change="selectTabs">
|
||||
<a-tab-pane key="faceAdvert" tab="刷脸设备广告">
|
||||
<div class="account-settings-info-view">
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm :searchFunc="searchFunc" :resetFunc="() => { vdata.searchData = {} }">
|
||||
<jeepay-text-up v-model:value="vdata.searchData['advertId']" :placeholder="'ID'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['title']" :placeholder="'标题'" />
|
||||
<jeepay-text-up v-model:value="vdata.searchData['mchNo']" :placeholder="'用户号'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="vdata.searchData['releaseState']" 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="infoTableFace"
|
||||
:initData="false"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumnsFace"
|
||||
:searchData="vdata.searchData"
|
||||
rowKey="advertId"
|
||||
:rowSelection="{ type: 'checkbox', onChange: infoTableSelectChangeFunc }"
|
||||
@btnLoadClose="vdata.btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<div>
|
||||
<a-button v-if="$access('ENT_ADVERT_ADD')" type="primary" class="mg-b-30" @click="addFunc"><plus-outlined />新建</a-button>
|
||||
<a-button v-if="$access('ENT_ADVERT_DEL')" type="danger" @click="deleteBatchFunc"><delete-outlined />批量删除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'advertType'">
|
||||
{{ record.advertType === 1?'刷脸设备广告':record.advertType === 2?'支付后广告':record.advertType === 3?$SYS_NAME_MAP.MCH_APP+'APP':$SYS_NAME_MAP.AGENT_APP+'APP' }}
|
||||
</template>
|
||||
<template v-if="column.key === 'releaseState'">
|
||||
<JeepayTableColState :showSwitchType="true" :badgeTextArray="['已发布','待发布','未知']" :state="record.releaseState" :on-change="(releaseState) => { return updateState(record.advertId, releaseState)}" />
|
||||
</template>
|
||||
<template v-if="column.key === 'imgUrl'">
|
||||
<a-image
|
||||
:width="60"
|
||||
:src="record.imgUrl"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'mchNo'">
|
||||
<div v-if="record.mchNo">
|
||||
用户号: {{ record.mchNo }} <br> 商户名:{{ record.infoName }}
|
||||
</div>
|
||||
<div v-else>全部商户</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_ADVERT_EDIT')" type="link" style="padding-right: 10px;padding-left: 10px;" @click="editFunc(record.advertId)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_ADVERT_DEL')" type="link" style="color: red" @click="delFunc(record.advertId)">删除</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
</page-header-wrapper>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
<!-- 新增 / 修改 页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_ADVERT, req, $batchDelAdvert, reqLoad} from '@/api/manage'
|
||||
import InfoAddOrEdit from './AddOrEdit.vue'
|
||||
import { ref, reactive, getCurrentInstance, nextTick, onMounted } from 'vue'
|
||||
|
||||
const { $infoBox, $access, $SYS_NAME_MAP } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
|
||||
const tableColumnsFace = reactive([
|
||||
{ title: 'ID', dataIndex: 'advertId' },
|
||||
{ title: '标题', key: 'title', dataIndex: 'title' },
|
||||
{ title: '预览图', key: 'imgUrl', dataIndex: 'imgUrl' },
|
||||
// { title: '广告类型', key: 'advertType', dataIndex: 'advertType' },
|
||||
{ title: '用户号', key: 'mchNo', dataIndex: 'mchNo' },
|
||||
{ title: '发布状态', key: 'releaseState', dataIndex: 'releaseState' },
|
||||
{ title: '创建时间', dataIndex: 'createdAt'},
|
||||
{ key: 'op',title: '操作', fixed: 'right', align: 'center'}
|
||||
])
|
||||
|
||||
const vdata : any = reactive ({
|
||||
btnLoading: false,
|
||||
tableColumnsFace: tableColumnsFace,
|
||||
searchData: {},
|
||||
allotDeviceIdList: [], // 要划拨的设备ID,划拨类型为 select-勾选划拨 时必填
|
||||
groupKey: 'faceAdvert',
|
||||
})
|
||||
|
||||
const infoTableFace = ref()
|
||||
|
||||
const infoAddOrEdit = ref()
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc (params) {
|
||||
return req.list(API_URL_ADVERT, vdata.searchData)
|
||||
}
|
||||
|
||||
onMounted(()=>{
|
||||
searchFunc()
|
||||
})
|
||||
|
||||
function searchFunc() { // 点击【查询】按钮点击事件
|
||||
vdata.btnLoading = true // 打开查询按钮的loading
|
||||
|
||||
vdata.searchData.advertType = '1'
|
||||
infoTableFace.value.refTable(true)
|
||||
}
|
||||
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show(vdata.groupKey)
|
||||
}
|
||||
function delFunc (recordId) { // 业务通用【删除】 函数
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
$batchDelAdvert(recordId).then((res: any) => {
|
||||
$infoBox.message.success('删除成功!')
|
||||
|
||||
infoTableFace.value.refTable(false)
|
||||
}).catch(err => {})
|
||||
})
|
||||
}
|
||||
function editFunc (recordId) { // 业务通用【修改】 函数
|
||||
infoAddOrEdit.value.show(vdata.groupKey, recordId)
|
||||
}
|
||||
|
||||
function selectTabs (key) { // 清空必填提示
|
||||
if (key) {
|
||||
vdata.groupKey = key
|
||||
nextTick(() => {
|
||||
searchFunc()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 表格多选
|
||||
function infoTableSelectChangeFunc(selectedRowKeys, selectedRows) {
|
||||
vdata.selectRecordIdList = selectedRowKeys
|
||||
}
|
||||
|
||||
function deleteBatchFunc() { // 批量删除
|
||||
if (!vdata.selectRecordIdList || vdata.selectRecordIdList.length < 1) {
|
||||
$infoBox.message.error('请选择广告配置')
|
||||
} else {
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
$batchDelAdvert(vdata.selectRecordIdList.join(',')).then((res: any) => {
|
||||
searchFunc()
|
||||
$infoBox.message.success('删除成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
return reqLoad.updateById(API_URL_ADVERT, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.flex {
|
||||
display:flex;
|
||||
margin-bottom: 8px;
|
||||
i {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
.bottom-btn{
|
||||
/deep/ div{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
400
jeepay-ui-agent/src/views/sysuser/AddOrEdit.vue
Normal file
400
jeepay-ui-agent/src/views/sysuser/AddOrEdit.vue
Normal file
@@ -0,0 +1,400 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.isShow"
|
||||
:title=" vdata.isAdd ? '新增操作员' : '修改操作员' "
|
||||
placement="right"
|
||||
:closable="true"
|
||||
width="600"
|
||||
:mask-closable="false"
|
||||
@ok="handleOkFunc"
|
||||
@close="onClose"
|
||||
>
|
||||
<!-- <a-modal :confirmLoading="confirmLoading"> -->
|
||||
|
||||
<a-form
|
||||
ref="infoFormModel"
|
||||
:model="vdata.saveObject"
|
||||
layout="vertical"
|
||||
:rules="rules"
|
||||
style="padding-bottom:50px"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="用户登录名:" name="loginUsername">
|
||||
<a-input v-model:value="vdata.saveObject['loginUsername']" :disabled="!vdata.isAdd" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="10">
|
||||
<a-form-item label="用户姓名:" name="realname">
|
||||
<a-input v-model:value="vdata.saveObject['realname']" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="10">
|
||||
<a-form-item label="手机号:" name="telphone">
|
||||
<a-input v-model:value="vdata.saveObject['telphone']" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="10">
|
||||
<a-form-item label="编号:" name="userNo">
|
||||
<a-input v-model:value="vdata.saveObject['userNo']" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="10">
|
||||
<a-form-item label="请选择性别:" name="sex">
|
||||
<a-radio-group v-model:value="vdata.saveObject['sex']">
|
||||
<a-radio :value="1">
|
||||
男
|
||||
</a-radio>
|
||||
<a-radio :value="2">
|
||||
女
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<!-- <a-col :span="10">
|
||||
<a-form-item label="是否为超级管理员:" name="isAdmin">
|
||||
<a-radio-group v-model:value="vdata.saveObject['isAdmin']">
|
||||
<a-radio :value="1">
|
||||
是
|
||||
</a-radio>
|
||||
<a-radio :value="0">
|
||||
否
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col> -->
|
||||
|
||||
<a-col :span="10">
|
||||
<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="10">
|
||||
<a-form-item label="用户类型:" name="userType">
|
||||
<a-select v-model:value="vdata.saveObject.userType" placeholder="请选择用户类型" @change="changeUserType">
|
||||
<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-col>
|
||||
|
||||
<a-col v-if="vdata.saveObject.userType == 3" :span="10">
|
||||
<a-form-item label="选择团队" name="provider">
|
||||
<a-select v-model:value="vdata.saveObject.teamId" placeholder="请选择团队">
|
||||
<a-select-option v-for="(item, key) in vdata.teamList" :key="key" v-model:value="item.teamId">
|
||||
{{ item.teamName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col v-if="vdata.saveObject.userType == 3" :span="10">
|
||||
<a-form-item label="是否队长" name="isTeamLeader">
|
||||
<a-radio-group v-model:value="vdata.saveObject.isTeamLeader">
|
||||
<a-radio :value="1">
|
||||
是
|
||||
</a-radio>
|
||||
<a-radio :value="0">
|
||||
否
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
账户安全
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
|
||||
<div v-if="vdata.isAdd">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="是否发送开通提醒">
|
||||
<a-radio-group v-model:value="vdata.saveObject['isNotify']">
|
||||
<a-radio :value="0">否</a-radio>
|
||||
<a-radio :value="1">是</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="密码设置">
|
||||
<a-radio-group v-model:value="vdata.saveObject['passwordType']">
|
||||
<a-radio value="default">默认密码</a-radio>
|
||||
<a-radio value="custom">自定义密码</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.saveObject['passwordType'] == 'custom'" :span="12">
|
||||
<a-form-item label="登录密码" name="loginPassword">
|
||||
<a-input
|
||||
v-model:value="vdata.saveObject['loginPassword']"
|
||||
placeholder="请输入登录密码"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-button type="primary" ghost @click="randomPassage(false, 6, 0)"><file-sync-outlined />随机生成密码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div style="display:flex;flex-direction:row;">
|
||||
<a-row justify="space-between" type="flex" style="width:100%">
|
||||
<a-col :span="10">
|
||||
<a-form-item v-if="vdata.resetIsShow" label="">
|
||||
重置密码:<a-checkbox v-model:checked="vdata.sysPassword.resetPass" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item v-if="vdata.sysPassword.resetPass" label="">
|
||||
恢复默认密码:<a-checkbox v-model:checked="vdata.sysPassword.defaultPass" @click="isResetPass" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
|
||||
<div v-if="vdata.sysPassword.resetPass">
|
||||
<div v-show="!vdata.sysPassword.defaultPass">
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="新密码:" name="newPwd">
|
||||
<a-input-password
|
||||
v-model:value="vdata.newPwd"
|
||||
autocomplete="new-password"
|
||||
:disabled="vdata.sysPassword.defaultPass"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="10">
|
||||
<a-form-item label="确认新密码:" name="confirmPwd">
|
||||
<a-input-password
|
||||
v-model:value="vdata.sysPassword.confirmPwd"
|
||||
autocomplete="new-password"
|
||||
:disabled="vdata.sysPassword.defaultPass"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose">
|
||||
<close-outlined />
|
||||
取消
|
||||
</a-button>
|
||||
<a-button type="primary" :loading="vdata.confirmLoading" @click="handleOkFunc">
|
||||
<check-outlined />
|
||||
保存
|
||||
</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { req, API_URL_SYS_USER_LIST, API_URL_SYS_USER_TEAM_LIST, $getPasswordRules } from '@/api/manage'
|
||||
import { reactive,ref } from 'vue'
|
||||
import { Base64 } from 'js-base64'
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
const props = defineProps ({
|
||||
callbackFunc: { type: Function, default: () => ({}) }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const vdata = reactive ({
|
||||
newPwd: '', // 新密码
|
||||
resetIsShow: false, // 重置密码是否展现
|
||||
passwordRules: /^$/, //密码规则
|
||||
passwordRulesText: '', //密码规则提示文字
|
||||
sysPassword: {
|
||||
resetPass: false, // 重置密码
|
||||
defaultPass: true, // 使用默认密码
|
||||
confirmPwd: '' // 确认密码
|
||||
},
|
||||
loading: false, // 按钮上的loading
|
||||
value: 1, // 单选框默认的值
|
||||
teamList: [] as any, // 团队列表
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isAdd: true, // 新增 or 修改页面标识
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: {} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
})
|
||||
const rules = reactive({
|
||||
realname: [{ required: true, message: '请输入用户姓名', trigger: 'blur' }],
|
||||
telphone: [{ required: true, pattern: /^[1][0-9]{10}$/, message: '请输入正确的手机号码', trigger: 'blur' }],
|
||||
userNo: [{ required: true, message: '请输入编号', trigger: 'blur' }],
|
||||
userType: [{ required: true, message: '请选择用户类型', trigger: 'blur' }],
|
||||
loginUsername: [] as any[],
|
||||
newPwd: [{ required: false, trigger: 'blur' }, {
|
||||
validator: (rule, value) => {
|
||||
if (!vdata.sysPassword.defaultPass) {
|
||||
if (!vdata.passwordRules.test(vdata.newPwd)) {
|
||||
return Promise.reject(vdata.passwordRulesText)
|
||||
} else if(vdata.newPwd !== vdata.sysPassword.confirmPwd) {
|
||||
return Promise.reject('新密码与确认密码不一致')
|
||||
} else return Promise.resolve()
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
}
|
||||
}], // 新密码
|
||||
confirmPwd: [{ required: false, trigger: 'blur' }, {
|
||||
validator: (rule, value) => {
|
||||
if (!vdata.sysPassword.defaultPass) {
|
||||
// vdata.newPwd === vdata.sysPassword.confirmPwd ? callBack() : callBack('新密码与确认密码不一致')
|
||||
if(!vdata.passwordRules.test(vdata.sysPassword.confirmPwd)){
|
||||
return Promise.reject(vdata.passwordRulesText)
|
||||
} else if(vdata.newPwd !== vdata.sysPassword.confirmPwd) {
|
||||
return Promise.reject('新密码与确认密码不一致')
|
||||
} else return Promise.resolve()
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
}] // 确认新密码
|
||||
})
|
||||
function getPasswordRules () { // 获取密码规则
|
||||
$getPasswordRules().then(res => {
|
||||
vdata.passwordRules = new RegExp(res.regexpRules)
|
||||
vdata.passwordRulesText = res.errTips
|
||||
})
|
||||
}
|
||||
defineExpose({show})
|
||||
function show (recordId) { // 弹层打开事件
|
||||
getPasswordRules()
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
vdata.isAdd = !recordId
|
||||
// 数据恢复为默认数据
|
||||
vdata.saveObject = {isAdmin: 1, state: 1, sex: 1, passwordType: 'default', isNotify: 0, userType: 1, isTeamLeader: 0}
|
||||
rules.loginUsername = []
|
||||
vdata.confirmLoading = false // 关闭loading
|
||||
|
||||
req.list(API_URL_SYS_USER_TEAM_LIST, { 'pageSize': -1 }).then(res => { // 团队下拉选择列表
|
||||
vdata.teamList = res.records
|
||||
})
|
||||
|
||||
if (vdata.isAdd) {
|
||||
rules.loginUsername.push({
|
||||
required: true,
|
||||
pattern: /^[a-zA-Z][a-zA-Z0-9]{5,17}$/,
|
||||
message: '请输入字母开头,长度为6-18位的登录名',
|
||||
trigger: 'blur'
|
||||
})
|
||||
}
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.resetIsShow = true // 展示重置密码板块
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_SYS_USER_LIST, recordId).then(res => { vdata.saveObject = res })
|
||||
vdata.isShow = true
|
||||
} else {
|
||||
vdata.isShow = true // 立马展示弹层信息
|
||||
}
|
||||
}
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then(valid=>{
|
||||
vdata.loading = true // 打开按钮上的 loading
|
||||
vdata.confirmLoading = true // 显示loading
|
||||
if (vdata.isAdd) {
|
||||
if(vdata.saveObject.passwordType == 'default' || !vdata.saveObject.loginPassword) {
|
||||
vdata.saveObject.loginPassword = ''
|
||||
}
|
||||
if(vdata.saveObject.passwordType == 'custom' && !vdata.passwordRules.test(vdata.saveObject.loginPassword)) {
|
||||
vdata.confirmLoading = false
|
||||
return message.error(vdata.passwordRulesText)
|
||||
}
|
||||
req.add(API_URL_SYS_USER_LIST, vdata.saveObject).then(res => {
|
||||
message.success('新增成功')
|
||||
vdata.isShow = false
|
||||
vdata.loading = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch((res) => {
|
||||
vdata.confirmLoading = false
|
||||
})
|
||||
} else {
|
||||
vdata.sysPassword.confirmPwd = Base64.encode(vdata.sysPassword.confirmPwd)
|
||||
Object.assign(vdata.saveObject, vdata.sysPassword) // 拼接对象
|
||||
console.log(vdata.saveObject)
|
||||
req.updateById(API_URL_SYS_USER_LIST, vdata.recordId, vdata.saveObject).then(res => {
|
||||
message.success('修改成功')
|
||||
vdata.isShow = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
vdata.resetIsShow = false // 取消展示
|
||||
vdata.sysPassword.resetPass = false
|
||||
vdata.sysPassword.defaultPass = true// 是否使用默认密码默认为true
|
||||
resetPassEmpty(vdata) // 清空密码
|
||||
}).catch(res => {
|
||||
vdata.confirmLoading = false
|
||||
vdata.resetIsShow = false // 取消展示
|
||||
vdata.sysPassword.resetPass = false
|
||||
vdata.sysPassword.defaultPass = true// 是否使用默认密码默认为true
|
||||
resetPassEmpty(vdata) // 清空密码
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 关闭抽屉
|
||||
function onClose () {
|
||||
vdata.isShow = false
|
||||
vdata.resetIsShow = false // 取消重置密码板块展示
|
||||
resetPassEmpty(vdata) // 清空密码
|
||||
vdata.sysPassword.resetPass = false // 关闭密码输入
|
||||
vdata.sysPassword.defaultPass = true// 是否使用默认密码默认为true
|
||||
}
|
||||
// 使用默认密码重置是否为true
|
||||
function isResetPass () {
|
||||
if (!vdata.sysPassword.defaultPass) {
|
||||
vdata.newPwd = ''
|
||||
vdata.sysPassword.confirmPwd = ''
|
||||
}
|
||||
}
|
||||
// 保存后清空密码
|
||||
function resetPassEmpty (that) {
|
||||
vdata.newPwd = ''
|
||||
vdata.sysPassword.confirmPwd = ''
|
||||
}
|
||||
|
||||
// 切换操作员类型
|
||||
function changeUserType() {
|
||||
if (vdata.saveObject.userType == 1 || vdata.saveObject.userType == 2) {
|
||||
vdata.saveObject.isTeamLeader = 0
|
||||
vdata.saveObject.teamId = ''
|
||||
}
|
||||
}
|
||||
|
||||
function randomPassage(randomFlag, min, max) { // 生成6位随机密码
|
||||
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['loginPassword'] = str
|
||||
}
|
||||
</script>
|
||||
150
jeepay-ui-agent/src/views/sysuser/Detail.vue
Normal file
150
jeepay-ui-agent/src/views/sysuser/Detail.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.visible"
|
||||
:title=" true ? '操作员详情' : '' "
|
||||
: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.realname }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="手机号">
|
||||
{{ vdata.detailData.telphone }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="登录名">
|
||||
{{ vdata.detailData.loginUsername }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="编号">
|
||||
{{ vdata.detailData.userNo }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="所属团队">
|
||||
{{ vdata.detailData.teamName || '无' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col v-if="vdata.detailData.teamId" :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="是否队长">
|
||||
{{ vdata.detailData.isTeamLeader === 1 ? '是' : '否' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="拓展员性别">
|
||||
{{ vdata.detailData.sex === 1 ? '男' : vdata.detailData.sex === 2 ? '女' : '未知' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="状态">
|
||||
<a-tag :color="vdata.detailData['state'] === 1?'green':'volcano'">
|
||||
{{ vdata.detailData.state === 0?'禁用':vdata.detailData.state === 1?'启用':'未知' }}
|
||||
</a-tag>
|
||||
</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-divider orientation="left" v-if="vdata.detailData.userType === 3">
|
||||
<a-tag color="green">
|
||||
数据统计
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
<a-tabs v-model:activeKey="vdata.activeKey" @change="changeDateTime" v-if="vdata.detailData.userType === 3">
|
||||
<a-tab-pane key="currMonth" tab="本月"><StatDetail :data="vdata.statData" /></a-tab-pane>
|
||||
<a-tab-pane key="prevMonth" tab="上月"><StatDetail :data="vdata.statData" /></a-tab-pane>
|
||||
<a-tab-pane key="today" tab="今天"><StatDetail :data="vdata.statData" /></a-tab-pane>
|
||||
<a-tab-pane key="yesterday" tab="昨天"><StatDetail :data="vdata.statData" /></a-tab-pane>
|
||||
<a-tab-pane key="customDateTime" tab="自定义">
|
||||
<a-range-picker v-model:value="vdata.customDateTimeValue" show-time @change="customDateTimeChange" />
|
||||
<StatDetail :data="vdata.statData" />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { API_URL_SYS_USER_LIST, req, $userChart } from '@/api/manage'
|
||||
import { defineProps, reactive, toRaw } from 'vue'
|
||||
import StatDetail from './StatDetail.vue'
|
||||
|
||||
const props = defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
const vdata = reactive({
|
||||
btnLoading: false,
|
||||
detailData: {} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
visible: false, // 是否显示弹层/抽屉
|
||||
activeKey: 'currMonth',
|
||||
customDateTimeValue: [] as any, // 自定义时间
|
||||
statData: {} // 拓展员统计数据
|
||||
})
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
vdata.recordId = recordId
|
||||
|
||||
req.getById(API_URL_SYS_USER_LIST, recordId).then(res => {
|
||||
vdata.detailData = res
|
||||
})
|
||||
vdata.visible = true
|
||||
|
||||
changeDateTime()
|
||||
}
|
||||
|
||||
function onClose () {
|
||||
vdata.visible = false
|
||||
}
|
||||
|
||||
function changeDateTime() {
|
||||
if (vdata.activeKey != 'customDateTime') {
|
||||
$userChart(vdata.recordId, vdata.activeKey).then(res => {
|
||||
vdata.statData = res
|
||||
})
|
||||
}else {
|
||||
customDateTimeChange()
|
||||
}
|
||||
}
|
||||
|
||||
function customDateTimeChange() {
|
||||
if (vdata.customDateTimeValue) {
|
||||
const queryDateRange = 'customDateTime_' + vdata.customDateTimeValue[0].format('YYYY-MM-DD HH:mm:ss') + '_' + vdata.customDateTimeValue[1].format('YYYY-MM-DD HH:mm:ss')
|
||||
$userChart(vdata.recordId, queryDateRange).then(res => {
|
||||
vdata.statData = res
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show //抛出show函数给父组件
|
||||
})
|
||||
</script>
|
||||
107
jeepay-ui-agent/src/views/sysuser/RoleDist.vue
Normal file
107
jeepay-ui-agent/src/views/sysuser/RoleDist.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.isShow"
|
||||
title="分配角色"
|
||||
width="30%"
|
||||
:mask-closable="true"
|
||||
@close="vdata.isShow = false"
|
||||
>
|
||||
<div>
|
||||
<div :style="{ borderBottom: '1px solid #E9E9E9' }">
|
||||
<a-checkbox
|
||||
:checked="vdata.checkedVal.length != 0 && vdata.allRoleList.length === vdata.checkedVal.length"
|
||||
:indeterminate="vdata.checkedVal.length != 0 && vdata.allRoleList.length != vdata.checkedVal.length"
|
||||
@change="onCheckAllChange"
|
||||
>
|
||||
全选
|
||||
</a-checkbox>
|
||||
</div>
|
||||
<br>
|
||||
<a-checkbox-group v-model:value="vdata.checkedVal" :options="vdata.allRoleList" />
|
||||
</div>
|
||||
|
||||
<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 { $uSysUserRoleRela, req, reqLoad, API_URL_ROLE_LIST, API_URL_USER_ROLE_RELA_LIST } from '@/api/manage'
|
||||
import {ref,reactive} from 'vue'
|
||||
import {message} from 'ant-design-vue'
|
||||
|
||||
const props =defineProps({
|
||||
callbackFunc: { type: Function,default:null }
|
||||
})
|
||||
|
||||
|
||||
const vdata = reactive ({
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
recordId: null, // 更新对象ID
|
||||
|
||||
allRoleList: []as any[], // 全部的角色集合 {label: '', value: ''}
|
||||
checkedVal: []as any[] // 已选择的数据集合
|
||||
})
|
||||
|
||||
|
||||
defineExpose({show})
|
||||
function show (recordId) { // 弹层打开事件
|
||||
// 重置数据
|
||||
vdata.allRoleList = []
|
||||
vdata.checkedVal = []
|
||||
vdata.confirmLoading = false // 关闭loading
|
||||
vdata.recordId = recordId
|
||||
|
||||
// 查询所有角色列表
|
||||
reqLoad.list(API_URL_ROLE_LIST, { pageSize: -1 }).then(res => {
|
||||
if (res.total <= 0) {
|
||||
return message.error(`当前暂无角色,请先行添加`)
|
||||
}
|
||||
|
||||
vdata.allRoleList = []
|
||||
res.records.map(role => {
|
||||
vdata.allRoleList.push({ label: role.roleName, value: role.roleId })
|
||||
vdata.isShow = true
|
||||
})
|
||||
|
||||
// 查询已分配的列表
|
||||
req.list(API_URL_USER_ROLE_RELA_LIST, { pageSize: -1, userId: recordId }).then(relaRes => {
|
||||
relaRes.records.map(rela => {
|
||||
vdata.checkedVal.push(rela.roleId)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
|
||||
|
||||
vdata.confirmLoading = true // 显示loading
|
||||
$uSysUserRoleRela(vdata.recordId, vdata.checkedVal).then(res => {
|
||||
message.success('更新成功!')
|
||||
vdata.isShow = false
|
||||
|
||||
if (props.callbackFunc !== undefined) {
|
||||
props.callbackFunc() // 刷新列表
|
||||
}
|
||||
}).catch(res => { vdata.confirmLoading = false }) // 恢复loading
|
||||
}
|
||||
|
||||
function onCheckAllChange (e) { // 点击全选/非全选的状态更改
|
||||
|
||||
|
||||
vdata.checkedVal = []
|
||||
if (e.target.checked) { // 全选
|
||||
vdata.allRoleList.map(role => { vdata.checkedVal.push(role.value) })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
32
jeepay-ui-agent/src/views/sysuser/StatDetail.vue
Normal file
32
jeepay-ui-agent/src/views/sysuser/StatDetail.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<a-row>
|
||||
<a-col :span="8">
|
||||
<a-statistic title="商户总数" :value="data.mchAllCount" style="margin-right: 50px" />
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-statistic title="新增商户数" :value="data.mchTodayAddCount" />
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-statistic title="商户交易总额" :precision="2" :value="(data.payAllAmount/100).toFixed(2)" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row style="margin-top: 30px;">
|
||||
<a-col :span="8">
|
||||
<a-statistic title="入网商户总数" :value="data.mchOnNetCount" style="margin-right: 50px" />
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-statistic title="新增入网商户数" :value="data.mchOnNetNewCount" />
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-statistic title="商户交易额" :precision="2" :value="(data.payAmount/100).toFixed(2)" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineProps, reactive } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
data: { type: Object, default:null }
|
||||
})
|
||||
</script>
|
||||
261
jeepay-ui-agent/src/views/sysuser/SysUserPage.vue
Normal file
261
jeepay-ui-agent/src/views/sysuser/SysUserPage.vue
Normal file
@@ -0,0 +1,261 @@
|
||||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<JeepaySearchForm v-if="$access('ENT_UR_ROLE_SEARCH')" :searchConditionNum="6" :searchFunc="searchFunc" :resetFunc="() => { data.searchData= {} }">
|
||||
<jeepay-text-up v-model:value="data.searchData['sysUserId']" :placeholder="'用户ID'" />
|
||||
<jeepay-text-up v-model:value="data.searchData['realname']" :placeholder="'用户姓名'" />
|
||||
<jeepay-text-up v-model:value="data.searchData['telphone']" :placeholder="'用户手机号'" />
|
||||
<a-form-item label="" class="table-search-item">
|
||||
<a-select v-model:value="data.searchData['userType']" 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>
|
||||
</JeepaySearchForm>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:init-data="true"
|
||||
:req-table-data-func="reqTableDataFunc"
|
||||
:table-columns="tableColumns"
|
||||
:search-data="data.searchData"
|
||||
row-key="sysUserId"
|
||||
@btnLoadClose="data.btnLoading=false"
|
||||
>
|
||||
<template #topBtnSlot>
|
||||
<div>
|
||||
<a-button
|
||||
v-if="$access('ENT_UR_USER_ADD')"
|
||||
type="primary"
|
||||
class="mg-b-30"
|
||||
@click="addFunc"
|
||||
>
|
||||
<plus-outlined />
|
||||
新建
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{column,record}">
|
||||
<template v-if="column.key === 'avatar'">
|
||||
<a-avatar size="default" :src="record.avatarUrl" />
|
||||
</template>
|
||||
<template v-if="column.key === 'realname'">
|
||||
{{ record.realname }}
|
||||
<a-tag v-if="record.initUser" :key="record.initUser" color="green">
|
||||
初始
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'state'">
|
||||
<JeepayTableColState :state="record.state" :show-switch-type="$access('ENT_UR_USER_EDIT')" :on-change="(state) => { return updateState(record.sysUserId, state)}" />
|
||||
</template>
|
||||
<template v-if="column.key === 'inviteCode'">
|
||||
<span v-if="record.userType == 1 || record.userType == 3">
|
||||
<a-button v-clipboard:copy="record.inviteCode" v-clipboard:success="() => $infoBox.message.success('邀请码已复制')" type="link" size="small">{{ record.inviteCode }}</a-button>
|
||||
<info-circle-outlined style="cursor: pointer;" @click="showQrImgFunc(record)" />
|
||||
</span>
|
||||
<span v-else />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'sex'">
|
||||
<span v-if="record.sex == 1">男</span>
|
||||
<span v-else-if="record.sex == 2">女</span>
|
||||
<span v-else>未知</span>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'userType'">
|
||||
<span v-if="record.userType == 1">超级管理员</span>
|
||||
<span v-else-if="record.userType == 2">普通操作员</span>
|
||||
<span v-else-if="record.userType == 3">商户拓展员</span>
|
||||
<span v-else>其他</span>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'op'">
|
||||
<!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button v-if="$access('ENT_UR_USER_VIEW')" type="link" @click="detailFunc(record.sysUserId)">详情</a-button>
|
||||
<a-button v-if="$access('ENT_UR_USER_UPD_ROLE') && record.userType == 2" type="link" @click="roleDistFun(record.sysUserId)">变更角色</a-button>
|
||||
<a-button v-if="$access('ENT_UR_USER_EDIT')" type="link" @click="editFunc(record.sysUserId)">修改</a-button>
|
||||
<a-button v-if="$access('ENT_UR_USER_MFA_DELETE') && (userStore.userInfo['userType'] == '1' && record.mfaBindState == '1')" style="color: red;" type="link" @click="mfaRelieve(record.sysUserId)">MFA解绑</a-button>
|
||||
<a-button v-if="$access('ENT_UR_USER_LOGIN_LIMIT_DELETE')" style="color: red;" type="link" @click="deleteLoginLimit(record.sysUserId)">解除登录限制</a-button>
|
||||
<a-button v-if="$access('ENT_UR_USER_DELETE')" type="link" style="color: red;margin-right: 20px;" @click="delFunc(record.sysUserId)">删除</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<a-modal v-model:visible="data.codeVisible" title="邀请码" :footer="null" :width="600" @ok="() => data.codeVisible = false">
|
||||
<div v-if="!data.inviteCode">
|
||||
<span>无邀请码</span>
|
||||
<a-button type="link" @click="setInviteCodeFunc(data.sysUserId)">点此修复</a-button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div>
|
||||
<span>邀请码:{{ data.inviteCode }}</span>
|
||||
<a-button v-clipboard:copy="data.inviteCode" v-clipboard:success="() => $infoBox.message.success('邀请码已复制')" type="link">复制</a-button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<span>商户注册链接:{{ data.inviteCodeUrl }}</span>
|
||||
<a-button v-clipboard:copy="data.inviteCodeUrl" v-clipboard:success="() => $infoBox.message.success('复制成功')" type="link">复制</a-button>
|
||||
</div>
|
||||
<div>
|
||||
<span>商户注册二维码:</span>
|
||||
<div style="padding: 20px 0 20px 50px;"><QrcodeVue :value="data.inviteCodeUrl" :size="200" /></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="data.sysType == 'PLATFORM' || data.sysType == 'AGENT'">
|
||||
<div>
|
||||
<span>代理商注册链接:{{ data.agentInviteCodeUrl }}</span>
|
||||
<a-button v-clipboard:copy="data.agentInviteCodeUrl" v-clipboard:success="() => $infoBox.message.success('复制成功')" type="link">复制</a-button>
|
||||
</div>
|
||||
<div>
|
||||
<span>代理商注册二维码:</span>
|
||||
<div style="padding: 20px 0 20px 50px;"><QrcodeVue :value="data.agentInviteCodeUrl" :size="200" /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 新增 / 修改 页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callback-func="searchFunc" />
|
||||
|
||||
<!-- 分配角色 页面组件 -->
|
||||
<RoleDist ref="roleDist" />
|
||||
|
||||
<!-- 详情页面组件 -->
|
||||
<InfoDetail ref="infoDetail" :callback-func="searchFunc" />
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { API_URL_SYS_USER_LIST, req, reqLoad, $deleteLoginLimit } from '@/api/manage'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import InfoAddOrEdit from './AddOrEdit.vue'
|
||||
import RoleDist from './RoleDist.vue'
|
||||
import InfoDetail from './Detail.vue'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
import { reactive,ref,getCurrentInstance} from 'vue'
|
||||
const { $infoBox,$access } = getCurrentInstance()!.appContext.config.globalProperties
|
||||
const userStore = useUserStore()
|
||||
|
||||
const tableColumns = reactive([
|
||||
{key:'avatar',title: '头像', },
|
||||
{key:'realname', title: '姓名', dataIndex: 'realname' },
|
||||
{key:'sysUserId', title: '用户ID', dataIndex: 'sysUserId',},
|
||||
{key:'sex', title: '性别', dataIndex: 'sex',},
|
||||
{key:'userNo', title: '编号', dataIndex: 'userNo', },
|
||||
{key:'telphone', title: '手机号', dataIndex: 'telphone', },
|
||||
{key:'userType' ,title: '操作员类型', dataIndex: 'userType', },
|
||||
{key:'teamName' ,title: '团队', dataIndex: 'teamName' },
|
||||
{key:'inviteCode' ,title: '邀请码', dataIndex: 'inviteCode', },
|
||||
{key:'state', title: '状态', align: 'center' ,},
|
||||
{key:'createdAt', title: '创建时间', dataIndex: 'createdAt',},
|
||||
{key: 'op',title: '操作', fixed: 'right',align: 'center' }
|
||||
])
|
||||
|
||||
const infoTable = ref()
|
||||
const infoAddOrEdit =ref()
|
||||
const infoDetail = ref()
|
||||
const roleDist = ref()
|
||||
const data : any =reactive ({
|
||||
tableColumns: tableColumns,
|
||||
searchData: {},
|
||||
btnLoading: false
|
||||
})
|
||||
|
||||
// 请求table接口数据
|
||||
function reqTableDataFunc(params){
|
||||
return req.list(API_URL_SYS_USER_LIST, params)
|
||||
}
|
||||
|
||||
function searchFunc() { // 点击【查询】按钮点击事件
|
||||
data.btnLoading = true // 打开查询按钮的loading
|
||||
infoTable.value.refTable(true)
|
||||
}
|
||||
|
||||
function addFunc () { // 业务通用【新增】 函数
|
||||
infoAddOrEdit.value.show()
|
||||
}
|
||||
|
||||
function editFunc (recordId) { // 业务通用【修改】 函数
|
||||
console.log(infoAddOrEdit)
|
||||
infoAddOrEdit.value.show(recordId)
|
||||
}
|
||||
|
||||
function detailFunc (recordId: any) { // 商户详情页
|
||||
infoDetail.value.show(recordId)
|
||||
}
|
||||
function setInviteCodeFunc (recordId: any) { // 修复邀请码
|
||||
return req.updateById(API_URL_SYS_USER_LIST, recordId, { setInviteCode: true }).then(res => {
|
||||
$infoBox.message.success('修复成功')
|
||||
console.log(res)
|
||||
showQrImgFunc(res)
|
||||
infoTable.value.refTable(false)
|
||||
})
|
||||
}
|
||||
|
||||
function delFunc(recordId) { // 业务通用【删除】 函数
|
||||
$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
return req.delById(API_URL_SYS_USER_LIST, recordId).then(res => {
|
||||
$infoBox.message.success('删除成功!')
|
||||
infoTable.value.refTable(false)
|
||||
})
|
||||
})
|
||||
}
|
||||
function roleDistFun(recordId) { // 【分配权限】 按钮点击事件
|
||||
roleDist.value.show(recordId)
|
||||
}
|
||||
|
||||
function updateState (recordId, state) { // 【更新状态】
|
||||
const title = state === 1 ? '确认[启用]该用户?' : '确认[停用]该用户?'
|
||||
const content = state === 1 ? '启用后用户可进行登陆等一系列操作' : '停用后该用户将立即退出系统并不可再次登陆'
|
||||
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$infoBox.confirmDanger(title, content, () => {
|
||||
return reqLoad.updateById(API_URL_SYS_USER_LIST, recordId, { state: state }).then(res => {
|
||||
searchFunc()
|
||||
resolve()
|
||||
}).catch(err => reject(err))
|
||||
},
|
||||
() => {
|
||||
reject(new Error())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 显示二维码图片
|
||||
function showQrImgFunc(record){
|
||||
data.codeVisible = true
|
||||
data.inviteCodeUrl = record.inviteCodeUrl
|
||||
data.inviteCode = record.inviteCode
|
||||
data.agentInviteCodeUrl = record.agentInviteCodeUrl
|
||||
data.sysUserId = record.sysUserId
|
||||
data.sysType = record.sysType
|
||||
}
|
||||
function onCopySuccess () {
|
||||
$infoBox.message.success('复制成功')
|
||||
}
|
||||
|
||||
function mfaRelieve(recordId) { // MFA解绑
|
||||
$infoBox.confirmDanger('确认解绑吗?', '', () => {
|
||||
return req.updateById(API_URL_SYS_USER_LIST, 'mfaRelieve', {recordId: recordId}).then(res => {
|
||||
$infoBox.message.success('解绑成功!')
|
||||
infoTable.value.refTable(false)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function deleteLoginLimit(recordId) { // 解除登录限制
|
||||
$infoBox.confirmDanger('确认解除吗?', '', () => {
|
||||
return $deleteLoginLimit(recordId).then(res => {
|
||||
$infoBox.message.success('解除成功!')
|
||||
infoTable.value.refTable(false)
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
133
jeepay-ui-agent/src/views/sysuserteam/AddOrEdit.vue
Normal file
133
jeepay-ui-agent/src/views/sysuserteam/AddOrEdit.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="vdata.isShow"
|
||||
:title=" vdata.isAdd ? '新增团队' : '修改团队' "
|
||||
placement="right"
|
||||
:closable="true"
|
||||
width="600"
|
||||
:mask-closable="false"
|
||||
@ok="handleOkFunc"
|
||||
@close="onClose"
|
||||
>
|
||||
<!-- <a-modal :confirmLoading="confirmLoading"> -->
|
||||
|
||||
<a-form
|
||||
ref="infoFormModel"
|
||||
:model="vdata.saveObject"
|
||||
layout="vertical"
|
||||
:rules="rules"
|
||||
style="padding-bottom:50px"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :span="10">
|
||||
<a-form-item label="团队名:" name="teamName">
|
||||
<a-input v-model:value="vdata.saveObject.teamName" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="10">
|
||||
<a-form-item label="团队编号:" name="teamNo">
|
||||
<a-input v-model:value="vdata.saveObject.teamNo" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="10">
|
||||
<a-form-item label="统计周期" name="statRangeType">
|
||||
<a-select v-model:value="vdata.saveObject.statRangeType" placeholder="请选择用户类型">
|
||||
<a-select-option value="year">年</a-select-option>
|
||||
<a-select-option value="quarter">季度</a-select-option>
|
||||
<a-select-option value="month">月</a-select-option>
|
||||
<a-select-option value="week">周</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose">
|
||||
<close-outlined />
|
||||
取消
|
||||
</a-button>
|
||||
<a-button type="primary" :loading="vdata.confirmLoading" @click="handleOkFunc">
|
||||
<check-outlined />
|
||||
保存
|
||||
</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { req, API_URL_SYS_USER_TEAM_LIST } from '@/api/manage'
|
||||
import { reactive,ref } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
const props = defineProps ({
|
||||
callbackFunc: { type: Function, default: () => ({}) }
|
||||
})
|
||||
|
||||
const infoFormModel = ref()
|
||||
const vdata = reactive ({
|
||||
loading: false, // 按钮上的loading
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isAdd: true, // 新增 or 修改页面标识
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: {} as any, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
})
|
||||
const rules = reactive({
|
||||
teamName: [{ required: true, message: '请输入团队名', trigger: 'blur' }],
|
||||
teamNo: [{ required: true, message: '请输入团队编号', trigger: 'blur' }],
|
||||
statRangeType: [{ required: true, message: '请选择统计周期', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
defineExpose({ show })
|
||||
|
||||
function show (recordId) { // 弹层打开事件
|
||||
if (infoFormModel.value !== undefined) {
|
||||
infoFormModel.value.resetFields()
|
||||
}
|
||||
|
||||
vdata.isAdd = !recordId
|
||||
// 数据恢复为默认数据
|
||||
// vdata.saveObject = {isAdmin: 1, state: 1, sex: 1, passwordType: 'default', isNotify: 0}
|
||||
vdata.confirmLoading = false // 关闭loading
|
||||
|
||||
if (!vdata.isAdd) { // 修改信息 延迟展示弹层
|
||||
vdata.recordId = recordId
|
||||
req.getById(API_URL_SYS_USER_TEAM_LIST, recordId).then(res => { vdata.saveObject = res })
|
||||
vdata.isShow = true
|
||||
} else {
|
||||
vdata.saveObject.statRangeType = 'year'
|
||||
vdata.isShow = true // 立马展示弹层信息
|
||||
}
|
||||
}
|
||||
function handleOkFunc () { // 点击【确认】按钮事件
|
||||
infoFormModel.value.validate().then(valid=>{
|
||||
vdata.loading = true // 打开按钮上的 loading
|
||||
vdata.confirmLoading = true // 显示loading
|
||||
if (vdata.isAdd) {
|
||||
req.add(API_URL_SYS_USER_TEAM_LIST, vdata.saveObject).then(res => {
|
||||
message.success('新增成功')
|
||||
vdata.isShow = false
|
||||
vdata.loading = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch((res) => {
|
||||
vdata.confirmLoading = false
|
||||
})
|
||||
} else {
|
||||
req.updateById(API_URL_SYS_USER_TEAM_LIST, vdata.recordId, vdata.saveObject).then(res => {
|
||||
message.success('修改成功')
|
||||
vdata.isShow = false
|
||||
props.callbackFunc() // 刷新列表
|
||||
}).catch(res => {
|
||||
vdata.confirmLoading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 关闭抽屉
|
||||
function onClose () {
|
||||
vdata.isShow = false
|
||||
}
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user