1983 lines
67 KiB
Vue
1983 lines
67 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>
|
|
<el-card
|
|
shadow="never"
|
|
class="channel-stat-card"
|
|
:class="{ 'channel-stat-card-clickable': auth('index') }"
|
|
@click="onCompanyTotalBetCardClick"
|
|
>
|
|
<div class="label">{{ t('channel.settle_stats_company_total_bet') }}</div>
|
|
<div class="value">{{ settleStats.company_total_bet_amount }}</div>
|
|
</el-card>
|
|
<el-card
|
|
shadow="never"
|
|
class="channel-stat-card"
|
|
:class="{ 'channel-stat-card-clickable': auth('index') }"
|
|
@click="onPaidDividendCardClick"
|
|
>
|
|
<div class="label">{{ t('channel.settle_stats_paid_dividend') }}</div>
|
|
<div class="value">{{ settleStats.paid_dividend_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="auth('batchSettlePending')" type="warning" @click="onBatchSettlePending">
|
|
{{ t('channel.batch_settle_pending') }}
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
|
|
<Table ref="tableRef"></Table>
|
|
|
|
<PopupForm />
|
|
|
|
<el-dialog
|
|
class="manual-settle-dialog"
|
|
:close-on-click-modal="false"
|
|
:model-value="manualSettle.visible"
|
|
:width="manualSettleDialogWidth"
|
|
align-center
|
|
append-to-body
|
|
destroy-on-close
|
|
@close="closeManualSettleDialog"
|
|
@opened="dismissFloatingTooltips"
|
|
>
|
|
<template #header>
|
|
<div class="title">{{ t('channel.manual_settle') }}</div>
|
|
</template>
|
|
<div v-loading="manualSettle.previewLoading" class="manual-settle-dialog-body">
|
|
<el-descriptions
|
|
class="manual-settle-summary"
|
|
:column="manualSettleSummaryColumns"
|
|
border
|
|
:size="manualSettleViewportMobile ? 'small' : 'default'"
|
|
>
|
|
<el-descriptions-item :label="t('channel.manual_settle_settlement_no')">
|
|
{{ manualSettle.form.settlement_no || '-' }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item :label="t('channel.manual_settle_period_start')">
|
|
{{ manualSettle.form.period_start_at || '-' }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item :label="t('channel.manual_settle_period_end')">
|
|
{{ manualSettle.form.period_end_at || '-' }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item :label="t('channel.manual_settle_total_bet')">
|
|
{{ manualSettle.form.total_bet_amount || '-' }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item :label="t('channel.manual_settle_total_payout')">
|
|
{{ manualSettle.form.total_payout_amount || '-' }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item :label="t('channel.manual_settle_platform_profit')">
|
|
{{ manualSettle.form.platform_profit_amount || '-' }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item :label="t('channel.manual_settle_commission_rate')">
|
|
{{ manualSettle.form.commission_rate || '-' }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item :label="t('channel.manual_settle_calc_base')">
|
|
{{ manualSettle.form.calc_base_amount || '-' }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item :label="t('channel.manual_settle_commission_amount')">
|
|
<span class="manual-settle-summary-highlight">{{ manualSettle.form.commission_amount || '-' }}</span>
|
|
</el-descriptions-item>
|
|
</el-descriptions>
|
|
|
|
<el-form
|
|
:model="manualSettle.form"
|
|
:label-width="manualSettleFormLabelWidth"
|
|
label-position="top"
|
|
:size="manualSettleFormSize"
|
|
class="manual-settle-form"
|
|
>
|
|
<el-form-item :label="t('channel.share_config')" class="manual-settle-form-item-full manual-settle-split-form-item">
|
|
<div class="manual-settle-split-block">
|
|
<div
|
|
class="manual-settle-split-table-scroll"
|
|
:class="{ 'is-mobile': manualSettleViewportMobile }"
|
|
>
|
|
<div
|
|
class="manual-settle-split-table-inner"
|
|
:class="{ 'is-mobile': manualSettleViewportMobile }"
|
|
:style="manualSettleSplitInnerStyle"
|
|
>
|
|
<el-table
|
|
:data="manualSettleSplitTree"
|
|
row-key="admin_id"
|
|
:tree-props="{ children: 'children' }"
|
|
default-expand-all
|
|
border
|
|
:size="manualSettleTableSize"
|
|
:fit="!manualSettleViewportMobile"
|
|
class="manual-settle-split-table"
|
|
:class="{ 'is-mobile': manualSettleViewportMobile, 'w100': !manualSettleViewportMobile }"
|
|
:table-layout="manualSettleTableLayout"
|
|
>
|
|
<el-table-column
|
|
prop="admin_username"
|
|
:label="t('channel.admin__username')"
|
|
:min-width="manualSettleViewportMobile ? undefined : manualSettleSplitCol.adminWidth"
|
|
:width="manualSettleViewportMobile ? manualSettleSplitCol.adminWidth : undefined"
|
|
:show-overflow-tooltip="!manualSettleViewportMobile"
|
|
/>
|
|
<el-table-column
|
|
prop="settlement_base_amount"
|
|
:label="t('channel.manual_settle_col_base')"
|
|
:width="manualSettleSplitCol.baseWidth"
|
|
align="center"
|
|
:formatter="formatSplitAmountCell"
|
|
/>
|
|
<el-table-column
|
|
prop="share_rate"
|
|
:label="t('channel.manual_settle_col_share')"
|
|
:width="manualSettleSplitCol.shareWidth"
|
|
align="center"
|
|
>
|
|
<template #default="scope">{{ scope.row.share_rate }}%</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="commission_amount"
|
|
:label="t('channel.manual_settle_col_gross')"
|
|
:width="manualSettleSplitCol.grossWidth"
|
|
align="center"
|
|
:formatter="formatSplitAmountCell"
|
|
/>
|
|
<el-table-column
|
|
prop="commission_share_percent"
|
|
:label="t('channel.manual_settle_col_commission_share')"
|
|
:width="manualSettleSplitCol.commissionShareWidth"
|
|
align="center"
|
|
>
|
|
<template #default="scope">{{ formatCommissionSharePercent(scope.row) }}</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="handling_fee"
|
|
:label="t('channel.manual_settle_col_fee')"
|
|
:width="manualSettleSplitCol.feeWidth"
|
|
align="center"
|
|
:formatter="formatSplitAmountCell"
|
|
/>
|
|
<el-table-column
|
|
:label="t('channel.manual_settle_col_net')"
|
|
:width="manualSettleSplitCol.netWidth"
|
|
align="center"
|
|
>
|
|
<template #default="scope">{{ formatNetCommission(scope.row) }}</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
<p v-if="manualSettleViewportMobile" class="manual-settle-split-scroll-tip">
|
|
{{ t('channel.manual_settle_split_scroll_tip') }}
|
|
</p>
|
|
</div>
|
|
<el-collapse v-model="manualSettleCalcCollapse" class="manual-settle-calc-collapse">
|
|
<el-collapse-item :title="t('channel.manual_settle_calc_title')" name="calc">
|
|
<ul class="manual-settle-calc-list">
|
|
<li v-for="(line, idx) in manualSettleCalcDescLines" :key="idx">{{ line }}</li>
|
|
</ul>
|
|
</el-collapse-item>
|
|
</el-collapse>
|
|
</div>
|
|
</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="channel-record-dialog"
|
|
:close-on-click-modal="false"
|
|
:model-value="dividendDialog.visible"
|
|
width="92%"
|
|
@close="closeDividendDialog"
|
|
>
|
|
<template #header>
|
|
<div class="title">{{ t('channel.dividend_record_dialog_title') }}</div>
|
|
</template>
|
|
<div v-loading="dividendDialog.loading" class="channel-record-dialog__body">
|
|
<div class="channel-record-table-wrap">
|
|
<el-table :data="dividendDialog.list" border size="small" class="channel-record-table">
|
|
<el-table-column prop="settlement_no" :label="t('channel.dividend_settlement_no')" min-width="150" show-overflow-tooltip />
|
|
<el-table-column prop="channel_name" :label="t('channel.dividend_channel_name')" min-width="100" />
|
|
<el-table-column prop="admin_username" :label="t('channel.dividend_admin_username')" min-width="100" />
|
|
<el-table-column prop="commission_amount" :label="t('channel.dividend_commission_amount')" min-width="100" align="right" />
|
|
<el-table-column :label="t('channel.dividend_period_range')" min-width="180">
|
|
<template #default="scope">
|
|
{{ scope.row.period_start_at || '-' }} ~ {{ scope.row.period_end_at || '-' }}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="settled_at" :label="t('channel.dividend_settled_at')" min-width="150" />
|
|
</el-table>
|
|
</div>
|
|
<div class="channel-record-pagination">
|
|
<el-pagination
|
|
background
|
|
layout="total, prev, pager, next"
|
|
:total="dividendDialog.total"
|
|
:page-size="dividendDialog.limit"
|
|
:current-page="dividendDialog.page"
|
|
@current-change="onDividendPageChange"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</el-dialog>
|
|
|
|
<el-dialog
|
|
class="channel-record-dialog channel-bet-record-dialog"
|
|
:close-on-click-modal="false"
|
|
:model-value="betRecordDialog.visible"
|
|
width="92%"
|
|
@close="closeBetRecordDialog"
|
|
>
|
|
<template #header>
|
|
<div class="title">{{ betRecordDialog.title }}</div>
|
|
</template>
|
|
<div v-loading="betRecordDialog.loading" class="channel-record-dialog__body">
|
|
<div class="channel-bet-summary">
|
|
<el-card shadow="never" class="channel-bet-summary-card channel-stat-card">
|
|
<div class="label">{{ t('channel.bet_record_summary_count') }}</div>
|
|
<div class="value">{{ betRecordDialog.summary.record_count }}</div>
|
|
</el-card>
|
|
<el-card shadow="never" class="channel-bet-summary-card channel-stat-card">
|
|
<div class="label">{{ t('channel.bet_record_summary_bet') }}</div>
|
|
<div class="value">{{ betRecordDialog.summary.total_bet_amount }}</div>
|
|
</el-card>
|
|
<el-card shadow="never" class="channel-bet-summary-card channel-stat-card">
|
|
<div class="label">{{ t('channel.bet_record_summary_win') }}</div>
|
|
<div class="value">{{ betRecordDialog.summary.total_win_amount }}</div>
|
|
</el-card>
|
|
</div>
|
|
<el-form :inline="true" size="small" class="channel-bet-filter" @submit.prevent="onBetRecordSearch">
|
|
<el-form-item :label="t('channel.bet_record_period_no')">
|
|
<el-input
|
|
v-model="betRecordDialog.filters.period_no"
|
|
clearable
|
|
:placeholder="t('Fuzzy query')"
|
|
class="channel-bet-filter-input"
|
|
@keyup.enter="onBetRecordSearch"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.bet_record_user_username')">
|
|
<el-input
|
|
v-model="betRecordDialog.filters.user_keyword"
|
|
clearable
|
|
:placeholder="t('Fuzzy query')"
|
|
class="channel-bet-filter-input"
|
|
@keyup.enter="onBetRecordSearch"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.bet_record_result_number')">
|
|
<el-input
|
|
v-model="betRecordDialog.filters.result_number"
|
|
clearable
|
|
class="channel-bet-filter-input--short"
|
|
@keyup.enter="onBetRecordSearch"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.bet_record_pick_numbers')">
|
|
<el-input
|
|
v-model="betRecordDialog.filters.pick_number"
|
|
clearable
|
|
:placeholder="t('channel.bet_record_pick_filter_placeholder')"
|
|
class="channel-bet-filter-input--short"
|
|
@keyup.enter="onBetRecordSearch"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item :label="t('channel.bet_record_win_hit')">
|
|
<el-select
|
|
v-model="betRecordDialog.filters.win_hit"
|
|
clearable
|
|
:placeholder="t('Please select field', { field: t('channel.bet_record_win_hit') })"
|
|
class="channel-bet-filter-select"
|
|
>
|
|
<el-option :label="t('channel.bet_record_win_hit_won')" value="won" />
|
|
<el-option :label="t('channel.bet_record_win_hit_lost')" value="lost" />
|
|
<el-option :label="t('channel.bet_record_win_hit_pending')" value="pending" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button type="primary" @click="onBetRecordSearch">{{ t('Search') }}</el-button>
|
|
<el-button @click="onBetRecordReset">{{ t('Reset') }}</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
<div class="channel-record-table-wrap">
|
|
<el-table
|
|
:data="betRecordDialog.list"
|
|
border
|
|
size="small"
|
|
class="channel-bet-record-table channel-record-table"
|
|
>
|
|
<el-table-column
|
|
prop="period_no"
|
|
:label="t('channel.bet_record_period_no')"
|
|
min-width="120"
|
|
align="center"
|
|
header-align="center"
|
|
show-overflow-tooltip
|
|
/>
|
|
<el-table-column
|
|
prop="user_username"
|
|
:label="t('channel.bet_record_user_username')"
|
|
min-width="120"
|
|
align="center"
|
|
header-align="center"
|
|
show-overflow-tooltip
|
|
/>
|
|
<el-table-column
|
|
v-if="betRecordDialog.mode === 'company'"
|
|
prop="channel_name"
|
|
:label="t('channel.bet_record_channel_name')"
|
|
min-width="100"
|
|
align="center"
|
|
header-align="center"
|
|
show-overflow-tooltip
|
|
/>
|
|
<el-table-column
|
|
prop="pick_numbers"
|
|
:label="t('channel.bet_record_pick_numbers')"
|
|
min-width="120"
|
|
align="center"
|
|
header-align="center"
|
|
show-overflow-tooltip
|
|
/>
|
|
<el-table-column
|
|
prop="result_number"
|
|
:label="t('channel.bet_record_result_number')"
|
|
min-width="90"
|
|
align="center"
|
|
header-align="center"
|
|
/>
|
|
<el-table-column
|
|
:label="t('channel.bet_record_win_hit')"
|
|
min-width="90"
|
|
align="center"
|
|
header-align="center"
|
|
>
|
|
<template #default="scope">
|
|
<el-tag
|
|
v-if="scope.row.win_hit"
|
|
:type="betRecordWinHitTagType(scope.row.win_hit)"
|
|
effect="dark"
|
|
size="small"
|
|
>
|
|
{{ formatBetRecordWinHit(scope.row.win_hit) }}
|
|
</el-tag>
|
|
<span v-else>-</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="total_amount"
|
|
:label="t('channel.bet_record_total_amount')"
|
|
min-width="100"
|
|
align="center"
|
|
header-align="center"
|
|
/>
|
|
<el-table-column
|
|
prop="win_amount"
|
|
:label="t('channel.bet_record_win_amount')"
|
|
min-width="100"
|
|
align="center"
|
|
header-align="center"
|
|
/>
|
|
</el-table>
|
|
</div>
|
|
<div class="channel-record-pagination">
|
|
<el-pagination
|
|
background
|
|
layout="total, prev, pager, next"
|
|
:total="betRecordDialog.total"
|
|
:page-size="betRecordDialog.limit"
|
|
:current-page="betRecordDialog.page"
|
|
@current-change="onBetRecordPageChange"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</el-dialog>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, nextTick, onMounted, onUnmounted, 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 { 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 MANUAL_SETTLE_MOBILE_BREAKPOINT = 768
|
|
const manualSettleViewportMobile = ref(typeof window !== 'undefined' ? window.innerWidth <= MANUAL_SETTLE_MOBILE_BREAKPOINT : false)
|
|
const manualSettleCalcCollapse = ref<string[]>([])
|
|
const manualSettleDialogWidth = computed(() => (manualSettleViewportMobile.value ? '96%' : '920px'))
|
|
const manualSettleSummaryColumns = computed(() => (manualSettleViewportMobile.value ? 1 : 3))
|
|
const manualSettleFormSize = computed(() => (manualSettleViewportMobile.value ? 'small' : 'default'))
|
|
const manualSettleTableSize = computed(() => (manualSettleViewportMobile.value ? 'small' : 'default'))
|
|
const manualSettleFormLabelWidth = computed(() => 'auto')
|
|
const manualSettleTableLayout = computed(() => 'fixed')
|
|
const manualSettleSplitCol = computed(() => {
|
|
if (manualSettleViewportMobile.value) {
|
|
return {
|
|
adminWidth: 120,
|
|
baseWidth: 72,
|
|
shareWidth: 58,
|
|
grossWidth: 72,
|
|
commissionShareWidth: 62,
|
|
feeWidth: 64,
|
|
netWidth: 72,
|
|
}
|
|
}
|
|
return {
|
|
adminWidth: 132,
|
|
baseWidth: 88,
|
|
shareWidth: 72,
|
|
grossWidth: 88,
|
|
commissionShareWidth: 76,
|
|
feeWidth: 80,
|
|
netWidth: 88,
|
|
}
|
|
})
|
|
|
|
const manualSettleSplitTableMinWidth = computed(() => {
|
|
const col = manualSettleSplitCol.value
|
|
return (
|
|
col.adminWidth +
|
|
col.baseWidth +
|
|
col.shareWidth +
|
|
col.grossWidth +
|
|
col.commissionShareWidth +
|
|
col.feeWidth +
|
|
col.netWidth +
|
|
32
|
|
)
|
|
})
|
|
|
|
const manualSettleSplitInnerStyle = computed(() => {
|
|
if (!manualSettleViewportMobile.value) {
|
|
return {}
|
|
}
|
|
return {
|
|
width: `${manualSettleSplitTableMinWidth.value}px`,
|
|
}
|
|
})
|
|
|
|
const syncManualSettleViewport = () => {
|
|
if (typeof window === 'undefined') {
|
|
return
|
|
}
|
|
manualSettleViewportMobile.value = window.innerWidth <= MANUAL_SETTLE_MOBILE_BREAKPOINT
|
|
}
|
|
|
|
const dismissFloatingTooltips = () => {
|
|
if (typeof document === 'undefined') {
|
|
return
|
|
}
|
|
document.querySelectorAll('.el-popper[role="tooltip"]').forEach((node) => node.remove())
|
|
const active = document.activeElement
|
|
if (active instanceof HTMLElement) {
|
|
active.blur()
|
|
}
|
|
}
|
|
const tableRef = useTemplateRef('tableRef')
|
|
let optButtons: OptButton[] = [
|
|
{
|
|
render: 'tipButton',
|
|
name: 'manualSettle',
|
|
title: 'channel.manual_settle',
|
|
text: '',
|
|
type: 'warning',
|
|
icon: 'el-icon-Clock',
|
|
class: 'table-row-manual-settle',
|
|
disabledTip: true,
|
|
display: () => 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 formatCommissionSharePercent = (row: { commission_amount?: string | number; commission_share_percent?: string | number }) => {
|
|
const preset = row.commission_share_percent
|
|
if (preset !== null && preset !== undefined && preset !== '') {
|
|
const n = Number(preset)
|
|
if (Number.isFinite(n)) {
|
|
return `${n.toFixed(2)}%`
|
|
}
|
|
}
|
|
const total = Number(manualSettle.form.commission_amount ?? 0)
|
|
const gross = Number(row.commission_amount ?? 0)
|
|
if (!Number.isFinite(total) || total <= 0 || !Number.isFinite(gross) || gross <= 0) {
|
|
return '0.00%'
|
|
}
|
|
return `${((gross / total) * 100).toFixed(2)}%`
|
|
}
|
|
|
|
const formatSplitAmountCell = (_row: anyObj, _column: any, cellValue: unknown) => {
|
|
if (cellValue === null || cellValue === undefined || cellValue === '') {
|
|
return '-'
|
|
}
|
|
const n = Number(cellValue)
|
|
if (!Number.isFinite(n)) {
|
|
return String(cellValue)
|
|
}
|
|
return n.toFixed(2)
|
|
}
|
|
|
|
const formatAmount2 = (_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.toFixed(2)
|
|
}
|
|
const formatBetRecordWinHit = (code: unknown) => {
|
|
const key = code === null || code === undefined ? '' : String(code)
|
|
if (!key) return '-'
|
|
const i18nKey = `channel.bet_record_win_hit_${key}`
|
|
const text = t(i18nKey)
|
|
return text !== i18nKey ? text : key
|
|
}
|
|
|
|
const betRecordWinHitTagType = (code: unknown): 'success' | 'info' | 'warning' | 'danger' => {
|
|
const key = code === null || code === undefined ? '' : String(code)
|
|
const map: Record<string, 'success' | 'info' | 'warning' | 'danger'> = {
|
|
won: 'success',
|
|
lost: 'info',
|
|
pending: 'warning',
|
|
}
|
|
return map[key] ?? 'info'
|
|
}
|
|
|
|
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: '',
|
|
agent_mode: 'turnover' as string,
|
|
settlement_handling_fee: '0.00',
|
|
commission_split: [] as Array<{
|
|
admin_id: number
|
|
admin_username: string
|
|
parent_admin_id?: number
|
|
level?: number
|
|
settlement_base_amount?: string
|
|
share_rate: string
|
|
commission_amount: string
|
|
commission_share_percent?: string
|
|
handling_fee_rate: number | string
|
|
handling_fee?: string
|
|
net_commission_amount?: string
|
|
}>,
|
|
remark: '',
|
|
},
|
|
})
|
|
|
|
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',
|
|
paid_dividend_total: '0.00',
|
|
company_total_bet_amount: '0.00',
|
|
})
|
|
|
|
const dividendDialog = reactive({
|
|
visible: false,
|
|
loading: false,
|
|
page: 1,
|
|
limit: 20,
|
|
total: 0,
|
|
list: [] as anyObj[],
|
|
})
|
|
|
|
const createBetRecordFilters = () => ({
|
|
period_no: '',
|
|
user_keyword: '',
|
|
result_number: '',
|
|
pick_number: '',
|
|
win_hit: '' as '' | 'won' | 'lost' | 'pending',
|
|
})
|
|
|
|
const betRecordDialog = reactive({
|
|
visible: false,
|
|
loading: false,
|
|
mode: '' as '' | 'direct' | 'company',
|
|
channelId: 0,
|
|
title: '',
|
|
page: 1,
|
|
limit: 20,
|
|
total: 0,
|
|
list: [] as anyObj[],
|
|
filters: createBetRecordFilters(),
|
|
summary: {
|
|
record_count: 0,
|
|
total_bet_amount: '0.00',
|
|
total_win_amount: '0.00',
|
|
},
|
|
})
|
|
|
|
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.agent_mode = 'turnover'
|
|
manualSettle.form.settlement_handling_fee = '0.00'
|
|
manualSettle.form.remark = ''
|
|
}
|
|
|
|
type ManualSettleSplitRow = {
|
|
admin_id: number
|
|
admin_username: string
|
|
parent_admin_id?: number
|
|
level?: number
|
|
settlement_base_amount?: string
|
|
share_rate: string
|
|
commission_amount: string
|
|
commission_share_percent?: string
|
|
handling_fee_rate: number | string
|
|
handling_fee?: string
|
|
net_commission_amount?: string
|
|
children?: ManualSettleSplitRow[]
|
|
}
|
|
|
|
const buildCommissionSplitTree = (flat: ManualSettleSplitRow[]): ManualSettleSplitRow[] => {
|
|
if (!flat.length) {
|
|
return []
|
|
}
|
|
const nodeMap = new Map<number, ManualSettleSplitRow>()
|
|
for (const row of flat) {
|
|
nodeMap.set(row.admin_id, { ...row, children: [] })
|
|
}
|
|
const roots: ManualSettleSplitRow[] = []
|
|
for (const row of flat) {
|
|
const node = nodeMap.get(row.admin_id)
|
|
if (!node) {
|
|
continue
|
|
}
|
|
const parentId = Number(row.parent_admin_id ?? 0)
|
|
if (parentId > 0 && nodeMap.has(parentId)) {
|
|
const parent = nodeMap.get(parentId)
|
|
if (parent) {
|
|
if (!parent.children) {
|
|
parent.children = []
|
|
}
|
|
parent.children.push(node)
|
|
}
|
|
continue
|
|
}
|
|
roots.push(node)
|
|
}
|
|
const pruneEmptyChildren = (nodes: ManualSettleSplitRow[]) => {
|
|
for (const node of nodes) {
|
|
if (node.children && node.children.length > 0) {
|
|
pruneEmptyChildren(node.children)
|
|
} else {
|
|
delete node.children
|
|
}
|
|
}
|
|
}
|
|
pruneEmptyChildren(roots)
|
|
return roots
|
|
}
|
|
|
|
const manualSettleSplitTree = computed(() => buildCommissionSplitTree(manualSettle.form.commission_split))
|
|
|
|
const manualSettleCalcDescLines = computed(() => {
|
|
const mode = manualSettle.form.agent_mode === 'affiliate' ? 'affiliate' : 'turnover'
|
|
const feeRate = manualSettle.form.settlement_handling_fee
|
|
const prefix =
|
|
mode === 'affiliate'
|
|
? [
|
|
t('channel.manual_settle_calc_intro_affiliate_1'),
|
|
t('channel.manual_settle_calc_intro_affiliate_2'),
|
|
t('channel.manual_settle_calc_intro_affiliate_3'),
|
|
]
|
|
: [
|
|
t('channel.manual_settle_calc_intro_turnover_1'),
|
|
t('channel.manual_settle_calc_intro_turnover_2'),
|
|
t('channel.manual_settle_calc_intro_turnover_3'),
|
|
]
|
|
return [
|
|
...prefix,
|
|
t('channel.manual_settle_calc_tree_1'),
|
|
t('channel.manual_settle_calc_tree_2'),
|
|
t('channel.manual_settle_calc_tree_3'),
|
|
t('channel.manual_settle_calc_handling_fee', { rate: feeRate }),
|
|
]
|
|
})
|
|
|
|
const closeManualSettleDialog = () => {
|
|
manualSettle.visible = false
|
|
resetManualSettleForm()
|
|
}
|
|
|
|
const openManualSettleDialog = async (row: TableRow) => {
|
|
dismissFloatingTooltips()
|
|
syncManualSettleViewport()
|
|
manualSettle.channelId = row.id
|
|
resetManualSettleForm()
|
|
manualSettle.visible = true
|
|
await nextTick()
|
|
dismissFloatingTooltips()
|
|
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.agent_mode = d.agent_mode ?? 'turnover'
|
|
manualSettle.form.settlement_handling_fee = d.settlement_handling_fee ?? '0.00'
|
|
manualSettle.form.commission_split = normalizeManualSettleSplit(d.commission_split, d.settlement_handling_fee)
|
|
manualSettle.form.remark = `${t('channel.manual_settle')}-CH${row.id}`
|
|
} catch {
|
|
manualSettle.visible = false
|
|
} finally {
|
|
manualSettle.previewLoading = false
|
|
}
|
|
}
|
|
|
|
const calcHandlingFeeByPercent = (gross: number, ratePercent: number) => {
|
|
const g = Number.isFinite(gross) && gross > 0 ? gross : 0
|
|
let rate = Number.isFinite(ratePercent) ? ratePercent : 0
|
|
if (rate < 0) rate = 0
|
|
if (rate > 100) rate = 100
|
|
return Math.round(g * rate * 100) / 10000
|
|
}
|
|
|
|
const applyManualSettleRowAmounts = (row: {
|
|
commission_amount?: string | number
|
|
handling_fee_rate?: string | number
|
|
handling_fee?: string | number
|
|
net_commission_amount?: string
|
|
}) => {
|
|
const gross = Number(row.commission_amount ?? 0)
|
|
const rate = Number(row.handling_fee_rate ?? 0)
|
|
const feeAmount = calcHandlingFeeByPercent(gross, rate)
|
|
row.handling_fee = feeAmount.toFixed(2)
|
|
row.net_commission_amount = Math.max(0, (Number.isFinite(gross) ? gross : 0) - feeAmount).toFixed(2)
|
|
}
|
|
|
|
const normalizeManualSettleSplit = (rows: unknown, defaultFeeRate: unknown) => {
|
|
const feeDefault = Number(defaultFeeRate)
|
|
const baseRate = Number.isFinite(feeDefault) && feeDefault >= 0 ? Math.min(100, feeDefault) : 0
|
|
if (!Array.isArray(rows)) {
|
|
return []
|
|
}
|
|
return rows.map((row: anyObj) => {
|
|
let rate = Number(row.handling_fee_rate ?? row.handling_fee ?? baseRate)
|
|
if (!Number.isFinite(rate) || rate < 0) {
|
|
rate = baseRate
|
|
}
|
|
if (rate > 100) {
|
|
rate = 100
|
|
}
|
|
const normalized = {
|
|
...row,
|
|
handling_fee_rate: rate,
|
|
}
|
|
applyManualSettleRowAmounts(normalized)
|
|
return normalized
|
|
})
|
|
}
|
|
|
|
const formatNetCommission = (row: {
|
|
commission_amount?: string | number
|
|
handling_fee_rate?: string | number
|
|
net_commission_amount?: string
|
|
}) => {
|
|
if (row.net_commission_amount !== undefined && row.net_commission_amount !== '') {
|
|
return row.net_commission_amount
|
|
}
|
|
const gross = Number(row.commission_amount ?? 0)
|
|
const rate = Number(row.handling_fee_rate ?? 0)
|
|
const net = Math.max(0, (Number.isFinite(gross) ? gross : 0) - calcHandlingFeeByPercent(gross, rate))
|
|
return net.toFixed(2)
|
|
}
|
|
|
|
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,
|
|
commission_split: manualSettle.form.commission_split.map((row) => ({
|
|
admin_id: row.admin_id,
|
|
handling_fee_rate: row.handling_fee_rate ?? 0,
|
|
})),
|
|
},
|
|
},
|
|
{ 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')
|
|
settleStats.paid_dividend_total = String(res.data.paid_dividend_total ?? '0.00')
|
|
settleStats.company_total_bet_amount = String(res.data.company_total_bet_amount ?? '0.00')
|
|
}
|
|
|
|
const loadDividendRecords = async () => {
|
|
dividendDialog.loading = true
|
|
try {
|
|
const res = await createAxios({
|
|
url: '/admin/channel/dividendRecordList',
|
|
method: 'get',
|
|
params: { page: dividendDialog.page, limit: dividendDialog.limit },
|
|
})
|
|
if (res.code !== 1 || !res.data) {
|
|
return
|
|
}
|
|
dividendDialog.list = Array.isArray(res.data.list) ? res.data.list : []
|
|
dividendDialog.total = Number(res.data.total ?? 0)
|
|
} finally {
|
|
dividendDialog.loading = false
|
|
}
|
|
}
|
|
|
|
const onPaidDividendCardClick = () => {
|
|
if (!auth('index')) {
|
|
return
|
|
}
|
|
dividendDialog.page = 1
|
|
dividendDialog.visible = true
|
|
void loadDividendRecords()
|
|
}
|
|
|
|
const onCompanyTotalBetCardClick = () => {
|
|
if (!auth('index')) {
|
|
return
|
|
}
|
|
resetBetRecordDialog()
|
|
betRecordDialog.mode = 'company'
|
|
betRecordDialog.channelId = 0
|
|
betRecordDialog.title = t('channel.company_bet_record_dialog_title')
|
|
betRecordDialog.visible = true
|
|
void loadBetRecords()
|
|
}
|
|
|
|
const closeDividendDialog = () => {
|
|
dividendDialog.visible = false
|
|
dividendDialog.list = []
|
|
dividendDialog.total = 0
|
|
dividendDialog.page = 1
|
|
}
|
|
|
|
const onDividendPageChange = (page: number) => {
|
|
dividendDialog.page = page
|
|
void loadDividendRecords()
|
|
}
|
|
|
|
const resetBetRecordDialog = () => {
|
|
betRecordDialog.mode = ''
|
|
betRecordDialog.channelId = 0
|
|
betRecordDialog.title = ''
|
|
betRecordDialog.page = 1
|
|
betRecordDialog.total = 0
|
|
betRecordDialog.list = []
|
|
betRecordDialog.summary = {
|
|
record_count: 0,
|
|
total_bet_amount: '0.00',
|
|
total_win_amount: '0.00',
|
|
}
|
|
Object.assign(betRecordDialog.filters, createBetRecordFilters())
|
|
}
|
|
|
|
const buildBetRecordFilterParams = () => {
|
|
const f = betRecordDialog.filters
|
|
const params: Record<string, string> = {}
|
|
if (f.period_no.trim()) {
|
|
params.period_no = f.period_no.trim()
|
|
}
|
|
if (f.user_keyword.trim()) {
|
|
params.user_keyword = f.user_keyword.trim()
|
|
}
|
|
if (f.result_number.trim()) {
|
|
params.result_number = f.result_number.trim()
|
|
}
|
|
if (f.pick_number.trim()) {
|
|
params.pick_number = f.pick_number.trim()
|
|
}
|
|
if (f.win_hit) {
|
|
params.win_hit = f.win_hit
|
|
}
|
|
return params
|
|
}
|
|
|
|
const loadBetRecords = async () => {
|
|
if (!betRecordDialog.mode) {
|
|
return
|
|
}
|
|
if (betRecordDialog.mode === 'direct' && !betRecordDialog.channelId) {
|
|
return
|
|
}
|
|
const url =
|
|
betRecordDialog.mode === 'direct'
|
|
? '/admin/channel/directBetRecordList'
|
|
: '/admin/channel/companyBetRecordList'
|
|
betRecordDialog.loading = true
|
|
try {
|
|
const params: Record<string, string | number> = {
|
|
page: betRecordDialog.page,
|
|
limit: betRecordDialog.limit,
|
|
...buildBetRecordFilterParams(),
|
|
}
|
|
if (betRecordDialog.mode === 'direct') {
|
|
params.channel_id = betRecordDialog.channelId
|
|
}
|
|
const res = await createAxios({
|
|
url,
|
|
method: 'get',
|
|
params,
|
|
})
|
|
if (res.code !== 1 || !res.data) {
|
|
return
|
|
}
|
|
betRecordDialog.list = Array.isArray(res.data.list) ? res.data.list : []
|
|
betRecordDialog.total = Number(res.data.total ?? 0)
|
|
const summary = res.data.summary
|
|
if (summary && typeof summary === 'object') {
|
|
betRecordDialog.summary.record_count = Number(summary.record_count ?? 0)
|
|
betRecordDialog.summary.total_bet_amount = String(summary.total_bet_amount ?? '0.00')
|
|
betRecordDialog.summary.total_win_amount = String(summary.total_win_amount ?? '0.00')
|
|
}
|
|
} finally {
|
|
betRecordDialog.loading = false
|
|
}
|
|
}
|
|
|
|
const openBetRecordDialog = (mode: 'direct' | 'company', row: TableRow) => {
|
|
if (!auth('index')) {
|
|
return
|
|
}
|
|
resetBetRecordDialog()
|
|
betRecordDialog.mode = mode
|
|
betRecordDialog.channelId = Number(row.id ?? 0)
|
|
betRecordDialog.title =
|
|
mode === 'direct'
|
|
? `${t('channel.direct_bet_record_dialog_title')} - ${row.name ?? row.id}`
|
|
: t('channel.company_bet_record_dialog_title')
|
|
betRecordDialog.visible = true
|
|
void loadBetRecords()
|
|
}
|
|
|
|
const closeBetRecordDialog = () => {
|
|
betRecordDialog.visible = false
|
|
resetBetRecordDialog()
|
|
}
|
|
|
|
const onBetRecordPageChange = (page: number) => {
|
|
betRecordDialog.page = page
|
|
void loadBetRecords()
|
|
}
|
|
|
|
const onBetRecordSearch = () => {
|
|
betRecordDialog.page = 1
|
|
void loadBetRecords()
|
|
}
|
|
|
|
const onBetRecordReset = () => {
|
|
Object.assign(betRecordDialog.filters, createBetRecordFilters())
|
|
onBetRecordSearch()
|
|
}
|
|
|
|
const openDirectBetDialog = (row: TableRow) => {
|
|
void openBetRecordDialog('direct', row)
|
|
}
|
|
|
|
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.direct_bet_amount'),
|
|
prop: 'direct_bet_amount',
|
|
align: 'center',
|
|
minWidth: 120,
|
|
sortable: false,
|
|
operator: false,
|
|
render: 'tag',
|
|
formatter: formatAmount2,
|
|
customRenderAttr: {
|
|
tag: ({ row }: { row: TableRow }) => ({
|
|
class: auth('index') ? 'channel-direct-bet-tag' : '',
|
|
onClick: auth('index') ? () => openDirectBetDialog(row) : undefined,
|
|
}),
|
|
},
|
|
},
|
|
{
|
|
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: 160, render: 'buttons', buttons: optButtons, operator: false, fixed: 'right' },
|
|
],
|
|
dblClickNotEditColumn: [undefined, 'status'],
|
|
},
|
|
{
|
|
defaultItems: {
|
|
status: '1',
|
|
agent_mode: 'turnover',
|
|
settlement_handling_fee: 0,
|
|
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(() => {
|
|
syncManualSettleViewport()
|
|
window.addEventListener('resize', syncManualSettleViewport)
|
|
baTable.table.ref = tableRef.value
|
|
baTable.mount()
|
|
baTable.getData()?.then(() => {
|
|
baTable.initSort()
|
|
baTable.dragSort()
|
|
})
|
|
void loadSettleStats()
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener('resize', syncManualSettleViewport)
|
|
})
|
|
</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(6, minmax(0, 1fr));
|
|
gap: 8px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.channel-stats-cards :deep(.el-card__body) {
|
|
padding: 10px 8px;
|
|
}
|
|
|
|
.channel-stat-card {
|
|
text-align: center;
|
|
min-width: 0;
|
|
}
|
|
|
|
.channel-stat-card-clickable {
|
|
cursor: pointer;
|
|
transition: box-shadow 0.2s ease;
|
|
}
|
|
|
|
.channel-stat-card-clickable:hover {
|
|
box-shadow: 0 0 0 1px var(--el-color-primary-light-5);
|
|
}
|
|
|
|
.channel-stat-card-clickable .value {
|
|
color: var(--el-color-primary);
|
|
}
|
|
|
|
:deep(.channel-direct-bet-tag) {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.channel-bet-filter {
|
|
margin-bottom: 12px;
|
|
padding: 10px 12px 2px;
|
|
background: var(--el-fill-color-lighter);
|
|
border-radius: 6px;
|
|
}
|
|
|
|
.channel-bet-filter :deep(.el-form-item) {
|
|
margin-bottom: 8px;
|
|
margin-right: 12px;
|
|
}
|
|
|
|
.channel-bet-filter-input {
|
|
width: 140px;
|
|
}
|
|
|
|
.channel-bet-filter-input--short {
|
|
width: 100px;
|
|
}
|
|
|
|
.channel-bet-filter-select {
|
|
width: 120px;
|
|
}
|
|
|
|
.channel-bet-summary {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
gap: 12px;
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
.channel-bet-summary-card {
|
|
text-align: center;
|
|
}
|
|
|
|
.channel-bet-summary-card .label {
|
|
font-size: 12px;
|
|
color: var(--el-text-color-secondary);
|
|
}
|
|
|
|
.channel-bet-summary-card .value {
|
|
margin-top: 6px;
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
color: var(--el-text-color-primary);
|
|
}
|
|
|
|
.channel-bet-record-table :deep(.el-table__cell) {
|
|
text-align: center;
|
|
}
|
|
|
|
.channel-bet-record-table :deep(.cell) {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.channel-record-pagination {
|
|
margin-top: 12px;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.channel-stat-card .label {
|
|
font-size: 11px;
|
|
color: var(--el-text-color-secondary);
|
|
line-height: 1.3;
|
|
word-break: break-all;
|
|
}
|
|
|
|
.channel-stat-card .value {
|
|
margin-top: 4px;
|
|
font-size: 17px;
|
|
font-weight: 600;
|
|
color: var(--el-text-color-primary);
|
|
line-height: 1.2;
|
|
}
|
|
|
|
.channel-action-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 10px;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
/* 手动结算弹窗:可滚动(勿使用 ba-operate-dialog 固定 58vh 高度) */
|
|
:deep(.manual-settle-dialog.el-dialog) {
|
|
display: flex !important;
|
|
flex-direction: column;
|
|
width: 92% !important;
|
|
max-width: 920px;
|
|
max-height: 90vh;
|
|
margin: 5vh auto !important;
|
|
padding-bottom: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
:deep(.manual-settle-dialog .el-dialog__header) {
|
|
flex-shrink: 0;
|
|
padding: 14px 20px;
|
|
margin-right: 0;
|
|
}
|
|
|
|
:deep(.manual-settle-dialog .el-dialog__header .title) {
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
:deep(.manual-settle-dialog .el-dialog__body) {
|
|
flex: 1 1 auto;
|
|
min-height: 0;
|
|
height: auto !important;
|
|
max-height: calc(90vh - 116px);
|
|
overflow-y: auto !important;
|
|
overflow-x: hidden;
|
|
-webkit-overflow-scrolling: touch;
|
|
overscroll-behavior: contain;
|
|
padding: 16px 20px 18px;
|
|
}
|
|
|
|
:deep(.manual-settle-dialog .el-dialog__footer) {
|
|
flex-shrink: 0;
|
|
position: static;
|
|
width: auto;
|
|
box-shadow: none;
|
|
border-top: 1px solid var(--el-border-color-lighter);
|
|
}
|
|
|
|
.manual-settle-dialog-body {
|
|
min-height: 0;
|
|
overflow: visible;
|
|
}
|
|
|
|
:deep(.manual-settle-dialog-body .el-loading-mask) {
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.manual-settle-summary {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.manual-settle-summary :deep(.el-descriptions__label) {
|
|
width: 148px;
|
|
font-size: 13px;
|
|
color: var(--el-text-color-secondary);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.manual-settle-summary :deep(.el-descriptions__content) {
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
color: var(--el-text-color-primary);
|
|
}
|
|
|
|
.manual-settle-summary-highlight {
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
color: var(--el-color-primary);
|
|
}
|
|
|
|
.manual-settle-form {
|
|
display: block;
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.manual-settle-form :deep(.el-form-item) {
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
.manual-settle-split-form-item :deep(.el-form-item__label) {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
line-height: 1.5;
|
|
padding-bottom: 8px;
|
|
color: var(--el-text-color-primary);
|
|
}
|
|
|
|
.manual-settle-form-item-full {
|
|
grid-column: 1 / -1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.manual-settle-form-item-full :deep(.el-form-item__content) {
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.manual-settle-split-block {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.manual-settle-split-table-scroll {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.manual-settle-split-table-scroll.is-mobile {
|
|
overflow-x: scroll;
|
|
overflow-y: hidden;
|
|
overscroll-behavior-x: contain;
|
|
-webkit-overflow-scrolling: touch;
|
|
touch-action: pan-x;
|
|
border: 1px solid var(--el-border-color-lighter);
|
|
border-radius: 6px;
|
|
background: var(--el-fill-color-blank);
|
|
}
|
|
|
|
.manual-settle-split-table-inner.is-mobile {
|
|
display: inline-block;
|
|
max-width: none;
|
|
vertical-align: top;
|
|
}
|
|
|
|
.manual-settle-split-table-scroll.is-mobile :deep(.el-table) {
|
|
width: 100% !important;
|
|
}
|
|
|
|
.manual-settle-split-table-scroll.is-mobile :deep(.el-table__inner-wrapper) {
|
|
width: 100% !important;
|
|
}
|
|
|
|
.manual-settle-split-table-scroll.is-mobile :deep(.el-table__body-wrapper),
|
|
.manual-settle-split-table-scroll.is-mobile :deep(.el-table__header-wrapper) {
|
|
overflow: visible !important;
|
|
}
|
|
|
|
.manual-settle-split-table-scroll.is-mobile :deep(.el-scrollbar__wrap) {
|
|
overflow: visible !important;
|
|
}
|
|
|
|
.manual-settle-split-table-scroll.is-mobile :deep(.el-scrollbar__bar.is-horizontal) {
|
|
display: none !important;
|
|
}
|
|
|
|
.manual-settle-split-scroll-tip {
|
|
margin: 6px 0 0;
|
|
font-size: 11px;
|
|
line-height: 1.4;
|
|
color: var(--el-text-color-secondary);
|
|
text-align: center;
|
|
}
|
|
|
|
.manual-settle-split-table:not(.is-mobile) {
|
|
width: 100%;
|
|
}
|
|
|
|
.manual-settle-split-table :deep(.el-table__header th.el-table__cell),
|
|
.manual-settle-split-table :deep(.el-table__body td.el-table__cell) {
|
|
padding: 10px 8px;
|
|
}
|
|
|
|
.manual-settle-split-table :deep(.el-table__header .cell),
|
|
.manual-settle-split-table :deep(.el-table__body .cell) {
|
|
padding: 0 4px;
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.manual-settle-split-table :deep(.el-table__header .cell) {
|
|
white-space: normal;
|
|
font-weight: 600;
|
|
color: var(--el-text-color-primary);
|
|
}
|
|
|
|
.manual-settle-split-table.is-mobile :deep(.el-table__header th.el-table__cell),
|
|
.manual-settle-split-table.is-mobile :deep(.el-table__body td.el-table__cell) {
|
|
padding: 5px 3px;
|
|
}
|
|
|
|
.manual-settle-split-table.is-mobile :deep(.el-table__header .cell),
|
|
.manual-settle-split-table.is-mobile :deep(.el-table__body .cell) {
|
|
font-size: 11px;
|
|
line-height: 1.3;
|
|
white-space: nowrap;
|
|
word-break: keep-all;
|
|
overflow-wrap: normal;
|
|
}
|
|
|
|
.manual-settle-split-table.is-mobile :deep(.el-table__body td:first-child .cell) {
|
|
white-space: nowrap;
|
|
word-break: keep-all;
|
|
}
|
|
|
|
.manual-settle-calc-collapse {
|
|
margin-top: 12px;
|
|
border: none;
|
|
}
|
|
|
|
.manual-settle-calc-collapse :deep(.el-collapse-item__header) {
|
|
height: 40px;
|
|
line-height: 40px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
border-bottom: none;
|
|
background: var(--el-fill-color-light);
|
|
border-radius: 6px;
|
|
padding: 0 12px;
|
|
}
|
|
|
|
.manual-settle-calc-collapse :deep(.el-collapse-item__wrap) {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.manual-settle-calc-collapse :deep(.el-collapse-item__content) {
|
|
padding: 10px 12px 4px;
|
|
}
|
|
|
|
.manual-settle-calc-list {
|
|
margin: 0;
|
|
padding-left: 20px;
|
|
line-height: 1.65;
|
|
font-size: 13px;
|
|
color: var(--el-text-color-regular);
|
|
}
|
|
|
|
.manual-settle-calc-list li + li {
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.manual-settle-footer {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 10px;
|
|
padding: 4px 0 0;
|
|
}
|
|
|
|
.manual-settle-footer .el-button {
|
|
min-width: 88px;
|
|
}
|
|
|
|
/* 渠道记录弹窗:可滚动、适配移动端(勿使用 ba-operate-dialog 固定高度) */
|
|
:deep(.channel-record-dialog.el-dialog) {
|
|
display: flex;
|
|
flex-direction: column;
|
|
max-height: 92vh;
|
|
margin: 4vh auto !important;
|
|
padding-bottom: 0;
|
|
overflow: hidden;
|
|
width: 92% !important;
|
|
max-width: 1080px;
|
|
}
|
|
|
|
:deep(.channel-record-dialog.channel-bet-record-dialog.el-dialog) {
|
|
max-width: 1080px;
|
|
}
|
|
|
|
:deep(.channel-record-dialog .el-dialog__header) {
|
|
flex-shrink: 0;
|
|
padding: 12px 16px;
|
|
margin-right: 0;
|
|
}
|
|
|
|
:deep(.channel-record-dialog .el-dialog__body) {
|
|
flex: 1;
|
|
min-height: 0;
|
|
height: auto !important;
|
|
max-height: calc(92vh - 56px);
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
-webkit-overflow-scrolling: touch;
|
|
padding: 12px 14px 16px;
|
|
}
|
|
|
|
.channel-record-dialog__body {
|
|
min-height: 0;
|
|
}
|
|
|
|
.channel-record-table-wrap {
|
|
width: 100%;
|
|
overflow-x: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.channel-record-table {
|
|
min-width: 640px;
|
|
}
|
|
|
|
.channel-bet-record-table {
|
|
min-width: 880px;
|
|
}
|
|
|
|
@media (max-width: 900px) {
|
|
.channel-stats-cards {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
|
|
.manual-settle-summary :deep(.el-descriptions__label) {
|
|
width: auto;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.manual-settle-summary :deep(.el-descriptions__content) {
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
:deep(.manual-settle-dialog.el-dialog) {
|
|
width: 96% !important;
|
|
max-width: none;
|
|
max-height: 94vh;
|
|
margin: 3vh auto !important;
|
|
}
|
|
|
|
:deep(.manual-settle-dialog .el-dialog__header) {
|
|
padding: 10px 12px;
|
|
}
|
|
|
|
:deep(.manual-settle-dialog .el-dialog__body) {
|
|
max-height: calc(94vh - 96px);
|
|
padding: 12px 12px 14px;
|
|
}
|
|
|
|
:deep(.manual-settle-dialog .el-dialog__footer) {
|
|
padding: 8px 10px 10px;
|
|
}
|
|
|
|
.manual-settle-summary {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.manual-settle-form :deep(.el-form-item) {
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.manual-settle-split-form-item :deep(.el-form-item__label) {
|
|
font-size: 13px;
|
|
padding-bottom: 6px;
|
|
}
|
|
|
|
.manual-settle-form-item-full :deep(.el-form-item__content) {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
min-width: 0;
|
|
}
|
|
|
|
.manual-settle-split-block {
|
|
max-width: 100%;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
margin: 0;
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
.manual-settle-split-table-scroll.is-mobile {
|
|
max-width: 100%;
|
|
}
|
|
|
|
.manual-settle-calc-collapse :deep(.el-collapse-item__header) {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.manual-settle-calc-list {
|
|
font-size: 11px;
|
|
padding-left: 16px;
|
|
}
|
|
|
|
.manual-settle-footer {
|
|
flex-wrap: wrap;
|
|
justify-content: stretch;
|
|
}
|
|
|
|
.manual-settle-footer .el-button {
|
|
flex: 1;
|
|
margin: 0;
|
|
}
|
|
|
|
:deep(.channel-record-dialog.el-dialog) {
|
|
width: 96% !important;
|
|
max-height: 94vh;
|
|
margin: 3vh auto !important;
|
|
}
|
|
|
|
:deep(.channel-record-dialog .el-dialog__body) {
|
|
max-height: calc(94vh - 52px);
|
|
padding: 10px 10px 14px;
|
|
}
|
|
|
|
.channel-bet-summary {
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
gap: 6px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.channel-bet-summary-card :deep(.el-card__body) {
|
|
padding: 8px 4px;
|
|
}
|
|
|
|
.channel-bet-summary-card .label {
|
|
font-size: 10px;
|
|
line-height: 1.3;
|
|
}
|
|
|
|
.channel-bet-summary-card .value {
|
|
margin-top: 4px;
|
|
font-size: 13px;
|
|
word-break: break-all;
|
|
}
|
|
|
|
.channel-bet-filter {
|
|
padding: 8px 10px 0;
|
|
}
|
|
|
|
.channel-bet-filter :deep(.el-form-item) {
|
|
display: flex;
|
|
width: 100%;
|
|
margin-right: 0;
|
|
}
|
|
|
|
.channel-bet-filter :deep(.el-form-item__label) {
|
|
width: 72px !important;
|
|
padding-right: 6px;
|
|
}
|
|
|
|
.channel-bet-filter :deep(.el-form-item__content) {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.channel-bet-filter-input,
|
|
.channel-bet-filter-input--short,
|
|
.channel-bet-filter-select {
|
|
width: 100%;
|
|
}
|
|
|
|
.channel-bet-filter :deep(.el-form-item:last-child .el-form-item__content) {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
}
|
|
|
|
.channel-record-pagination {
|
|
justify-content: center;
|
|
}
|
|
|
|
.channel-record-pagination :deep(.el-pagination) {
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
row-gap: 6px;
|
|
}
|
|
}
|
|
</style>
|