feat: 客服「成交与自动结算」配置页与指标列表
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -57,6 +57,7 @@
|
||||
</template>
|
||||
<el-menu-item v-if="canShow('order.platform')" index="/order/platform">平台订单</el-menu-item>
|
||||
<el-menu-item v-if="canShow('order.merchant')" index="/order/merchant">商家订单</el-menu-item>
|
||||
<el-menu-item v-if="canShow('order.deal-config')" index="/order/deal-config">成交与自动结算</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
<!-- 跨平台管理 -->
|
||||
@@ -156,6 +157,7 @@
|
||||
<el-menu-item v-if="canShow('miniapp.dashou-exam')" index="/miniapp/dashou-exam">打手接单考试</el-menu-item>
|
||||
<el-menu-item v-if="canShow('miniapp.rank-reward')" index="/miniapp/rank-reward">排行榜奖励</el-menu-item>
|
||||
<el-menu-item v-if="canShow('miniapp.recharge-copy')" index="/miniapp/recharge-copy">充值页文案</el-menu-item>
|
||||
<el-menu-item v-if="canShow('miniapp.role-agreement')" index="/miniapp/role-agreement">角色协议</el-menu-item>
|
||||
<el-menu-item v-if="canShow('miniapp.withdraw-settings')" index="/withdraw/settings">提现与收款设置</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
|
||||
165
src/views/order/OrderDealConfig.vue
Normal file
165
src/views/order/OrderDealConfig.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<div class="page" v-loading="loading">
|
||||
<ClubScopeHint />
|
||||
<div class="header">
|
||||
<h2>成交指标与自动结算</h2>
|
||||
<el-button @click="load">刷新</el-button>
|
||||
</div>
|
||||
<el-alert
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
title="默认全关。打开自动结算后,仅「本次开启之后新进入结算中」的订单会计时并到期自动完成;历史结算中老单永远不会被自动结。"
|
||||
style="margin-bottom: 16px"
|
||||
/>
|
||||
<div v-if="form.club_id" class="club">当前俱乐部:{{ form.club_id }}</div>
|
||||
|
||||
<el-card shadow="never" class="card">
|
||||
<template #header>自动结算</template>
|
||||
<el-form label-width="160px">
|
||||
<el-form-item label="启用自动结算">
|
||||
<el-switch v-model="form.auto_settle_enabled" />
|
||||
</el-form-item>
|
||||
<el-form-item label="平台单超时(小时)">
|
||||
<el-input-number v-model="form.hours_platform" :min="1" :max="720" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商家单超时(小时)">
|
||||
<el-input-number v-model="form.hours_merchant" :min="1" :max="720" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.auto_settle_enabled_at" label="本次开启时间">
|
||||
<span>{{ form.auto_settle_enabled_at }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="card">
|
||||
<template #header>成交 / 罚款指标统计</template>
|
||||
<el-form label-width="160px">
|
||||
<el-form-item label="启用指标统计">
|
||||
<el-switch v-model="form.stats_enabled" />
|
||||
<span class="tip">从开启时刻起记账,不算历史单</span>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.stats_since" label="统计起点">
|
||||
<span>{{ form.stats_since }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-button type="primary" :loading="saving" @click="save">保存</el-button>
|
||||
|
||||
<el-card v-if="form.stats_enabled" shadow="never" class="card" style="margin-top:16px">
|
||||
<template #header>商家指标(本俱乐部)</template>
|
||||
<el-table :data="merchantList" size="small" max-height="360">
|
||||
<el-table-column prop="merchant_uid" label="商家UID" width="120" />
|
||||
<el-table-column prop="order_count" label="订单量" width="90" />
|
||||
<el-table-column prop="deal_rate" label="成交率" width="100">
|
||||
<template #default="{ row }">{{ pct(row.deal_rate) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="fine_rate" label="罚款率" width="100">
|
||||
<template #default="{ row }">{{ pct(row.fine_rate) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="refund_rate" label="退款率" width="100">
|
||||
<template #default="{ row }">{{ pct(row.refund_rate) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="avg_deal_hours" label="平均成交时长(h)" min-width="120" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-card v-if="form.stats_enabled" shadow="never" class="card">
|
||||
<template #header>打手指标(本俱乐部)</template>
|
||||
<el-table :data="dashouList" size="small" max-height="360">
|
||||
<el-table-column prop="dashou_uid" label="打手UID" width="120" />
|
||||
<el-table-column prop="order_count" label="接单量" width="90" />
|
||||
<el-table-column prop="deal_rate" label="成交率" width="100">
|
||||
<template #default="{ row }">{{ pct(row.deal_rate) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="fined_rate" label="被罚款率" width="100">
|
||||
<template #default="{ row }">{{ pct(row.fined_rate) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import request from '@/utils/request'
|
||||
import { JITUAN_API } from '@/utils/club-context'
|
||||
import ClubScopeHint from '@/components/ClubScopeHint.vue'
|
||||
|
||||
const username = localStorage.getItem('username') || ''
|
||||
const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const merchantList = ref([])
|
||||
const dashouList = ref([])
|
||||
const form = reactive({
|
||||
club_id: '',
|
||||
auto_settle_enabled: false,
|
||||
auto_settle_enabled_at: '',
|
||||
hours_platform: 48,
|
||||
hours_merchant: 48,
|
||||
stats_enabled: false,
|
||||
stats_since: '',
|
||||
})
|
||||
|
||||
function pct(v) {
|
||||
const n = Number(v) || 0
|
||||
return `${(n * 100).toFixed(2)}%`
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await request.post(JITUAN_API.orderDealConfig, { username, action: 'get' })
|
||||
if (res.code === 0 || res.code === 200) {
|
||||
Object.assign(form, res.data || {})
|
||||
} else {
|
||||
ElMessage.error(res.msg || '加载失败')
|
||||
}
|
||||
if (form.stats_enabled) {
|
||||
const [m, d] = await Promise.all([
|
||||
request.post(JITUAN_API.merchantDealStat, { username, action: 'list' }),
|
||||
request.post(JITUAN_API.dashouDealStat, { username, action: 'list' }),
|
||||
])
|
||||
merchantList.value = m.data?.list || []
|
||||
dashouList.value = d.data?.list || []
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function save() {
|
||||
saving.value = true
|
||||
try {
|
||||
const res = await request.post(JITUAN_API.orderDealConfig, {
|
||||
username,
|
||||
action: 'save',
|
||||
auto_settle_enabled: form.auto_settle_enabled,
|
||||
hours_platform: form.hours_platform,
|
||||
hours_merchant: form.hours_merchant,
|
||||
stats_enabled: form.stats_enabled,
|
||||
})
|
||||
if (res.code === 0 || res.code === 200) {
|
||||
Object.assign(form, res.data || {})
|
||||
ElMessage.success('已保存')
|
||||
load()
|
||||
} else {
|
||||
ElMessage.error(res.msg || '保存失败')
|
||||
}
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page { padding: 16px; }
|
||||
.header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
|
||||
.club { margin-bottom: 12px; color: #64748b; font-size: 13px; }
|
||||
.card { margin-bottom: 16px; }
|
||||
.tip { margin-left: 12px; color: #94a3b8; font-size: 12px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user