770 lines
28 KiB
Vue
770 lines
28 KiB
Vue
<template>
|
|
<div class="default-main ba-table-box">
|
|
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
|
|
|
<TableHeader
|
|
:buttons="['refresh', 'add', 'edit', 'delete', 'comSearch', 'quickSearch', 'columnDisplay']"
|
|
:quick-search-placeholder="t('Quick search placeholder', { fields: t('channel.quick Search Fields') })"
|
|
></TableHeader>
|
|
<div class="channel-top-actions">
|
|
<div class="channel-stats-cards">
|
|
<el-card shadow="never" class="channel-stat-card">
|
|
<div class="label">{{ t('channel.settle_stats_channel_total') }}</div>
|
|
<div class="value">{{ settleStats.channel_total }}</div>
|
|
</el-card>
|
|
<el-card shadow="never" class="channel-stat-card">
|
|
<div class="label">{{ t('channel.settle_stats_enabled') }}</div>
|
|
<div class="value">{{ settleStats.enabled_count }}</div>
|
|
</el-card>
|
|
<el-card shadow="never" class="channel-stat-card">
|
|
<div class="label">{{ t('channel.settle_stats_pending_dividend') }}</div>
|
|
<div class="value">{{ settleStats.carryover_positive_count }}</div>
|
|
</el-card>
|
|
<el-card shadow="never" class="channel-stat-card">
|
|
<div class="label">{{ t('channel.settle_stats_pending_amount') }}</div>
|
|
<div class="value">{{ settleStats.carryover_positive_total }}</div>
|
|
</el-card>
|
|
</div>
|
|
<div class="channel-action-row">
|
|
<el-radio-group v-model="settleFilterMode" size="small" @change="onSettleFilterChange">
|
|
<el-radio-button label="all">{{ t('channel.settle_filter_all') }}</el-radio-button>
|
|
<el-radio-button label="with_balance">{{ t('channel.settle_filter_with_balance') }}</el-radio-button>
|
|
<el-radio-button label="no_balance">{{ t('channel.settle_filter_no_balance') }}</el-radio-button>
|
|
<el-radio-button label="enabled">{{ t('channel.settle_filter_enabled') }}</el-radio-button>
|
|
<el-radio-button label="disabled">{{ t('channel.settle_filter_disabled') }}</el-radio-button>
|
|
</el-radio-group>
|
|
<el-button v-if="adminInfo.super && auth('batchSettlePending')" type="warning" @click="onBatchSettlePending">
|
|
{{ t('channel.batch_settle_pending') }}
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
|
|
<Table ref="tableRef"></Table>
|
|
|
|
<PopupForm />
|
|
|
|
<el-dialog
|
|
class="ba-operate-dialog manual-settle-dialog"
|
|
:close-on-click-modal="false"
|
|
:model-value="manualSettle.visible"
|
|
width="860px"
|
|
@close="closeManualSettleDialog"
|
|
>
|
|
<template #header>
|
|
<div class="title">{{ t('channel.manual_settle') }}</div>
|
|
</template>
|
|
<div v-loading="manualSettle.previewLoading" class="manual-settle-dialog-body">
|
|
<el-form :model="manualSettle.form" label-width="140px" class="manual-settle-form">
|
|
<el-form-item :label="t('channel.manual_settle_settlement_no')">
|
|
<el-input v-model="manualSettle.form.settlement_no" readonly />
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.manual_settle_period_start')">
|
|
<el-input v-model="manualSettle.form.period_start_at" readonly />
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.manual_settle_period_end')">
|
|
<el-input v-model="manualSettle.form.period_end_at" readonly />
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.manual_settle_total_bet')">
|
|
<el-input v-model="manualSettle.form.total_bet_amount" readonly />
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.manual_settle_total_payout')">
|
|
<el-input v-model="manualSettle.form.total_payout_amount" readonly />
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.manual_settle_platform_profit')">
|
|
<el-input v-model="manualSettle.form.platform_profit_amount" readonly />
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.manual_settle_commission_rate')">
|
|
<el-input v-model="manualSettle.form.commission_rate" readonly />
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.manual_settle_calc_base')">
|
|
<el-input v-model="manualSettle.form.calc_base_amount" readonly />
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.manual_settle_commission_amount')">
|
|
<el-input v-model="manualSettle.form.commission_amount" readonly />
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.share_config')" class="manual-settle-form-item-full">
|
|
<el-table :data="manualSettle.form.commission_split" border size="small" class="w100" max-height="220">
|
|
<el-table-column prop="admin_username" :label="t('channel.admin__username')" min-width="100" />
|
|
<el-table-column prop="share_rate" :label="t('channel.share_rate_percent')" min-width="90">
|
|
<template #default="scope">{{ scope.row.share_rate }}%</template>
|
|
</el-table-column>
|
|
<el-table-column prop="commission_amount" :label="t('channel.manual_settle_commission_amount')" min-width="110" />
|
|
</el-table>
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.manual_settle_remark')" class="manual-settle-form-item-full">
|
|
<el-input v-model="manualSettle.form.remark" type="textarea" :rows="2" />
|
|
</el-form-item>
|
|
</el-form>
|
|
</div>
|
|
<template #footer>
|
|
<div class="manual-settle-footer">
|
|
<el-button @click="closeManualSettleDialog">{{ t('Cancel') }}</el-button>
|
|
<el-button type="primary" :disabled="manualSettle.previewLoading" :loading="manualSettle.loading" @click="submitManualSettle">
|
|
{{ t('channel.manual_settle_submit') }}
|
|
</el-button>
|
|
</div>
|
|
</template>
|
|
</el-dialog>
|
|
|
|
<el-dialog class="ba-operate-dialog" :close-on-click-modal="false" :model-value="shareDialog.visible" @close="closeShareDialog">
|
|
<template #header>
|
|
<div class="title">{{ t('channel.share_config_title') }}</div>
|
|
</template>
|
|
<div v-loading="shareDialog.loading" class="manual-settle-dialog-body">
|
|
<el-alert type="info" :closable="false" show-icon class="mb-12">
|
|
{{ t('channel.share_config_tip') }}
|
|
</el-alert>
|
|
<el-table :data="shareDialog.list" border size="small">
|
|
<el-table-column :label="t('channel.admin_group_names')" min-width="260">
|
|
<template #default="scope">
|
|
<span v-if="scope.row.role_group_name" class="share-group-single">{{ scope.row.role_group_name }}</span>
|
|
<span v-else class="share-group-empty">-</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="username" :label="t('channel.admin__username')" min-width="120" />
|
|
<el-table-column :label="t('channel.status')" width="120">
|
|
<template #default="scope">
|
|
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" />
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column :label="t('channel.share_rate_percent')" min-width="180">
|
|
<template #default="scope">
|
|
<el-input-number
|
|
v-model="scope.row.share_rate"
|
|
:disabled="scope.row.status !== 1"
|
|
:min="0"
|
|
:max="100"
|
|
:step="0.01"
|
|
:precision="2"
|
|
class="w100"
|
|
/>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<div class="share-total-row">
|
|
<span>{{ t('channel.share_total_enabled') }}: </span>
|
|
<el-tag :type="shareEnabledTotal === '100.00' ? 'success' : 'danger'">{{ shareEnabledTotal }}%</el-tag>
|
|
</div>
|
|
</div>
|
|
<template #footer>
|
|
<el-button @click="closeShareDialog">{{ t('Cancel') }}</el-button>
|
|
<el-button type="primary" :loading="shareDialog.saving" @click="saveShareDialog">{{ t('Save') }}</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, onMounted, provide, reactive, ref, useTemplateRef } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { ElMessage } from 'element-plus'
|
|
import PopupForm from './popupForm.vue'
|
|
import { baTableApi } from '/@/api/common'
|
|
import { auth } from '/@/utils/common'
|
|
import { useAdminInfo } from '/@/stores/adminInfo'
|
|
import { defaultOptButtons } from '/@/components/table'
|
|
import TableHeader from '/@/components/table/header/index.vue'
|
|
import Table from '/@/components/table/index.vue'
|
|
import baTableClass from '/@/utils/baTable'
|
|
import createAxios from '/@/utils/axios'
|
|
|
|
defineOptions({
|
|
name: 'channel',
|
|
})
|
|
|
|
const { t } = useI18n()
|
|
const adminInfo = useAdminInfo()
|
|
const tableRef = useTemplateRef('tableRef')
|
|
let optButtons: OptButton[] = [
|
|
{
|
|
render: 'tipButton',
|
|
name: 'shareConfig',
|
|
title: 'channel.share_config',
|
|
text: '',
|
|
type: 'primary',
|
|
icon: 'el-icon-Setting',
|
|
class: 'table-row-share-config',
|
|
disabledTip: false,
|
|
display: () => auth('edit'),
|
|
click: (row: TableRow) => {
|
|
void openShareDialog(row)
|
|
},
|
|
},
|
|
{
|
|
render: 'tipButton',
|
|
name: 'manualSettle',
|
|
title: 'channel.manual_settle',
|
|
text: '',
|
|
type: 'warning',
|
|
icon: 'el-icon-Clock',
|
|
class: 'table-row-manual-settle',
|
|
disabledTip: false,
|
|
display: () => adminInfo.super && auth('manualSettle'),
|
|
click: (row: TableRow) => {
|
|
void openManualSettleDialog(row)
|
|
},
|
|
},
|
|
]
|
|
optButtons = optButtons.concat(defaultOptButtons(['edit', 'delete']))
|
|
const formatAmountInt = (_row: any, _column: any, cellValue: number | string | null) => {
|
|
if (cellValue === null || cellValue === undefined || cellValue === '') return '-'
|
|
const num = Number(cellValue)
|
|
if (Number.isNaN(num)) return '-'
|
|
return `${num}`
|
|
}
|
|
const formatSettleDay = (row: anyObj) => {
|
|
if (row.settle_cycle === 'weekly') {
|
|
return t(`channel.weekday ${row.settle_weekday ?? 1}`)
|
|
}
|
|
if (row.settle_cycle === 'monthly') {
|
|
return `${row.settle_monthday ?? 1}${t('channel.day_suffix')}`
|
|
}
|
|
return t('channel.settle_day_daily')
|
|
}
|
|
|
|
const manualSettle = reactive({
|
|
visible: false,
|
|
loading: false,
|
|
previewLoading: false,
|
|
channelId: 0,
|
|
form: {
|
|
settlement_no: '',
|
|
period_start_at: '',
|
|
period_end_at: '',
|
|
total_bet_amount: '',
|
|
total_payout_amount: '',
|
|
platform_profit_amount: '',
|
|
commission_rate: '',
|
|
calc_base_amount: '',
|
|
commission_amount: '',
|
|
commission_split: [] as Array<{ admin_id: number; admin_username: string; share_rate: string; commission_amount: string }>,
|
|
remark: '',
|
|
},
|
|
})
|
|
|
|
const shareDialog = reactive({
|
|
visible: false,
|
|
loading: false,
|
|
saving: false,
|
|
channelId: 0,
|
|
list: [] as Array<{ admin_id: number; username: string; role_group_name: string; role_level: number; status: number; share_rate: number | null }>,
|
|
})
|
|
const settleFilterMode = ref<'all' | 'with_balance' | 'no_balance' | 'enabled' | 'disabled'>('all')
|
|
const settleStats = reactive({
|
|
channel_total: 0,
|
|
enabled_count: 0,
|
|
disabled_count: 0,
|
|
carryover_positive_count: 0,
|
|
carryover_total: '0.00',
|
|
carryover_positive_total: '0.00',
|
|
})
|
|
|
|
const shareEnabledTotal = computed(() => {
|
|
let sum = 0
|
|
for (const row of shareDialog.list) {
|
|
if (row.status === 1) {
|
|
const n = Number(row.share_rate ?? 0)
|
|
if (Number.isFinite(n)) {
|
|
sum += n
|
|
}
|
|
}
|
|
}
|
|
return sum.toFixed(2)
|
|
})
|
|
|
|
const closeShareDialog = () => {
|
|
shareDialog.visible = false
|
|
shareDialog.channelId = 0
|
|
shareDialog.list = []
|
|
}
|
|
|
|
const openShareDialog = async (row: TableRow) => {
|
|
shareDialog.channelId = Number(row.id || 0)
|
|
shareDialog.visible = true
|
|
shareDialog.loading = true
|
|
try {
|
|
const res = await createAxios(
|
|
{
|
|
url: '/admin/channel/channelAdminShareList',
|
|
method: 'get',
|
|
params: { id: row.id },
|
|
},
|
|
{ showErrorMessage: true }
|
|
)
|
|
if (res.code !== 1 || !res.data) {
|
|
closeShareDialog()
|
|
return
|
|
}
|
|
const list = Array.isArray(res.data.list) ? res.data.list : []
|
|
shareDialog.list = list.map((item: anyObj) => {
|
|
const rate = item.share_rate
|
|
return {
|
|
admin_id: Number(item.admin_id || 0),
|
|
username: String(item.username || ''),
|
|
role_group_name: String(item.role_group_name || ''),
|
|
role_level: Number(item.role_level ?? 9999),
|
|
status: Number(item.status ?? 1) === 1 ? 1 : 0,
|
|
share_rate: rate === null || rate === undefined || rate === '' ? null : Number(rate),
|
|
}
|
|
})
|
|
} finally {
|
|
shareDialog.loading = false
|
|
}
|
|
}
|
|
|
|
const saveShareDialog = async () => {
|
|
if (!shareDialog.channelId) {
|
|
return
|
|
}
|
|
if (shareEnabledTotal.value !== '100.00') {
|
|
ElMessage.error(t('channel.share_total_must_100'))
|
|
return
|
|
}
|
|
shareDialog.saving = true
|
|
try {
|
|
await createAxios(
|
|
{
|
|
url: '/admin/channel/saveChannelAdminShare',
|
|
method: 'post',
|
|
data: {
|
|
id: shareDialog.channelId,
|
|
list: shareDialog.list.map((row) => ({
|
|
admin_id: row.admin_id,
|
|
status: row.status,
|
|
share_rate: Number(row.share_rate || 0).toFixed(2),
|
|
})),
|
|
},
|
|
},
|
|
{ showSuccessMessage: true }
|
|
)
|
|
closeShareDialog()
|
|
} finally {
|
|
shareDialog.saving = false
|
|
}
|
|
}
|
|
|
|
const resetManualSettleForm = () => {
|
|
manualSettle.form.settlement_no = ''
|
|
manualSettle.form.period_start_at = ''
|
|
manualSettle.form.period_end_at = ''
|
|
manualSettle.form.total_bet_amount = ''
|
|
manualSettle.form.total_payout_amount = ''
|
|
manualSettle.form.platform_profit_amount = ''
|
|
manualSettle.form.commission_rate = ''
|
|
manualSettle.form.calc_base_amount = ''
|
|
manualSettle.form.commission_amount = ''
|
|
manualSettle.form.commission_split = []
|
|
manualSettle.form.remark = ''
|
|
}
|
|
|
|
const closeManualSettleDialog = () => {
|
|
manualSettle.visible = false
|
|
resetManualSettleForm()
|
|
}
|
|
|
|
const openManualSettleDialog = async (row: TableRow) => {
|
|
manualSettle.channelId = row.id
|
|
resetManualSettleForm()
|
|
manualSettle.visible = true
|
|
manualSettle.previewLoading = true
|
|
try {
|
|
const res = await createAxios(
|
|
{
|
|
url: '/admin/channel/manualSettlePreview',
|
|
method: 'get',
|
|
params: { id: row.id },
|
|
},
|
|
{ showErrorMessage: true }
|
|
)
|
|
if (res.code !== 1 || !res.data) {
|
|
manualSettle.visible = false
|
|
return
|
|
}
|
|
const d = res.data as anyObj
|
|
manualSettle.form.settlement_no = d.settlement_no ?? ''
|
|
manualSettle.form.period_start_at = d.period_start_at ?? ''
|
|
manualSettle.form.period_end_at = d.period_end_at ?? ''
|
|
manualSettle.form.total_bet_amount = d.total_bet_amount ?? ''
|
|
manualSettle.form.total_payout_amount = d.total_payout_amount ?? ''
|
|
manualSettle.form.platform_profit_amount = d.platform_profit_amount ?? ''
|
|
manualSettle.form.commission_rate = d.commission_rate ?? ''
|
|
manualSettle.form.calc_base_amount = d.calc_base_amount ?? ''
|
|
manualSettle.form.commission_amount = d.commission_amount ?? ''
|
|
manualSettle.form.commission_split = Array.isArray(d.commission_split) ? d.commission_split : []
|
|
manualSettle.form.remark = `${t('channel.manual_settle')}-CH${row.id}`
|
|
} catch {
|
|
manualSettle.visible = false
|
|
} finally {
|
|
manualSettle.previewLoading = false
|
|
}
|
|
}
|
|
|
|
const submitManualSettle = async () => {
|
|
if (!manualSettle.channelId) return
|
|
manualSettle.loading = true
|
|
try {
|
|
await createAxios(
|
|
{
|
|
url: '/admin/channel/manualSettle',
|
|
method: 'post',
|
|
data: {
|
|
id: manualSettle.channelId,
|
|
remark: manualSettle.form.remark,
|
|
},
|
|
},
|
|
{ showSuccessMessage: true }
|
|
)
|
|
closeManualSettleDialog()
|
|
baTable.onTableHeaderAction('refresh', { event: 'manual-settle' })
|
|
} finally {
|
|
manualSettle.loading = false
|
|
}
|
|
}
|
|
|
|
const onBatchSettlePending = async () => {
|
|
await createAxios(
|
|
{
|
|
url: '/admin/channel/batchSettlePending',
|
|
method: 'post',
|
|
},
|
|
{ showSuccessMessage: true }
|
|
)
|
|
await loadSettleStats()
|
|
baTable.onTableHeaderAction('refresh', { event: 'batch-settle' })
|
|
}
|
|
|
|
const onSettleFilterChange = () => {
|
|
baTable.getData()
|
|
}
|
|
|
|
const loadSettleStats = async () => {
|
|
const res = await createAxios({ url: '/admin/channel/settleStats', method: 'get' })
|
|
if (res.code !== 1 || !res.data) {
|
|
return
|
|
}
|
|
settleStats.channel_total = Number(res.data.channel_total ?? 0)
|
|
settleStats.enabled_count = Number(res.data.enabled_count ?? 0)
|
|
settleStats.disabled_count = Number(res.data.disabled_count ?? 0)
|
|
settleStats.carryover_positive_count = Number(res.data.carryover_positive_count ?? 0)
|
|
settleStats.carryover_total = String(res.data.carryover_total ?? '0.00')
|
|
settleStats.carryover_positive_total = String(res.data.carryover_positive_total ?? '0.00')
|
|
}
|
|
|
|
const baTable = new baTableClass(
|
|
new baTableApi('/admin/channel/'),
|
|
{
|
|
pk: 'id',
|
|
column: [
|
|
{ type: 'selection', align: 'center', operator: false },
|
|
{ label: t('channel.id'), prop: 'id', align: 'center', width: 70, operator: 'RANGE', sortable: 'custom' },
|
|
{
|
|
label: t('channel.code'),
|
|
prop: 'code',
|
|
align: 'center',
|
|
operatorPlaceholder: t('Fuzzy query'),
|
|
sortable: false,
|
|
operator: 'LIKE',
|
|
},
|
|
{
|
|
label: t('channel.name'),
|
|
prop: 'name',
|
|
align: 'center',
|
|
operatorPlaceholder: t('Fuzzy query'),
|
|
sortable: false,
|
|
operator: 'LIKE',
|
|
},
|
|
{
|
|
label: t('channel.agent_mode'),
|
|
prop: 'agent_mode',
|
|
align: 'center',
|
|
minWidth: 120,
|
|
operator: 'eq',
|
|
sortable: false,
|
|
render: 'tag',
|
|
custom: {
|
|
turnover: 'primary',
|
|
affiliate: 'success',
|
|
},
|
|
replaceValue: {
|
|
turnover: t('channel.agent_mode turnover'),
|
|
affiliate: t('channel.agent_mode affiliate'),
|
|
},
|
|
},
|
|
{
|
|
label: t('channel.carryover_balance'),
|
|
prop: 'carryover_balance',
|
|
align: 'center',
|
|
minWidth: 130,
|
|
sortable: false,
|
|
operator: 'RANGE',
|
|
formatter: formatAmountInt,
|
|
},
|
|
{
|
|
label: t('channel.affiliate_contract_no'),
|
|
prop: 'affiliate_contract_no',
|
|
align: 'center',
|
|
minWidth: 140,
|
|
sortable: false,
|
|
operator: 'LIKE',
|
|
operatorPlaceholder: t('Fuzzy query'),
|
|
showOverflowTooltip: true,
|
|
},
|
|
{
|
|
label: t('channel.settle_cycle'),
|
|
prop: 'settle_cycle',
|
|
align: 'center',
|
|
width: 110,
|
|
operator: 'eq',
|
|
sortable: false,
|
|
render: 'tag',
|
|
custom: { daily: 'info', weekly: 'primary', monthly: 'success' },
|
|
replaceValue: {
|
|
daily: t('channel.settle_cycle daily'),
|
|
weekly: t('channel.settle_cycle weekly'),
|
|
monthly: t('channel.settle_cycle monthly'),
|
|
},
|
|
},
|
|
{
|
|
label: t('channel.settle_weekday'),
|
|
prop: 'settle_day',
|
|
align: 'center',
|
|
width: 110,
|
|
operator: false,
|
|
sortable: false,
|
|
formatter: (row: anyObj) => formatSettleDay(row),
|
|
},
|
|
{
|
|
label: t('channel.settle_time'),
|
|
prop: 'settle_time',
|
|
align: 'center',
|
|
width: 100,
|
|
operator: 'LIKE',
|
|
sortable: false,
|
|
},
|
|
{
|
|
label: t('channel.affiliate_effective_start_at'),
|
|
prop: 'affiliate_effective_start_at',
|
|
align: 'center',
|
|
render: 'datetime',
|
|
operator: 'RANGE',
|
|
comSearchRender: 'datetime',
|
|
sortable: 'custom',
|
|
width: 160,
|
|
timeFormat: 'yyyy-mm-dd hh:MM:ss',
|
|
},
|
|
{
|
|
label: t('channel.affiliate_effective_end_at'),
|
|
prop: 'affiliate_effective_end_at',
|
|
align: 'center',
|
|
render: 'datetime',
|
|
operator: 'RANGE',
|
|
comSearchRender: 'datetime',
|
|
sortable: 'custom',
|
|
width: 160,
|
|
timeFormat: 'yyyy-mm-dd hh:MM:ss',
|
|
},
|
|
{
|
|
label: t('channel.user_count'),
|
|
prop: 'user_count',
|
|
align: 'center',
|
|
sortable: false,
|
|
operator: 'RANGE',
|
|
},
|
|
{
|
|
label: t('channel.profit_amount'),
|
|
prop: 'profit_amount',
|
|
align: 'center',
|
|
minWidth: 110,
|
|
sortable: false,
|
|
operator: 'RANGE',
|
|
formatter: formatAmountInt,
|
|
},
|
|
{
|
|
label: t('channel.total_profit_amount'),
|
|
prop: 'total_profit_amount',
|
|
align: 'center',
|
|
minWidth: 110,
|
|
sortable: false,
|
|
operator: 'RANGE',
|
|
formatter: formatAmountInt,
|
|
},
|
|
{
|
|
label: t('channel.commission_pool_amount'),
|
|
prop: 'commission_pool_amount',
|
|
align: 'center',
|
|
minWidth: 110,
|
|
sortable: false,
|
|
operator: 'RANGE',
|
|
formatter: formatAmountInt,
|
|
},
|
|
{
|
|
label: t('channel.status'),
|
|
prop: 'status',
|
|
align: 'center',
|
|
operator: 'eq',
|
|
sortable: false,
|
|
render: 'switch',
|
|
replaceValue: { '0': t('channel.status 0'), '1': t('channel.status 1') },
|
|
},
|
|
{
|
|
label: t('channel.create_time'),
|
|
prop: 'create_time',
|
|
align: 'center',
|
|
render: 'datetime',
|
|
operator: 'RANGE',
|
|
comSearchRender: 'datetime',
|
|
sortable: 'custom',
|
|
width: 160,
|
|
timeFormat: 'yyyy-mm-dd hh:MM:ss',
|
|
},
|
|
{
|
|
label: t('channel.update_time'),
|
|
prop: 'update_time',
|
|
align: 'center',
|
|
render: 'datetime',
|
|
operator: 'RANGE',
|
|
comSearchRender: 'datetime',
|
|
sortable: 'custom',
|
|
width: 160,
|
|
timeFormat: 'yyyy-mm-dd hh:MM:ss',
|
|
},
|
|
{ label: t('Operate'), align: 'center', width: 120, render: 'buttons', buttons: optButtons, operator: false, fixed: 'right' },
|
|
],
|
|
dblClickNotEditColumn: [undefined, 'status'],
|
|
},
|
|
{
|
|
defaultItems: {
|
|
status: '1',
|
|
agent_mode: 'turnover',
|
|
settle_cycle: 'weekly',
|
|
settle_weekday: 1,
|
|
settle_monthday: 1,
|
|
settle_time: '02:00:00',
|
|
},
|
|
}
|
|
)
|
|
|
|
baTable.before.getData = () => {
|
|
const filter = baTable.table.filter || {}
|
|
const searchRaw = filter.search
|
|
const search = Array.isArray(searchRaw) ? searchRaw.filter((item: any) => item && item.field !== 'carryover_balance' && item.field !== 'status') : []
|
|
if (settleFilterMode.value === 'with_balance') {
|
|
search.push({ field: 'carryover_balance', operator: 'gt', val: 0 })
|
|
} else if (settleFilterMode.value === 'no_balance') {
|
|
search.push({ field: 'carryover_balance', operator: 'elt', val: 0 })
|
|
} else if (settleFilterMode.value === 'enabled') {
|
|
search.push({ field: 'status', operator: 'eq', val: 1 })
|
|
} else if (settleFilterMode.value === 'disabled') {
|
|
search.push({ field: 'status', operator: 'eq', val: 0 })
|
|
}
|
|
filter.search = search
|
|
baTable.table.filter = filter
|
|
}
|
|
|
|
baTable.after.getData = () => {
|
|
void loadSettleStats()
|
|
}
|
|
|
|
provide('baTable', baTable)
|
|
|
|
onMounted(() => {
|
|
baTable.table.ref = tableRef.value
|
|
baTable.mount()
|
|
baTable.getData()?.then(() => {
|
|
baTable.initSort()
|
|
baTable.dragSort()
|
|
})
|
|
void loadSettleStats()
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.mb-12 {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.share-total-row {
|
|
margin-top: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.share-group-single {
|
|
font-size: 12px;
|
|
line-height: 1.4;
|
|
color: var(--el-text-color-regular);
|
|
}
|
|
|
|
.share-group-empty {
|
|
color: var(--el-text-color-placeholder);
|
|
}
|
|
|
|
.channel-top-actions {
|
|
margin: 8px 0 12px;
|
|
}
|
|
|
|
.channel-stats-cards {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
gap: 10px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.channel-stat-card .label {
|
|
font-size: 12px;
|
|
color: var(--el-text-color-secondary);
|
|
}
|
|
|
|
.channel-stat-card .value {
|
|
margin-top: 6px;
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
color: var(--el-text-color-primary);
|
|
}
|
|
|
|
.channel-action-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 10px;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.manual-settle-dialog-body {
|
|
max-height: min(70vh, 680px);
|
|
overflow: auto;
|
|
padding-right: 2px;
|
|
}
|
|
|
|
.manual-settle-form {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
column-gap: 16px;
|
|
}
|
|
|
|
.manual-settle-form :deep(.el-form-item) {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.manual-settle-form-item-full {
|
|
grid-column: 1 / -1;
|
|
}
|
|
|
|
.manual-settle-footer {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 8px;
|
|
}
|
|
|
|
@media (max-width: 900px) {
|
|
.channel-stats-cards {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
|
|
.manual-settle-form {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style>
|