Files
medical-mall/pages/mall/consumer/coupons.uvue
2026-06-05 10:34:02 +08:00

1025 lines
25 KiB
Plaintext

<template>
<view class="coupons-page">
<!-- 顶部 Tabs -->
<view class="tab-bar">
<view class="tab-item" :class="[activeStatus == 'unused' ? 'active' : '']" @click="switchStatus('unused')">
<text class="tab-text">待使用 {{ unusedCount }}</text>
<view v-if="activeStatus == 'unused'" class="tab-line"></view>
</view>
<view class="tab-item" :class="[activeStatus == 'used' ? 'active' : '']" @click="switchStatus('used')">
<text class="tab-text">已使用 {{ usedCount }}</text>
<view v-if="activeStatus == 'used'" class="tab-line"></view>
</view>
<view class="tab-item" :class="[activeStatus == 'expired' ? 'active' : '']" @click="switchStatus('expired')">
<text class="tab-text">已过期 {{ expiredCount }}</text>
<view v-if="activeStatus == 'expired'" class="tab-line"></view>
</view>
<view class="tab-manage" @click="toggleManage">
<text class="manage-text">{{ manageMode ? '完成' : '管理' }}</text>
</view>
</view>
<!-- 筛选 tabs -->
<view class="filter-tabs">
<view class="filter-tab" :class="[activeFilterPanel == 'type' ? 'active' : '']" @click="toggleFilterPanel('type')">
<text class="filter-tab-text">类型</text>
<text class="filter-arrow">⌄</text>
</view>
<view class="filter-tab" :class="[activeFilterPanel == 'sort' ? 'active' : '']" @click="toggleFilterPanel('sort')">
<text class="filter-tab-text">优惠力度</text>
<text class="filter-arrow">⌄</text>
</view>
<view class="filter-tab filter-collapse" @click="closeFilterPanel">
<text class="filter-arrow-big">{{ activeFilterPanel != '' ? '⌃' : '⌄' }}</text>
</view>
</view>
<!-- 筛选下拉面板 -->
<view v-if="activeFilterPanel != ''" class="filter-dropdown">
<view v-if="activeFilterPanel == 'type'" class="dropdown-list">
<view class="dropdown-row" :class="[typeFilter == 'all' ? 'selected' : '']" @click="setTypeFilter('all')">
<text class="dropdown-text">全部</text>
<text v-if="typeFilter == 'all'" class="dropdown-check">✓</text>
</view>
<view class="dropdown-row" :class="[typeFilter == 'store' ? 'selected' : '']" @click="setTypeFilter('store')">
<text class="dropdown-text">店铺券</text>
<text v-if="typeFilter == 'store'" class="dropdown-check">✓</text>
</view>
<view class="dropdown-row" :class="[typeFilter == 'product' ? 'selected' : '']" @click="setTypeFilter('product')">
<text class="dropdown-text">商品券</text>
<text v-if="typeFilter == 'product'" class="dropdown-check">✓</text>
</view>
</view>
<view v-if="activeFilterPanel == 'sort'" class="dropdown-list">
<view class="dropdown-row" :class="[sortMode == 'default' ? 'selected' : '']" @click="setSortMode('default')">
<text class="dropdown-text">默认排序</text>
<text v-if="sortMode == 'default'" class="dropdown-check">✓</text>
</view>
<view class="dropdown-row" :class="[sortMode == 'discount_desc' ? 'selected' : '']" @click="setSortMode('discount_desc')">
<text class="dropdown-text">从高到低</text>
<text v-if="sortMode == 'discount_desc'" class="dropdown-check">✓</text>
</view>
<view class="dropdown-row" :class="[sortMode == 'discount_asc' ? 'selected' : '']" @click="setSortMode('discount_asc')">
<text class="dropdown-text">从低到高</text>
<text v-if="sortMode == 'discount_asc'" class="dropdown-check">✓</text>
</view>
</view>
</view>
<view v-if="activeFilterPanel != ''" class="filter-mask" @click="closeFilterPanel"></view>
<!-- 优惠券列表 -->
<scroll-view class="coupon-list" :scroll-y="true" :style="{ paddingBottom: manageMode ? '60px' : '0' }">
<view v-if="loading" class="empty-state">
<text class="empty-text">加载中...</text>
</view>
<view v-else-if="loadError" class="empty-state">
<text class="empty-icon">⚠️</text>
<text class="empty-text">优惠券加载失败</text>
<button class="retry-btn" @click="loadCoupons">重新加载</button>
</view>
<view v-else-if="storeGroups.length == 0" class="empty-state">
<text class="empty-icon">🎫</text>
<text class="empty-text">暂无优惠券</text>
</view>
<view v-else>
<view v-for="group in storeGroups" :key="group.shopId" class="store-group">
<!-- 店铺标题 -->
<view class="store-header">
<view class="store-logo-wrap">
<image v-if="group.shopLogo != ''" class="store-logo" :src="group.shopLogo" mode="aspectFill"></image>
<text v-else class="store-logo-placeholder">🏪</text>
</view>
<text class="store-name">{{ group.shopName }}</text>
</view>
<!-- 该店铺下的优惠券 -->
<view v-for="coupon in group.coupons" :key="coupon.id" class="coupon-card" :class="[coupon.status]">
<!-- 上下圆形凹槽 -->
<view class="coupon-notch coupon-notch-top"></view>
<view class="coupon-notch coupon-notch-bottom"></view>
<!-- 管理模式选择圆点 -->
<view v-if="manageMode" class="select-dot-wrap" @click.stop="toggleSelectCoupon(coupon)">
<view class="select-dot" :class="[coupon.selected ? 'selected' : '']">
<text v-if="coupon.selected" class="check-mark">✓</text>
</view>
</view>
<!-- 左侧金额区 -->
<view class="coupon-left">
<text class="coupon-amount">{{ coupon.displayAmount }}</text>
<text class="coupon-threshold">{{ coupon.thresholdText }}</text>
</view>
<!-- 中间分割线 -->
<view class="coupon-divider">
<view class="coupon-dash"></view>
</view>
<!-- 右侧信息区 -->
<view class="coupon-right">
<view class="coupon-info-top">
<text class="coupon-title">{{ coupon.title }}</text>
<text class="coupon-expiry">{{ coupon.expiryText }}</text>
<text class="coupon-scope">{{ coupon.scopeText }}</text>
</view>
<view class="coupon-info-bottom">
<button
v-if="coupon.status == 'unused' && !manageMode"
class="use-btn"
@click="useCoupon(coupon)"
>去使用</button>
<text v-else-if="coupon.status == 'used'" class="status-text">已使用</text>
<text v-else-if="coupon.status == 'expired'" class="status-text">已过期</text>
<text v-else-if="manageMode" class="status-text">-</text>
</view>
</view>
</view>
</view>
<!-- 底部安全距离 -->
<view class="safe-bottom"></view>
</view>
</scroll-view>
<!-- 底部管理操作栏 -->
<view v-if="manageMode" class="manage-bar">
<view class="manage-left" @click="selectAllCurrent">
<view class="select-dot" :class="[isAllSelected ? 'selected' : '']">
<text v-if="isAllSelected" class="check-mark">✓</text>
</view>
<text class="manage-bar-text">全选</text>
</view>
<text class="manage-count">已选 {{ selectedCount }} 张</text>
<button class="delete-btn" @click="deleteSelectedCoupons">删除</button>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, computed, onMounted } from 'vue'
import supabaseService from '@/utils/supabaseService.uts'
import type { UserCoupon } from '@/utils/supabaseService.uts'
type CouponStatus = string
type CouponScope = string
type SortMode = string
type TypeFilter = string
type Coupon = {
id: string
templateId: string
shopId: string
shopName: string
shopLogo: string
title: string
displayAmount: string
amount: number
discountType: number
discountValue: number
discountSortValue: number
thresholdText: string
scope: CouponScope
scopeText: string
validStartAt: string
expireAt: string
expiryText: string
usedAt: string
receivedAt: string
status: CouponStatus
selected: boolean
}
type CouponStoreGroup = {
shopId: string
shopName: string
shopLogo: string
coupons: Coupon[]
}
const allCoupons = ref<Coupon[]>([])
const loading = ref<boolean>(true)
const loadError = ref<boolean>(false)
const activeStatus = ref<CouponStatus>('unused')
const typeFilter = ref<TypeFilter>('all')
const sortMode = ref<SortMode>('default')
const manageMode = ref<boolean>(false)
const activeFilterPanel = ref<string>('')
const typeFilterOptions = [
{ value: 'all' as TypeFilter, label: '全部' },
{ value: 'store' as TypeFilter, label: '店铺券' },
{ value: 'product' as TypeFilter, label: '商品券' }
]
const sortModeOptions = [
{ value: 'default' as SortMode, label: '默认排序' },
{ value: 'discount_desc' as SortMode, label: '从高到低' },
{ value: 'discount_asc' as SortMode, label: '从低到高' }
]
// 状态数量统计
const unusedCount = computed((): number => {
let count = 0
for (let i = 0; i < allCoupons.value.length; i++) {
if (allCoupons.value[i].status == 'unused') count++
}
return count
})
const usedCount = computed((): number => {
let count = 0
for (let i = 0; i < allCoupons.value.length; i++) {
if (allCoupons.value[i].status == 'used') count++
}
return count
})
const expiredCount = computed((): number => {
let count = 0
for (let i = 0; i < allCoupons.value.length; i++) {
if (allCoupons.value[i].status == 'expired') count++
}
return count
})
// 过滤后的优惠券
const filteredCoupons = computed((): Coupon[] => {
let result: Coupon[] = []
// 按状态过滤
for (let i = 0; i < allCoupons.value.length; i++) {
const c = allCoupons.value[i]
if (c.status == activeStatus.value) {
result.push(c)
}
}
// 按类型过滤
if (typeFilter.value != 'all') {
const filtered: Coupon[] = []
for (let i = 0; i < result.length; i++) {
if (result[i].scope == typeFilter.value) {
filtered.push(result[i])
}
}
result = filtered
}
// 排序
if (sortMode.value == 'discount_desc') {
result.sort((a: Coupon, b: Coupon) => {
return b.discountSortValue - a.discountSortValue
})
} else if (sortMode.value == 'discount_asc') {
result.sort((a: Coupon, b: Coupon) => {
return a.discountSortValue - b.discountSortValue
})
} else {
// 默认排序规则
if (activeStatus.value == 'unused') {
result.sort((a: Coupon, b: Coupon) => {
if (a.expireAt < b.expireAt) return -1
if (a.expireAt > b.expireAt) return 1
if (a.receivedAt > b.receivedAt) return -1
if (a.receivedAt < b.receivedAt) return 1
return 0
})
} else if (activeStatus.value == 'used') {
result.sort((a: Coupon, b: Coupon) => {
if (a.usedAt > b.usedAt) return -1
if (a.usedAt < b.usedAt) return 1
return 0
})
} else if (activeStatus.value == 'expired') {
result.sort((a: Coupon, b: Coupon) => {
if (a.expireAt > b.expireAt) return -1
if (a.expireAt < b.expireAt) return 1
return 0
})
}
}
return result
})
// 按店铺分组
const storeGroups = computed((): CouponStoreGroup[] => {
const groups: CouponStoreGroup[] = []
const coupons = filteredCoupons.value
for (let i = 0; i < coupons.length; i++) {
const c = coupons[i]
let found = false
for (let j = 0; j < groups.length; j++) {
if (groups[j].shopId == c.shopId) {
groups[j].coupons.push(c)
found = true
break
}
}
if (!found) {
groups.push({
shopId: c.shopId,
shopName: c.shopName,
shopLogo: c.shopLogo,
coupons: [c]
})
}
}
return groups
})
// 管理模式:已选数量
const selectedCount = computed((): number => {
let count = 0
for (let i = 0; i < allCoupons.value.length; i++) {
if (allCoupons.value[i].selected) count++
}
return count
})
// 管理模式:当前列表是否全选
const isAllSelected = computed((): boolean => {
const current = filteredCoupons.value
if (current.length == 0) return false
for (let i = 0; i < current.length; i++) {
if (!current[i].selected) return false
}
return true
})
// 将后端 UserCoupon 映射为前端 Coupon
function mapUserCouponToCoupon(item: UserCoupon): Coupon {
const discountType = item.discount_type
const amountVal = item.amount
let displayAmount = ''
let discountSortValue = 0
if (discountType == 2) {
displayAmount = Math.round(amountVal * 100) / 10 + '折'
discountSortValue = 10 - amountVal
} else {
displayAmount = '¥' + amountVal.toString()
discountSortValue = amountVal
}
const thresholdText = item.min_spend > 0
? '满' + item.min_spend.toString() + '元可用'
: '无门槛'
const scope = item.scope_type == 'product' ? 'product' : 'store'
const scopeText = scope == 'product' ? '限该店铺内指定商品可用' : '限该店铺内全部商品可用'
let status: CouponStatus = 'unused'
if (item.status == 2) {
status = 'used'
} else if (item.status == 3) {
status = 'expired'
}
let expiryText = '长期有效'
if (item.expire_at != '' && item.expire_at != null) {
const tIndex = item.expire_at.indexOf('T')
if (tIndex > 0) {
const datePart = item.expire_at.substring(0, tIndex)
const timePart = item.expire_at.substring(tIndex + 1, tIndex + 6)
expiryText = datePart + ' ' + timePart + ' 到期'
} else {
expiryText = item.expire_at + ' 到期'
}
}
return {
id: item.id,
templateId: item.template_id,
shopId: item.merchant_id != '' ? item.merchant_id : 'platform',
shopName: item.shop_name != '' ? item.shop_name : (item.merchant_id != '' ? '未知店铺' : '平台优惠券'),
shopLogo: item.shop_logo,
title: item.template_name != '' ? item.template_name : '优惠券',
displayAmount: displayAmount,
amount: amountVal,
discountType: discountType,
discountValue: amountVal,
discountSortValue: discountSortValue,
thresholdText: thresholdText,
scope: scope,
scopeText: scopeText,
validStartAt: item.received_at,
expireAt: item.expire_at,
expiryText: expiryText,
usedAt: item.used_at,
receivedAt: item.received_at,
status: status,
selected: false
}
}
const loadCoupons = async () => {
loading.value = true
loadError.value = false
try {
// 不传 status 参数,查询该用户所有优惠券
const userCoupons = await supabaseService.getUserCoupons()
const couponList: Coupon[] = []
for (let i = 0; i < userCoupons.length; i++) {
const item = userCoupons[i]
// 兼容:过滤掉 consumer_deleted_at 不为空的记录(后端补充该字段后生效)
if (item.consumer_deleted_at != null && item.consumer_deleted_at != '') {
continue
}
const coupon = mapUserCouponToCoupon(item)
couponList.push(coupon)
}
allCoupons.value = couponList
} catch (e) {
console.error('加载优惠券失败', e)
loadError.value = true
allCoupons.value = [] as Coupon[]
uni.showToast({
title: '优惠券加载失败,请稍后重试',
icon: 'none'
})
} finally {
loading.value = false
}
}
onMounted(() => {
loadCoupons()
})
const switchStatus = (status: CouponStatus) => {
activeStatus.value = status
activeFilterPanel.value = ''
// 切换 tab 时取消管理模式,避免误操作
if (manageMode.value) {
manageMode.value = false
clearSelection()
}
}
const toggleFilterPanel = (panel: string) => {
if (activeFilterPanel.value == panel) {
activeFilterPanel.value = ''
} else {
activeFilterPanel.value = panel
}
}
const closeFilterPanel = () => {
activeFilterPanel.value = ''
}
const setTypeFilter = (value: TypeFilter) => {
typeFilter.value = value
activeFilterPanel.value = ''
}
const setSortMode = (value: SortMode) => {
sortMode.value = value
activeFilterPanel.value = ''
}
const toggleManage = () => {
manageMode.value = !manageMode.value
if (!manageMode.value) {
clearSelection()
}
}
const clearSelection = () => {
for (let i = 0; i < allCoupons.value.length; i++) {
allCoupons.value[i].selected = false
}
}
const toggleSelectCoupon = (coupon: Coupon) => {
coupon.selected = !coupon.selected
}
const selectAllCurrent = () => {
const current = filteredCoupons.value
const allSelected = isAllSelected.value
for (let i = 0; i < current.length; i++) {
current[i].selected = !allSelected
}
}
const deleteSelectedCoupons = () => {
const ids: string[] = []
for (let i = 0; i < allCoupons.value.length; i++) {
if (allCoupons.value[i].selected) {
ids.push(allCoupons.value[i].id)
}
}
if (ids.length == 0) {
uni.showToast({ title: '请先选择优惠券', icon: 'none' })
return
}
uni.showModal({
title: '提示',
content: '确定删除选中的 ' + ids.length.toString() + ' 张优惠券吗?删除后前端不再展示,但后台仍保留记录。',
success: (res) => {
if (res.confirm) {
doDelete(ids)
}
}
})
}
const doDelete = async (ids: string[]) => {
const success = await supabaseService.softDeleteUserCoupons(ids)
if (success) {
const remaining: Coupon[] = []
for (let i = 0; i < allCoupons.value.length; i++) {
if (!allCoupons.value[i].selected) {
remaining.push(allCoupons.value[i])
}
}
allCoupons.value = remaining
manageMode.value = false
uni.showToast({ title: '已删除', icon: 'success' })
} else {
uni.showToast({ title: '删除失败,请稍后重试', icon: 'none' })
}
}
const useCoupon = (coupon: Coupon) => {
if (manageMode.value) return
if (coupon.status != 'unused') return
// TODO: 根据优惠券类型和店铺跳转到对应页面
// 如果 coupon.scope == 'product' 且有具体商品,可跳转到商品详情
// 如果 coupon.shopId != 'platform',可跳转到店铺页
// 暂时保留首页跳转作为兜底
uni.switchTab({
url: '/pages/main/index'
})
}
</script>
<style>
.coupons-page {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #fefefe;
display: flex;
flex-direction: column;
}
/* 顶部 Tabs */
.tab-bar {
display: flex;
flex-direction: row;
align-items: center;
background-color: #ffffff;
padding: 0 12px;
border-bottom: 1px solid #eeeeee;
}
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 12px 0;
position: relative;
}
.tab-text {
font-size: 14px;
color: #666666;
}
.tab-item.active .tab-text {
color: #ff2b2b;
font-weight: bold;
}
.tab-line {
position: absolute;
bottom: 0;
width: 40px;
height: 3px;
background-color: #ff2b2b;
border-radius: 2px;
}
.tab-manage {
padding: 12px 8px;
}
.manage-text {
font-size: 14px;
color: #666666;
}
/* 筛选 tabs */
.filter-tabs {
display: flex;
flex-direction: row;
align-items: center;
height: 44px;
background-color: #ffffff;
border-bottom: 1px solid #eeeeee;
position: relative;
z-index: 20;
}
.filter-tab {
flex: 1;
height: 44px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.filter-tab-text {
font-size: 13px;
color: #666666;
}
.filter-arrow {
font-size: 10px;
color: #999999;
margin-left: 4px;
}
.filter-tab.active .filter-tab-text,
.filter-tab.active .filter-arrow {
color: #ff2b2b;
font-weight: 600;
}
.filter-collapse {
flex: 0 0 48px;
border-left: 1px solid #eeeeee;
}
.filter-arrow-big {
font-size: 16px;
color: #999999;
}
/* 筛选下拉面板 */
.filter-dropdown {
position: relative;
z-index: 30;
background-color: #ffffff;
border-bottom: 1px solid #eeeeee;
}
.dropdown-list {
background-color: #ffffff;
}
.dropdown-row {
height: 44px;
padding: 0 20px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #f1f1f1;
}
.dropdown-text {
font-size: 14px;
color: #333333;
}
.dropdown-row.selected .dropdown-text {
color: #ff2b2b;
font-weight: 600;
}
.dropdown-check {
font-size: 16px;
color: #ff2b2b;
}
/* 遮罩 */
.filter-mask {
position: fixed;
left: 0;
right: 0;
top: 132px;
bottom: 0;
background-color: rgba(0, 0, 0, 0.35);
z-index: 10;
}
/* 优惠券列表 */
.coupon-list {
flex: 1;
min-height: 0;
width: 100%;
padding: 0 24rpx;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-top: 100px;
}
.empty-icon {
font-size: 60px;
margin-bottom: 20px;
}
.empty-text {
font-size: 16px;
color: #999999;
margin-bottom: 15px;
}
.retry-btn {
font-size: 14px;
background-color: #FF5722;
color: white;
padding: 6px 16px;
border-radius: 15px;
line-height: 1.5;
}
/* 店铺分组 */
.store-group {
margin-top: 16px;
}
.store-header {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 10px;
}
.store-logo-wrap {
width: 24px;
height: 24px;
border-radius: 12px;
background-color: #eeeeee;
display: flex;
align-items: center;
justify-content: center;
margin-right: 8px;
overflow: hidden;
}
.store-logo {
width: 24px;
height: 24px;
border-radius: 12px;
}
.store-logo-placeholder {
font-size: 14px;
}
.store-name {
font-size: 14px;
color: #333333;
font-weight: bold;
}
/* 优惠券卡片 */
.coupon-card {
display: flex;
flex-direction: row;
height: 220rpx;
border-radius: 20rpx;
overflow: hidden;
background-color: #fef0f3;
margin-bottom: 20rpx;
position: relative;
}
.coupon-card.used,
.coupon-card.expired {
opacity: 0.6;
}
.coupon-card.used .coupon-left,
.coupon-card.expired .coupon-left {
background-color: #f0f0f0;
}
.coupon-card.used .coupon-right,
.coupon-card.expired .coupon-right {
background-color: #f0f0f0;
}
/* 管理模式选择圆点 */
.select-dot-wrap {
position: absolute;
top: 16rpx;
left: 16rpx;
z-index: 2;
padding: 4rpx;
}
.select-dot {
width: 20px;
height: 20px;
border-radius: 10px;
border: 2px solid #cccccc;
background-color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
.select-dot.selected {
border-color: #ff2b2b;
background-color: #ff2b2b;
}
.check-mark {
font-size: 12px;
color: #ffffff;
}
/* 左侧金额区 */
.coupon-left {
width: 210rpx;
background-color: #fef0f3;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 16rpx;
}
.coupon-amount {
font-size: 28px;
font-weight: bold;
color: #ff2b2b;
}
.coupon-threshold {
font-size: 12px;
color: #ff3b30;
margin-top: 8rpx;
}
/* 中间分割线 */
.coupon-divider {
width: 2rpx;
height: 100%;
background-color: #fef0f3;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.coupon-dash {
width: 0;
height: 180rpx;
border-left: 3rpx dashed #f28fa1;
}
/* 上下圆形凹槽 */
.coupon-notch {
position: absolute;
width: 34rpx;
height: 34rpx;
border-radius: 50%;
background-color: #fefefe;
left: 193rpx;
z-index: 5;
}
.coupon-notch-top {
top: -17rpx;
}
.coupon-notch-bottom {
bottom: -17rpx;
}
/* 右侧信息区 */
.coupon-right {
flex: 1;
background-color: #fef0f3;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 28rpx 24rpx;
}
.coupon-info-top {
display: flex;
flex-direction: column;
flex: 1;
}
.coupon-title {
font-size: 15px;
font-weight: bold;
color: #333333;
margin-bottom: 8rpx;
}
.coupon-expiry {
font-size: 11px;
color: #999999;
margin-bottom: 4rpx;
}
.coupon-scope {
font-size: 11px;
color: #ff6666;
}
.coupon-info-bottom {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
margin-left: 12rpx;
}
.use-btn {
font-size: 12px;
background-color: #ff2b2b;
color: #ffffff;
padding: 6px 14px;
border-radius: 12px;
line-height: 1.5;
}
.status-text {
font-size: 12px;
color: #999999;
}
/* 底部安全距离 */
.safe-bottom {
height: 20px;
}
/* 底部管理操作栏 */
.manage-bar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: 52px;
background-color: #ffffff;
border-top: 1px solid #eeeeee;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0 16px;
}
.manage-left {
display: flex;
flex-direction: row;
align-items: center;
}
.manage-bar-text {
font-size: 14px;
color: #666666;
margin-left: 8px;
}
.manage-count {
font-size: 14px;
color: #333333;
}
.delete-btn {
font-size: 14px;
background-color: #ff2b2b;
color: #ffffff;
padding: 5px 16px;
border-radius: 16px;
line-height: 1.5;
}
</style>