1.新增充值档位配置
2.新增充值/提现配置
This commit is contained in:
@@ -1,278 +1,209 @@
|
||||
<template>
|
||||
<div class="default-main ba-table-box deposit-tier-page">
|
||||
<el-alert type="info" :closable="false" show-icon>
|
||||
<div class="default-main ba-table-box">
|
||||
<el-alert class="ba-table-alert" type="info" :closable="false" show-icon>
|
||||
{{ t('config.depositTier.desc') }}
|
||||
</el-alert>
|
||||
|
||||
<div class="toolbar">
|
||||
<el-button type="primary" :disabled="loading" @click="onAdd">
|
||||
<Icon name="el-icon-Plus" />
|
||||
<span class="ml-6">{{ t('config.depositTier.btn_add') }}</span>
|
||||
</el-button>
|
||||
<el-button type="success" :loading="saving" :disabled="loading" @click="onSave">
|
||||
{{ t('config.depositTier.btn_save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<TableHeader
|
||||
:buttons="['refresh', 'add', 'edit', 'delete', 'quickSearch', 'columnDisplay']"
|
||||
:quick-search-placeholder="t('Quick search placeholder', { fields: t('config.depositTier.quick Search Fields') })"
|
||||
></TableHeader>
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
stripe
|
||||
:data="items"
|
||||
row-key="_rowKey"
|
||||
max-height="720"
|
||||
class="deposit-tier-table"
|
||||
header-align="center"
|
||||
>
|
||||
<el-table-column prop="sort" :label="t('config.depositTier.sort')" width="100" align="center" header-align="center">
|
||||
<template #default="{ row }">
|
||||
<div class="cell-center">
|
||||
<el-input-number v-model="row.sort" :min="0" :max="9999" :controls="false" style="width: 100%; max-width: 160px" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<Table ref="tableRef"></Table>
|
||||
|
||||
<el-table-column :label="t('config.depositTier.status')" width="100" align="center" header-align="center">
|
||||
<template #default="{ row }">
|
||||
<div class="cell-center">
|
||||
<el-switch v-model="row.status" :active-value="1" :inactive-value="0" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('config.depositTier.title_col')" min-width="180" align="center" header-align="center">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.title" maxlength="64" :placeholder="t('config.depositTier.title_ph')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('config.depositTier.title_en_col')" min-width="180" align="center" header-align="center">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.title_en" maxlength="64" :placeholder="t('config.depositTier.title_en_ph')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('config.depositTier.amount')" min-width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.amount" :placeholder="t('config.depositTier.amount_ph')">
|
||||
<template #suffix>
|
||||
<span class="currency">{{ t('config.depositTier.currency') }}</span>
|
||||
</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('config.depositTier.bonus_amount')" min-width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.bonus_amount" :placeholder="t('config.depositTier.bonus_ph')">
|
||||
<template #suffix>
|
||||
<span class="currency">{{ t('config.depositTier.currency') }}</span>
|
||||
</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('config.depositTier.desc_col')" min-width="220" align="center" header-align="center">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.desc" maxlength="255" :autosize="{ minRows: 1, maxRows: 3 }" type="textarea" :placeholder="t('config.depositTier.desc_ph')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('config.depositTier.desc_en_col')" min-width="220" align="center" header-align="center">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.desc_en" maxlength="255" :autosize="{ minRows: 1, maxRows: 3 }" type="textarea" :placeholder="t('config.depositTier.desc_en_ph')" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('config.depositTier.tier_id')" width="140" align="center" header-align="center">
|
||||
<template #default="{ row }">
|
||||
<el-text class="tier-id" truncated>{{ row.id || t('config.depositTier.auto_id') }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('config.depositTier.operate')" width="90" align="center" header-align="center" fixed="right">
|
||||
<template #default="{ $index }">
|
||||
<el-button type="danger" link @click="onRemove($index)">
|
||||
{{ t('config.depositTier.btn_remove') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<PopupForm />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { onMounted, provide, useTemplateRef } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import createAxios from '/@/utils/axios'
|
||||
import { auth } from '/@/utils/common'
|
||||
import PopupForm from './popupForm.vue'
|
||||
import { baTableApi } from '/@/api/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'
|
||||
|
||||
defineOptions({
|
||||
name: 'config/depositTier',
|
||||
})
|
||||
|
||||
const { t } = useI18n()
|
||||
const tableRef = useTemplateRef('tableRef')
|
||||
const optButtons: OptButton[] = defaultOptButtons(['edit', 'delete'])
|
||||
|
||||
type Tier = {
|
||||
id: string
|
||||
title: string
|
||||
title_en: string
|
||||
amount: string
|
||||
bonus_amount: string
|
||||
desc: string
|
||||
desc_en: string
|
||||
sort: number
|
||||
status: number
|
||||
_rowKey?: string
|
||||
}
|
||||
|
||||
const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const items = ref<Tier[]>([])
|
||||
|
||||
function genRowKey(): string {
|
||||
return 'r_' + Math.random().toString(36).slice(2, 10)
|
||||
}
|
||||
|
||||
function emptyTier(): Tier {
|
||||
return {
|
||||
id: '',
|
||||
title: '',
|
||||
title_en: '',
|
||||
amount: '',
|
||||
bonus_amount: '0',
|
||||
desc: '',
|
||||
desc_en: '',
|
||||
sort: 0,
|
||||
status: 1,
|
||||
_rowKey: genRowKey(),
|
||||
function formatAmount4(_row: anyObj, _column: any, cellValue: unknown) {
|
||||
if (cellValue === null || cellValue === undefined || cellValue === '') {
|
||||
return '-'
|
||||
}
|
||||
const s = String(cellValue).trim().replace(',', '.')
|
||||
const n = parseFloat(s)
|
||||
if (!Number.isFinite(n)) {
|
||||
return String(cellValue)
|
||||
}
|
||||
return n.toFixed(4)
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await createAxios({
|
||||
url: '/admin/config.DepositTier/index',
|
||||
method: 'get',
|
||||
})
|
||||
if (res.code === 1 && res.data) {
|
||||
const list = (res.data.items || []) as Tier[]
|
||||
items.value = (Array.isArray(list) ? list : []).map((it) => ({
|
||||
...emptyTier(),
|
||||
...it,
|
||||
_rowKey: genRowKey(),
|
||||
}))
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
function formatPayCell(row: anyObj, _column: any, cellValue: unknown) {
|
||||
const amt = formatAmount4(row, _column, cellValue)
|
||||
const cur = row.currency && String(row.currency).trim() !== '' ? String(row.currency).toUpperCase() : ''
|
||||
if (amt === '-' || cur === '') {
|
||||
return amt
|
||||
}
|
||||
return `${amt} ${cur}`
|
||||
}
|
||||
|
||||
function onAdd() {
|
||||
items.value.push(emptyTier())
|
||||
function formatTotalPlatform(row: anyObj) {
|
||||
const a = parseFloat(String(row.amount ?? '0').replace(',', '.'))
|
||||
const b = parseFloat(String(row.bonus_amount ?? '0').replace(',', '.'))
|
||||
const base = Number.isFinite(a) ? a : 0
|
||||
const bonus = Number.isFinite(b) ? b : 0
|
||||
return (base + bonus).toFixed(4)
|
||||
}
|
||||
|
||||
async function onRemove(idx: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm(t('config.depositTier.confirm_remove'), t('Warning'), {
|
||||
type: 'warning',
|
||||
confirmButtonText: t('Delete'),
|
||||
cancelButtonText: t('Cancel'),
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
items.value.splice(idx, 1)
|
||||
}
|
||||
|
||||
async function onSave() {
|
||||
if (!auth('save')) {
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < items.value.length; i++) {
|
||||
const row = items.value[i]
|
||||
if (!row.title || !row.title.trim()) {
|
||||
ElMessage.warning(t('config.depositTier.err_title', { no: i + 1 }))
|
||||
return
|
||||
}
|
||||
const amount = Number(row.amount)
|
||||
if (!row.amount || Number.isNaN(amount) || amount <= 0) {
|
||||
ElMessage.warning(t('config.depositTier.err_amount', { no: i + 1 }))
|
||||
return
|
||||
}
|
||||
const bonusRaw = row.bonus_amount === '' || row.bonus_amount === null || row.bonus_amount === undefined ? '0' : row.bonus_amount
|
||||
const bonus = Number(bonusRaw)
|
||||
if (Number.isNaN(bonus) || bonus < 0) {
|
||||
ElMessage.warning(t('config.depositTier.err_bonus', { no: i + 1 }))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
saving.value = true
|
||||
try {
|
||||
await createAxios({
|
||||
url: '/admin/config.DepositTier/save',
|
||||
method: 'post',
|
||||
data: {
|
||||
items: items.value.map((r) => ({
|
||||
id: r.id,
|
||||
title: r.title,
|
||||
title_en: r.title_en || '',
|
||||
amount: r.amount,
|
||||
bonus_amount: r.bonus_amount === '' || r.bonus_amount === null || r.bonus_amount === undefined ? '0' : r.bonus_amount,
|
||||
desc: r.desc || '',
|
||||
desc_en: r.desc_en || '',
|
||||
sort: r.sort,
|
||||
status: r.status,
|
||||
})),
|
||||
const baTable = new baTableClass(
|
||||
new baTableApi('/admin/config.DepositTier/'),
|
||||
{
|
||||
pk: 'id',
|
||||
filter: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
},
|
||||
defaultOrder: { prop: 'sort', order: 'asc' },
|
||||
column: [
|
||||
{ type: 'selection', align: 'center', operator: false },
|
||||
{
|
||||
label: t('config.depositTier.sort'),
|
||||
prop: 'sort',
|
||||
align: 'center',
|
||||
width: 88,
|
||||
operator: 'RANGE',
|
||||
sortable: 'custom',
|
||||
},
|
||||
showSuccessMessage: true,
|
||||
})
|
||||
await load()
|
||||
} finally {
|
||||
saving.value = false
|
||||
{
|
||||
label: t('config.depositTier.status'),
|
||||
prop: 'status',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
operator: 'eq',
|
||||
sortable: false,
|
||||
render: 'switch',
|
||||
replaceValue: { 0: t('config.depositTier.status_off'), 1: t('config.depositTier.status_on') },
|
||||
},
|
||||
{
|
||||
label: t('config.depositTier.tier_id'),
|
||||
prop: 'id',
|
||||
align: 'center',
|
||||
minWidth: 120,
|
||||
operator: 'LIKE',
|
||||
operatorPlaceholder: t('Fuzzy query'),
|
||||
showOverflowTooltip: true,
|
||||
},
|
||||
{
|
||||
label: t('config.depositTier.title_col'),
|
||||
prop: 'title',
|
||||
align: 'center',
|
||||
minWidth: 140,
|
||||
operator: 'LIKE',
|
||||
operatorPlaceholder: t('Fuzzy query'),
|
||||
showOverflowTooltip: true,
|
||||
},
|
||||
{
|
||||
label: t('config.depositTier.title_en_col'),
|
||||
prop: 'title_en',
|
||||
align: 'center',
|
||||
minWidth: 120,
|
||||
operator: 'LIKE',
|
||||
operatorPlaceholder: t('Fuzzy query'),
|
||||
showOverflowTooltip: true,
|
||||
},
|
||||
{
|
||||
label: t('config.depositTier.pay_currency'),
|
||||
prop: 'currency',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
operator: 'eq',
|
||||
},
|
||||
{
|
||||
label: t('config.depositTier.pay_amount'),
|
||||
prop: 'pay_amount',
|
||||
align: 'center',
|
||||
minWidth: 130,
|
||||
operator: 'RANGE',
|
||||
formatter: formatPayCell,
|
||||
},
|
||||
{
|
||||
label: t('config.depositTier.platform_base'),
|
||||
prop: 'amount',
|
||||
align: 'center',
|
||||
minWidth: 120,
|
||||
operator: 'RANGE',
|
||||
formatter: formatAmount4,
|
||||
},
|
||||
{
|
||||
label: t('config.depositTier.bonus_amount'),
|
||||
prop: 'bonus_amount',
|
||||
align: 'center',
|
||||
minWidth: 110,
|
||||
operator: 'RANGE',
|
||||
formatter: formatAmount4,
|
||||
},
|
||||
{
|
||||
label: t('config.depositTier.total_platform'),
|
||||
prop: '__total_platform',
|
||||
align: 'center',
|
||||
minWidth: 120,
|
||||
operator: false,
|
||||
formatter: (row: anyObj) => formatTotalPlatform(row),
|
||||
},
|
||||
{
|
||||
label: t('config.depositTier.desc_col'),
|
||||
prop: 'desc',
|
||||
align: 'center',
|
||||
minWidth: 160,
|
||||
operator: 'LIKE',
|
||||
operatorPlaceholder: t('Fuzzy query'),
|
||||
showOverflowTooltip: true,
|
||||
},
|
||||
{
|
||||
label: t('Operate'),
|
||||
align: 'center',
|
||||
width: 100,
|
||||
render: 'buttons',
|
||||
buttons: optButtons,
|
||||
operator: false,
|
||||
fixed: 'right',
|
||||
},
|
||||
],
|
||||
dblClickNotEditColumn: [undefined, 'status'],
|
||||
},
|
||||
{
|
||||
defaultItems: {
|
||||
id: '',
|
||||
title: '',
|
||||
title_en: '',
|
||||
currency: 'MYR',
|
||||
pay_amount: '',
|
||||
amount: '',
|
||||
bonus_amount: '0',
|
||||
desc: '',
|
||||
desc_en: '',
|
||||
sort: 10,
|
||||
status: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
provide('baTable', baTable)
|
||||
|
||||
onMounted(() => {
|
||||
void load()
|
||||
baTable.table.ref = tableRef.value
|
||||
baTable.mount()
|
||||
baTable.getData()?.then(() => {
|
||||
baTable.initSort()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.deposit-tier-page {
|
||||
.toolbar {
|
||||
margin: 12px 0;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.currency {
|
||||
color: var(--el-text-color-placeholder);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.tier-id {
|
||||
display: inline-block;
|
||||
max-width: 120px;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.deposit-tier-table {
|
||||
:deep(.el-table__header th),
|
||||
:deep(.el-table__body td) {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.cell-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
Reference in New Issue
Block a user