- 玩家/代理/赛事/注单/审计列表分页,默认每页 10 条,无页面滚动条布局 - ECharts 控制台概览、注单管理中文化与列宽优化 - zhibo 赛事字段迁移与导入,玩家编辑可改所属代理 - 管理端 API 分页与 dashboard 统计接口 Co-authored-by: Cursor <cursoragent@cursor.com>
586 lines
20 KiB
Vue
586 lines
20 KiB
Vue
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue';
|
||
import api from '../api';
|
||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||
import {
|
||
emptyPlayerCreateForm,
|
||
emptyPlayerEditForm,
|
||
editFormFromDetail,
|
||
buildCreatePlayerPayload,
|
||
type PlayerRow,
|
||
type PlayerDetail,
|
||
type PlayerCreateForm,
|
||
type PlayerEditForm,
|
||
} from './user-form';
|
||
import {
|
||
formatAmount,
|
||
formatAmountFull,
|
||
shouldCompactAmount as shouldCompact,
|
||
} from '../utils/format-amount';
|
||
|
||
const users = ref<PlayerRow[]>([]);
|
||
const total = ref(0);
|
||
const page = ref(1);
|
||
const pageSize = ref(10);
|
||
const keyword = ref('');
|
||
const filterStatus = ref('');
|
||
const filterParentId = ref('');
|
||
|
||
const agentOptions = ref<{ id: string; username: string }[]>([]);
|
||
|
||
const createVisible = ref(false);
|
||
const editVisible = ref(false);
|
||
const detailVisible = ref(false);
|
||
const depositVisible = ref(false);
|
||
const createLoading = ref(false);
|
||
const editLoading = ref(false);
|
||
const depositLoading = ref(false);
|
||
|
||
const createForm = ref<PlayerCreateForm>(emptyPlayerCreateForm());
|
||
const editForm = ref<PlayerEditForm>(emptyPlayerEditForm());
|
||
const detail = ref<PlayerDetail | null>(null);
|
||
const editingId = ref('');
|
||
|
||
const depositForm = ref({ userId: '', amount: 100, remark: '' });
|
||
|
||
onMounted(() => {
|
||
loadAgentOptions();
|
||
load();
|
||
});
|
||
|
||
async function loadAgentOptions() {
|
||
const { data } = await api.get('/admin/agents/options');
|
||
agentOptions.value = data.data;
|
||
}
|
||
|
||
async function load() {
|
||
const { data } = await api.get('/admin/users', {
|
||
params: {
|
||
page: page.value,
|
||
pageSize: pageSize.value,
|
||
keyword: keyword.value || undefined,
|
||
status: filterStatus.value || undefined,
|
||
parentId: filterParentId.value || undefined,
|
||
},
|
||
});
|
||
users.value = data.data.items;
|
||
total.value = data.data.total;
|
||
}
|
||
|
||
function onPageChange(p: number) {
|
||
page.value = p;
|
||
load();
|
||
}
|
||
|
||
function onSizeChange(size: number) {
|
||
pageSize.value = size;
|
||
page.value = 1;
|
||
load();
|
||
}
|
||
|
||
function openCreate() {
|
||
createForm.value = emptyPlayerCreateForm();
|
||
createVisible.value = true;
|
||
}
|
||
|
||
function parentLabel(row: PlayerRow) {
|
||
return row.parentUsername ?? '平台直属';
|
||
}
|
||
|
||
async function openDetail(id: string) {
|
||
const { data } = await api.get(`/admin/users/${id}`);
|
||
detail.value = data.data as PlayerDetail;
|
||
detailVisible.value = true;
|
||
}
|
||
|
||
async function openEdit(id: string) {
|
||
const { data } = await api.get(`/admin/users/${id}`);
|
||
const d = data.data as PlayerDetail;
|
||
editingId.value = id;
|
||
editForm.value = editFormFromDetail(d);
|
||
editVisible.value = true;
|
||
}
|
||
|
||
function openDeposit(row: PlayerRow) {
|
||
depositForm.value = { userId: row.id, amount: 100, remark: '管理员上分' };
|
||
depositVisible.value = true;
|
||
}
|
||
|
||
async function submitCreate() {
|
||
let payload: ReturnType<typeof buildCreatePlayerPayload>;
|
||
try {
|
||
payload = buildCreatePlayerPayload(createForm.value);
|
||
} catch (e) {
|
||
ElMessage.warning(e instanceof Error ? e.message : '请检查表单');
|
||
return;
|
||
}
|
||
createLoading.value = true;
|
||
try {
|
||
await api.post('/admin/users', payload);
|
||
ElMessage.success('玩家已创建');
|
||
createVisible.value = false;
|
||
load();
|
||
} catch (e: unknown) {
|
||
const err = e as { response?: { data?: { error?: string } } };
|
||
ElMessage.error(err.response?.data?.error ?? '创建失败');
|
||
} finally {
|
||
createLoading.value = false;
|
||
}
|
||
}
|
||
|
||
async function toggleFreeze(row: PlayerRow) {
|
||
const freeze = row.status === 'ACTIVE';
|
||
const action = freeze ? '冻结' : '解冻';
|
||
try {
|
||
await ElMessageBox.confirm(
|
||
`确定要${action}玩家「${row.username}」吗?${freeze ? '冻结后该账号将无法登录。' : ''}`,
|
||
`${action}账号`,
|
||
{ type: 'warning', confirmButtonText: action, cancelButtonText: '取消' },
|
||
);
|
||
} catch {
|
||
return;
|
||
}
|
||
try {
|
||
await api.put(`/admin/users/${row.id}`, {
|
||
status: freeze ? 'SUSPENDED' : 'ACTIVE',
|
||
});
|
||
ElMessage.success(`已${action}`);
|
||
load();
|
||
} catch (e: unknown) {
|
||
const err = e as { response?: { data?: { error?: string } } };
|
||
ElMessage.error(err.response?.data?.error ?? `${action}失败`);
|
||
}
|
||
}
|
||
|
||
async function submitEdit() {
|
||
editLoading.value = true;
|
||
try {
|
||
await api.put(`/admin/users/${editingId.value}`, {
|
||
parentId: editForm.value.parentId || '',
|
||
phone: editForm.value.phone.trim() || undefined,
|
||
email: editForm.value.email.trim() || undefined,
|
||
});
|
||
ElMessage.success('已保存');
|
||
editVisible.value = false;
|
||
load();
|
||
} catch (e: unknown) {
|
||
const err = e as { response?: { data?: { error?: string } } };
|
||
ElMessage.error(err.response?.data?.error ?? '保存失败');
|
||
} finally {
|
||
editLoading.value = false;
|
||
}
|
||
}
|
||
|
||
async function submitDeposit() {
|
||
if (depositForm.value.amount <= 0) {
|
||
ElMessage.warning('金额须大于 0');
|
||
return;
|
||
}
|
||
depositLoading.value = true;
|
||
try {
|
||
await api.post('/admin/wallet/deposit', {
|
||
userId: depositForm.value.userId,
|
||
amount: depositForm.value.amount,
|
||
remark: depositForm.value.remark,
|
||
requestId: `dep-${depositForm.value.userId}-${Date.now()}`,
|
||
});
|
||
ElMessage.success('上分成功');
|
||
depositVisible.value = false;
|
||
load();
|
||
} catch (e: unknown) {
|
||
const err = e as { response?: { data?: { error?: string } } };
|
||
ElMessage.error(err.response?.data?.error ?? '上分失败');
|
||
} finally {
|
||
depositLoading.value = false;
|
||
}
|
||
}
|
||
|
||
function formatTime(v: string) {
|
||
if (!v) return '—';
|
||
return new Date(v).toLocaleString('zh-CN');
|
||
}
|
||
|
||
function formatLastLogin(v: string | null) {
|
||
if (!v) return '从未登录';
|
||
const d = new Date(v);
|
||
const now = new Date();
|
||
const sameDay =
|
||
d.getFullYear() === now.getFullYear() &&
|
||
d.getMonth() === now.getMonth() &&
|
||
d.getDate() === now.getDate();
|
||
if (sameDay) {
|
||
return d.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
|
||
}
|
||
return d.toLocaleString('zh-CN', {
|
||
month: '2-digit',
|
||
day: '2-digit',
|
||
hour: '2-digit',
|
||
minute: '2-digit',
|
||
});
|
||
}
|
||
|
||
function statusTagType(s: string) {
|
||
return s === 'ACTIVE' ? 'success' : 'warning';
|
||
}
|
||
|
||
function statusLabel(s: string) {
|
||
return s === 'ACTIVE' ? '正常' : s === 'SUSPENDED' ? '停用' : s;
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div class="admin-list-page users-page">
|
||
<div class="page-header">
|
||
<div>
|
||
<h2 class="page-title">玩家管理</h2>
|
||
<span class="page-desc">创建玩家、查看余额与投注概况,支持上分与状态管理</span>
|
||
</div>
|
||
<el-button type="primary" @click="openCreate">+ 新建玩家</el-button>
|
||
</div>
|
||
|
||
<el-card class="filter-card" shadow="never">
|
||
<el-form inline>
|
||
<el-form-item label="关键词">
|
||
<el-input
|
||
v-model="keyword"
|
||
placeholder="用户名"
|
||
clearable
|
||
style="width: 160px"
|
||
@keyup.enter="load"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="所属代理">
|
||
<el-select
|
||
v-model="filterParentId"
|
||
placeholder="全部"
|
||
clearable
|
||
style="width: 180px"
|
||
>
|
||
<el-option
|
||
v-for="a in agentOptions"
|
||
:key="a.id"
|
||
:label="a.username"
|
||
:value="a.id"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="状态">
|
||
<el-select v-model="filterStatus" placeholder="全部" clearable style="width: 120px">
|
||
<el-option label="正常" value="ACTIVE" />
|
||
<el-option label="停用" value="SUSPENDED" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" @click="load">查询</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-card>
|
||
|
||
<el-card class="data-card" shadow="never">
|
||
<div class="table-wrap">
|
||
<el-table :data="users" stripe>
|
||
<el-table-column prop="id" label="ID" width="72" />
|
||
<el-table-column prop="username" label="用户名" min-width="120" />
|
||
<el-table-column label="状态" width="88">
|
||
<template #default="{ row }">
|
||
<el-tag :type="statusTagType(row.status)" size="small">
|
||
{{ statusLabel(row.status) }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="所属代理" min-width="120">
|
||
<template #default="{ row }">{{ parentLabel(row) }}</template>
|
||
</el-table-column>
|
||
<el-table-column label="可用 / 冻结" min-width="128" align="right">
|
||
<template #default="{ row }">
|
||
<el-tooltip
|
||
:content="`${formatAmountFull(row.availableBalance)} / ${formatAmountFull(row.frozenBalance)}`"
|
||
placement="top"
|
||
>
|
||
<span class="amount-compact">
|
||
{{ formatAmount(row.availableBalance) }} / {{ formatAmount(row.frozenBalance) }}
|
||
</span>
|
||
</el-tooltip>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="betCount" label="注单" width="64" align="center" />
|
||
<el-table-column label="投注 / 派彩" min-width="108" align="right">
|
||
<template #default="{ row }">
|
||
<span class="amount-compact">
|
||
{{ formatAmount(row.totalStake) }} / {{ formatAmount(row.totalReturn) }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="最后登录" width="108">
|
||
<template #default="{ row }">
|
||
<el-tooltip v-if="row.lastLoginAt" :content="formatTime(row.lastLoginAt)" placement="top">
|
||
<span>{{ formatLastLogin(row.lastLoginAt) }}</span>
|
||
</el-tooltip>
|
||
<span v-else class="text-muted">从未登录</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="注册时间" width="108">
|
||
<template #default="{ row }">
|
||
<el-tooltip :content="formatTime(row.createdAt)" placement="top">
|
||
<span>{{ formatLastLogin(row.createdAt) }}</span>
|
||
</el-tooltip>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="300" fixed="right" align="center">
|
||
<template #default="{ row }">
|
||
<el-button size="small" link type="primary" @click="openDetail(row.id)">详情</el-button>
|
||
<el-button size="small" link type="primary" @click="openEdit(row.id)">编辑</el-button>
|
||
<el-button size="small" link type="primary" @click="openDeposit(row)">上分</el-button>
|
||
<el-button
|
||
v-if="row.status === 'ACTIVE'"
|
||
size="small"
|
||
link
|
||
type="warning"
|
||
@click="toggleFreeze(row)"
|
||
>
|
||
冻结
|
||
</el-button>
|
||
<el-button
|
||
v-else
|
||
size="small"
|
||
link
|
||
type="primary"
|
||
@click="toggleFreeze(row)"
|
||
>
|
||
解冻
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
<div class="pager">
|
||
<el-pagination
|
||
v-model:current-page="page"
|
||
v-model:page-size="pageSize"
|
||
:total="total"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
layout="total, sizes, prev, pager, next"
|
||
background
|
||
@current-change="onPageChange"
|
||
@size-change="onSizeChange"
|
||
/>
|
||
</div>
|
||
</el-card>
|
||
|
||
<el-dialog v-model="createVisible" title="新建玩家" width="520px" destroy-on-close>
|
||
<el-form label-width="100px">
|
||
<el-form-item label="用户名" required>
|
||
<el-input v-model="createForm.username" placeholder="登录用户名,唯一" />
|
||
</el-form-item>
|
||
<el-form-item label="登录密码" required>
|
||
<el-input v-model="createForm.password" type="text" autocomplete="off" />
|
||
</el-form-item>
|
||
<el-form-item label="确认密码" required>
|
||
<el-input v-model="createForm.confirmPassword" type="text" autocomplete="off" />
|
||
</el-form-item>
|
||
<el-form-item label="所属代理">
|
||
<el-select
|
||
v-model="createForm.parentId"
|
||
placeholder="不设置(平台直属玩家)"
|
||
clearable
|
||
style="width: 100%"
|
||
>
|
||
<el-option
|
||
v-for="a in agentOptions"
|
||
:key="a.id"
|
||
:label="`${a.username} (#${a.id})`"
|
||
:value="a.id"
|
||
/>
|
||
</el-select>
|
||
<div class="field-hint">留空表示不挂靠代理,由平台直接管理</div>
|
||
</el-form-item>
|
||
<el-form-item label="手机号">
|
||
<el-input v-model="createForm.phone" placeholder="选填" />
|
||
</el-form-item>
|
||
<el-form-item label="邮箱">
|
||
<el-input v-model="createForm.email" placeholder="选填" />
|
||
</el-form-item>
|
||
<el-form-item label="初始余额">
|
||
<el-input-number v-model="createForm.initialDeposit" :min="0" :step="100" style="width: 100%" />
|
||
<div class="field-hint">创建后自动上分,0 表示不开户赠金</div>
|
||
</el-form-item>
|
||
<el-form-item label="上分备注">
|
||
<el-input v-model="createForm.remark" placeholder="有初始余额时写入流水备注" />
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<el-button @click="createVisible = false">取消</el-button>
|
||
<el-button type="primary" :loading="createLoading" @click="submitCreate">创建</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<el-dialog v-model="editVisible" title="编辑玩家" width="560px" destroy-on-close>
|
||
<el-form label-width="100px">
|
||
<el-form-item label="玩家 ID">
|
||
<el-input :model-value="editForm.id" disabled />
|
||
</el-form-item>
|
||
<el-form-item label="用户名">
|
||
<el-input :model-value="editForm.username" disabled />
|
||
</el-form-item>
|
||
<el-form-item label="账号状态">
|
||
<el-tag :type="statusTagType(editForm.status)" size="small">
|
||
{{ statusLabel(editForm.status) }}
|
||
</el-tag>
|
||
<span class="field-hint inline-hint">冻结/解冻请在列表操作列进行</span>
|
||
</el-form-item>
|
||
<el-form-item label="所属代理">
|
||
<el-select
|
||
v-model="editForm.parentId"
|
||
placeholder="不设置(平台直属玩家)"
|
||
clearable
|
||
style="width: 100%"
|
||
>
|
||
<el-option
|
||
v-for="a in agentOptions"
|
||
:key="a.id"
|
||
:label="`${a.username} (#${a.id})`"
|
||
:value="a.id"
|
||
/>
|
||
</el-select>
|
||
<div class="field-hint">留空表示平台直属;变更后会重算相关代理已用授信</div>
|
||
</el-form-item>
|
||
<el-form-item label="可用余额">
|
||
<el-input :model-value="formatAmount(editForm.availableBalance)" disabled />
|
||
</el-form-item>
|
||
<el-form-item label="冻结余额">
|
||
<el-input :model-value="formatAmount(editForm.frozenBalance)" disabled />
|
||
</el-form-item>
|
||
<el-form-item label="注单 / 投注">
|
||
<el-input
|
||
:model-value="`${editForm.betCount} 笔 / ${formatAmount(editForm.totalStake)}`"
|
||
disabled
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="累计派彩">
|
||
<el-input :model-value="formatAmount(editForm.totalReturn)" disabled />
|
||
</el-form-item>
|
||
<el-form-item label="最后登录">
|
||
<el-input
|
||
:model-value="editForm.lastLoginAt ? formatTime(editForm.lastLoginAt) : '从未登录'"
|
||
disabled
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="登录失败">
|
||
<el-input :model-value="`${editForm.loginFailCount} 次`" disabled />
|
||
</el-form-item>
|
||
<el-form-item label="注册时间">
|
||
<el-input :model-value="formatTime(editForm.createdAt)" disabled />
|
||
</el-form-item>
|
||
<el-divider />
|
||
<el-form-item label="手机号">
|
||
<el-input v-model="editForm.phone" placeholder="选填" />
|
||
</el-form-item>
|
||
<el-form-item label="邮箱">
|
||
<el-input v-model="editForm.email" placeholder="选填" />
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<el-button @click="editVisible = false">取消</el-button>
|
||
<el-button type="primary" :loading="editLoading" @click="submitEdit">保存资料</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<el-dialog v-model="depositVisible" title="玩家上分" width="400px" destroy-on-close>
|
||
<el-form label-width="80px">
|
||
<el-form-item label="玩家 ID">
|
||
<el-input :model-value="depositForm.userId" disabled />
|
||
</el-form-item>
|
||
<el-form-item label="金额">
|
||
<el-input-number v-model="depositForm.amount" :min="0.01" :step="10" style="width: 100%" />
|
||
</el-form-item>
|
||
<el-form-item label="备注">
|
||
<el-input v-model="depositForm.remark" />
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<el-button @click="depositVisible = false">取消</el-button>
|
||
<el-button type="primary" :loading="depositLoading" @click="submitDeposit">确认上分</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<el-dialog v-model="detailVisible" title="玩家详情" width="560px" destroy-on-close>
|
||
<template v-if="detail">
|
||
<el-descriptions :column="2" border size="small">
|
||
<el-descriptions-item label="ID">{{ detail.id }}</el-descriptions-item>
|
||
<el-descriptions-item label="用户名">{{ detail.username }}</el-descriptions-item>
|
||
<el-descriptions-item label="状态">
|
||
<el-tag :type="statusTagType(detail.status)" size="small">
|
||
{{ statusLabel(detail.status) }}
|
||
</el-tag>
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="所属代理">
|
||
{{ detail.parentUsername ?? '平台直属' }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="可用余额">
|
||
{{ formatAmount(detail.availableBalance) }}
|
||
<span v-if="shouldCompact(detail.availableBalance)" class="amount-full-hint">
|
||
({{ formatAmountFull(detail.availableBalance) }})
|
||
</span>
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="冻结余额">
|
||
{{ formatAmount(detail.frozenBalance) }}
|
||
<span v-if="shouldCompact(detail.frozenBalance)" class="amount-full-hint">
|
||
({{ formatAmountFull(detail.frozenBalance) }})
|
||
</span>
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="手机">{{ detail.phone ?? '—' }}</el-descriptions-item>
|
||
<el-descriptions-item label="邮箱">{{ detail.email ?? '—' }}</el-descriptions-item>
|
||
<el-descriptions-item label="注单数">{{ detail.betCount }}</el-descriptions-item>
|
||
<el-descriptions-item label="累计投注">{{ formatAmount(detail.totalStake) }}</el-descriptions-item>
|
||
<el-descriptions-item label="累计派彩">{{ formatAmount(detail.totalReturn) }}</el-descriptions-item>
|
||
<el-descriptions-item label="最后登录">
|
||
{{ detail.lastLoginAt ? formatTime(detail.lastLoginAt) : '从未登录' }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="登录失败">{{ detail.loginFailCount }} 次</el-descriptions-item>
|
||
<el-descriptions-item label="注册时间" :span="2">
|
||
{{ formatTime(detail.createdAt) }}
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.page-header {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
margin-bottom: 20px;
|
||
}
|
||
.page-title { font-size: 20px; font-weight: 700; color: #e0e0e0; margin: 0 0 4px; }
|
||
.page-desc { font-size: 13px; color: #666; }
|
||
.filter-card { margin-bottom: 16px; border-radius: 12px; }
|
||
.data-card { border-radius: 12px; }
|
||
.pager { margin-top: 16px; display: flex; justify-content: flex-end; }
|
||
.field-hint { font-size: 12px; color: #888; margin-top: 4px; }
|
||
.inline-hint { margin-top: 0; margin-left: 10px; display: inline-block; }
|
||
.amount-compact { white-space: nowrap; font-variant-numeric: tabular-nums; cursor: default; }
|
||
.amount-full-hint { font-size: 11px; color: #666; margin-left: 4px; }
|
||
.text-muted { color: #666; font-size: 12px; }
|
||
</style>
|
||
|
||
<style>
|
||
/* 玩家列表「冻结」:橙黄底白字 */
|
||
.users-page .el-button.is-link.el-button--warning {
|
||
color: #ffffff !important;
|
||
background: linear-gradient(165deg, #e8a84a 0%, #c47a18 42%, #9a5c10 100%) !important;
|
||
border: 1px solid rgba(232, 168, 74, 0.45) !important;
|
||
border-radius: 6px !important;
|
||
padding: 5px 11px !important;
|
||
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.12) inset, 0 1px 6px rgba(0, 0, 0, 0.35) !important;
|
||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||
}
|
||
.users-page .el-button.is-link.el-button--warning:hover,
|
||
.users-page .el-button.is-link.el-button--warning:focus {
|
||
color: #ffffff !important;
|
||
background: linear-gradient(165deg, #f0bc62 0%, #d48a28 42%, #a86814 100%) !important;
|
||
border-color: rgba(240, 188, 98, 0.55) !important;
|
||
}
|
||
</style>
|