完成了基本调整调整
This commit is contained in:
@@ -6,7 +6,12 @@ const api = {
|
||||
share: '/partners.order/share',
|
||||
qrCode: '/partners.order/qrCode',
|
||||
oilCallback: '/partners.order/oilCallback',
|
||||
useCallback: '/partners.order/useCallback'
|
||||
useCallback: '/partners.order/useCallback',
|
||||
refund: '/partners.order/refund',
|
||||
refundConfirm: '/partners.order/refundConfirm',
|
||||
refundResolve: '/partners.order/refundResolve',
|
||||
refundLog: '/partners.order/refundLog',
|
||||
invoice: '/partners.order/invoice'
|
||||
}
|
||||
|
||||
// 列表记录
|
||||
@@ -65,3 +70,63 @@ export function useCallback (data) {
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款(整单全额:企油通 7.17 查凭证 + 7.16 调低额度)
|
||||
* @param {*} data { orderId, reason }
|
||||
*/
|
||||
export function refund (data) {
|
||||
return axios({
|
||||
url: api.refund,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 待人工确认的退款:向企油通取证确认
|
||||
* @param {*} data { orderId }
|
||||
*/
|
||||
export function refundConfirm (data) {
|
||||
return axios({
|
||||
url: api.refundConfirm,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 待人工确认的退款:人工判定
|
||||
* @param {*} data { orderId, result: success|failed, remark }
|
||||
*/
|
||||
export function refundResolve (data) {
|
||||
return axios({
|
||||
url: api.refundResolve,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单退款流水
|
||||
* @param {*} params { orderId }
|
||||
*/
|
||||
export function refundLog (params) {
|
||||
return axios({
|
||||
url: api.refundLog,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单关联发票(企油通 7.14,按企业+消费月份+司机)
|
||||
* @param {*} params { orderId, refresh }
|
||||
*/
|
||||
export function invoice (params) {
|
||||
return axios({
|
||||
url: api.invoice,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { axios } from '@/utils/request'
|
||||
|
||||
// api接口列表
|
||||
const api = {
|
||||
list: '/qyt.driver/list',
|
||||
detail: '/qyt.driver/detail',
|
||||
upstream: '/qyt.driver/upstream'
|
||||
}
|
||||
|
||||
// 司机列表
|
||||
export function list (params) {
|
||||
return axios({ url: api.list, method: 'get', params })
|
||||
}
|
||||
|
||||
// 司机详情
|
||||
export function detail (params) {
|
||||
return axios({ url: api.detail, method: 'get', params })
|
||||
}
|
||||
|
||||
// 实时查企油通:type = balance(7.12) / wallet(7.13) / voucher(7.17)
|
||||
export function upstream (params) {
|
||||
return axios({ url: api.upstream, method: 'get', params })
|
||||
}
|
||||
@@ -11,7 +11,8 @@ const api = {
|
||||
setDefault: '/qyt.enterprise/setDefault',
|
||||
apply: '/qyt.enterprise/apply',
|
||||
syncAccount: '/qyt.enterprise/syncAccount',
|
||||
syncList: '/qyt.enterprise/syncList'
|
||||
syncList: '/qyt.enterprise/syncList',
|
||||
balance: '/qyt.enterprise/balance'
|
||||
}
|
||||
|
||||
// 企业列表
|
||||
@@ -63,3 +64,8 @@ export function syncAccount (data) {
|
||||
export function syncList (data) {
|
||||
return axios({ url: api.syncList, method: 'post', data })
|
||||
}
|
||||
|
||||
// 7.11 企业账户余额(仅平安银行通道)
|
||||
export function balance (params) {
|
||||
return axios({ url: api.balance, method: 'get', params })
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { axios } from '@/utils/request'
|
||||
|
||||
// api接口列表
|
||||
const api = {
|
||||
list: '/qyt.invoice/list',
|
||||
sync: '/qyt.invoice/sync'
|
||||
}
|
||||
|
||||
// 发票记录
|
||||
export function list (params) {
|
||||
return axios({ url: api.list, method: 'get', params })
|
||||
}
|
||||
|
||||
// 同步发票(企油通 7.14):enterpriseId 不传则批量同步所有启用企业当月全量
|
||||
export function sync (data) {
|
||||
return axios({ url: api.sync, method: 'post', data })
|
||||
}
|
||||
@@ -55,9 +55,11 @@ export default {
|
||||
'appKey', 'callback', 'create_time'
|
||||
])
|
||||
partnersFormData.callback = partnersFormData.callback.toString()
|
||||
console.log(partnersFormData)
|
||||
// 企油通企业:0 表示未绑定(走默认企业),下拉框要给 undefined 才会显示占位提示
|
||||
const enterpriseId = Number(partnersInfo.qyt_enterprise_id || 0)
|
||||
return {
|
||||
...partnersFormData
|
||||
...partnersFormData,
|
||||
qyt_enterprise_id: enterpriseId > 0 ? enterpriseId : undefined
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -570,6 +570,16 @@ export const asyncRouterMap = [
|
||||
component: () => import(/* webpackChunkName: "goods" */ '@/views/partners/order/Index'),
|
||||
meta: { title: '订单列表', keepAlive: false, permission: ['/partners/order/index'] }
|
||||
},
|
||||
{
|
||||
path: '/qyt/driver/index',
|
||||
component: () => import(/* webpackChunkName: "goods" */ '@/views/qyt/driver/Index'),
|
||||
meta: { title: '司机管理', keepAlive: false, permission: ['/qyt/driver/index'] }
|
||||
},
|
||||
{
|
||||
path: '/qyt/invoice/index',
|
||||
component: () => import(/* webpackChunkName: "goods" */ '@/views/qyt/invoice/Index'),
|
||||
meta: { title: '发票管理', keepAlive: false, permission: ['/qyt/invoice/index'] }
|
||||
},
|
||||
{
|
||||
path: '/partners/balance',
|
||||
component: RouteView,
|
||||
|
||||
@@ -152,7 +152,7 @@ export default {
|
||||
onFormSubmit (values) {
|
||||
this.isLoading = true
|
||||
this.isBtnLoading = true
|
||||
PartnersApi.add({ form: values })
|
||||
PartnersApi.add({ form: { ...values, qyt_enterprise_id: values.qyt_enterprise_id || 0 } })
|
||||
.then(result => {
|
||||
// 显示提示信息
|
||||
this.$message.success(result.message, 1.5)
|
||||
|
||||
@@ -37,8 +37,24 @@
|
||||
:data="loadData"
|
||||
:rowSelection="rowSelection"
|
||||
:pageSize="15"
|
||||
:scroll="{ x: 1450 }"
|
||||
:scroll="{ x: 1670 }"
|
||||
>
|
||||
<!-- 企油通企业:下单时实际使用的企业 -->
|
||||
<div slot="qyt" slot-scope="text, item">
|
||||
<template v-if="item.qyt_enterprise_source === 'bind'">
|
||||
<p class="qyt-name">{{ item.qyt_enterprise_name }}</p>
|
||||
<p class="qyt-sub">已绑定 · {{ item.qyt_enterprise_channel }}</p>
|
||||
</template>
|
||||
<template v-else-if="item.qyt_enterprise_source === 'default'">
|
||||
<p class="qyt-name">{{ item.qyt_enterprise_name }}</p>
|
||||
<p class="qyt-sub">未绑定,使用默认企业 · {{ item.qyt_enterprise_channel }}</p>
|
||||
</template>
|
||||
<template v-else-if="item.qyt_enterprise_source === 'invalid'">
|
||||
<p class="qyt-name text-red">绑定失效:{{ item.qyt_bind_name || '企业已删除' }}</p>
|
||||
<p class="qyt-sub">{{ item.qyt_enterprise_name ? '实际使用默认企业 ' + item.qyt_enterprise_name : '且没有默认企业,下单会被拒绝' }}</p>
|
||||
</template>
|
||||
<p v-else class="qyt-name text-red">无可用企业,下单会被拒绝</p>
|
||||
</div>
|
||||
<!-- 商品名称 -->
|
||||
<span slot="address" slot-scope="text">
|
||||
<p class="twoline-hide" style="width: 270px;">{{ text }}</p>
|
||||
@@ -79,6 +95,11 @@ const columns = [
|
||||
width: '150px',
|
||||
dataIndex: 'name'
|
||||
},
|
||||
{
|
||||
title: '企油通企业',
|
||||
width: '220px',
|
||||
scopedSlots: { customRender: 'qyt' }
|
||||
},
|
||||
{
|
||||
title: '合作商地址',
|
||||
width: '200px',
|
||||
@@ -260,4 +281,15 @@ export default {
|
||||
.tab-list {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.qyt-name {
|
||||
margin: 0;
|
||||
}
|
||||
.qyt-sub {
|
||||
margin: 2px 0 0;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
.text-red {
|
||||
color: #f5222d;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -180,7 +180,8 @@ export default {
|
||||
onFormSubmit (values) {
|
||||
this.isLoading = true
|
||||
this.isBtnLoading = true
|
||||
PartnersApi.edit({ partnersId: this.partnersId, form: values })
|
||||
// 清空企业下拉框时值是 undefined,JSON 序列化会丢掉该字段,后端就不会解绑;显式提交 0
|
||||
PartnersApi.edit({ partnersId: this.partnersId, form: { ...values, qyt_enterprise_id: values.qyt_enterprise_id || 0 } })
|
||||
.then(result => {
|
||||
// 显示提示信息
|
||||
this.$message.success(result.message, 1.5)
|
||||
|
||||
@@ -43,6 +43,16 @@
|
||||
>{{ item.name }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="退款状态">
|
||||
<a-select v-decorator="['refund_status', { initialValue: -1 }]">
|
||||
<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>
|
||||
</a-form-item>
|
||||
<a-form-item label="合作商">
|
||||
<a-select v-decorator="['partners_id', { initialValue: -1 }]">
|
||||
<a-select-option :value="-1">全部</a-select-option>
|
||||
@@ -91,9 +101,9 @@
|
||||
</div>
|
||||
<div slot="consume" slot-scope="item">
|
||||
<template v-if="item.use_status === 1">
|
||||
<p class="mtb-2 f-13">{{ item.station_name || '-' }}</p>
|
||||
<p class="mtb-2 f-13">{{ item.oil_name }} {{ item.litter }}L</p>
|
||||
<p class="mtb-2 f-13">实付:¥{{ (item.pay_fee / 100).toFixed(2) }}</p>
|
||||
<p class="mtb-2 f-13">已加油:¥{{ item.used_amount }}({{ item.used_num }} 次)</p>
|
||||
<p class="mtb-2 f-13">剩余:¥{{ remainAmount(item) }}</p>
|
||||
<p class="mtb-2 f-13">最近:{{ item.station_name || '-' }} {{ item.oil_name }} {{ item.litter }}L</p>
|
||||
</template>
|
||||
<span v-else>-</span>
|
||||
</div>
|
||||
@@ -115,6 +125,10 @@
|
||||
<a-tag :color="qytColor(item.oil_status_zsy)">{{ qytText(item.oil_status_zsy) }}</a-tag>
|
||||
</p>
|
||||
<p v-if="item.oil_text" class="mtb-2 f-13 order-remark">{{ item.oil_text }}</p>
|
||||
<p v-if="item.refund_status > 0" class="mtb-2">
|
||||
<span class="f-13">退款:</span>
|
||||
<a-tag :color="refundColor(item.refund_status)">{{ refundText(item.refund_status) }}</a-tag>
|
||||
</p>
|
||||
</div>
|
||||
<div class="actions" slot="action" slot-scope="item">
|
||||
<!--有付款权限,订单状态为进行中,已支付,并且未使用-->
|
||||
@@ -123,7 +137,7 @@
|
||||
@click="handleShare(item)"
|
||||
>重新发放</a>
|
||||
<a
|
||||
v-if="(inArray(item.oil_status_zsy, [2])) && item.oil_status === 1 && item.use_status === 0 && item.oilCardType === 'zsy_ticket'"
|
||||
v-if="(inArray(item.oil_status_zsy, [2])) && item.oil_status === 1 && item.refund_status !== 2 && Number(remainAmount(item)) > 0 && item.oilCardType === 'zsy_ticket'"
|
||||
@click="handlePay(item)"
|
||||
>加油链接</a>
|
||||
<a
|
||||
@@ -134,12 +148,16 @@
|
||||
v-if="(inArray(item.oil_status_zsy, [2])) && item.oil_status === 1 && item.use_status === 1 && item.oilCardType === 'zsy_ticket'"
|
||||
@click="handleUse(item)"
|
||||
>重推加油结果</a>
|
||||
<a v-if="canRefund(item)" @click="handleRefund(item)">{{ refundLabel(item) }}</a>
|
||||
<a v-if="item.use_status === 1" @click="handleInvoice(item)">发票</a>
|
||||
</div>
|
||||
</s-table>
|
||||
<ShareForm ref="ShareForm" @handleSubmit="handleRefresh" />
|
||||
<PayForm ref="PayForm" @handleSubmit="handleRefresh" />
|
||||
<OilForm ref="OilForm" @handleSubmit="handleRefresh" />
|
||||
<UseForm ref="UseForm" @handleSubmit="handleRefresh" />
|
||||
<RefundForm ref="RefundForm" @handleSubmit="handleRefresh" />
|
||||
<InvoiceModal ref="InvoiceModal" />
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
@@ -149,7 +167,7 @@ import { STable } from '@/components/Table'
|
||||
import {
|
||||
OilStatusEnum, UseStatusEnum
|
||||
} from '@/common/enum/order'
|
||||
import { OilForm, UseForm, ShareForm, PayForm } from './modules'
|
||||
import { OilForm, UseForm, ShareForm, PayForm, RefundForm, InvoiceModal } from './modules'
|
||||
import { assignment, inArray } from '@/utils/util'
|
||||
import zhCN from 'ant-design-vue/es/locale/zh_CN'
|
||||
import * as PartnersApi from '@/api/partners'
|
||||
@@ -161,7 +179,9 @@ export default {
|
||||
ShareForm,
|
||||
PayForm,
|
||||
OilForm,
|
||||
UseForm
|
||||
UseForm,
|
||||
RefundForm,
|
||||
InvoiceModal
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -219,7 +239,7 @@ export default {
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
width: '180px',
|
||||
width: '220px',
|
||||
scopedSlots: { customRender: 'action' }
|
||||
},
|
||||
{
|
||||
@@ -300,6 +320,36 @@ export default {
|
||||
this.$refs.UseForm.show(record)
|
||||
},
|
||||
|
||||
// 退款状态文案 / 颜色
|
||||
refundText (v) {
|
||||
return { 0: '未退款', 1: '退款中', 2: '已退款', 3: '退款失败', 4: '待人工确认' }[v] || '未知'
|
||||
},
|
||||
refundColor (v) {
|
||||
return { 1: 'blue', 2: 'green', 3: 'red', 4: 'orange' }[v] || ''
|
||||
},
|
||||
// 发放成功才可能退款;已经有退款记录的单总是可以打开看流水
|
||||
canRefund (item) {
|
||||
if (item.oilCardType !== 'zsy_ticket' || item.oil_status_zsy !== 2 || item.oil_status !== 1) {
|
||||
return false
|
||||
}
|
||||
return item.refund_status > 0 || Number(this.remainAmount(item)) > 0
|
||||
},
|
||||
// 剩余未加油金额:订单金额 − 已加油 −(已退款时)退款金额
|
||||
remainAmount (item) {
|
||||
const refunded = item.refund_status === 2 ? Number(item.refund_amount || 0) : 0
|
||||
const remain = Number(item.total_price || 0) - Number(item.used_amount || 0) - refunded
|
||||
return Math.max(0, remain).toFixed(2)
|
||||
},
|
||||
refundLabel (item) {
|
||||
return { 2: '退款记录', 4: '确认退款' }[item.refund_status] || '退款'
|
||||
},
|
||||
handleRefund (record) {
|
||||
this.$refs.RefundForm.show(record)
|
||||
},
|
||||
handleInvoice (record) {
|
||||
this.$refs.InvoiceModal.show(record)
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取代理商列表
|
||||
*/
|
||||
@@ -325,6 +375,17 @@ export default {
|
||||
.flex-box{
|
||||
display: flex;
|
||||
}
|
||||
// 操作栏:按钮较多会换行,横向纵向都留出间距(覆盖全局 .actions>a 的 8px 右边距)
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px 16px;
|
||||
|
||||
& > a {
|
||||
margin-right: 0 !important;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.form-total{
|
||||
color: #1890ff;
|
||||
margin-right: 10px;
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<a-modal
|
||||
title="加油发票"
|
||||
:width="620"
|
||||
:visible="visible"
|
||||
:footer="null"
|
||||
@cancel="visible = false"
|
||||
>
|
||||
<a-spin :spinning="isLoading">
|
||||
<a-alert type="info" show-icon class="block">
|
||||
<div slot="message">
|
||||
企油通发票按「企业 + 月份 + 司机」出具,和单笔订单没有一一对应关系。
|
||||
这里展示的是<b>该订单所属企业、该司机在消费当月</b>的全部发票,同一司机当月的其他订单看到的是同一批。
|
||||
</div>
|
||||
</a-alert>
|
||||
|
||||
<p>消费月份:<b>{{ month || '-' }}</b> 司机:{{ record.driver_name || '-' }} {{ record.mobile }}</p>
|
||||
<p v-if="row.sync_time_text" class="sub">最近同步:{{ row.sync_time_text }} {{ row.sync_text }}</p>
|
||||
<p v-else-if="message" class="sub">{{ message }}</p>
|
||||
|
||||
<div v-if="urls.length" class="links">
|
||||
<p v-for="(url, index) in urls" :key="url">
|
||||
<a :href="url" target="_blank" rel="noopener noreferrer">发票 {{ index + 1 }}</a>
|
||||
<span class="url">{{ url }}</span>
|
||||
</p>
|
||||
</div>
|
||||
<a-empty v-else-if="!isLoading" description="企油通暂未出具该月发票" />
|
||||
|
||||
<div class="btns">
|
||||
<a-button :loading="isLoading" @click="load(true)">重新同步</a-button>
|
||||
</div>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Api from '@/api/partners/order'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
visible: false,
|
||||
isLoading: false,
|
||||
record: {},
|
||||
month: '',
|
||||
message: '',
|
||||
row: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
urls () {
|
||||
return this.row.invoice_urls || []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
show (record) {
|
||||
this.visible = true
|
||||
this.record = record
|
||||
this.month = ''
|
||||
this.message = ''
|
||||
this.row = {}
|
||||
this.load(false)
|
||||
},
|
||||
|
||||
load (refresh) {
|
||||
this.isLoading = true
|
||||
Api.invoice({ orderId: this.record.order_id, refresh: refresh ? 1 : 0 })
|
||||
.then(result => {
|
||||
this.month = result.data.month
|
||||
this.message = result.data.message
|
||||
this.row = result.data.row || {}
|
||||
refresh && this.$message.success(result.message, 1.5)
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.block {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.sub {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
.links p {
|
||||
margin-bottom: 6px;
|
||||
word-break: break-all;
|
||||
}
|
||||
.url {
|
||||
margin-left: 8px;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
.btns {
|
||||
margin-top: 12px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<a-modal
|
||||
title="订单退款"
|
||||
:width="760"
|
||||
:visible="visible"
|
||||
:footer="null"
|
||||
:maskClosable="false"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-spin :spinning="isLoading">
|
||||
<div class="info">
|
||||
<p>油卡编号:{{ record.oilCardNo }}</p>
|
||||
<p>司机:{{ record.driver_name || '-' }} {{ record.mobile }}</p>
|
||||
<p>订单金额:¥{{ record.total_price }} 已加油:¥{{ record.used_amount || '0.00' }}({{ record.used_num || 0 }} 次)</p>
|
||||
<p>
|
||||
退款金额:<b class="amount">¥{{ refundAmount }}</b>
|
||||
<span v-if="status === 2">(实际退款)</span>
|
||||
<span v-else>(剩余未加油金额,固定不可修改)</span>
|
||||
</p>
|
||||
<p>当前状态:<a-tag :color="statusColor">{{ statusText }}</a-tag></p>
|
||||
<p v-if="record.refund_text" class="sub">{{ record.refund_text }}</p>
|
||||
</div>
|
||||
|
||||
<a-alert v-if="(status === 0 || status === 3) && Number(refundAmount) <= 0" type="warning" show-icon class="block" message="订单金额已全部加油,没有可退金额" />
|
||||
|
||||
<!-- 可发起:未退款 / 退款失败,且还有剩余未加油金额 -->
|
||||
<template v-if="(status === 0 || status === 3) && Number(refundAmount) > 0">
|
||||
<a-alert type="info" show-icon class="block">
|
||||
<div slot="message">
|
||||
一张订单可以分多次加油,<b>退款金额固定为剩余未加油金额</b>,已加油的部分不退,每单只能成功退一次。
|
||||
<br>退款会先用企油通 7.17 查询司机支付凭证,再用 7.16 把凭证额度调低退款金额;成功后原路回补合作商余额,并推送油卡变动通知。
|
||||
<br>额度在凭证上按司机累计,若凭证可用余额不足退款金额(被该司机其他订单用掉),会直接拒绝。
|
||||
</div>
|
||||
</a-alert>
|
||||
<a-textarea v-model="reason" :rows="2" :maxLength="100" placeholder="退款原因(选填,会写入企油通调额记录)" />
|
||||
<div class="btns">
|
||||
<a-button type="primary" :loading="isLoading" @click="handleRefund">确认退款</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 待人工确认 -->
|
||||
<template v-if="status === 4">
|
||||
<a-alert type="warning" show-icon class="block">
|
||||
<div slot="message">
|
||||
调额请求已发给企油通但没有拿到明确结果。企油通调额接口<b>没有幂等保护</b>,重复发起会被重复扣减,所以这里不允许直接重试。
|
||||
<br>请先点「向企油通取证」:系统会查司机钱包流水(找退款单号)和凭证额度变化自动判定;判定不了再人工核对后提交。
|
||||
</div>
|
||||
</a-alert>
|
||||
<div class="btns">
|
||||
<a-button type="primary" :loading="isLoading" @click="handleConfirm">向企油通取证</a-button>
|
||||
</div>
|
||||
<a-divider orientation="left">人工判定</a-divider>
|
||||
<a-radio-group v-model="resolveResult">
|
||||
<a-radio value="success">企油通已调低额度(退款成功)</a-radio>
|
||||
<a-radio value="failed">企油通未调额(退款失败,可重新发起)</a-radio>
|
||||
</a-radio-group>
|
||||
<a-textarea v-model="resolveRemark" class="mt-10" :rows="2" :maxLength="100" placeholder="判定依据(必填),如:已在企油通后台核对凭证 xxx 总额度由 300 变为 200" />
|
||||
<div class="btns">
|
||||
<a-button :loading="isLoading" @click="handleResolve">提交人工判定</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<a-divider orientation="left">退款流水</a-divider>
|
||||
<a-table
|
||||
size="small"
|
||||
rowKey="refund_id"
|
||||
:columns="columns"
|
||||
:dataSource="logs"
|
||||
:pagination="false"
|
||||
>
|
||||
<span slot="status" slot-scope="text, row">
|
||||
<a-tag :color="logColor(row.status)">{{ row.status_text }}</a-tag>
|
||||
</span>
|
||||
</a-table>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Api from '@/api/partners/order'
|
||||
|
||||
const STATUS_TEXT = { 0: '未退款', 1: '退款中', 2: '已退款', 3: '退款失败', 4: '待人工确认' }
|
||||
const STATUS_COLOR = { 1: 'blue', 2: 'green', 3: 'red', 4: 'orange' }
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
visible: false,
|
||||
isLoading: false,
|
||||
record: {},
|
||||
reason: '',
|
||||
resolveResult: 'success',
|
||||
resolveRemark: '',
|
||||
logs: [],
|
||||
columns: [
|
||||
{ title: '退款单号', dataIndex: 'refund_no' },
|
||||
{ title: '状态', scopedSlots: { customRender: 'status' } },
|
||||
{ title: '凭证', dataIndex: 'quota_id' },
|
||||
{ title: '调额前可用', dataIndex: 'available_before' },
|
||||
{ title: '说明', dataIndex: 'message' },
|
||||
{ title: '操作人', dataIndex: 'operator' },
|
||||
{ title: '时间', dataIndex: 'create_time_text' }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
status () {
|
||||
return Number(this.record.refund_status || 0)
|
||||
},
|
||||
statusText () {
|
||||
return STATUS_TEXT[this.status] || '-'
|
||||
},
|
||||
statusColor () {
|
||||
return STATUS_COLOR[this.status] || ''
|
||||
},
|
||||
// 已退款显示实际退款金额;否则为剩余未加油金额(后端同口径计算)
|
||||
refundAmount () {
|
||||
if (this.status === 2) {
|
||||
return Number(this.record.refund_amount || 0).toFixed(2)
|
||||
}
|
||||
const remain = Number(this.record.total_price || 0) - Number(this.record.used_amount || 0)
|
||||
return Math.max(0, remain).toFixed(2)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
show (record) {
|
||||
this.visible = true
|
||||
this.record = { ...record }
|
||||
this.reason = ''
|
||||
this.resolveResult = 'success'
|
||||
this.resolveRemark = ''
|
||||
this.loadLogs()
|
||||
},
|
||||
|
||||
handleCancel () {
|
||||
this.visible = false
|
||||
},
|
||||
|
||||
loadLogs () {
|
||||
Api.refundLog({ orderId: this.record.order_id }).then(result => {
|
||||
this.logs = result.data.list
|
||||
// 流水状态码与订单退款状态一致:用最新一条同步弹窗状态,失败 / 转人工后界面跟着切换
|
||||
if (this.logs.length) {
|
||||
this.record = { ...this.record, refund_status: Number(this.logs[0].status), refund_text: this.logs[0].message }
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
logColor (status) {
|
||||
return STATUS_COLOR[Number(status)] || ''
|
||||
},
|
||||
|
||||
// 退款 / 取证 / 判定之后统一刷新:弹窗里的状态 + 父列表
|
||||
afterAction (result, status) {
|
||||
this.$message.success(result.message, 2)
|
||||
if (status !== undefined) {
|
||||
this.record = { ...this.record, refund_status: status, refund_text: result.message }
|
||||
}
|
||||
this.loadLogs()
|
||||
this.$emit('handleSubmit')
|
||||
},
|
||||
|
||||
// 业务失败时后端返回错误,request 拦截器已弹出提示;这里仍需刷新状态(可能已变成失败/待确认)
|
||||
afterError () {
|
||||
this.loadLogs()
|
||||
this.$emit('handleSubmit')
|
||||
},
|
||||
|
||||
handleRefund () {
|
||||
this.$confirm({
|
||||
title: '确认退款 ¥' + this.refundAmount + '?',
|
||||
content: '退还剩余未加油金额:将调低该司机企油通凭证额度,成功后回补合作商余额。',
|
||||
onOk: () => {
|
||||
this.isLoading = true
|
||||
return Api.refund({ orderId: this.record.order_id, reason: this.reason })
|
||||
.then(result => this.afterAction(result, 2))
|
||||
.catch(() => this.afterError())
|
||||
.finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleConfirm () {
|
||||
this.isLoading = true
|
||||
Api.refundConfirm({ orderId: this.record.order_id })
|
||||
.then(result => this.afterAction(result, result.data.refundStatus))
|
||||
.catch(() => this.afterError())
|
||||
.finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
|
||||
handleResolve () {
|
||||
if (!this.resolveRemark.trim()) {
|
||||
this.$message.warning('请填写判定依据')
|
||||
return
|
||||
}
|
||||
this.isLoading = true
|
||||
Api.refundResolve({ orderId: this.record.order_id, result: this.resolveResult, remark: this.resolveRemark })
|
||||
.then(result => this.afterAction(result, result.data.refundStatus))
|
||||
.catch(() => this.afterError())
|
||||
.finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.info p {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.amount {
|
||||
color: #f5222d;
|
||||
}
|
||||
.sub {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
.block {
|
||||
margin: 12px 0;
|
||||
}
|
||||
.btns {
|
||||
margin-top: 12px;
|
||||
text-align: right;
|
||||
}
|
||||
.mt-10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -2,5 +2,7 @@ import OilForm from './OilForm'
|
||||
import UseForm from './UseForm'
|
||||
import ShareForm from './ShareForm'
|
||||
import PayForm from './PayForm'
|
||||
import RefundForm from './RefundForm'
|
||||
import InvoiceModal from './InvoiceModal'
|
||||
|
||||
export { OilForm, UseForm, ShareForm, PayForm }
|
||||
export { OilForm, UseForm, ShareForm, PayForm, RefundForm, InvoiceModal }
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
<template>
|
||||
<a-card :bordered="false">
|
||||
<div class="card-title">{{ $route.meta.title }}</div>
|
||||
|
||||
<a-alert type="info" show-icon class="tips-alert">
|
||||
<div slot="message">
|
||||
司机按身份证号归档。企油通发放到同一司机的额度会<b>在凭证上累计</b>,列表里的累计发放 / 已退款是按本地订单汇总的参考值,
|
||||
<b>真实可用额度以详情里实时查询的企油通数据为准</b>。
|
||||
标红的「信息冲突」会导致上游实名二要素核验失败,建议先让下单平台核对司机信息。
|
||||
</div>
|
||||
</a-alert>
|
||||
|
||||
<a-form layout="inline" :form="searchForm" class="search-form" @submit="handleSearch">
|
||||
<a-form-item label="司机">
|
||||
<a-input v-decorator="['keyword']" placeholder="姓名 / 手机号 / 完整身份证号" allowClear style="width: 240px" />
|
||||
</a-form-item>
|
||||
<a-form-item label="信息冲突">
|
||||
<a-select v-decorator="['conflict', { initialValue: -1 }]" style="width: 110px">
|
||||
<a-select-option :value="-1">全部</a-select-option>
|
||||
<a-select-option :value="1">有冲突</a-select-option>
|
||||
<a-select-option :value="0">正常</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" html-type="submit" icon="search">搜索</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<s-table ref="table" rowKey="driver_id" :columns="columns" :data="loadData">
|
||||
<template slot="driver" slot-scope="item">
|
||||
<p class="mtb-2">
|
||||
<b>{{ item.name || '-' }}</b>
|
||||
<a-tag v-if="item.conflict" color="red" class="ml-6">信息冲突</a-tag>
|
||||
</p>
|
||||
<p class="mtb-2 sub">{{ item.mobile }} {{ item.id_card_mask }}</p>
|
||||
<p v-if="item.conflict" class="mtb-2 text-red">{{ item.conflict_text }}</p>
|
||||
</template>
|
||||
<template slot="orders" slot-scope="item">
|
||||
<p class="mtb-2">共 {{ item.order_num }} 单</p>
|
||||
<p class="mtb-2 sub">已加油 {{ item.used_num }} 发放中 {{ item.pending_num }} 失败 {{ item.fail_num }}</p>
|
||||
</template>
|
||||
<template slot="amount" slot-scope="item">
|
||||
<p class="mtb-2">累计发放 ¥{{ item.grant_amount }}</p>
|
||||
<p class="mtb-2 sub">已加油 ¥{{ item.used_amount }} 已退款 ¥{{ item.refund_amount }} 净额 ¥{{ item.net_amount }}</p>
|
||||
</template>
|
||||
<template slot="action" slot-scope="item">
|
||||
<a @click="openDetail(item)">详情 / 查额度</a>
|
||||
</template>
|
||||
</s-table>
|
||||
|
||||
<a-drawer
|
||||
title="司机详情"
|
||||
:width="960"
|
||||
:visible="drawer"
|
||||
@close="drawer = false"
|
||||
>
|
||||
<a-spin :spinning="detailLoading">
|
||||
<template v-if="detail.driver_id">
|
||||
<p class="head">
|
||||
<b>{{ detail.name }}</b> {{ detail.mobile }} {{ detail.id_card_mask }}
|
||||
<a-tag v-if="detail.conflict" color="red" class="ml-6">信息冲突</a-tag>
|
||||
</p>
|
||||
<a-alert v-if="detail.conflict" type="error" :message="detail.conflict_text" show-icon class="block" />
|
||||
<p class="sub">
|
||||
本地汇总:共 {{ detail.order_num }} 单,累计发放 ¥{{ detail.grant_amount }},已退款 ¥{{ detail.refund_amount }},
|
||||
净额 ¥{{ detail.net_amount }};最近下单 {{ detail.last_order_time_text }}
|
||||
</p>
|
||||
|
||||
<a-divider orientation="left">企油通实时数据</a-divider>
|
||||
<div class="toolbar">
|
||||
<span>企业:</span>
|
||||
<a-select v-model="enterpriseId" style="width: 280px" placeholder="选择企业">
|
||||
<a-select-option v-for="item in enterprises" :key="item.enterprise_id" :value="item.enterprise_id">
|
||||
{{ item.company_name }}({{ item.passageway === 'pingan' ? '平安银行' : '支付宝企业码' }})
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<span v-if="!enterprises.length" class="sub ml-6">该司机还没有关联企业的订单</span>
|
||||
</div>
|
||||
|
||||
<a-tabs v-model="tab" @change="onTabChange">
|
||||
<a-tab-pane key="balance" tab="钱包余额(7.12)">
|
||||
<a-button :loading="upLoading" :disabled="!enterpriseId" @click="query('balance')">查询</a-button>
|
||||
<template v-if="result.balance">
|
||||
<p class="big">
|
||||
钱包发放总额 ¥{{ result.balance.totalGrantAmountYuan || '0.00' }}
|
||||
当前可用 <b class="green">¥{{ result.balance.availableBalanceYuan || '0.00' }}</b>
|
||||
</p>
|
||||
<a-table size="small" rowKey="business_license" :pagination="false" :columns="balanceColumns" :dataSource="result.balance.list || []" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="voucher" tab="支付凭证(7.17)">
|
||||
<a-button :loading="upLoading" :disabled="!enterpriseId" @click="query('voucher')">查询</a-button>
|
||||
<p class="sub mt-8">额度按凭证累计;退款时就是把其中「生效中、可用余额最大」的一张调低订单金额。</p>
|
||||
<a-table
|
||||
v-if="result.voucher"
|
||||
size="small"
|
||||
rowKey="quota_id"
|
||||
:pagination="false"
|
||||
:columns="voucherColumns"
|
||||
:dataSource="result.voucher.list || []"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="wallet" tab="钱包流水(7.13)">
|
||||
<a-button :loading="upLoading" :disabled="!enterpriseId" @click="query('wallet')">查询</a-button>
|
||||
<p class="sub mt-8">企油通默认只回溯近 1 个月流水。</p>
|
||||
<a-table
|
||||
v-if="result.wallet"
|
||||
size="small"
|
||||
rowKey="transactionId"
|
||||
:pagination="false"
|
||||
:columns="walletColumns"
|
||||
:dataSource="result.wallet.transactionDetails || []"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="orders" tab="最近订单">
|
||||
<p class="sub">发放失败原因里能看到上游实名二要素核验的结果。</p>
|
||||
<a-table size="small" rowKey="order_id" :pagination="false" :columns="orderColumns" :dataSource="orders">
|
||||
<span slot="zsy" slot-scope="text, row">
|
||||
<a-tag :color="{ 1: 'blue', 2: 'green', 3: 'red' }[row.oil_status_zsy] || ''">
|
||||
{{ { 0: '未提交', 1: '发放中', 2: '发放成功', 3: '发放失败' }[row.oil_status_zsy] }}
|
||||
</a-tag>
|
||||
</span>
|
||||
</a-table>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</template>
|
||||
</a-spin>
|
||||
</a-drawer>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Api from '@/api/qyt/driver'
|
||||
import { STable } from '@/components/Table'
|
||||
|
||||
export default {
|
||||
name: 'QytDriverIndex',
|
||||
components: { STable },
|
||||
data () {
|
||||
return {
|
||||
searchForm: this.$form.createForm(this),
|
||||
queryParam: {},
|
||||
columns: [
|
||||
{ title: 'ID', dataIndex: 'driver_id', width: 70 },
|
||||
{ title: '司机', scopedSlots: { customRender: 'driver' } },
|
||||
{ title: '订单', scopedSlots: { customRender: 'orders' } },
|
||||
{ title: '金额(本地口径)', scopedSlots: { customRender: 'amount' } },
|
||||
{ title: '最近下单', dataIndex: 'last_order_time_text', width: 170 },
|
||||
{ title: '操作', width: 120, scopedSlots: { customRender: 'action' } }
|
||||
],
|
||||
loadData: param => {
|
||||
return Api.list({ ...param, ...this.queryParam }).then(result => result.data.list)
|
||||
},
|
||||
|
||||
drawer: false,
|
||||
detailLoading: false,
|
||||
detail: {},
|
||||
enterprises: [],
|
||||
orders: [],
|
||||
enterpriseId: undefined,
|
||||
tab: 'balance',
|
||||
upLoading: false,
|
||||
result: {},
|
||||
|
||||
balanceColumns: [
|
||||
{ title: '企业', dataIndex: 'enterprise_name' },
|
||||
{ title: '凭证总额(元)', dataIndex: 'total_amount_yuan' },
|
||||
{ title: '可用(元)', dataIndex: 'available_amount_yuan' }
|
||||
],
|
||||
voucherColumns: [
|
||||
{ title: '凭证ID', dataIndex: 'quota_id' },
|
||||
{ title: '名称', dataIndex: 'quota_name' },
|
||||
{ title: '总额度', dataIndex: 'total_amount' },
|
||||
{ title: '可用', dataIndex: 'available_amount' },
|
||||
{ title: '已用', dataIndex: 'used_amount' },
|
||||
{ title: '冻结', dataIndex: 'freeze_amount' },
|
||||
{ title: '状态', dataIndex: 'status_text' },
|
||||
{ title: '有效期至', dataIndex: 'effective_end' }
|
||||
],
|
||||
walletColumns: [
|
||||
{ title: '时间', dataIndex: 'transactionTime' },
|
||||
{ title: '类型', dataIndex: 'transactionType' },
|
||||
{ title: '金额(元)', dataIndex: 'amount_yuan' },
|
||||
{ title: '备注', dataIndex: 'remark' },
|
||||
{ title: '流水号', dataIndex: 'transactionId' }
|
||||
],
|
||||
orderColumns: [
|
||||
{ title: '油卡编号', dataIndex: 'oilCardNo' },
|
||||
{ title: '金额', dataIndex: 'total_price' },
|
||||
{ title: '发放', scopedSlots: { customRender: 'zsy' } },
|
||||
{ title: '说明', dataIndex: 'oil_text' },
|
||||
{ title: '退款', dataIndex: 'refund_status_text' },
|
||||
{ title: '下单时间', dataIndex: 'create_time_text' }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
handleSearch (e) {
|
||||
e.preventDefault()
|
||||
this.searchForm.validateFields((errors, values) => {
|
||||
if (errors) return
|
||||
this.queryParam = { keyword: values.keyword || '', conflict: values.conflict }
|
||||
this.$refs.table.refresh(true)
|
||||
})
|
||||
},
|
||||
|
||||
openDetail (item) {
|
||||
this.drawer = true
|
||||
this.detail = {}
|
||||
this.enterprises = []
|
||||
this.orders = []
|
||||
this.result = {}
|
||||
this.tab = 'balance'
|
||||
this.enterpriseId = undefined
|
||||
this.detailLoading = true
|
||||
Api.detail({ driverId: item.driver_id })
|
||||
.then(result => {
|
||||
this.detail = result.data.detail
|
||||
this.enterprises = result.data.enterprises
|
||||
this.orders = result.data.orders
|
||||
this.enterpriseId = this.enterprises.length ? this.enterprises[0].enterprise_id : undefined
|
||||
})
|
||||
.finally(() => {
|
||||
this.detailLoading = false
|
||||
})
|
||||
},
|
||||
|
||||
onTabChange () {
|
||||
// 切换页签不自动查上游,避免无意义地打企油通;需要时点「查询」
|
||||
},
|
||||
|
||||
query (type) {
|
||||
this.upLoading = true
|
||||
Api.upstream({ driverId: this.detail.driver_id, enterpriseId: this.enterpriseId, type })
|
||||
.then(result => {
|
||||
this.result = { ...this.result, [type]: result.data.data }
|
||||
})
|
||||
.finally(() => {
|
||||
this.upLoading = false
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.tips-alert {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.search-form {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.sub {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
.ml-6 {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.mt-8 {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.text-red {
|
||||
color: #f5222d;
|
||||
font-size: 12px;
|
||||
}
|
||||
.green {
|
||||
color: #52c41a;
|
||||
}
|
||||
.head {
|
||||
font-size: 15px;
|
||||
}
|
||||
.block {
|
||||
margin: 10px 0;
|
||||
}
|
||||
.toolbar {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.big {
|
||||
margin: 12px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
</style>
|
||||
@@ -64,18 +64,15 @@
|
||||
<div v-if="item.sync_text" class="sub">{{ item.sync_text }}</div>
|
||||
</template>
|
||||
|
||||
<template slot="action" slot-scope="item">
|
||||
<div slot="action" slot-scope="item" class="op-actions">
|
||||
<a @click="handleUpdate(item)">编辑</a>
|
||||
<a-divider type="vertical" />
|
||||
<a @click="handleApply(item)">提交开户</a>
|
||||
<a-divider type="vertical" />
|
||||
<a @click="handleSyncAccount(item)">同步账户</a>
|
||||
<a-divider type="vertical" />
|
||||
<a v-if="item.passageway === 'pingan'" @click="handleBalance(item)">账户余额</a>
|
||||
<a v-if="!item.is_default" @click="handleSetDefault(item)">设为默认</a>
|
||||
<span v-else class="text-grey">设为默认</span>
|
||||
<a-divider type="vertical" />
|
||||
<a class="text-red" @click="handleDelete(item)">删除</a>
|
||||
</template>
|
||||
</div>
|
||||
</s-table>
|
||||
|
||||
<a-modal
|
||||
@@ -190,7 +187,7 @@ export default {
|
||||
{ title: '企业', scopedSlots: { customRender: 'company' } },
|
||||
{ title: '通道与机构号', scopedSlots: { customRender: 'passageway' } },
|
||||
{ title: '企油通状态', scopedSlots: { customRender: 'status' } },
|
||||
{ title: '操作', width: 260, scopedSlots: { customRender: 'action' } }
|
||||
{ title: '操作', width: 280, scopedSlots: { customRender: 'action' } }
|
||||
],
|
||||
loadData: param => {
|
||||
return Api.list({ ...param, ...this.queryParam }).then(result => result.data.list)
|
||||
@@ -310,6 +307,17 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
// 7.11 企业账户余额(平安银行银行侧实时查询,勿频繁点击)
|
||||
handleBalance (item) {
|
||||
Api.balance({ enterpriseId: item.enterprise_id }).then(result => {
|
||||
this.$info({
|
||||
title: item.company_name + ' · 平安银行账户余额',
|
||||
content: '账面余额 ¥' + result.data.balance + ',可用余额 ¥' + result.data.available_balance +
|
||||
'(可用余额已扣除冻结/止付金额,即当前可发放凭证的资金上限)'
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
handleSyncList () {
|
||||
this.isSyncing = true
|
||||
Api.syncList({})
|
||||
@@ -351,4 +359,15 @@ export default {
|
||||
.text-grey {
|
||||
color: #bbb;
|
||||
}
|
||||
// 操作栏:按钮较多会换行,用 gap 统一横纵间距,不用竖线分隔(换行后竖线会悬在行首行尾)
|
||||
.op-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px 16px;
|
||||
|
||||
& > a,
|
||||
& > span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<a-card :bordered="false">
|
||||
<div class="card-title">{{ $route.meta.title }}</div>
|
||||
|
||||
<a-alert type="info" show-icon class="tips-alert">
|
||||
<div slot="message">
|
||||
企油通 7.14 按「企业 + 月份(+ 司机手机号)」出具发票,发票地址与单笔订单没有对应关系。
|
||||
订单列表里点「发票」会自动按该订单的企业、消费月份、司机同步;这里可以按月批量同步或手动补同步。
|
||||
</div>
|
||||
</a-alert>
|
||||
|
||||
<a-form layout="inline" :form="syncForm" class="sync-form" @submit="handleSync">
|
||||
<a-form-item label="企业">
|
||||
<a-select v-decorator="['enterpriseId', { initialValue: 0 }]" style="width: 220px">
|
||||
<a-select-option :value="0">全部启用企业(企业全量)</a-select-option>
|
||||
<a-select-option v-for="item in enterpriseList" :key="item.enterprise_id" :value="item.enterprise_id">
|
||||
{{ item.company_name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="月份">
|
||||
<a-month-picker v-decorator="['month', { rules: [{ required: true, message: '请选择月份' }] }]" placeholder="选择月份" />
|
||||
</a-form-item>
|
||||
<a-form-item label="司机手机号">
|
||||
<a-input v-decorator="['mobile']" placeholder="选填,仅指定企业时有效" allowClear />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" html-type="submit" icon="sync" :loading="isSyncing">同步发票</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<a-divider />
|
||||
|
||||
<a-form layout="inline" :form="searchForm" class="search-form" @submit="handleSearch">
|
||||
<a-form-item label="企业">
|
||||
<a-select v-decorator="['qyt_enterprise_id', { initialValue: 0 }]" style="width: 200px">
|
||||
<a-select-option :value="0">全部</a-select-option>
|
||||
<a-select-option v-for="item in enterpriseList" :key="item.enterprise_id" :value="item.enterprise_id">
|
||||
{{ item.company_name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="月份">
|
||||
<a-month-picker v-decorator="['month']" placeholder="全部" />
|
||||
</a-form-item>
|
||||
<a-form-item label="司机手机号">
|
||||
<a-input v-decorator="['mobile']" placeholder="手机号" allowClear />
|
||||
</a-form-item>
|
||||
<a-form-item label="发票">
|
||||
<a-select v-decorator="['has_invoice', { initialValue: -1 }]" style="width: 110px">
|
||||
<a-select-option :value="-1">全部</a-select-option>
|
||||
<a-select-option :value="1">已出具</a-select-option>
|
||||
<a-select-option :value="0">暂无</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" html-type="submit" icon="search">搜索</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<s-table ref="table" rowKey="invoice_id" :columns="columns" :data="loadData">
|
||||
<template slot="dimension" slot-scope="item">
|
||||
<p class="mtb-2"><b>{{ item.company_name }}</b></p>
|
||||
<p class="mtb-2 sub">{{ item.passageway === 'pingan' ? '平安银行' : '支付宝企业码' }} {{ item.month }} {{ item.mobile_mask }}</p>
|
||||
</template>
|
||||
<template slot="invoices" slot-scope="item">
|
||||
<template v-if="item.invoice_urls.length">
|
||||
<p v-for="(url, index) in item.invoice_urls" :key="url" class="mtb-2">
|
||||
<a :href="url" target="_blank" rel="noopener noreferrer">发票 {{ index + 1 }}</a>
|
||||
</p>
|
||||
</template>
|
||||
<span v-else class="sub">暂无</span>
|
||||
</template>
|
||||
<template slot="sync" slot-scope="item">
|
||||
<a-tag :color="{ 1: 'green', 2: 'red' }[item.sync_status] || ''">{{ { 0: '未同步', 1: '成功', 2: '失败' }[item.sync_status] }}</a-tag>
|
||||
<p class="mtb-2 sub">{{ item.sync_text }}</p>
|
||||
<p class="mtb-2 sub">{{ item.sync_time_text }}</p>
|
||||
</template>
|
||||
<template slot="action" slot-scope="item">
|
||||
<a @click="handleResync(item)">重新同步</a>
|
||||
</template>
|
||||
</s-table>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Api from '@/api/qyt/invoice'
|
||||
import * as EnterpriseApi from '@/api/qyt/enterprise'
|
||||
import { STable } from '@/components/Table'
|
||||
|
||||
export default {
|
||||
name: 'QytInvoiceIndex',
|
||||
components: { STable },
|
||||
data () {
|
||||
return {
|
||||
syncForm: this.$form.createForm(this),
|
||||
searchForm: this.$form.createForm(this),
|
||||
enterpriseList: [],
|
||||
isSyncing: false,
|
||||
queryParam: {},
|
||||
columns: [
|
||||
{ title: 'ID', dataIndex: 'invoice_id', width: 70 },
|
||||
{ title: '企业 / 通道 / 月份 / 维度', scopedSlots: { customRender: 'dimension' } },
|
||||
{ title: '发票', scopedSlots: { customRender: 'invoices' } },
|
||||
{ title: '加油明细条数', dataIndex: 'order_count', width: 110 },
|
||||
{ title: '同步状态', scopedSlots: { customRender: 'sync' } },
|
||||
{ title: '操作', width: 100, scopedSlots: { customRender: 'action' } }
|
||||
],
|
||||
loadData: param => {
|
||||
return Api.list({ ...param, ...this.queryParam }).then(result => result.data.list)
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
EnterpriseApi.options().then(result => {
|
||||
this.enterpriseList = result.data.list
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
|
||||
handleSync (e) {
|
||||
e.preventDefault()
|
||||
this.syncForm.validateFields((errors, values) => {
|
||||
if (errors) return
|
||||
this.doSync({
|
||||
enterpriseId: values.enterpriseId || 0,
|
||||
month: values.month.format('YYYY-MM'),
|
||||
mobile: values.enterpriseId ? (values.mobile || '') : ''
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
handleResync (item) {
|
||||
this.doSync({ enterpriseId: item.qyt_enterprise_id, month: item.month, mobile: item.mobile })
|
||||
},
|
||||
|
||||
doSync (data) {
|
||||
this.isSyncing = true
|
||||
Api.sync(data)
|
||||
.then(result => {
|
||||
this.$message.success(result.message, 2)
|
||||
this.$refs.table.refresh()
|
||||
})
|
||||
.finally(() => {
|
||||
this.isSyncing = false
|
||||
})
|
||||
},
|
||||
|
||||
handleSearch (e) {
|
||||
e.preventDefault()
|
||||
this.searchForm.validateFields((errors, values) => {
|
||||
if (errors) return
|
||||
this.queryParam = {
|
||||
qyt_enterprise_id: values.qyt_enterprise_id || '',
|
||||
month: values.month ? values.month.format('YYYY-MM') : '',
|
||||
mobile: values.mobile || '',
|
||||
has_invoice: values.has_invoice
|
||||
}
|
||||
this.$refs.table.refresh(true)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.tips-alert {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.sub {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
.search-form {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user