Files
medical-mall/pages/mall/admin/user/list.uvue
2026-02-02 21:45:59 +08:00

436 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="user-list-page">
<!-- 筛选面板 -->
<view class="filter-card">
<view class="filter-row">
<view class="filter-item">
<text class="label">用户搜索:</text>
<view class="input-group">
<view class="compact-select">
<text>请选择</text>
<text class="arrow">▼</text>
</view>
<input class="filter-input" placeholder="请输入用户" />
</view>
</view>
<view class="filter-item">
<text class="label">用户等级:</text>
<view class="filter-select">
<text class="select-placeholder">请选择用户等级</text>
<text class="arrow">▼</text>
</view>
</view>
<view class="filter-item">
<text class="label">用户分组:</text>
<view class="filter-select">
<text class="select-placeholder">请选择用户分组</text>
<text class="arrow">▼</text>
</view>
</view>
<view class="filter-btns">
<button class="btn primary" @click="onSearch">搜索</button>
<button class="btn" @click="onReset">重置</button>
<text class="expand-btn">展开 </text>
</view>
</view>
</view>
<!-- 内容卡片 -->
<view class="content-card">
<!-- 平台切换 Tabs -->
<view class="tabs-row">
<view
v-for="(tab, index) in tabs"
:key="index"
class="tab-item"
:class="{ active: activeTab === index }"
@click="activeTab = index"
>
<text>{{ tab }}</text>
</view>
</view>
<!-- 操作按钮行 -->
<view class="action-bar">
<button class="btn primary small" @click="onAddUser">添加用户</button>
<button class="btn ghost small">发送优惠券</button>
<button class="btn ghost small">发送图文消息</button>
<button class="btn ghost small">批量设置分组</button>
<button class="btn ghost small">批量设置标签</button>
<button class="btn ghost small">导出</button>
</view>
<!-- 用户列表表格 -->
<view class="table-container">
<!-- 表头 -->
<view class="table-header">
<view class="col col-check"><checkbox :checked="isAllChecked" /></view>
<view class="col col-expand"></view>
<view class="col col-id"><text>用户ID</text></view>
<view class="col col-avatar"><text>头像</text></view>
<view class="col col-name"><text>姓名</text></view>
<view class="col col-member"><text>付费会员</text></view>
<view class="col col-level"><text>用户等级</text></view>
<view class="col col-group"><text>分组</text></view>
<view class="col col-spread"><text>分销等级</text></view>
<view class="col col-phone"><text>手机号</text></view>
<view class="col col-type"><text>用户类型</text></view>
<view class="col col-balance sortable">
<text>余额</text>
<text class="sort-icon">↕</text>
</view>
<view class="col col-ops"><text>操作</text></view>
</view>
<!-- 表格内容 -->
<view class="table-body">
<view v-for="user in userList" :key="user.id" class="table-row">
<view class="col col-check"><checkbox :checked="user.checked" /></view>
<view class="col col-expand"><text class="expand-arrow"></text></view>
<view class="col col-id"><text>{{ user.id }}</text></view>
<view class="col col-avatar">
<image class="avatar-img" :src="user.avatar" mode="aspectFill" />
</view>
<view class="col col-name">
<text class="name-text">{{ user.nickname }}</text>
</view>
<view class="col col-member">
<text :class="user.isMember === '是' ? 'status-yes' : 'status-no'">{{ user.isMember }}</text>
</view>
<view class="col col-level"><text>{{ user.level }}</text></view>
<view class="col col-group"><text>{{ user.group }}</text></view>
<view class="col col-spread"><text>{{ user.spreadLevel }}</text></view>
<view class="col col-phone"><text>{{ user.phone }}</text></view>
<view class="col col-type"><text>{{ user.userType }}</text></view>
<view class="col col-balance"><text>{{ user.balance }}</text></view>
<view class="col col-ops">
<text class="op-link" @click="onDetail(user)">详情</text>
<view class="op-divider"></view>
<text class="op-link more">更多 ⌵</text>
</view>
</view>
</view>
</view>
<!-- 分页区域 (模拟) -->
<view class="pagination">
<text class="page-info">共 80834 条数据</text>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref } from 'vue'
const activeTab = ref(0)
const tabs = ['全部', '微信公众号', '微信小程序', 'H5', 'PC', 'APP']
const isAllChecked = ref(false)
const userList = ref([
{ id: '77414', avatar: 'https://img.crmeb.com/crmeb_demo/77414.png', nickname: '199****0268', isMember: '否', level: '无', group: '无', spreadLevel: '', phone: '199****0268', userType: '公众号', balance: '88888.00', checked: false },
{ id: '75311', avatar: 'https://img.crmeb.com/crmeb_demo/75311.png', nickname: 'wljbhg', isMember: '否', level: '无', group: 'A类客户', spreadLevel: '', phone: '', userType: '公众号', balance: '100002.00', checked: false },
{ id: '75305', avatar: 'https://img.crmeb.com/crmeb_demo/75305.png', nickname: '相见欢', isMember: '否', level: '无', group: 'A类客户', spreadLevel: '', phone: '', userType: '公众号', balance: '100000.00', checked: false },
{ id: '75296', avatar: 'https://img.crmeb.com/crmeb_demo/75296.png', nickname: '..', isMember: '否', level: '无', group: 'A类客户', spreadLevel: '', phone: '', userType: '公众号', balance: '100000.00', checked: false },
{ id: '75293', avatar: 'https://img.crmeb.com/crmeb_demo/75293.png', nickname: '钟(钏)华', isMember: '否', level: '无', group: 'A类客户', spreadLevel: '', phone: '', userType: '公众号', balance: '100000.00', checked: false },
{ id: '75289', avatar: 'https://img.crmeb.com/crmeb_demo/75289.png', nickname: '小二上酒', isMember: '否', level: '无', group: 'A类客户', spreadLevel: '', phone: '', userType: '公众号', balance: '100000.00', checked: false },
{ id: '75257', avatar: 'https://img.crmeb.com/crmeb_demo/75257.png', nickname: '5+7', isMember: '是', level: '无', group: 'A类客户', spreadLevel: '', phone: '', userType: '公众号', balance: '100000.00', checked: false },
{ id: '75226', avatar: 'https://img.crmeb.com/crmeb_demo/75226.png', nickname: '慢步前行', isMember: '是', level: '无', group: 'A类客户', spreadLevel: '', phone: '', userType: '公众号', balance: '100000.00', checked: false },
{ id: '75211', avatar: 'https://img.crmeb.com/crmeb_demo/75211.png', nickname: '难得糊涂', isMember: '否', level: '无', group: 'A类客户', spreadLevel: '', phone: '', userType: '公众号', balance: '100000.00', checked: false }
])
function onSearch() {
uni.showToast({ title: '搜索中...', icon: 'none' })
}
function onReset() {
uni.showToast({ title: '已重置', icon: 'none' })
}
function onAddUser() {
uni.showToast({ title: '添加用户', icon: 'none' })
}
function onDetail(user: any) {
uni.showToast({ title: '查看用户: ' + user.id, icon: 'none' })
}
</script>
<style scoped lang="scss">
.user-list-page {
padding: 16px;
background-color: #f0f2f5;
min-height: 100vh;
}
/* 筛选卡片 */
.filter-card {
background: #fff;
border-radius: 4px;
padding: 24px;
margin-bottom: 16px;
}
.filter-row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
gap: 24px;
}
.filter-item {
display: flex;
flex-direction: row;
align-items: center;
}
.label {
font-size: 14px;
color: #333;
width: 70px;
}
.input-group {
display: flex;
flex-direction: row;
border: 1px solid #d9d9d9;
border-radius: 2px;
height: 32px;
width: 260px;
}
.compact-select {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 12px;
border-right: 1px solid #d9d9d9;
background: #fafafa;
text { font-size: 14px; color: #666; }
.arrow { font-size: 10px; margin-left: 4px; color: #bfbfbf; }
}
.filter-input {
flex: 1;
height: 30px;
padding: 0 12px;
font-size: 14px;
}
.filter-select {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
border: 1px solid #d9d9d9;
border-radius: 2px;
height: 32px;
width: 220px;
padding: 0 12px;
background: #fff;
}
.select-placeholder { font-size: 14px; color: #bfbfbf; }
.arrow { font-size: 10px; color: #bfbfbf; }
.filter-btns {
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
}
.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;
margin: 0;
}
.btn.primary {
background: #2f54eb;
border-color: #2f54eb;
color: #fff;
}
.btn.ghost {
color: #2f54eb;
border-color: #2f54eb;
background: #fff;
}
.btn.small {
height: 28px;
padding: 0 12px;
font-size: 13px;
}
.expand-btn {
font-size: 14px;
color: #2f54eb;
cursor: pointer;
}
/* 内容卡片 */
.content-card {
background: #fff;
border-radius: 4px;
padding: 0;
overflow: hidden;
}
/* Tabs */
.tabs-row {
display: flex;
flex-direction: row;
padding: 0 24px;
border-bottom: 1px solid #f0f0f0;
}
.tab-item {
padding: 16px 20px;
cursor: pointer;
position: relative;
text { font-size: 15px; color: #666; }
&.active {
text { color: #2f54eb; font-weight: 500; }
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2px;
background: #2f54eb;
}
}
}
/* 操作栏 */
.action-bar {
padding: 16px 24px;
display: flex;
flex-direction: row;
gap: 12px;
}
/* 表格 */
.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: 16px 0;
align-items: center;
&:hover {
background: #fafafa;
}
}
.col {
padding: 0 8px;
display: flex;
align-items: center;
font-size: 14px;
color: #333;
}
.col-check { width: 40px; justify-content: center; }
.col-expand { width: 30px; justify-content: center; }
.col-id { width: 80px; }
.col-avatar { width: 80px; justify-content: center; }
.col-name { width: 140px; }
.col-member { width: 90px; justify-content: center; }
.col-level { width: 90px; justify-content: center; }
.col-group { width: 110px; justify-content: center; }
.col-spread { width: 110px; justify-content: center; }
.col-phone { width: 130px; }
.col-type { width: 90px; }
.col-balance { width: 110px; }
.col-ops { flex: 1; min-width: 120px; justify-content: flex-end; padding-right: 16px; }
.table-header .col {
color: #5c5c5c;
font-weight: 500;
}
.sort-icon {
font-size: 12px;
margin-left: 4px;
color: #bfbfbf;
}
.expand-arrow {
color: #bfbfbf;
font-size: 18px;
}
.avatar-img {
width: 40px;
height: 40px;
border-radius: 4px;
background: #f5f5f5;
}
.name-text {
font-weight: 400;
}
.status-yes { color: #52c41a; }
.status-no { color: #ff4d4f; }
.op-link {
color: #2f54eb;
cursor: pointer;
font-size: 14px;
&.more {
margin-left: 4px;
}
}
.op-divider {
width: 1px;
height: 14px;
background: #e8e8e8;
margin: 0 8px;
}
.pagination {
padding: 16px 24px;
border-top: 1px solid #f0f0f0;
display: flex;
flex-direction: row;
justify-content: flex-start;
}
.page-info {
font-size: 14px;
color: #999;
}
</style>