853 lines
18 KiB
Vue
853 lines
18 KiB
Vue
<template>
|
|
<view class="my-published-container page-container-with-bg">
|
|
<!-- 统计卡片 -->
|
|
<view class="stats-card">
|
|
<view class="stats-grid">
|
|
<view class="stat-item" :class="{ active: currentFilter === 'all' }" @click="setFilter('all')">
|
|
<view class="stat-number">{{ totalCount }}</view>
|
|
<view class="stat-label">全部</view>
|
|
</view>
|
|
<view class="stat-item" :class="{ active: currentFilter === 'active' }" @click="setFilter('active')">
|
|
<view class="stat-number">{{ activeCount }}</view>
|
|
<view class="stat-label">招募中</view>
|
|
</view>
|
|
<view class="stat-item" :class="{ active: currentFilter === 'completed' }" @click="setFilter('completed')">
|
|
<view class="stat-number">{{ completedCount }}</view>
|
|
<view class="stat-label">已完成</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 发布列表 -->
|
|
<view class="published-list" v-if="filteredList.length > 0">
|
|
<view
|
|
class="published-item"
|
|
v-for="item in filteredList"
|
|
:key="item.id"
|
|
@click="viewDetail(item)"
|
|
>
|
|
<view class="item-image">
|
|
<image class="pet-image" :src="item.photos[0] || '/static/default-pet.png'" mode="aspectFill" />
|
|
<view class="status-badge" :class="item.status">
|
|
<text class="status-text">{{ getStatusText(item.status) }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="item-content">
|
|
<view class="item-header">
|
|
<view class="pet-name">{{ item.name }}</view>
|
|
<view class="item-actions" @click.stop="showActions(item)">
|
|
<text class="action-icon">⋯</text>
|
|
</view>
|
|
</view>
|
|
<view class="pet-info">
|
|
<view class="info-row">
|
|
<text class="info-label">品种:</text>
|
|
<text class="info-value">{{ item.breed }}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="info-label">性别:</text>
|
|
<text class="info-value">{{ item.gender }}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="info-label">年龄:</text>
|
|
<text class="info-value">{{ item.age }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="item-stats">
|
|
<view class="stat-group">
|
|
<text class="stat-icon">👁️</text>
|
|
<text class="stat-text">{{ item.viewCount || 0 }} 浏览</text>
|
|
</view>
|
|
<view class="stat-group">
|
|
<text class="stat-icon">📝</text>
|
|
<text class="stat-text">{{ item.applicationCount || 0 }} 申请</text>
|
|
</view>
|
|
<view class="stat-group">
|
|
<text class="stat-icon">🕐</text>
|
|
<text class="stat-text">{{ formatTime(item.publishTime) }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="item-description" v-if="item.description">
|
|
{{ item.description }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 空状态 -->
|
|
<view class="empty-state" v-else>
|
|
<view class="empty-icon">📝</view>
|
|
<view class="empty-text">{{ getEmptyText() }}</view>
|
|
<view class="empty-action" @click="publishNew" v-if="currentFilter === 'all'">
|
|
<text class="action-text">发布第一个领养信息</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 浮动发布按钮 -->
|
|
<view class="fab-button" @click="publishNew">
|
|
<text class="fab-icon">+</text>
|
|
</view>
|
|
|
|
<!-- 操作菜单 -->
|
|
<u-action-sheet
|
|
:show="showActionSheet"
|
|
:actions="actionList"
|
|
@close="showActionSheet = false"
|
|
@select="onActionSelect"
|
|
></u-action-sheet>
|
|
|
|
<!-- 编辑状态弹窗 -->
|
|
<u-modal
|
|
:show="showStatusModal"
|
|
title="修改状态"
|
|
@confirm="confirmStatusChange"
|
|
@cancel="showStatusModal = false"
|
|
>
|
|
<view class="status-options">
|
|
<view
|
|
class="status-option"
|
|
v-for="status in statusOptions"
|
|
:key="status.value"
|
|
:class="{ active: selectedStatus === status.value }"
|
|
@click="selectStatus(status.value)"
|
|
>
|
|
<view class="option-icon" :class="status.value">
|
|
<text class="icon-text">{{ status.icon }}</text>
|
|
</view>
|
|
<view class="option-info">
|
|
<text class="option-title">{{ status.label }}</text>
|
|
<text class="option-desc">{{ status.desc }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</u-modal>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { reactive, ref, onMounted, computed } from 'vue'
|
|
|
|
export default {
|
|
name: 'MyPublishedPage',
|
|
setup() {
|
|
// 响应式数据
|
|
const publishedList = ref([])
|
|
const currentFilter = ref('all')
|
|
const showActionSheet = ref(false)
|
|
const showStatusModal = ref(false)
|
|
const currentItem = ref(null)
|
|
const selectedStatus = ref('')
|
|
|
|
const actionList = ref([
|
|
{ name: '查看详情', value: 'detail' },
|
|
{ name: '查看申请', value: 'applications' },
|
|
{ name: '编辑信息', value: 'edit' },
|
|
{ name: '修改状态', value: 'status' },
|
|
{ name: '删除', value: 'delete', color: '#FF5722' }
|
|
])
|
|
|
|
const statusOptions = ref([
|
|
{
|
|
value: 'active',
|
|
label: '招募中',
|
|
desc: '正在寻找领养家庭',
|
|
icon: '🟢'
|
|
},
|
|
{
|
|
value: 'paused',
|
|
label: '已暂停',
|
|
desc: '暂时停止接收申请',
|
|
icon: '🟡'
|
|
},
|
|
{
|
|
value: 'completed',
|
|
label: '已完成',
|
|
desc: '已找到合适的领养家庭',
|
|
icon: '🔵'
|
|
},
|
|
{
|
|
value: 'cancelled',
|
|
label: '已取消',
|
|
desc: '取消领养计划',
|
|
icon: '🔴'
|
|
}
|
|
])
|
|
|
|
// 计算属性
|
|
const totalCount = computed(() => publishedList.value.length)
|
|
const activeCount = computed(() => publishedList.value.filter(item => item.status === 'active').length)
|
|
const completedCount = computed(() => publishedList.value.filter(item => item.status === 'completed').length)
|
|
|
|
const filteredList = computed(() => {
|
|
if (currentFilter.value === 'all') {
|
|
return publishedList.value
|
|
}
|
|
return publishedList.value.filter(item => item.status === currentFilter.value)
|
|
})
|
|
|
|
// 生命周期
|
|
onMounted(() => {
|
|
loadPublishedList()
|
|
})
|
|
|
|
// 方法定义
|
|
const loadPublishedList = () => {
|
|
try {
|
|
const savedList = uni.getStorageSync('myPublishedAdoptions') || []
|
|
|
|
// 如果没有数据,创建模拟数据
|
|
if (savedList.length === 0) {
|
|
const mockData = [
|
|
{
|
|
id: 'pub_1',
|
|
name: '小橘',
|
|
breed: '橘猫',
|
|
gender: '公',
|
|
age: '2岁',
|
|
photos: ['/static/mock-cat1.jpg'],
|
|
status: 'active',
|
|
description: '性格温顺,喜欢和人亲近,已绝育,疫苗齐全。',
|
|
publishTime: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
|
|
applicationCount: 3,
|
|
viewCount: 25
|
|
},
|
|
{
|
|
id: 'pub_2',
|
|
name: '小白',
|
|
breed: '英短',
|
|
gender: '母',
|
|
age: '1岁',
|
|
photos: ['/static/mock-cat2.jpg'],
|
|
status: 'completed',
|
|
description: '活泼可爱,适合有经验的铲屎官。',
|
|
publishTime: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
applicationCount: 8,
|
|
viewCount: 45
|
|
}
|
|
]
|
|
|
|
uni.setStorageSync('myPublishedAdoptions', mockData)
|
|
publishedList.value = mockData
|
|
} else {
|
|
publishedList.value = savedList
|
|
}
|
|
} catch (error) {
|
|
console.error('加载发布列表失败:', error)
|
|
}
|
|
}
|
|
|
|
const savePublishedList = () => {
|
|
uni.setStorageSync('myPublishedAdoptions', publishedList.value)
|
|
}
|
|
|
|
const setFilter = (filter) => {
|
|
currentFilter.value = filter
|
|
}
|
|
|
|
const getStatusText = (status) => {
|
|
const statusMap = {
|
|
'active': '招募中',
|
|
'paused': '已暂停',
|
|
'completed': '已完成',
|
|
'cancelled': '已取消'
|
|
}
|
|
return statusMap[status] || '未知'
|
|
}
|
|
|
|
const getEmptyText = () => {
|
|
switch (currentFilter.value) {
|
|
case 'active':
|
|
return '暂无招募中的领养信息'
|
|
case 'completed':
|
|
return '暂无已完成的领养信息'
|
|
default:
|
|
return '还没有发布过领养信息'
|
|
}
|
|
}
|
|
|
|
const formatTime = (timeString) => {
|
|
if (!timeString) return ''
|
|
const date = new Date(timeString)
|
|
const now = new Date()
|
|
const diffTime = now - date
|
|
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24))
|
|
|
|
if (diffDays === 0) {
|
|
return '今天'
|
|
} else if (diffDays === 1) {
|
|
return '昨天'
|
|
} else if (diffDays < 7) {
|
|
return `${diffDays}天前`
|
|
} else {
|
|
return date.toLocaleDateString('zh-CN')
|
|
}
|
|
}
|
|
|
|
const viewDetail = (item) => {
|
|
uni.navigateTo({
|
|
url: `/pages/adoption/adoption-detail?id=${item.id}&from=published`,
|
|
fail: () => {
|
|
uni.showToast({
|
|
title: '页面开发中',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
const showActions = (item) => {
|
|
currentItem.value = item
|
|
showActionSheet.value = true
|
|
}
|
|
|
|
const onActionSelect = (action) => {
|
|
switch (action.value) {
|
|
case 'detail':
|
|
viewDetail(currentItem.value)
|
|
break
|
|
case 'applications':
|
|
viewApplications(currentItem.value)
|
|
break
|
|
case 'edit':
|
|
editItem(currentItem.value)
|
|
break
|
|
case 'status':
|
|
changeStatus(currentItem.value)
|
|
break
|
|
case 'delete':
|
|
deleteItem(currentItem.value)
|
|
break
|
|
}
|
|
showActionSheet.value = false
|
|
}
|
|
|
|
const viewApplications = (item) => {
|
|
uni.navigateTo({
|
|
url: `/pages/adoption/applications?publishId=${item.id}`,
|
|
fail: () => {
|
|
uni.showToast({
|
|
title: '页面开发中',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
const editItem = (item) => {
|
|
uni.navigateTo({
|
|
url: `/pages/adoption/publish?id=${item.id}&mode=edit`,
|
|
fail: () => {
|
|
uni.showToast({
|
|
title: '页面开发中',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
const changeStatus = (item) => {
|
|
currentItem.value = item
|
|
selectedStatus.value = item.status
|
|
showStatusModal.value = true
|
|
}
|
|
|
|
const selectStatus = (status) => {
|
|
selectedStatus.value = status
|
|
}
|
|
|
|
const confirmStatusChange = () => {
|
|
if (currentItem.value && selectedStatus.value !== currentItem.value.status) {
|
|
currentItem.value.status = selectedStatus.value
|
|
savePublishedList()
|
|
|
|
uni.showToast({
|
|
title: '状态已更新',
|
|
icon: 'success'
|
|
})
|
|
}
|
|
showStatusModal.value = false
|
|
}
|
|
|
|
const deleteItem = (item) => {
|
|
uni.showModal({
|
|
title: '确认删除',
|
|
content: '删除后无法恢复,确定要删除这个领养信息吗?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
const index = publishedList.value.findIndex(p => p.id === item.id)
|
|
if (index > -1) {
|
|
publishedList.value.splice(index, 1)
|
|
savePublishedList()
|
|
uni.showToast({
|
|
title: '已删除',
|
|
icon: 'success'
|
|
})
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
const publishNew = () => {
|
|
uni.navigateTo({
|
|
url: '/pages/adoption/publish',
|
|
fail: () => {
|
|
uni.showToast({
|
|
title: '页面开发中',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
return {
|
|
publishedList,
|
|
currentFilter,
|
|
showActionSheet,
|
|
showStatusModal,
|
|
selectedStatus,
|
|
actionList,
|
|
statusOptions,
|
|
totalCount,
|
|
activeCount,
|
|
completedCount,
|
|
filteredList,
|
|
setFilter,
|
|
getStatusText,
|
|
getEmptyText,
|
|
formatTime,
|
|
viewDetail,
|
|
showActions,
|
|
onActionSelect,
|
|
selectStatus,
|
|
confirmStatusChange,
|
|
publishNew
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.my-published-container {
|
|
background: linear-gradient(135deg, #FF8A80 0%, #FFB6C1 25%, #FECFEF 50%, #F8BBD9 100%);
|
|
min-height: 100vh;
|
|
padding-bottom: 120rpx;
|
|
}
|
|
|
|
/* 统计卡片 */
|
|
.stats-card {
|
|
background: rgba(255, 255, 255, 0.95);
|
|
backdrop-filter: blur(20rpx);
|
|
margin: 0 30rpx 24rpx 30rpx;
|
|
border-radius: 24rpx;
|
|
padding: 32rpx;
|
|
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
|
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
|
|
|
.stats-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr 1fr;
|
|
gap: 20rpx;
|
|
|
|
.stat-item {
|
|
text-align: center;
|
|
padding: 24rpx 16rpx;
|
|
border-radius: 16rpx;
|
|
background: rgba(255, 138, 128, 0.05);
|
|
transition: all 0.3s ease;
|
|
cursor: pointer;
|
|
|
|
&.active {
|
|
background: linear-gradient(135deg, #FF8A80, #FFB6C1);
|
|
|
|
.stat-number,
|
|
.stat-label {
|
|
color: white;
|
|
}
|
|
}
|
|
|
|
&:active {
|
|
transform: scale(0.95);
|
|
}
|
|
|
|
.stat-number {
|
|
font-size: 40rpx;
|
|
font-weight: 700;
|
|
color: #FF8A80;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 22rpx;
|
|
color: #666666;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 发布列表 */
|
|
.published-list {
|
|
margin: 0 30rpx;
|
|
|
|
.published-item {
|
|
background: rgba(255, 255, 255, 0.95);
|
|
backdrop-filter: blur(20rpx);
|
|
border-radius: 20rpx;
|
|
padding: 24rpx;
|
|
margin-bottom: 16rpx;
|
|
box-shadow: 0 4rpx 16rpx rgba(255, 138, 128, 0.1);
|
|
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
|
transition: all 0.3s ease;
|
|
|
|
&:active {
|
|
transform: scale(0.98);
|
|
}
|
|
|
|
.item-image {
|
|
position: relative;
|
|
margin-bottom: 16rpx;
|
|
|
|
.pet-image {
|
|
width: 100%;
|
|
height: 300rpx;
|
|
border-radius: 16rpx;
|
|
}
|
|
|
|
.status-badge {
|
|
position: absolute;
|
|
top: 16rpx;
|
|
right: 16rpx;
|
|
padding: 8rpx 16rpx;
|
|
border-radius: 16rpx;
|
|
font-size: 20rpx;
|
|
|
|
&.active {
|
|
background: rgba(76, 175, 80, 0.9);
|
|
color: white;
|
|
}
|
|
|
|
&.paused {
|
|
background: rgba(255, 152, 0, 0.9);
|
|
color: white;
|
|
}
|
|
|
|
&.completed {
|
|
background: rgba(33, 150, 243, 0.9);
|
|
color: white;
|
|
}
|
|
|
|
&.cancelled {
|
|
background: rgba(244, 67, 54, 0.9);
|
|
color: white;
|
|
}
|
|
|
|
.status-text {
|
|
font-size: 20rpx;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
}
|
|
|
|
.item-content {
|
|
.item-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 16rpx;
|
|
|
|
.pet-name {
|
|
font-size: 32rpx;
|
|
font-weight: 700;
|
|
color: #333333;
|
|
}
|
|
|
|
.item-actions {
|
|
padding: 8rpx 12rpx;
|
|
border-radius: 12rpx;
|
|
background: rgba(255, 138, 128, 0.1);
|
|
|
|
.action-icon {
|
|
font-size: 24rpx;
|
|
color: #FF8A80;
|
|
}
|
|
}
|
|
}
|
|
|
|
.pet-info {
|
|
margin-bottom: 16rpx;
|
|
|
|
.info-row {
|
|
display: flex;
|
|
margin-bottom: 8rpx;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.info-label {
|
|
font-size: 24rpx;
|
|
color: #666666;
|
|
width: 80rpx;
|
|
}
|
|
|
|
.info-value {
|
|
font-size: 24rpx;
|
|
color: #333333;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
}
|
|
|
|
.item-stats {
|
|
display: flex;
|
|
gap: 24rpx;
|
|
margin-bottom: 16rpx;
|
|
|
|
.stat-group {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.stat-icon {
|
|
font-size: 20rpx;
|
|
margin-right: 6rpx;
|
|
}
|
|
|
|
.stat-text {
|
|
font-size: 22rpx;
|
|
color: #666666;
|
|
}
|
|
}
|
|
}
|
|
|
|
.item-description {
|
|
font-size: 24rpx;
|
|
color: #666666;
|
|
line-height: 1.6;
|
|
background: rgba(255, 138, 128, 0.05);
|
|
padding: 16rpx;
|
|
border-radius: 12rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 空状态 */
|
|
.empty-state {
|
|
text-align: center;
|
|
padding: 80rpx 40rpx;
|
|
margin: 0 30rpx;
|
|
background: rgba(255, 255, 255, 0.95);
|
|
backdrop-filter: blur(20rpx);
|
|
border-radius: 24rpx;
|
|
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
|
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
|
|
|
.empty-icon {
|
|
font-size: 80rpx;
|
|
margin-bottom: 24rpx;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 28rpx;
|
|
color: #999999;
|
|
margin-bottom: 32rpx;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.empty-action {
|
|
display: inline-block;
|
|
padding: 16rpx 32rpx;
|
|
background: linear-gradient(135deg, #FF8A80, #FFB6C1);
|
|
border-radius: 20rpx;
|
|
|
|
.action-text {
|
|
font-size: 26rpx;
|
|
color: white;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 浮动发布按钮 */
|
|
.fab-button {
|
|
position: fixed;
|
|
bottom: 120rpx;
|
|
right: 40rpx;
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
background: linear-gradient(135deg, #FF8A80, #FFB6C1);
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
box-shadow: 0 8rpx 24rpx rgba(255, 138, 128, 0.4);
|
|
z-index: 100;
|
|
transition: all 0.3s ease;
|
|
|
|
&:active {
|
|
transform: scale(0.9);
|
|
}
|
|
|
|
.fab-icon {
|
|
font-size: 48rpx;
|
|
color: white;
|
|
font-weight: 300;
|
|
}
|
|
}
|
|
|
|
/* 状态选择弹窗 */
|
|
.status-options {
|
|
padding: 20rpx 0;
|
|
|
|
.status-option {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 20rpx;
|
|
margin-bottom: 16rpx;
|
|
border-radius: 16rpx;
|
|
background: rgba(255, 138, 128, 0.05);
|
|
border: 2rpx solid transparent;
|
|
transition: all 0.3s ease;
|
|
|
|
&.active {
|
|
border-color: #FF8A80;
|
|
background: rgba(255, 138, 128, 0.1);
|
|
}
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.option-icon {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 20rpx;
|
|
|
|
&.active {
|
|
background: rgba(76, 175, 80, 0.1);
|
|
}
|
|
|
|
&.paused {
|
|
background: rgba(255, 152, 0, 0.1);
|
|
}
|
|
|
|
&.completed {
|
|
background: rgba(33, 150, 243, 0.1);
|
|
}
|
|
|
|
&.cancelled {
|
|
background: rgba(244, 67, 54, 0.1);
|
|
}
|
|
|
|
.icon-text {
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
|
|
.option-info {
|
|
flex: 1;
|
|
|
|
.option-title {
|
|
display: block;
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
color: #333333;
|
|
margin-bottom: 6rpx;
|
|
}
|
|
|
|
.option-desc {
|
|
font-size: 22rpx;
|
|
color: #666666;
|
|
line-height: 1.4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 响应式设计 */
|
|
@media (max-width: 375px) {
|
|
.my-published-container {
|
|
.stats-card,
|
|
.published-list,
|
|
.empty-state {
|
|
margin-left: 20rpx;
|
|
margin-right: 20rpx;
|
|
}
|
|
|
|
.stats-card {
|
|
padding: 24rpx;
|
|
}
|
|
|
|
.stats-grid {
|
|
gap: 16rpx;
|
|
|
|
.stat-item {
|
|
padding: 20rpx 12rpx;
|
|
|
|
.stat-number {
|
|
font-size: 36rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.published-item {
|
|
padding: 20rpx;
|
|
|
|
.item-image {
|
|
.pet-image {
|
|
height: 250rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.fab-button {
|
|
right: 30rpx;
|
|
bottom: 100rpx;
|
|
width: 80rpx;
|
|
height: 80rpx;
|
|
|
|
.fab-icon {
|
|
font-size: 40rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 动画效果 */
|
|
@keyframes fadeIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(20rpx);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.my-published-container > view {
|
|
animation: fadeIn 0.5s ease-out;
|
|
}
|
|
|
|
.published-item {
|
|
animation: fadeIn 0.3s ease-out;
|
|
}
|
|
|
|
.fab-button {
|
|
animation: fadeIn 0.6s ease-out;
|
|
}
|
|
|
|
/* 状态过渡动画 */
|
|
.status-badge {
|
|
animation: fadeIn 0.4s ease-out;
|
|
}
|
|
|
|
.item-actions:active {
|
|
transform: scale(0.9);
|
|
}
|
|
</style>
|