268 lines
7.5 KiB
Vue
268 lines
7.5 KiB
Vue
<template>
|
||
<div class="art-full-height">
|
||
<!-- 搜索条件 -->
|
||
<TableSearch v-model="searchForm" @search="handleSearch" @reset="resetSearchParams" />
|
||
|
||
<ElCard class="art-table-card" shadow="never">
|
||
<!-- 表格操作 -->
|
||
<ArtTableHeader v-model:columns="columnChecks" :loading="loading" @refresh="refreshData">
|
||
<template #left>
|
||
<ElSpace wrap>
|
||
<ElButton v-permission="'dice:player:index:save'" @click="showDialog('add')" v-ripple>
|
||
<template #icon>
|
||
<ArtSvgIcon icon="ri:add-fill" />
|
||
</template>
|
||
新增
|
||
</ElButton>
|
||
<ElButton
|
||
v-permission="'dice:player:index:destroy'"
|
||
:disabled="selectedRows.length === 0"
|
||
@click="deleteSelectedRows(api.delete, refreshData)"
|
||
v-ripple
|
||
>
|
||
<template #icon>
|
||
<ArtSvgIcon icon="ri:delete-bin-5-line" />
|
||
</template>
|
||
删除
|
||
</ElButton>
|
||
</ElSpace>
|
||
</template>
|
||
</ArtTableHeader>
|
||
|
||
<!-- 表格 -->
|
||
<ArtTable
|
||
ref="tableRef"
|
||
rowKey="id"
|
||
:loading="loading"
|
||
:data="data"
|
||
:columns="columns"
|
||
:pagination="pagination"
|
||
@sort-change="handleSortChange"
|
||
@selection-change="handleSelectionChange"
|
||
@pagination:size-change="handleSizeChange"
|
||
@pagination:current-change="handleCurrentChange"
|
||
>
|
||
<!-- 状态列 -->
|
||
<template #status="{ row }">
|
||
<ElSwitch
|
||
v-permission="'dice:player:index:update'"
|
||
:model-value="row.status === 1"
|
||
:loading="row._statusLoading"
|
||
@change="(v: string | number | boolean) => handleStatusChange(row, v ? 1 : 0)"
|
||
/>
|
||
</template>
|
||
<!-- 平台币,点击可操作 -->
|
||
<template #coin="{ row }">
|
||
<ElTag
|
||
type="info"
|
||
size="small"
|
||
class="cursor-pointer hover:opacity-80"
|
||
@click="openWalletOperate(row)"
|
||
>
|
||
{{ row.coin ?? 0 }}
|
||
</ElTag>
|
||
</template>
|
||
<!-- 操作 -->
|
||
<template #operation="{ row }">
|
||
<div class="flex gap-2">
|
||
<SaButton
|
||
v-permission="'dice:player:index:update'"
|
||
type="secondary"
|
||
@click="showDialog('edit', row)"
|
||
/>
|
||
<SaButton
|
||
v-permission="'dice:player:index:destroy'"
|
||
type="error"
|
||
@click="deleteRow(row, api.delete, refreshData)"
|
||
/>
|
||
</div>
|
||
</template>
|
||
</ArtTable>
|
||
</ElCard>
|
||
|
||
<!-- 编辑弹窗 -->
|
||
<EditDialog
|
||
v-model="dialogVisible"
|
||
:dialog-type="dialogType"
|
||
:data="dialogData"
|
||
@success="refreshData"
|
||
/>
|
||
|
||
<!-- 钱包操作弹窗 -->
|
||
<WalletOperateDialog
|
||
v-model="walletDialogVisible"
|
||
:player="walletOperatePlayer"
|
||
@success="refreshData"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { useTable } from '@/hooks/core/useTable'
|
||
import { useSaiAdmin } from '@/composables/useSaiAdmin'
|
||
import api from '../../api/player/index'
|
||
import TableSearch from './modules/table-search.vue'
|
||
import EditDialog from './modules/edit-dialog.vue'
|
||
import WalletOperateDialog from './modules/WalletOperateDialog.vue'
|
||
|
||
// 搜索表单
|
||
const searchForm = ref({
|
||
username: undefined,
|
||
name: undefined,
|
||
phone: undefined,
|
||
status: undefined,
|
||
coin: undefined,
|
||
lottery_config_id: undefined
|
||
})
|
||
|
||
// 搜索
|
||
const handleSearch = (params: Record<string, any>) => {
|
||
Object.assign(searchParams, params)
|
||
getData()
|
||
}
|
||
|
||
// 权重列显示为百分比
|
||
const weightFormatter = (prop: string) => (row: any) => {
|
||
const cellValue = row[prop]
|
||
return cellValue != null && cellValue !== '' ? `${cellValue}%` : '-'
|
||
}
|
||
|
||
// 根据 lottery_config_id 显示彩金池配置名称
|
||
const lotteryConfigNameFormatter = (row: any) =>
|
||
row?.diceLotteryPoolConfig?.name ?? (row?.lottery_config_id ? `#${row.lottery_config_id}` : '未知')
|
||
|
||
// 表格
|
||
const {
|
||
columns,
|
||
columnChecks,
|
||
data,
|
||
loading,
|
||
getData,
|
||
searchParams,
|
||
pagination,
|
||
resetSearchParams,
|
||
handleSortChange,
|
||
handleSizeChange,
|
||
handleCurrentChange,
|
||
refreshData
|
||
} = useTable({
|
||
core: {
|
||
apiFn: api.list,
|
||
columnsFactory: () => [
|
||
{ type: 'selection' },
|
||
{ prop: 'username', label: '用户名', align: 'center' },
|
||
{ prop: 'phone', label: '手机号', align: 'center' },
|
||
{ prop: 'name', label: '昵称', align: 'center' },
|
||
{
|
||
prop: 'status',
|
||
label: '状态',
|
||
width: 88,
|
||
align: 'center',
|
||
useSlot: true
|
||
},
|
||
{
|
||
prop: 'coin',
|
||
label: '平台币',
|
||
width: 100,
|
||
align: 'center',
|
||
useSlot: true
|
||
},
|
||
{
|
||
prop: 'lottery_config_id',
|
||
label: '彩金池配置',
|
||
width: 120,
|
||
align: 'center',
|
||
formatter: (row: any) => lotteryConfigNameFormatter(row)
|
||
},
|
||
{
|
||
prop: 't1_weight',
|
||
label: 'T1权重',
|
||
width: 80,
|
||
align: 'center',
|
||
formatter: weightFormatter('t1_weight')
|
||
},
|
||
{
|
||
prop: 't2_weight',
|
||
label: 'T2权重',
|
||
width: 100,
|
||
align: 'center',
|
||
formatter: weightFormatter('t2_weight')
|
||
},
|
||
{
|
||
prop: 't3_weight',
|
||
label: 'T3权重',
|
||
width: 100,
|
||
align: 'center',
|
||
formatter: weightFormatter('t3_weight')
|
||
},
|
||
{
|
||
prop: 't4_weight',
|
||
label: 'T4权重',
|
||
width: 100,
|
||
align: 'center',
|
||
formatter: weightFormatter('t4_weight')
|
||
},
|
||
{
|
||
prop: 't5_weight',
|
||
label: 'T5权重',
|
||
width: 100,
|
||
align: 'center',
|
||
formatter: weightFormatter('t5_weight')
|
||
},
|
||
{ prop: 'total_ticket_count', label: '总抽奖次数', align: 'center' },
|
||
{ prop: 'paid_ticket_count', label: '购买抽奖次数', align: 'center' },
|
||
{ prop: 'free_ticket_count', label: '赠送抽奖次数', align: 'center' },
|
||
{ prop: 'create_time', label: '创建时间', align: 'center' },
|
||
{ prop: 'update_time', label: '更新时间', align: 'center' },
|
||
{
|
||
prop: 'operation',
|
||
label: '操作',
|
||
width: 100,
|
||
align: 'center',
|
||
fixed: 'right',
|
||
useSlot: true
|
||
}
|
||
]
|
||
}
|
||
})
|
||
|
||
// 状态切换
|
||
const handleStatusChange = async (row: Record<string, any>, status: number) => {
|
||
row._statusLoading = true
|
||
try {
|
||
await api.updateStatus({ id: row.id, status })
|
||
row.status = status
|
||
} catch {
|
||
refreshData()
|
||
} finally {
|
||
row._statusLoading = false
|
||
}
|
||
}
|
||
|
||
// 弹窗与删除
|
||
const {
|
||
dialogType,
|
||
dialogVisible,
|
||
dialogData,
|
||
showDialog,
|
||
deleteRow,
|
||
deleteSelectedRows,
|
||
handleSelectionChange,
|
||
selectedRows
|
||
} = useSaiAdmin()
|
||
|
||
// 钱包操作弹窗
|
||
const walletDialogVisible = ref(false)
|
||
type WalletPlayer = { id: number; username?: string; coin?: number }
|
||
const walletOperatePlayer = ref<WalletPlayer | null>(null)
|
||
|
||
function openWalletOperate(row: Record<string, any>) {
|
||
walletOperatePlayer.value = {
|
||
id: Number(row.id),
|
||
username: row.username,
|
||
coin: row.coin != null ? Number(row.coin) : undefined
|
||
}
|
||
walletDialogVisible.value = true
|
||
}
|
||
</script>
|