Files
medical-mall/pages/mall/admin/distribution/level/index.uvue

166 lines
9.9 KiB
Plaintext

<template>
<view class="admin-page">
<view class="filter-card">
<view class="filter-row">
<view class="filter-item">
<text class="label">是否显示:</text>
<view class="select-mock"><text>全部</text><text class="arrow">▼</text></view>
</view>
<view class="filter-item">
<text class="label">等级名称:</text>
<input class="filter-input" placeholder="请输入等级名称" />
</view>
<view class="filter-btns">
<button class="btn primary" @click="onSearch">查询</button>
</view>
</view>
</view>
<view class="content-card">
<view class="action-bar">
<button class="btn primary small" @click="onAdd">添加等级</button>
</view>
<view class="table-container">
<view class="table-header">
<view class="col col-id"><text>ID</text></view>
<view class="col col-img"><text>商品图片</text></view>
<view class="col col-name"><text>名称</text></view>
<view class="col col-level"><text>等级</text></view>
<view class="col col-percent"><text>一级分佣比例</text></view>
<view class="col col-percent"><text>二级分佣比例</text></view>
<view class="col col-stat"><text>任务总数</text></view>
<view class="col col-stat"><text>需完成数量</text></view>
<view class="col col-status"><text>是否显示</text></view>
<view class="col col-ops"><text>操作</text></view>
</view>
<view class="table-body">
<view v-for="item in pagedList" :key="item.id" class="table-row">
<view class="col col-id"><text>{{ item.id }}</text></view>
<view class="col col-img">
<image class="table-img" src="/static/logo.png" mode="aspectFill" />
</view>
<view class="col col-name"><text>{{ item.name }}</text></view>
<view class="col col-level"><text>{{ item.level }}</text></view>
<view class="col col-percent"><text>{{ item.percent1 }}%</text></view>
<view class="col col-percent"><text>{{ item.percent2 }}%</text></view>
<view class="col col-stat"><text>{{ item.taskTotal }}</text></view>
<view class="col col-stat"><text>{{ item.taskFinish }}</text></view>
<view class="col col-status">
<switch :checked="item.show" color="#1890ff" scale="0.8" />
</view>
<view class="col col-ops">
<text class="op-link">等级任务</text>
<text class="op-divider">|</text>
<text class="op-link">编辑</text>
<text class="op-divider">|</text>
<text class="op-link">删除</text>
</view>
</view>
</view>
</view>
<CommonPagination
v-if="total > 0"
:total="total"
:loading="false"
:currentPage="currentPage"
:pageSize="pageSize"
:pageSizeOptionLabels="pageSizeOptionLabels"
:pageSizeIndex="pageSizeIndex"
:visiblePages="visiblePages"
:totalPage="totalPage"
:jumpPageInput="jumpPageInput"
@page-size-change="handlePageSizeChange"
@page-change="handlePageChange"
@update:jumpPageInput="(val: string) => { jumpPageInput.value = val }"
@jump-page="handleJumpPage"
/>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, computed } from 'vue'
import CommonPagination from '@/components/CommonPagination/CommonPagination.uvue'
// ========== MOCK DATA START ==========
// TODO: 接真实接口时替换此处 levelList 为 fetchLevelList() 调用
const levelList = ref([
{ id: '1', name: '一级分销员', level: 1, percent1: 20.00, percent2: 10.00, taskTotal: 5, taskFinish: 3, show: true },
{ id: '2', name: '二级分销员', level: 2, percent1: 15.00, percent2: 8.00, taskTotal: 3, taskFinish: 2, show: true },
{ id: '3', name: '三级分销员', level: 3, percent1: 10.00, percent2: 5.00, taskTotal: 2, taskFinish: 1, show: true },
{ id: '4', name: '铂金分销员', level: 4, percent1: 25.00, percent2: 12.00, taskTotal: 8, taskFinish: 6, show: true },
{ id: '5', name: '钻石分销员', level: 5, percent1: 30.00, percent2: 15.00, taskTotal: 10, taskFinish: 8, show: false },
{ id: '6', name: '精英分销员', level: 6, percent1: 18.00, percent2: 9.00, taskTotal: 4, taskFinish: 4, show: true },
{ id: '7', name: '超级分销员', level: 7, percent1: 35.00, percent2: 18.00, taskTotal: 12, taskFinish: 10, show: true },
{ id: '8', name: '黄金分销员', level: 8, percent1: 22.00, percent2: 11.00, taskTotal: 6, taskFinish: 5, show: true },
{ id: '9', name: '白银分销员', level: 9, percent1: 12.00, percent2: 6.00, taskTotal: 3, taskFinish: 1, show: false },
{ id: '10', name: '青铜分销员', level: 10, percent1: 8.00, percent2: 4.00, taskTotal: 2, taskFinish: 0, show: true },
{ id: '11', name: '新人分销员', level: 11, percent1: 5.00, percent2: 2.00, taskTotal: 1, taskFinish: 0, show: true },
{ id: '12', name: 'VIP分销员', level: 12, percent1: 28.00, percent2: 14.00, taskTotal: 7, taskFinish: 7, show: true },
{ id: '13', name: '明星分销员', level: 13, percent1: 32.00, percent2: 16.00, taskTotal: 9, taskFinish: 8, show: true },
{ id: '14', name: '王者分销员', level: 14, percent1: 40.00, percent2: 20.00, taskTotal: 15, taskFinish: 12, show: false },
{ id: '15', name: '传奇分销员', level: 15, percent1: 45.00, percent2: 22.00, taskTotal: 20, taskFinish: 18, show: true },
{ id: '16', name: '荣耀分销员', level: 16, percent1: 38.00, percent2: 19.00, taskTotal: 11, taskFinish: 9, show: true },
{ id: '17', name: '至尊分销员', level: 17, percent1: 42.00, percent2: 21.00, taskTotal: 14, taskFinish: 11, show: true },
{ id: '18', name: '神话分销员', level: 18, percent1: 48.00, percent2: 24.00, taskTotal: 18, taskFinish: 15, show: false },
{ id: '19', name: '无双分销员', level: 19, percent1: 50.00, percent2: 25.00, taskTotal: 20, taskFinish: 20, show: true },
{ id: '20', name: '巅峰分销员', level: 20, percent1: 55.00, percent2: 28.00, taskTotal: 25, taskFinish: 22, show: true },
])
// ========== MOCK DATA END ==========
// ========== PAGINATION STATE ==========
const currentPage = ref(1)
const pageSize = ref(15)
const jumpPageInput = ref('')
const pageSizeOptions = [10, 15, 20, 30, 50]
const pageSizeOptionLabels = computed(() => pageSizeOptions.map((n: number) => `${n}条/页`))
const pageSizeIndex = computed(() => { const idx = pageSizeOptions.indexOf(pageSize.value); return idx >= 0 ? idx : 0 })
const total = computed(() => levelList.value.length)
const totalPage = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)))
const pagedList = computed(() => {
const start = (currentPage.value - 1) * pageSize.value
return levelList.value.slice(start, start + pageSize.value)
})
const visiblePages = computed((): number[] => {
const t = totalPage.value; const cur = currentPage.value
if (t <= 7) return Array.from({ length: t }, (_: any, i: number) => i + 1)
if (cur <= 4) return [1, 2, 3, 4, 5, -1, t]
if (cur >= t - 3) return [1, -1, t - 4, t - 3, t - 2, t - 1, t]
return [1, -1, cur - 1, cur, cur + 1, -1, t]
})
const handlePageChange = (p: number) => { currentPage.value = p }
const handlePageSizeChange = (e: any) => {
const idx = Number(e.detail.value)
pageSize.value = pageSizeOptions[idx] ?? pageSizeOptions[0]
currentPage.value = 1
}
const handleJumpPage = () => {
const p = parseInt(jumpPageInput.value)
if (!isNaN(p) && p >= 1 && p <= totalPage.value) currentPage.value = p
}
// ========== END PAGINATION STATE ==========
function onSearch() { uni.showToast({ title: '查询中...', icon: 'none' }) }
function onAdd() { uni.showToast({ title: '添加中...', icon: 'none' }) }
</script>
<style scoped lang="scss">
.admin-page { padding: 0; }
.filter-card { background: #fff; padding: 24px; margin-bottom: 16px; border-radius: 4px; }
.filter-row { display: flex; flex-direction: row; align-items: center; gap: 24px; }
.label { font-size: 14px; color: #333; }
.select-mock { display: flex; flex-direction: row; align-items: center; justify-content: space-between; border: 1px solid #d9d9d9; border-radius: 2px; height: 32px; width: 160px; padding: 0 12px; background: #fff; text { font-size: 14px; color: #666; } .arrow { font-size: 10px; color: #bfbfbf; } }
.filter-input { border: 1px solid #d9d9d9; height: 32px; width: 220px; padding: 0 12px; font-size: 14px; }
.btn { height: 32px; padding: 0 16px; font-size: 14px; border-radius: 2px; border: 1px solid #d9d9d9; background: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.btn.primary { background: #1890ff; border-color: #1890ff; color: #fff; }
.content-card { background: #fff; border-radius: 4px; }
.action-bar { padding: 16px 24px; }
.table-container { padding: 0 24px 24px; }
.table-header { display: flex; flex-direction: row; background: #f8faff; border-bottom: 1px solid #f0f0f0; padding: 12px 0; }
.table-row { display: flex; flex-direction: row; border-bottom: 1px solid #f0f0f0; padding: 12px 0; align-items: center; &:hover { background: #fafafa; } }
.col { padding: 0 8px; display: flex; align-items: center; font-size: 14px; color: #333; }
.col-id { width: 50px; } .col-img { width: 80px; justify-content: center; } .col-name { width: 120px; } .col-level { width: 80px; justify-content: center; } .col-percent { width: 120px; justify-content: center; } .col-stat { width: 100px; justify-content: center; } .col-status { width: 100px; justify-content: center; }
.col-ops { flex: 1; justify-content: flex-end; padding-right: 16px; display: flex; flex-direction: row; }
.table-img { width: 32px; height: 32px; border-radius: 2px; }
.op-link { color: #1890ff; cursor: pointer; }
.op-divider { color: #e8e8e8; margin: 0 8px; }
.pagination { padding: 16px 24px; border-top: 1px solid #f0f0f0; }
.page-info { font-size: 14px; color: #999; }
</style>