1轮修复
This commit is contained in:
@@ -2,34 +2,53 @@
|
||||
<!-- #ifdef APP -->
|
||||
<scroll-view style="flex:1">
|
||||
<!-- #endif -->
|
||||
<view class="page">
|
||||
<!-- 自定义导航栏 -->
|
||||
<view class="nav" :style="{ paddingTop: headerPaddingTop + 'px', height: headerTotalHeight + 'px' }">
|
||||
<view class="nav-back" @tap="goBack">
|
||||
<view class="nav-back-icon"></view>
|
||||
<view class="page">
|
||||
<!-- 自定义导航栏 -->
|
||||
<view class="nav" :style="{ paddingTop: headerPaddingTop + 'px', height: headerTotalHeight + 'px' }">
|
||||
<view class="nav-back" @tap="goBack">
|
||||
<view class="nav-back-icon"></view>
|
||||
</view>
|
||||
<text class="nav-title">我的工单</text>
|
||||
<view class="nav-capsule"></view>
|
||||
</view>
|
||||
<text class="nav-title">我的工单</text>
|
||||
<view class="nav-capsule"></view>
|
||||
</view>
|
||||
|
||||
<!-- Tab切换 -->
|
||||
<view class="tabs" :style="{ marginTop: headerTotalHeight + 'px' }">
|
||||
<view class="tab-item" :class="{ active: activeTab === 'all' }" @tap="changeTab('all')">
|
||||
<text class="tab-text">全部</text>
|
||||
<!-- Tab切换 -->
|
||||
<view class="tabs" :style="{ marginTop: headerTotalHeight + 'px' }">
|
||||
<view class="tab-item" :class="{ active: activeTab === 'all' }" @tap="changeTab('all')">
|
||||
<text class="tab-text">全部</text>
|
||||
</view>
|
||||
<view class="tab-item" :class="{ active: activeTab === 'pending' }" @tap="changeTab('pending')">
|
||||
<text class="tab-text">待处理</text>
|
||||
</view>
|
||||
<view class="tab-item" :class="{ active: activeTab === 'processing' }" @tap="changeTab('processing')">
|
||||
<text class="tab-text">处理中</text>
|
||||
</view>
|
||||
<view class="tab-item" :class="{ active: activeTab === 'done' }" @tap="changeTab('done')">
|
||||
<text class="tab-text">已完成</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tab-item" :class="{ active: activeTab === 'pending' }" @tap="changeTab('pending')">
|
||||
<text class="tab-text">待处理</text>
|
||||
<!-- 用户筛选组件(仅非guest用户可见) -->
|
||||
<view class="filter-section" v-if="!isGuest" :style="{ marginTop: headerTotalHeight + 44 + 'px' }">
|
||||
<view class="filter-label">选择用户:</view>
|
||||
<view class="filter-content">
|
||||
<view class="guest-selector" @tap="showGuestSelector = true">
|
||||
<text v-if="selectedGuestId" class="selected-guest">
|
||||
{{ guestsList.find(g => g.userId === selectedGuestId)?.name || '请选择用户' }}
|
||||
</text>
|
||||
<text v-else class="placeholder">请选择用户</text>
|
||||
<view class="selector-arrow">▼</view>
|
||||
</view>
|
||||
<view class="btn-group">
|
||||
<view class="reset-btn" @tap="clearGuestSelect">重置</view>
|
||||
<view class="query-btn" @tap="handleQuery">查询</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tab-item" :class="{ active: activeTab === 'processing' }" @tap="changeTab('processing')">
|
||||
<text class="tab-text">处理中</text>
|
||||
</view>
|
||||
<view class="tab-item" :class="{ active: activeTab === 'done' }" @tap="changeTab('done')">
|
||||
<text class="tab-text">已完成</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 工单列表 -->
|
||||
<scroll-view class="list" scroll-y="true">
|
||||
<!-- 工单列表 -->
|
||||
<scroll-view class="list" scroll-y="true"
|
||||
:style="{ marginTop: headerTotalHeight + 44 + (isGuest ? 0 : 44) + 'px' }"
|
||||
@scrolltolower="handleScrollToLower">
|
||||
<view class="card" v-for="(item, index) in filteredOrders" :key="index">
|
||||
<view class="card-header">
|
||||
<view class="card-title">
|
||||
@@ -74,128 +93,569 @@
|
||||
<view class="empty-state" v-if="filteredOrders.length === 0">
|
||||
<text class="empty-text">暂无工单数据</text>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多提示 -->
|
||||
<view class="load-more" v-if="loading">
|
||||
<text class="load-text">加载中...</text>
|
||||
</view>
|
||||
<view class="load-more" v-else-if="!hasMore && filteredOrders.length > 0">
|
||||
<text class="load-text">没有更多数据了</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 用户选择弹窗 -->
|
||||
<view class="modal-mask" v-if="showGuestSelector" @tap="showGuestSelector = false"></view>
|
||||
<view class="modal-content" v-if="showGuestSelector">
|
||||
<view class="modal-header">
|
||||
<text class="modal-title">选择用户</text>
|
||||
</view>
|
||||
<view class="modal-body">
|
||||
<view class="guest-item" v-for="guest in guestsList" :key="guest.userId"
|
||||
@tap="handleGuestSelect(guest)">
|
||||
<text class="guest-name">{{ guest.name }} {{ guest.phone || '无电话' }}</text>
|
||||
</view>
|
||||
<view class="empty-item" v-if="guestsList.length === 0">
|
||||
<text>暂无可选用户</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef APP -->
|
||||
</scroll-view>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import type { TbWorkcaseDTO } from '@/types/workcase'
|
||||
import { workcaseAPI } from '@/api/workcase/workcase'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import type { TbWorkcaseDTO, TbGuestDTO, PageRequest, PageParam } from '@/types'
|
||||
import { workcaseAPI } from '@/api/workcase/workcase'
|
||||
import { guestAPI } from '@/api/sys/guest'
|
||||
|
||||
// 响应式数据
|
||||
const headerPaddingTop = ref<number>(44)
|
||||
const headerTotalHeight = ref<number>(88)
|
||||
const activeTab = ref<string>('all')
|
||||
const orders = ref<TbWorkcaseDTO[]>([])
|
||||
const loading = ref<boolean>(false)
|
||||
const error = ref<string>('')
|
||||
// 响应式数据
|
||||
const headerPaddingTop = ref<number>(44)
|
||||
const headerTotalHeight = ref<number>(88)
|
||||
const activeTab = ref<string>('all')
|
||||
const orders = ref<TbWorkcaseDTO[]>([])
|
||||
const loading = ref<boolean>(false)
|
||||
const loadingUsers = ref<boolean>(false)
|
||||
const error = ref<string>('')
|
||||
|
||||
// 计算属性:根据tab筛选工单
|
||||
const filteredOrders = computed(() => {
|
||||
if (activeTab.value === 'all') {
|
||||
// 分页相关
|
||||
const currentPage = ref<number>(1)
|
||||
const pageSize = ref<number>(10)
|
||||
const total = ref<number>(0)
|
||||
const hasMore = ref<boolean>(true)
|
||||
|
||||
// 用户筛选相关
|
||||
const isGuest = ref(true)
|
||||
const guestsList = ref<TbGuestDTO[]>([])
|
||||
const selectedGuestId = ref<string>('')
|
||||
const showGuestSelector = ref<boolean>(false)
|
||||
|
||||
// 计算属性:直接返回分页数据(API已处理筛选)
|
||||
const filteredOrders = computed(() => {
|
||||
return orders.value
|
||||
}
|
||||
return orders.value.filter(o => o.status === activeTab.value)
|
||||
})
|
||||
})
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
const windowInfo = uni.getWindowInfo()
|
||||
const statusBarHeight = windowInfo.statusBarHeight || 44
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
try {
|
||||
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
|
||||
headerPaddingTop.value = menuButtonInfo.top
|
||||
headerTotalHeight.value = menuButtonInfo.bottom + 8
|
||||
} catch (e) {
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
const windowInfo = uni.getWindowInfo()
|
||||
const statusBarHeight = windowInfo.statusBarHeight || 44
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
try {
|
||||
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
|
||||
headerPaddingTop.value = menuButtonInfo.top
|
||||
headerTotalHeight.value = menuButtonInfo.bottom + 8
|
||||
} catch (e) {
|
||||
headerPaddingTop.value = statusBarHeight
|
||||
headerTotalHeight.value = statusBarHeight + 44
|
||||
}
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
headerPaddingTop.value = statusBarHeight
|
||||
headerTotalHeight.value = statusBarHeight + 44
|
||||
}
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
headerPaddingTop.value = statusBarHeight
|
||||
headerTotalHeight.value = statusBarHeight + 44
|
||||
// #endif
|
||||
|
||||
// 调用API获取工单列表
|
||||
loadWorkcaseList()
|
||||
})
|
||||
// #endif
|
||||
|
||||
// 加载工单列表
|
||||
async function loadWorkcaseList() {
|
||||
loading.value = true
|
||||
error.value = ''
|
||||
try {
|
||||
const filter: TbWorkcaseDTO = {}
|
||||
if (activeTab.value !== 'all') {
|
||||
filter.status = activeTab.value as TbWorkcaseDTO['status']
|
||||
// 检查用户类型
|
||||
checkUserType()
|
||||
|
||||
// 调用API获取工单列表
|
||||
loadWorkcaseList()
|
||||
})
|
||||
|
||||
// 检查用户类型
|
||||
function checkUserType() {
|
||||
try {
|
||||
const userInfo = uni.getStorageSync('userInfo')
|
||||
const parsedUserInfo = typeof userInfo === 'string' ? JSON.parse(userInfo) : userInfo
|
||||
isGuest.value = parsedUserInfo.status === 'guest'
|
||||
|
||||
// 如果是非guest用户,加载可选人员列表
|
||||
if (!isGuest.value) {
|
||||
loadGuestsList()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('检查用户类型失败:', error)
|
||||
isGuest.value = true
|
||||
}
|
||||
const res = await workcaseAPI.getWorkcaseList(filter)
|
||||
if (res.success && res.dataList) {
|
||||
orders.value = res.dataList || []
|
||||
} else {
|
||||
error.value = res.message || '加载失败'
|
||||
}
|
||||
|
||||
// 加载可选人员列表
|
||||
async function loadGuestsList() {
|
||||
loadingUsers.value = true
|
||||
try {
|
||||
const res = await guestAPI.listGuest()
|
||||
if (res.success && res.dataList) {
|
||||
guestsList.value = res.dataList
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载可选人员列表失败:', error)
|
||||
} finally {
|
||||
loadingUsers.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 加载工单列表 - 滚动分页查询
|
||||
async function loadWorkcaseList(isLoadMore = false) {
|
||||
// 如果正在加载或没有更多数据,直接返回
|
||||
if (loading.value || (!isLoadMore && !hasMore.value)) return
|
||||
|
||||
loading.value = true
|
||||
error.value = ''
|
||||
try {
|
||||
const filter: TbWorkcaseDTO = {}
|
||||
if (activeTab.value !== 'all') {
|
||||
filter.status = activeTab.value as TbWorkcaseDTO['status']
|
||||
}
|
||||
|
||||
// 如果是非guest用户且选择了特定用户,添加userId筛选
|
||||
if (!isGuest.value && selectedGuestId.value) {
|
||||
filter.userId = selectedGuestId.value
|
||||
}
|
||||
|
||||
// 计算当前页码
|
||||
const currentPageNum = isLoadMore ? currentPage.value + 1 : 1
|
||||
|
||||
const pageParam: PageParam = {
|
||||
page: currentPageNum,
|
||||
pageSize: pageSize.value
|
||||
}
|
||||
|
||||
const pageRequest: PageRequest<TbWorkcaseDTO> = {
|
||||
filter,
|
||||
pageParam
|
||||
}
|
||||
|
||||
const res = await workcaseAPI.getWorkcasePage(pageRequest)
|
||||
if (res.success) {
|
||||
const newOrders = res.dataList || res.pageDomain?.dataList || []
|
||||
total.value = res.pageDomain?.pageParam?.total || 0
|
||||
|
||||
// 根据是否加载更多来处理数据
|
||||
if (isLoadMore) {
|
||||
// 加载更多:追加数据
|
||||
orders.value = [...orders.value, ...newOrders]
|
||||
currentPage.value++
|
||||
} else {
|
||||
// 刷新:替换数据
|
||||
orders.value = newOrders
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
// 判断是否还有更多数据
|
||||
hasMore.value = orders.value.length < total.value
|
||||
} else {
|
||||
error.value = res.message || '加载失败'
|
||||
uni.showToast({
|
||||
title: res.message || '加载失败',
|
||||
icon: 'error'
|
||||
})
|
||||
// 如果是加载更多失败,保持hasMore不变
|
||||
if (!isLoadMore) {
|
||||
hasMore.value = false
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
error.value = '网络错误,请稍后重试'
|
||||
uni.showToast({
|
||||
title: res.message || '加载失败',
|
||||
title: '网络错误,请稍后重试',
|
||||
icon: 'error'
|
||||
})
|
||||
// 如果是加载更多失败,保持hasMore不变
|
||||
if (!isLoadMore) {
|
||||
hasMore.value = false
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
} catch (e) {
|
||||
error.value = '网络错误,请稍后重试'
|
||||
uni.showToast({
|
||||
title: '网络错误,请稍后重试',
|
||||
icon: 'error'
|
||||
}
|
||||
|
||||
// 处理滚动到底部事件
|
||||
function handleScrollToLower() {
|
||||
if (hasMore.value && !loading.value) {
|
||||
loadWorkcaseList(true)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理用户选择
|
||||
function handleGuestSelect(guest : TbGuestDTO) {
|
||||
selectedGuestId.value = guest.userId || ''
|
||||
showGuestSelector.value = false
|
||||
// 重置分页状态
|
||||
hasMore.value = true
|
||||
loadWorkcaseList() // 根据选中的用户重新加载工单列表
|
||||
}
|
||||
|
||||
// 清除用户选择
|
||||
function clearGuestSelect() {
|
||||
selectedGuestId.value = ''
|
||||
// 重置分页状态
|
||||
hasMore.value = true
|
||||
loadWorkcaseList() // 重新加载所有工单列表
|
||||
}
|
||||
|
||||
// 查询工单列表
|
||||
function handleQuery() {
|
||||
// 重置分页状态
|
||||
hasMore.value = true
|
||||
loadWorkcaseList() // 根据当前筛选条件重新加载工单列表
|
||||
}
|
||||
|
||||
// 切换Tab
|
||||
function changeTab(tab : string) {
|
||||
activeTab.value = tab
|
||||
// 重置分页状态
|
||||
hasMore.value = true
|
||||
loadWorkcaseList()
|
||||
}
|
||||
|
||||
// 获取状态样式类
|
||||
function getStatusClass(status ?: string) : string {
|
||||
switch (status) {
|
||||
case 'pending': return 'status-pending'
|
||||
case 'processing': return 'status-processing'
|
||||
case 'done': return 'status-done'
|
||||
default: return 'status-pending'
|
||||
}
|
||||
}
|
||||
|
||||
// 获取状态文本
|
||||
function getStatusText(status ?: string) : string {
|
||||
switch (status) {
|
||||
case 'pending': return '待处理'
|
||||
case 'processing': return '处理中'
|
||||
case 'done': return '已完成'
|
||||
default: return '未知'
|
||||
}
|
||||
}
|
||||
|
||||
// 返回上一页
|
||||
function goBack() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
// 跳转到工单详情
|
||||
function goDetail(workcaseId ?: string) {
|
||||
if (!workcaseId) return
|
||||
uni.navigateTo({
|
||||
url: `/pages/workcase/workcaseDetail/workcaseDetail?workcaseId=${workcaseId}`
|
||||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 切换Tab
|
||||
function changeTab(tab: string) {
|
||||
activeTab.value = tab
|
||||
loadWorkcaseList()
|
||||
}
|
||||
|
||||
// 获取状态样式类
|
||||
function getStatusClass(status?: string): string {
|
||||
switch (status) {
|
||||
case 'pending': return 'status-pending'
|
||||
case 'processing': return 'status-processing'
|
||||
case 'done': return 'status-done'
|
||||
default: return 'status-pending'
|
||||
}
|
||||
}
|
||||
|
||||
// 获取状态文本
|
||||
function getStatusText(status?: string): string {
|
||||
switch (status) {
|
||||
case 'pending': return '待处理'
|
||||
case 'processing': return '处理中'
|
||||
case 'done': return '已完成'
|
||||
default: return '未知'
|
||||
}
|
||||
}
|
||||
|
||||
// 返回上一页
|
||||
function goBack() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
// 跳转到工单详情
|
||||
function goDetail(workcaseId?: string) {
|
||||
if (!workcaseId) return
|
||||
uni.navigateTo({
|
||||
url: `/pages/workcase/workcaseDetail/workcaseDetail?workcaseId=${workcaseId}`
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "./workcaseList.scss";
|
||||
@import "./workcaseList.scss";
|
||||
|
||||
// 用户筛选组件样式
|
||||
.filter-section {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 44px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 0 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.guest-selector {
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
height: 32px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 16px;
|
||||
padding: 0 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: #f9f9f9;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.guest-selector:active {
|
||||
background: #e9e9e9;
|
||||
border-color: #bbb;
|
||||
}
|
||||
|
||||
.selected-guest {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.selector-arrow {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.filter-section:active .selector-arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* 按钮组样式 */
|
||||
.btn-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.reset-btn,
|
||||
.query-btn {
|
||||
height: 32px;
|
||||
padding: 0 16px;
|
||||
border-radius: 16px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.reset-btn {
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #ddd;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.reset-btn:active {
|
||||
background: #e9e9e9;
|
||||
border-color: #bbb;
|
||||
}
|
||||
|
||||
.query-btn {
|
||||
background: #1989fa;
|
||||
border: 1px solid #1989fa;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.query-btn:active {
|
||||
background: #0066cc;
|
||||
border-color: #0066cc;
|
||||
}
|
||||
|
||||
// 弹窗样式
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1000;
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 80%;
|
||||
max-width: 400px;
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 12px 48px rgba(0, 0, 0, 0.25);
|
||||
z-index: 1001;
|
||||
animation: slideUp 0.3s ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 弹窗动画 */
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -45%);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 18px 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
background: linear-gradient(135deg, #fafafa 0%, #f5f5f5 100%);
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
font-size: 24px;
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.modal-close:active {
|
||||
background: #f0f0f0;
|
||||
color: #666;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
max-height: 350px;
|
||||
overflow-y: auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
.modal-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.modal-body::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.modal-body::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.modal-body::-webkit-scrollbar-thumb:hover {
|
||||
background: #a8a8a8;
|
||||
}
|
||||
|
||||
.guest-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 16px 20px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
|
||||
.guest-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.guest-item:active {
|
||||
background-color: #f8f8f8;
|
||||
transform: translateX(5px);
|
||||
}
|
||||
|
||||
.guest-item:active .guest-name {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.guest-name {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 6px;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.guest-phone {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.guest-phone::before {
|
||||
content: "📞";
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.empty-item {
|
||||
padding: 30px 20px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.empty-item::before {
|
||||
content: "👤";
|
||||
font-size: 48px;
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* 加载更多样式 */
|
||||
.load-more {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
border-top: 1px solid #eee;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.load-text {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user