sql数据流,amdin业务逻辑接入
This commit is contained in:
@@ -4,29 +4,31 @@
|
||||
<view class="filter-card box-shadow">
|
||||
<view class="filter-row">
|
||||
<view class="filter-item">
|
||||
<text class="label">活动时间:</text>
|
||||
<view class="date-range-mock">
|
||||
<text class="date-text">开始日期 - 结束日期</text>
|
||||
<text class="iconfont icon-calendar"></text>
|
||||
</view>
|
||||
<text class="label">活动时段:</text>
|
||||
<AnalyticsDateRangePicker
|
||||
:initialStartDate="startDate"
|
||||
:initialEndDate="endDate"
|
||||
@apply="onApplyRange"
|
||||
@clear="onClearRange"
|
||||
/>
|
||||
</view>
|
||||
<view class="filter-item">
|
||||
<text class="label">活动状态:</text>
|
||||
<picker :range="statusOptions" range-key="label" @change="statusChange">
|
||||
<view class="picker-value">{{ getStatusLabel(currentStatus) }} <text class="iconfont icon-arrow-down"></text></view>
|
||||
<view class="picker-value">{{ statusOptions[statusIndex].label }} <text class="iconfont icon-arrow-down">▼</text></view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="filter-item">
|
||||
<text class="label">活动类型:</text>
|
||||
<picker :range="typeOptions" range-key="label" @change="typeChange">
|
||||
<view class="picker-value">{{ getTypeLabel(currentType) }} <text class="iconfont icon-arrow-down"></text></view>
|
||||
<view class="picker-value">{{ typeOptions[typeIndex].label }} <text class="iconfont icon-arrow-down">▼</text></view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="filter-row second-row">
|
||||
<view class="filter-item">
|
||||
<text class="label">搜索抽奖:</text>
|
||||
<input class="admin-input" placeholder="请输入活动名称" v-model="searchQuery" style="width: 200px;" />
|
||||
<input class="admin-input" placeholder="请输入活动名称" v-model="searchQuery" style="width: 200px;" @confirm="handleSearch" />
|
||||
</view>
|
||||
<view class="filter-item">
|
||||
<button class="admin-btn admin-btn-primary search-btn" @click="handleSearch">搜索</button>
|
||||
@@ -36,52 +38,62 @@
|
||||
|
||||
<!-- 操作工具栏 -->
|
||||
<view class="table-toolbar">
|
||||
<button class="admin-btn admin-btn-primary">创建抽奖活动</button>
|
||||
<button class="admin-btn admin-btn-primary" @click="handleAdd">创建抽奖活动</button>
|
||||
</view>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<view class="table-card box-shadow">
|
||||
<view class="table-header">
|
||||
<text class="col-60 center">ID</text>
|
||||
<text class="col-120">活动名称</text>
|
||||
<text class="col-100">活动类型</text>
|
||||
<text class="col-80 center">抽奖人数</text>
|
||||
<text class="col-80 center">中奖人数</text>
|
||||
<text class="col-80 center">抽奖次数</text>
|
||||
<text class="col-80 center">中奖次数</text>
|
||||
<text class="col-80 center">活动状态</text>
|
||||
<text class="col-80 center">开启状态</text>
|
||||
<text class="col-180">活动时间</text>
|
||||
<text class="col-120 center">操作</text>
|
||||
</view>
|
||||
<view class="table-container">
|
||||
<!-- Loading 遮罩 -->
|
||||
<view v-if="isLoading" class="loading-mask">
|
||||
<text class="loading-text">数据加载中...</text>
|
||||
</view>
|
||||
|
||||
<view class="table-body">
|
||||
<view v-for="(item, index) in tableData" :key="index" class="table-row">
|
||||
<view class="col-60 center"><text class="id-text">{{ item.id }}</text></view>
|
||||
<view class="col-120"><text class="cell-text">{{ item.name }}</text></view>
|
||||
<view class="col-100"><text class="cell-text">{{ item.typeName }}</text></view>
|
||||
<view class="col-80 center"><text class="cell-text">{{ item.memberCount }}</text></view>
|
||||
<view class="col-80 center"><text class="cell-text">{{ item.winningMemberCount }}</text></view>
|
||||
<view class="col-80 center"><text class="cell-text">{{ item.lotteryTimes }}</text></view>
|
||||
<view class="col-80 center"><text class="cell-text">{{ item.winningTimes }}</text></view>
|
||||
<view class="col-80 center">
|
||||
<text class="status-text">{{ item.statusText }}</text>
|
||||
<view class="table-header">
|
||||
<text class="col-60 center">ID</text>
|
||||
<text class="col-120">活动名称</text>
|
||||
<text class="col-100">活动类型</text>
|
||||
<text class="col-80 center">抽奖人数</text>
|
||||
<text class="col-80 center">中奖人数</text>
|
||||
<text class="col-80 center">抽奖次数</text>
|
||||
<text class="col-80 center">中奖次数</text>
|
||||
<text class="col-80 center">活动状态</text>
|
||||
<text class="col-80 center">开启状态</text>
|
||||
<text class="col-180">活动时间</text>
|
||||
<text class="col-120 center">操作</text>
|
||||
</view>
|
||||
|
||||
<view class="table-body">
|
||||
<view v-if="tableData.length === 0 && !isLoading" class="empty-row">
|
||||
<text>暂无抽奖活动数据</text>
|
||||
</view>
|
||||
<view class="col-80 center">
|
||||
<view class="switch-box" :class="item.isOpen ? 'active' : ''" @click="toggleStatus(item)">
|
||||
<view class="switch-dot"></view>
|
||||
<view v-for="(item, index) in tableData" :key="index" class="table-row">
|
||||
<view class="col-60 center"><text class="id-text">{{ item.id }}</text></view>
|
||||
<view class="col-120"><text class="cell-text">{{ item.name }}</text></view>
|
||||
<view class="col-100"><text class="cell-text">{{ getTypeName(item.type) }}</text></view>
|
||||
<view class="col-80 center"><text class="cell-text">{{ item.memberCount ?? 0 }}</text></view>
|
||||
<view class="col-80 center"><text class="cell-text">{{ item.winningMemberCount ?? 0 }}</text></view>
|
||||
<view class="col-80 center"><text class="cell-text">{{ item.lotteryTimes ?? 0 }}</text></view>
|
||||
<view class="col-80 center"><text class="cell-text">{{ item.winningTimes ?? 0 }}</text></view>
|
||||
<view class="col-80 center">
|
||||
<text class="status-text">{{ getStatusLabel(item) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="col-180">
|
||||
<view class="time-range">
|
||||
<text class="time-label">开始: {{ item.startTime }}</text>
|
||||
<text class="time-label">结束: {{ item.endTime }}</text>
|
||||
<view class="col-80 center">
|
||||
<view class="switch-box" :class="item.is_open ? 'active' : ''" @click="toggleStatus(item)">
|
||||
<view class="switch-dot"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="col-180">
|
||||
<view class="time-range">
|
||||
<text class="time-label">始: {{ formatDateTime(item.start_time) }}</text>
|
||||
<text class="time-label">终: {{ formatDateTime(item.end_time) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="col-120 center ops-cell">
|
||||
<text class="op-link" @click="handleEdit(item)">编辑</text>
|
||||
<text class="op-link" @click="handleRecords(item)">记录</text>
|
||||
<text class="op-link danger" @click="handleDelete(item.id)">删除</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="col-120 center ops-cell">
|
||||
<text class="op-link">编辑</text>
|
||||
<text class="op-link">抽奖记录</text>
|
||||
<text class="op-link">更多 <text class="iconfont icon-arrow-down" style="font-size: 10px;"></text></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -90,127 +102,171 @@
|
||||
<view class="table-pagination">
|
||||
<text class="total-text">共 {{ total }} 条</text>
|
||||
<view class="page-ops">
|
||||
<picker :range="pageSizes" @change="pageSizeChange">
|
||||
<view class="size-picker">{{ currentSize }}条/页 <text class="iconfont icon-arrow-down"></text></view>
|
||||
</picker>
|
||||
<button class="page-btn" disabled>上一页</button>
|
||||
<text class="current-page">1</text>
|
||||
<button class="page-btn" disabled>下一页</button>
|
||||
<text class="jump-text">前往</text>
|
||||
<input class="jump-input" value="1" />
|
||||
<text class="jump-text">页</text>
|
||||
<button class="page-btn" :disabled="page <= 1" @click="onPrevPage">上一页</button>
|
||||
<text class="current-page">{{ page }}</text>
|
||||
<button class="page-btn" :disabled="tableData.length < pageSize" @click="onNextPage">下一页</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script uts>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
searchQuery: '',
|
||||
currentStatus: 0,
|
||||
currentType: 0,
|
||||
total: 4,
|
||||
currentSize: 15,
|
||||
pageSizes: ['15条/页', '30条/页', '50条/页'],
|
||||
statusOptions: [
|
||||
{ label: '全部', value: 0 },
|
||||
{ label: '未开始', value: 1 },
|
||||
{ label: '进行中', value: 2 },
|
||||
{ label: '已结束', value: 3 }
|
||||
] as any[],
|
||||
typeOptions: [
|
||||
{ label: '全部', value: 0 },
|
||||
{ label: '积分抽奖', value: 1 },
|
||||
{ label: '订单评价', value: 2 },
|
||||
{ label: '订单支付', value: 3 }
|
||||
] as any[],
|
||||
tableData: [
|
||||
{
|
||||
id: 87,
|
||||
name: '积分抽奖',
|
||||
typeName: '积分抽取',
|
||||
memberCount: 166,
|
||||
winningMemberCount: 0,
|
||||
lotteryTimes: 329,
|
||||
winningTimes: 0,
|
||||
statusText: '已结束',
|
||||
isOpen: true,
|
||||
startTime: '2025-12-04 00:00:00',
|
||||
endTime: '2026-01-31 23:59:59'
|
||||
},
|
||||
{
|
||||
id: 86,
|
||||
name: '评价抽奖',
|
||||
typeName: '订单评价',
|
||||
memberCount: 3,
|
||||
winningMemberCount: 3,
|
||||
lotteryTimes: 4,
|
||||
winningTimes: 3,
|
||||
statusText: '已结束',
|
||||
isOpen: true,
|
||||
startTime: '2023-12-12 00:00:00',
|
||||
endTime: '2024-01-16 23:59:59'
|
||||
},
|
||||
{
|
||||
id: 82,
|
||||
name: '订单抽奖',
|
||||
typeName: '订单支付',
|
||||
memberCount: 100,
|
||||
winningMemberCount: 5,
|
||||
lotteryTimes: 124,
|
||||
winningTimes: 6,
|
||||
statusText: '已结束',
|
||||
isOpen: true,
|
||||
startTime: '2023-08-16 00:00:00',
|
||||
endTime: '2024-01-31 23:59:59'
|
||||
},
|
||||
{
|
||||
id: 75,
|
||||
name: '积分',
|
||||
typeName: '积分抽取',
|
||||
memberCount: 1288,
|
||||
winningMemberCount: 1130,
|
||||
lotteryTimes: 3413,
|
||||
winningTimes: 2628,
|
||||
statusText: '已结束',
|
||||
isOpen: true,
|
||||
startTime: '2025-10-01 00:00:00',
|
||||
endTime: '2025-11-30 23:59:59'
|
||||
}
|
||||
] as any[]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getStatusLabel(val : number) : string {
|
||||
const found = this.statusOptions.find((item : any) : boolean => item.value == val)
|
||||
return found != null ? (found['label'] as string) : '全部'
|
||||
},
|
||||
getTypeLabel(val : number) : string {
|
||||
const found = this.typeOptions.find((item : any) : boolean => item.value == val)
|
||||
return found != null ? (found['label'] as string) : '全部'
|
||||
},
|
||||
statusChange(e : any) {
|
||||
this.currentStatus = this.statusOptions[e.detail.value].value
|
||||
},
|
||||
typeChange(e : any) {
|
||||
this.currentType = this.typeOptions[e.detail.value].value
|
||||
},
|
||||
pageSizeChange(e : any) {
|
||||
const val = this.pageSizes[e.detail.value]
|
||||
this.currentSize = parseInt(val.replace('条/页', ''))
|
||||
},
|
||||
handleSearch() {
|
||||
uni.showToast({ title: '搜索', icon: 'none' })
|
||||
},
|
||||
toggleStatus(item : any) {
|
||||
item.isOpen = !item.isOpen
|
||||
uni.showToast({ title: '状态已变更', icon: 'none' })
|
||||
}
|
||||
<script setup lang="uts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import AnalyticsDateRangePicker from '@/components/analytics/AnalyticsDateRangePicker.uvue'
|
||||
import { fetchLotteryList, saveLotteryActivity, deleteLotteryActivity, LotteryActivity } from '@/services/admin/marketingService.uts'
|
||||
|
||||
const searchQuery = ref('')
|
||||
const isLoading = ref(false)
|
||||
const total = ref(0)
|
||||
const tableData = ref<LotteryActivity[]>([])
|
||||
const page = ref(1)
|
||||
const pageSize = ref(15)
|
||||
|
||||
const startDate = ref('')
|
||||
const endDate = ref('')
|
||||
|
||||
const statusOptions = [
|
||||
{ label: '全部', value: 0 },
|
||||
{ label: '开启', value: 1 },
|
||||
{ label: '关闭', value: 2 }
|
||||
]
|
||||
const statusIndex = ref(0)
|
||||
|
||||
const typeOptions = [
|
||||
{ label: '全部', value: 0 },
|
||||
{ label: '积分抽奖', value: 1 },
|
||||
{ label: '订单评价', value: 2 },
|
||||
{ label: '订单支付', value: 3 }
|
||||
]
|
||||
const typeIndex = ref(0)
|
||||
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
|
||||
async function loadData() {
|
||||
isLoading.value = true
|
||||
try {
|
||||
const st = startDate.value ? (startDate.value + ' 00:00:00') : null
|
||||
const et = endDate.value ? (endDate.value + ' 23:59:59') : null
|
||||
|
||||
const res = await fetchLotteryList({
|
||||
search: searchQuery.value,
|
||||
status: statusOptions[statusIndex.value].value,
|
||||
type: typeOptions[typeIndex.value].value,
|
||||
page: page.value,
|
||||
pageSize: pageSize,
|
||||
startTime: st,
|
||||
endTime: et
|
||||
} as any)
|
||||
tableData.value = res.items
|
||||
total.value = res.total
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '加载失败', icon: 'none' })
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
page.value = 1
|
||||
loadData()
|
||||
}
|
||||
|
||||
function onStatusChange(e : any) {
|
||||
statusIndex.value = parseInt(String(e.detail.value))
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
function onTypeChange(e : any) {
|
||||
typeIndex.value = parseInt(String(e.detail.value))
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
async function toggleStatus(item : LotteryActivity) {
|
||||
if (item.id == null) return
|
||||
const nextOpen = !item.is_open
|
||||
const success = await saveLotteryActivity({ ...item, is_open: nextOpen } as LotteryActivity)
|
||||
if (success) {
|
||||
item.is_open = nextOpen
|
||||
uni.showToast({ title: '状态已变更', icon: 'success' })
|
||||
}
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
uni.showToast({ title: '添加功能开发中', icon: 'none' })
|
||||
}
|
||||
|
||||
function handleEdit(item : LotteryActivity) {
|
||||
uni.showToast({ title: '编辑功能开发中', icon: 'none' })
|
||||
}
|
||||
|
||||
function handleRecords(item : LotteryActivity) {
|
||||
uni.showToast({ title: '记录功能开发中', icon: 'none' })
|
||||
}
|
||||
|
||||
async function handleDelete(id : string | undefined) {
|
||||
if (id == null) return
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要删除该抽奖活动吗?',
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
const success = await deleteLotteryActivity(id!)
|
||||
if (success) {
|
||||
uni.showToast({ title: '删除成功' })
|
||||
loadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onApplyRange(payload : any) {
|
||||
startDate.value = payload?.start ?? ''
|
||||
endDate.value = payload?.end ?? ''
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
function onClearRange() {
|
||||
startDate.value = ''
|
||||
endDate.value = ''
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
function onPrevPage() {
|
||||
if (page.value > 1) {
|
||||
page.value--
|
||||
loadData()
|
||||
}
|
||||
}
|
||||
|
||||
function onNextPage() {
|
||||
if (tableData.value.length >= pageSize) {
|
||||
page.value++
|
||||
loadData()
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeName(type : number) : string {
|
||||
const found = typeOptions.find(o => o.value === type)
|
||||
return found != null ? found.label : '未知'
|
||||
}
|
||||
|
||||
function getStatusLabel(item : LotteryActivity) : string {
|
||||
const now = Date.now()
|
||||
const start = new Date(item.start_time).getTime()
|
||||
const end = new Date(item.end_time).getTime()
|
||||
|
||||
if (now < start) return '未开始'
|
||||
if (now > end) return '已结束'
|
||||
return '进行中'
|
||||
}
|
||||
|
||||
function formatDateTime(iso : string) : string {
|
||||
return iso.substring(0, 16).replace('T', ' ')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -253,21 +309,8 @@ export default {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.date-range-mock {
|
||||
width: 280px;
|
||||
height: 32px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.date-text { font-size: 13px; color: #c0c4cc; }
|
||||
|
||||
.picker-value {
|
||||
width: 160px;
|
||||
min-width: 120px;
|
||||
height: 32px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid #dcdfe6;
|
||||
@@ -277,6 +320,7 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.admin-input {
|
||||
@@ -293,6 +337,20 @@ export default {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.admin-btn {
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.admin-btn-primary {
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 表格工具栏 */
|
||||
.table-toolbar {
|
||||
margin-bottom: 16px;
|
||||
@@ -301,7 +359,18 @@ export default {
|
||||
/* 表格主体 */
|
||||
.table-card {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.table-container {
|
||||
min-height: 400px;
|
||||
position: relative;
|
||||
}
|
||||
.loading-mask {
|
||||
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: rgba(255,255,255,0.7); display: flex; align-items: center; justify-content: center; z-index: 10;
|
||||
}
|
||||
.loading-text { color: #1890ff; font-size: 14px; }
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -321,6 +390,7 @@ export default {
|
||||
border-bottom: 1px solid #e8eaec;
|
||||
padding: 12px 0;
|
||||
}
|
||||
.table-row:hover { background-color: #fafafa; }
|
||||
|
||||
/* 列定义 */
|
||||
.col-60 { width: 60px; }
|
||||
@@ -328,11 +398,11 @@ export default {
|
||||
.col-100 { width: 100px; }
|
||||
.col-120 { width: 120px; }
|
||||
.col-180 { width: 180px; }
|
||||
.center { text-align: center; justify-content: center; }
|
||||
.center { text-align: center; justify-content: center; display: flex; align-items: center; }
|
||||
|
||||
.cell-text { font-size: 13px; color: #515a6e; }
|
||||
.id-text { font-size: 13px; color: #808695; }
|
||||
.status-text { font-size: 13px; color: #515a6e; }
|
||||
.status-text { font-size: 13px; color: #1890ff; }
|
||||
|
||||
/* 开关组件 */
|
||||
.switch-box {
|
||||
@@ -355,10 +425,10 @@ export default {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
transition: transform 0.3s;
|
||||
transition: left 0.3s;
|
||||
}
|
||||
.switch-box.active .switch-dot {
|
||||
transform: translateX(20px);
|
||||
left: 22px;
|
||||
}
|
||||
|
||||
.time-range {
|
||||
@@ -374,13 +444,14 @@ export default {
|
||||
.ops-cell {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 8px;
|
||||
}
|
||||
.op-link {
|
||||
font-size: 13px;
|
||||
color: #2d8cf0;
|
||||
margin: 0 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.op-link.danger { color: #f5222d; }
|
||||
|
||||
/* 分页 */
|
||||
.table-pagination {
|
||||
@@ -399,47 +470,22 @@ export default {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.size-picker {
|
||||
font-size: 14px;
|
||||
color: #515a6e;
|
||||
border: 1px solid #dcdfe6;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
margin-right: 15px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.page-btn {
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
padding: 0 8px;
|
||||
padding: 0 12px;
|
||||
font-size: 12px;
|
||||
border: 1px solid #dcdfe6;
|
||||
background-color: #fff;
|
||||
}
|
||||
.current-page {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
text-align: center;
|
||||
background-color: #2d8cf0;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
border-radius: 2px;
|
||||
margin: 0 8px;
|
||||
}
|
||||
.jump-text { font-size: 14px; color: #515a6e; margin: 0 5px; }
|
||||
.jump-input {
|
||||
width: 40px;
|
||||
height: 28px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
.page-btn[disabled] { opacity: 0.5; }
|
||||
.current-page {
|
||||
font-size: 14px;
|
||||
color: #2d8cf0;
|
||||
font-weight: bold;
|
||||
}
|
||||
.empty-row { padding: 60px 0; text-align: center; color: #999; }
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user