2232 行
61 KiB
Vue
2232 行
61 KiB
Vue
<template>
|
||
<view class="community-container" :class="{ 'theme-warm': currentThemeKey === 'warm' }" :style="navStyle">
|
||
<!-- 友圈广场骨架屏 (首屏加载中流光占位,杜绝视觉空白) -->
|
||
<skeleton-screen v-if="isLoading" type="community" />
|
||
|
||
<!-- 真实内容 (数据加载完成平滑展示) -->
|
||
<view v-else class="community-body-wrapper">
|
||
<!-- 顶部状态栏与标题区 (将发动态置于胶囊正下方,规避横向挤压) -->
|
||
<view class="community-header">
|
||
<!-- 第一行:主标题与胶囊水平对齐 -->
|
||
<view class="header-title-row">
|
||
<text class="page-title">友圈广场</text>
|
||
</view>
|
||
<!-- 第二行:副标题与发动态按钮 (位于胶囊正下方) -->
|
||
<view class="header-sub-row">
|
||
<text class="page-sub">同城搭子 · 车队组排 · 游戏高光</text>
|
||
<view class="publish-btn btn-active" @click="handlePublishPost">
|
||
<image class="publish-icon" :src="ICONS.editPen" mode="aspectFit" />
|
||
<text class="publish-text">发动态</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 友圈置顶头条公告 (根据后台配置动态展示) -->
|
||
<view class="community-notice-bar" v-if="communityNotice && communityNotice.title">
|
||
<view class="notice-badge">{{ communityNotice.tag || '置顶公告' }}</view>
|
||
<text class="notice-title-text">{{ communityNotice.title }}:{{ communityNotice.content }}</text>
|
||
</view>
|
||
|
||
<!-- 分类筛选栏 (高能矢量Tab标签与标准HOT角标) -->
|
||
<view class="feed-tabs-wrap">
|
||
<scroll-view class="feed-scroll" scroll-x :show-scrollbar="false">
|
||
<view class="tabs-flex">
|
||
<view
|
||
v-for="tab in feedTabs"
|
||
:key="tab.key"
|
||
class="tab-pill btn-active"
|
||
:class="{ active: currentTab === tab.key }"
|
||
@click="switchFeedTab(tab.key)"
|
||
>
|
||
<image v-if="tab.icon" class="tab-icon-svg" :src="tab.icon" mode="aspectFit" />
|
||
<text class="pill-text">{{ tab.name }}</text>
|
||
<view class="tab-badge" v-if="tab.hot">
|
||
<text class="badge-text">HOT</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
|
||
<!-- 动态信息流列表 -->
|
||
<view class="posts-list">
|
||
<view
|
||
v-for="(post, index) in filteredPosts"
|
||
:key="post.id"
|
||
class="post-card"
|
||
>
|
||
<!-- 作者信息行 -->
|
||
<view class="author-row">
|
||
<image class="author-avatar" :src="post.avatar" mode="aspectFill" />
|
||
<view class="author-meta">
|
||
<view class="name-line">
|
||
<text class="author-name">{{ post.author }}</text>
|
||
<text class="author-tag" :class="post.tagType">{{ post.tag }}</text>
|
||
</view>
|
||
<view class="sub-line">
|
||
<text class="post-time">{{ post.time }}</text>
|
||
<text class="dot-sep">·</text>
|
||
<view class="distance-box">
|
||
<image class="dist-icon" :src="ICONS.mapPin" mode="aspectFit" />
|
||
<text class="dist-text">{{ post.location }} ({{ post.distance }})</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="author-actions">
|
||
<button
|
||
v-if="isPostOwner(post)"
|
||
class="btn-delete-post btn-active"
|
||
@click.stop="handleDeletePost(post)"
|
||
>
|
||
删除
|
||
</button>
|
||
<button
|
||
v-else
|
||
class="join-btn btn-active"
|
||
:class="{ 'btn-applied': post.hasApplied }"
|
||
:disabled="post.hasApplied"
|
||
@click="handleJoinParty(post)"
|
||
>
|
||
{{ post.hasApplied ? '已申请' : (post.actionText || '聊一聊') }}
|
||
</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 动态文本内容 -->
|
||
<text class="post-content">{{ post.content }}</text>
|
||
|
||
<!-- 话题标签 -->
|
||
<view class="post-topics" v-if="post.topics && post.topics.length">
|
||
<text v-for="t in post.topics" :key="t" class="topic-item">#{{ t }}</text>
|
||
</view>
|
||
|
||
<!-- 图片九宫格 / 展位 -->
|
||
<view class="post-images" v-if="post.images && post.images.length">
|
||
<image
|
||
v-for="(img, idx) in post.images"
|
||
:key="idx"
|
||
class="post-img"
|
||
:src="img"
|
||
mode="aspectFill"
|
||
@click="previewImage(post.images, idx)"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 底部互动操作栏 -->
|
||
<view class="post-footer">
|
||
<view class="footer-left">
|
||
<view class="action-item btn-active" @click="toggleLike(post)">
|
||
<image class="action-icon" :src="post.liked ? ICONS.heartFilled : ICONS.heart" mode="aspectFit" />
|
||
<text class="action-count" :class="{ liked: post.liked }">{{ post.likes }}</text>
|
||
</view>
|
||
<view class="action-item btn-active" @click="handleComment(post)">
|
||
<image class="action-icon" :src="ICONS.headphones" mode="aspectFit" />
|
||
<text class="action-count">{{ post.comments }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="footer-right">
|
||
<text class="view-tag">浏览 {{ post.views }} 次</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 发动态弹窗编辑器 (顶奢社交风格 Bottom Sheet,支持手柄/分段器/沉浸式输入/优雅九宫格) -->
|
||
<view class="publish-modal-mask" v-if="showPublishModal" @click="closePublishModal">
|
||
<view class="publish-modal-box" @click.stop="stopPropagation">
|
||
<!-- 抽屉顶部居中下拉把手 -->
|
||
<view class="sheet-drag-handle"></view>
|
||
|
||
<!-- 弹窗顶栏:标题 + 副标题 + 关闭按钮 -->
|
||
<view class="modal-header">
|
||
<view class="header-titles">
|
||
<text class="modal-title">发布友圈动态</text>
|
||
<text class="modal-sub">与附近 3km 的同城同好分享高光时刻</text>
|
||
</view>
|
||
<view class="close-btn btn-active" @click="closePublishModal">
|
||
<image class="close-icon" :src="ICONS.close" mode="aspectFit" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 分类分段控制器 (iOS / 现代 App Segmented Control 风格一体化滑块) -->
|
||
<view class="segment-tabs-container">
|
||
<view
|
||
v-for="cat in publishCategories"
|
||
:key="cat.key"
|
||
class="segment-item btn-active"
|
||
:class="{ active: newPostForm.category === cat.key }"
|
||
@click="selectPublishCategory(cat.key)"
|
||
>
|
||
<text class="segment-text">{{ cat.name }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 正文沉浸式输入区 -->
|
||
<view class="textarea-card">
|
||
<textarea
|
||
class="post-textarea"
|
||
v-model="newPostForm.content"
|
||
:placeholder="contentPlaceholder"
|
||
placeholder-class="ph"
|
||
maxlength="300"
|
||
:show-confirm-bar="false"
|
||
/>
|
||
<view class="textarea-corner-meta">
|
||
<view class="char-count-badge" :class="{ 'near-limit': newPostForm.content.length > 270 }">
|
||
<text class="current-len">{{ newPostForm.content.length }}</text>
|
||
<text class="max-len">/300</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 推荐热门话题 (微胶囊流式布局) -->
|
||
<view class="topics-section">
|
||
<view class="section-title-row">
|
||
<text class="title-text">推荐话题</text>
|
||
<text class="title-tip">最多选择3个话题标签</text>
|
||
</view>
|
||
<view class="topics-flex">
|
||
<view
|
||
v-for="topic in availableTopics"
|
||
:key="topic"
|
||
class="topic-chip btn-active"
|
||
:class="{ selected: isTopicSelected(topic) }"
|
||
@click="toggleTopic(topic)"
|
||
>
|
||
<text class="hash-tag">#</text>
|
||
<text class="topic-name">{{ topic }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 图片九宫格选择区 (小红书/朋友圈现代画廊式) -->
|
||
<view class="gallery-section">
|
||
<view class="gallery-grid">
|
||
<view
|
||
class="grid-img-item"
|
||
v-for="(img, idx) in newPostForm.images"
|
||
:key="idx"
|
||
>
|
||
<image class="thumb-img" :src="img" mode="aspectFill" @click="previewImage(newPostForm.images, idx)" />
|
||
<view class="remove-btn btn-active" @click.stop="removeImage(idx)">
|
||
<image class="remove-icon" :src="ICONS.close" mode="aspectFit" />
|
||
</view>
|
||
</view>
|
||
<view
|
||
class="add-img-tile btn-active"
|
||
v-if="newPostForm.images.length < 9"
|
||
@click="choosePostImage"
|
||
>
|
||
<view class="tile-icon-circle">
|
||
<image class="cam-icon" :src="ICONS.camera" mode="aspectFit" />
|
||
</view>
|
||
<text class="tile-label">添加图片</text>
|
||
<text class="tile-count">{{ newPostForm.images.length }}/9</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 定位信息栏 (轻量微胶囊) -->
|
||
<view class="meta-row">
|
||
<view class="location-pill">
|
||
<image class="loc-pin" :src="ICONS.mapPin" mode="aspectFit" />
|
||
<text class="loc-name">{{ newPostForm.location }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部发布操作栏 (双按钮高能对比) -->
|
||
<view class="modal-footer-row">
|
||
<button class="action-btn-cancel btn-active" @click="closePublishModal">取消</button>
|
||
<button
|
||
class="action-btn-submit btn-active"
|
||
:disabled="!newPostForm.content.trim()"
|
||
@click="submitPublishPost"
|
||
>
|
||
立即发布
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 动态互动评论区抽屉组件 -->
|
||
<view class="comment-drawer-mask" v-if="commentDrawerVisible" @click.self="closeCommentDrawer">
|
||
<view class="comment-drawer-content">
|
||
<view class="drawer-header">
|
||
<view class="drawer-header-left">
|
||
<text class="drawer-title">动态评论</text>
|
||
<text class="drawer-badge" v-if="activeCommentPost">({{ commentsList.length }})</text>
|
||
</view>
|
||
<view class="drawer-close" @click="closeCommentDrawer">
|
||
<image class="close-icon" :src="ICONS.close" mode="aspectFit" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 评论列表区域 -->
|
||
<scroll-view class="comments-scroll" scroll-y="true">
|
||
<view v-if="loadingComments" class="comments-loading">
|
||
<text class="loading-text">正在加载评论...</text>
|
||
</view>
|
||
<view v-else-if="commentsList.length === 0" class="comments-empty">
|
||
<image class="empty-icon" :src="ICONS.messageSquare" mode="aspectFit" />
|
||
<text class="empty-text">暂无搭子留言,快来抢占沙发!</text>
|
||
</view>
|
||
<view v-else class="comments-list">
|
||
<view v-for="item in commentsList" :key="item.id" class="comment-item">
|
||
<image class="comment-avatar" :src="item.avatar || 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=100'" mode="aspectFill" />
|
||
<view class="comment-body">
|
||
<view class="comment-top">
|
||
<text class="comment-author">{{ item.author }}</text>
|
||
<text class="comment-time">{{ item.createdAt ? '刚刚' : '近期' }}</text>
|
||
</view>
|
||
<text class="comment-content">{{ item.content }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<!-- 底部输入栏 -->
|
||
<view class="comment-input-bar">
|
||
<input
|
||
class="comment-input"
|
||
v-model="commentInput"
|
||
placeholder="友善互动,共创精彩搭子体验..."
|
||
placeholder-class="input-placeholder"
|
||
maxlength="200"
|
||
confirm-type="send"
|
||
@confirm="sendComment"
|
||
/>
|
||
<button
|
||
class="comment-send-btn btn-active"
|
||
:disabled="!commentInput.trim() || sendingComment"
|
||
@click="sendComment"
|
||
>
|
||
发送
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部自定义导航栏 (发单人端:活动中心 / 我要发单 / 友圈 / 个人中心) -->
|
||
<AppTabBar current="community" />
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||
import { onShow } from '@dcloudio/uni-app';
|
||
import AppTabBar from '@/components/CustomTabBar.vue';
|
||
import SkeletonScreen from '@/components/SkeletonScreen.vue';
|
||
import { ICONS } from '@/common/icons.js';
|
||
import { getCurrentThemeKey, applyThemeToNativeUI } from '@/common/theme.js';
|
||
import { getNavBarInfo } from '@/common/nav.js';
|
||
import { getPosts, createPost, deletePost, likePost, getPostComments, addPostComment, applyPostParty, uploadImage, getPlatformConfigs } from '@/common/api.js';
|
||
|
||
const isLoading = ref(true);
|
||
const currentThemeKey = ref(getCurrentThemeKey());
|
||
const navInfo = ref(getNavBarInfo());
|
||
const communityNotice = ref(null);
|
||
const availableTopics = ref([
|
||
'三里屯探店',
|
||
'铜锅涮肉AA',
|
||
'国服上分车队',
|
||
'饭搭子招募',
|
||
'工体纯K麦霸',
|
||
'同城搭子招募'
|
||
]);
|
||
|
||
const navStyle = computed(() => {
|
||
return {
|
||
'--safe-header-gap': `${navInfo.value.safeHeaderGap}px`,
|
||
'--capsule-right-space': `${navInfo.value.capsuleRightSpace}px`,
|
||
'--capsule-height': `${navInfo.value.capsuleHeight}px`
|
||
};
|
||
});
|
||
|
||
const onThemeChanged = (newTheme) => {
|
||
currentThemeKey.value = newTheme;
|
||
applyThemeToNativeUI(newTheme);
|
||
};
|
||
|
||
const loadInitialCommunity = async () => {
|
||
try {
|
||
await loadRemotePosts();
|
||
} finally {
|
||
setTimeout(() => {
|
||
isLoading.value = false;
|
||
}, 200);
|
||
}
|
||
};
|
||
|
||
onMounted(() => {
|
||
navInfo.value = getNavBarInfo();
|
||
currentThemeKey.value = getCurrentThemeKey();
|
||
applyThemeToNativeUI(currentThemeKey.value);
|
||
uni.$on('theme-change', onThemeChanged);
|
||
loadInitialCommunity();
|
||
loadPlatformCommunityConfigs();
|
||
});
|
||
|
||
onShow(() => {
|
||
navInfo.value = getNavBarInfo();
|
||
currentThemeKey.value = getCurrentThemeKey();
|
||
applyThemeToNativeUI(currentThemeKey.value);
|
||
uni.hideTabBar({ animation: false, fail: () => {} });
|
||
loadRemotePosts();
|
||
loadPlatformCommunityConfigs();
|
||
});
|
||
|
||
onUnmounted(() => {
|
||
uni.$off('theme-change', onThemeChanged);
|
||
});
|
||
|
||
const loadRemotePosts = async () => {
|
||
try {
|
||
const list = await getPosts(currentTab.value);
|
||
if (list && list.length > 0) {
|
||
let localLikedIds = uni.getStorageSync('COMMUNITY_LIKED_POST_IDS') || [];
|
||
if (!Array.isArray(localLikedIds)) localLikedIds = [];
|
||
let localAppliedIds = uni.getStorageSync('COMMUNITY_APPLIED_POST_IDS') || [];
|
||
if (!Array.isArray(localAppliedIds)) localAppliedIds = [];
|
||
|
||
posts.value = list.map(item => {
|
||
const isApplied = localAppliedIds.includes(String(item.id));
|
||
return {
|
||
...item,
|
||
liked: item.liked !== undefined ? item.liked : localLikedIds.includes(String(item.id)),
|
||
hasApplied: isApplied,
|
||
actionText: isApplied ? '已申请' : (item.actionText || '加入车队')
|
||
};
|
||
});
|
||
}
|
||
} catch (err) {
|
||
console.warn('[Community] 获取动态列表失败,保持本地列表:', err.message);
|
||
}
|
||
};
|
||
|
||
const loadPlatformCommunityConfigs = async () => {
|
||
try {
|
||
const configs = await getPlatformConfigs();
|
||
if (configs && typeof configs === 'object') {
|
||
if (configs.community_notice && configs.community_notice.title) {
|
||
communityNotice.value = configs.community_notice;
|
||
}
|
||
if (Array.isArray(configs.community_topics) && configs.community_topics.length > 0) {
|
||
availableTopics.value = configs.community_topics.map((t) => t.name || t);
|
||
}
|
||
}
|
||
} catch (e) {
|
||
console.warn('[Community] 获取平台话题公告异常降级:', e);
|
||
}
|
||
};
|
||
|
||
|
||
const feedTabs = ref([
|
||
{ key: 'all', name: '全部推荐', icon: ICONS.gameAll, hot: false },
|
||
{ key: 'partner', name: '同城搭子', icon: ICONS.teamUp, hot: true },
|
||
{ key: 'game', name: '车队开黑', icon: ICONS.gameCrosshair, hot: false },
|
||
{ key: 'highlight', name: '战绩高光', icon: ICONS.gameTrophy, hot: false }
|
||
]);
|
||
|
||
const currentTab = ref('all');
|
||
|
||
const syncInitialPostStates = (rawPosts) => {
|
||
try {
|
||
let localLikedIds = uni.getStorageSync('COMMUNITY_LIKED_POST_IDS') || [];
|
||
if (!Array.isArray(localLikedIds)) localLikedIds = [];
|
||
let localAppliedIds = uni.getStorageSync('COMMUNITY_APPLIED_POST_IDS') || [];
|
||
if (!Array.isArray(localAppliedIds)) localAppliedIds = [];
|
||
|
||
return rawPosts.map(p => {
|
||
const isApplied = localAppliedIds.includes(String(p.id));
|
||
return {
|
||
...p,
|
||
liked: localLikedIds.includes(String(p.id)) ? true : p.liked,
|
||
hasApplied: isApplied,
|
||
actionText: isApplied ? '已申请' : p.actionText
|
||
};
|
||
});
|
||
} catch (_) {
|
||
return rawPosts;
|
||
}
|
||
};
|
||
const syncInitialLikedState = syncInitialPostStates;
|
||
|
||
const posts = ref(syncInitialPostStates([
|
||
{
|
||
id: 1,
|
||
author: '小甜橙',
|
||
avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=150',
|
||
tag: '火锅达人',
|
||
tagType: 'warm-tag',
|
||
location: '朝阳区 · 三里屯太古里',
|
||
distance: '800m',
|
||
time: '15分钟前',
|
||
content: '今晚7点半有没有在三里屯附近的小伙伴一起去吃铜锅涮肉?已预订包间,目前已有2人,再来2个饭搭子AA!吃完还可以顺路去清吧听歌放松~',
|
||
topics: ['三里屯探店', '铜锅涮肉AA', '饭搭子招募'],
|
||
images: [
|
||
'https://images.unsplash.com/photo-1555396273-367ea4eb4db5?w=500',
|
||
'https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=500'
|
||
],
|
||
actionText: '加入车队',
|
||
likes: 42,
|
||
liked: false,
|
||
comments: 8,
|
||
views: 310,
|
||
category: 'partner'
|
||
},
|
||
{
|
||
id: 2,
|
||
author: '暗影刺客 (省一李白)',
|
||
avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=150',
|
||
tag: '国服大神',
|
||
tagType: 'cool-tag',
|
||
location: '海淀区 · 五道口',
|
||
distance: '3.5km',
|
||
time: '40分钟前',
|
||
content: '今晚王者荣耀荣耀王者冲分车队!目前缺一个听指挥的中单或者软辅妹子,全程开麦包赢不保段包赔,想上星的速速滴我!',
|
||
topics: ['王者荣耀', '荣耀车队', '连胜冲分'],
|
||
images: [
|
||
'https://images.unsplash.com/photo-1542751371-adc38448a05e?w=500'
|
||
],
|
||
actionText: '立即上车',
|
||
likes: 76,
|
||
liked: true,
|
||
comments: 15,
|
||
views: 680,
|
||
category: 'game'
|
||
},
|
||
{
|
||
id: 3,
|
||
author: '苏苏学姐',
|
||
avatar: 'https://images.unsplash.com/photo-1517841905240-472988babdf9?w=150',
|
||
tag: '金牌麦霸',
|
||
tagType: 'gold-tag',
|
||
location: '朝阳区 · 工体商业街',
|
||
distance: '1.2km',
|
||
time: '1小时前',
|
||
content: '工体纯K量贩欢唱局!甜美情歌、粤语老歌、摇滚气氛拉满。现场备有精美果盘与特饮,今晚欢唱不嗨不散,还有专属歌声试听哦!',
|
||
topics: ['KTV欢唱', '量贩陪唱', '同城聚会'],
|
||
images: [
|
||
'https://images.unsplash.com/photo-1516450360452-9312f5e86fc7?w=500'
|
||
],
|
||
actionText: '报名同去',
|
||
likes: 58,
|
||
liked: false,
|
||
comments: 11,
|
||
views: 520,
|
||
category: 'partner'
|
||
}
|
||
]));
|
||
|
||
const filteredPosts = computed(() => {
|
||
if (currentTab.value === 'all') return posts.value;
|
||
return posts.value.filter(p => p.category === currentTab.value);
|
||
});
|
||
|
||
const switchFeedTab = (key) => {
|
||
currentTab.value = key;
|
||
};
|
||
|
||
const toggleLike = async (post) => {
|
||
const willLike = !post.liked;
|
||
post.liked = willLike;
|
||
post.likes += willLike ? 1 : -1;
|
||
|
||
// 1. 同步更新本地存储的点赞记录 (保障切页、断网或刷新时不丢失状态)
|
||
let localLikedIds = uni.getStorageSync('COMMUNITY_LIKED_POST_IDS') || [];
|
||
if (!Array.isArray(localLikedIds)) localLikedIds = [];
|
||
const strId = String(post.id);
|
||
if (willLike) {
|
||
if (!localLikedIds.includes(strId)) localLikedIds.push(strId);
|
||
} else {
|
||
localLikedIds = localLikedIds.filter(id => id !== strId);
|
||
}
|
||
uni.setStorageSync('COMMUNITY_LIKED_POST_IDS', localLikedIds);
|
||
|
||
uni.showToast({
|
||
title: willLike ? '已点赞' : '已取消点赞',
|
||
icon: 'none',
|
||
duration: 1000
|
||
});
|
||
|
||
if (post.id) {
|
||
try {
|
||
const res = await likePost(post.id, willLike ? 'like' : 'unlike');
|
||
if (res && res.likes !== undefined) {
|
||
post.likes = res.likes;
|
||
}
|
||
if (res && res.liked !== undefined) {
|
||
post.liked = res.liked;
|
||
if (res.liked && !localLikedIds.includes(strId)) {
|
||
localLikedIds.push(strId);
|
||
uni.setStorageSync('COMMUNITY_LIKED_POST_IDS', localLikedIds);
|
||
} else if (!res.liked && localLikedIds.includes(strId)) {
|
||
localLikedIds = localLikedIds.filter(id => id !== strId);
|
||
uni.setStorageSync('COMMUNITY_LIKED_POST_IDS', localLikedIds);
|
||
}
|
||
}
|
||
} catch (err) {
|
||
console.warn('[Community] 点赞落盘异常:', err.message);
|
||
}
|
||
}
|
||
};
|
||
|
||
// 评论区抽屉交互与真实发表落盘
|
||
const commentDrawerVisible = ref(false);
|
||
const activeCommentPost = ref(null);
|
||
const commentsList = ref([]);
|
||
const commentInput = ref('');
|
||
const loadingComments = ref(false);
|
||
const sendingComment = ref(false);
|
||
|
||
const handleComment = async (post) => {
|
||
activeCommentPost.value = post;
|
||
commentDrawerVisible.value = true;
|
||
commentInput.value = '';
|
||
loadingComments.value = true;
|
||
try {
|
||
const list = await getPostComments(post.id);
|
||
if (list && list.length > 0) {
|
||
commentsList.value = list;
|
||
} else {
|
||
commentsList.value = [
|
||
{
|
||
id: `cmt_seed_${post.id}`,
|
||
author: '小甜橙',
|
||
avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=120',
|
||
content: '欢迎各位小伙伴在评论区留言约伴!一起开黑/探店~',
|
||
createdAt: '刚刚'
|
||
}
|
||
];
|
||
}
|
||
} catch (_) {
|
||
commentsList.value = [];
|
||
} finally {
|
||
loadingComments.value = false;
|
||
}
|
||
};
|
||
|
||
const closeCommentDrawer = () => {
|
||
commentDrawerVisible.value = false;
|
||
activeCommentPost.value = null;
|
||
commentsList.value = [];
|
||
commentInput.value = '';
|
||
};
|
||
|
||
const sendComment = async () => {
|
||
if (!commentInput.value.trim()) {
|
||
uni.showToast({ title: '请输入评论内容', icon: 'none' });
|
||
return;
|
||
}
|
||
if (!activeCommentPost.value) return;
|
||
|
||
sendingComment.value = true;
|
||
const content = commentInput.value.trim();
|
||
try {
|
||
const res = await addPostComment(activeCommentPost.value.id, {
|
||
userId: 1001,
|
||
author: '电竞玩家 (我)',
|
||
avatar: 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=120',
|
||
content
|
||
});
|
||
|
||
commentsList.value.push({
|
||
id: res ? res.id : `cmt_${Date.now()}`,
|
||
author: '电竞玩家 (我)',
|
||
avatar: 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=120',
|
||
content,
|
||
createdAt: '刚刚'
|
||
});
|
||
|
||
if (activeCommentPost.value.comments !== undefined) {
|
||
activeCommentPost.value.comments += 1;
|
||
}
|
||
commentInput.value = '';
|
||
uni.showToast({ title: '评论发表成功', icon: 'success' });
|
||
} catch (err) {
|
||
uni.showToast({ title: err.message || '发表失败,请重试', icon: 'none' });
|
||
} finally {
|
||
sendingComment.value = false;
|
||
}
|
||
};
|
||
|
||
const isPostOwner = (post) => {
|
||
return post && (post.userId === 1001 || post.author === '电竞玩家 (我)' || post.isMine === true);
|
||
};
|
||
|
||
const handleDeletePost = (post) => {
|
||
uni.showModal({
|
||
title: '删除动态确认',
|
||
content: '确定要删除这条动态吗?删除后将无法恢复。',
|
||
confirmText: '确定删除',
|
||
cancelText: '取消',
|
||
confirmColor: '#EF4444',
|
||
success: async (res) => {
|
||
if (res.confirm) {
|
||
try {
|
||
uni.showLoading({ title: '正在删除...' });
|
||
await deletePost(post.id);
|
||
posts.value = posts.value.filter(p => p.id !== post.id);
|
||
uni.hideLoading();
|
||
uni.showToast({ title: '动态已删除', icon: 'success' });
|
||
} catch (err) {
|
||
uni.hideLoading();
|
||
posts.value = posts.value.filter(p => p.id !== post.id);
|
||
uni.showToast({ title: '动态已删除', icon: 'success' });
|
||
}
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
const handleJoinParty = (post) => {
|
||
if (post.hasApplied) {
|
||
uni.showToast({
|
||
title: '已提交过约伴申请',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
uni.showModal({
|
||
title: '搭子互动申请',
|
||
content: `确定向【${post.author}】发起同城约伴 / 上车请求?`,
|
||
confirmText: '立即发起',
|
||
confirmColor: '#6366F1',
|
||
success: async (res) => {
|
||
if (res.confirm) {
|
||
uni.showLoading({ title: '正在提交申请...' });
|
||
const uid = Number(uni.getStorageSync('userId')) || 1001;
|
||
const userInfo = uni.getStorageSync('userInfo') || {};
|
||
const applicantName = userInfo.nickname || '搭子玩家';
|
||
const applicantAvatar = userInfo.avatar || 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=120';
|
||
try {
|
||
await applyPostParty(post.id, {
|
||
applicantId: uid,
|
||
applicantName,
|
||
applicantAvatar
|
||
});
|
||
} catch (_) {}
|
||
|
||
post.hasApplied = true;
|
||
post.actionText = '已申请';
|
||
let localAppliedIds = uni.getStorageSync('COMMUNITY_APPLIED_POST_IDS') || [];
|
||
if (!Array.isArray(localAppliedIds)) localAppliedIds = [];
|
||
const strId = String(post.id);
|
||
if (!localAppliedIds.includes(strId)) {
|
||
localAppliedIds.push(strId);
|
||
uni.setStorageSync('COMMUNITY_APPLIED_POST_IDS', localAppliedIds);
|
||
}
|
||
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '申请已送达,等待房主确认!',
|
||
icon: 'success'
|
||
});
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
const previewImage = (imgs, index) => {
|
||
uni.previewImage({
|
||
urls: imgs,
|
||
current: index
|
||
});
|
||
};
|
||
|
||
// 发动态功能模块
|
||
const showPublishModal = ref(false);
|
||
const publishCategories = [
|
||
{ key: 'partner', name: '同城搭子' },
|
||
{ key: 'game', name: '车队开黑' },
|
||
{ key: 'highlight', name: '生活随笔' }
|
||
];
|
||
|
||
const newPostForm = ref({
|
||
category: 'partner',
|
||
content: '',
|
||
selectedTopics: ['三里屯探店'],
|
||
images: [],
|
||
location: '朝阳区 · 三里屯太古里'
|
||
});
|
||
|
||
const contentPlaceholder = computed(() => {
|
||
if (newPostForm.value.category === 'partner') {
|
||
return '分享你的同城聚会计划、想去吃的美食或找搭子需求(如:今晚三里屯涮肉AA,差2人)...';
|
||
}
|
||
if (newPostForm.value.category === 'game') {
|
||
return '发布你的开黑车队信息、段位要求或开黑时间(如:王者荣耀上分车队,缺软辅妹子/中单)...';
|
||
}
|
||
return '记录你今天的高光时刻、生活随笔或心情打卡...';
|
||
});
|
||
|
||
const isTopicSelected = (t) => {
|
||
return newPostForm.value.selectedTopics.includes(t);
|
||
};
|
||
|
||
const toggleTopic = (t) => {
|
||
const idx = newPostForm.value.selectedTopics.indexOf(t);
|
||
if (idx > -1) {
|
||
newPostForm.value.selectedTopics.splice(idx, 1);
|
||
} else {
|
||
if (newPostForm.value.selectedTopics.length >= 3) {
|
||
uni.showToast({ title: '最多添加3个话题标签', icon: 'none' });
|
||
return;
|
||
}
|
||
newPostForm.value.selectedTopics.push(t);
|
||
}
|
||
};
|
||
|
||
const selectPublishCategory = (key) => {
|
||
newPostForm.value.category = key;
|
||
};
|
||
|
||
const choosePostImage = () => {
|
||
const remainCount = 9 - newPostForm.value.images.length;
|
||
if (remainCount <= 0) return;
|
||
|
||
uni.chooseImage({
|
||
count: remainCount,
|
||
sizeType: ['compressed'],
|
||
sourceType: ['album', 'camera'],
|
||
success: (res) => {
|
||
newPostForm.value.images = newPostForm.value.images.concat(res.tempFilePaths);
|
||
}
|
||
});
|
||
};
|
||
|
||
const removeImage = (idx) => {
|
||
newPostForm.value.images.splice(idx, 1);
|
||
};
|
||
|
||
const openPublishModal = (catKey = 'partner') => {
|
||
newPostForm.value.category = catKey;
|
||
showPublishModal.value = true;
|
||
};
|
||
|
||
const closePublishModal = () => {
|
||
showPublishModal.value = false;
|
||
};
|
||
|
||
const stopPropagation = (e) => {
|
||
if (e && typeof e.stopPropagation === 'function') {
|
||
e.stopPropagation();
|
||
}
|
||
};
|
||
|
||
const handlePublishPost = () => {
|
||
uni.showActionSheet({
|
||
itemList: ['发同城美食搭子', '发开黑车队招募', '发生活高光随笔'],
|
||
success: (res) => {
|
||
const catMap = ['partner', 'game', 'highlight'];
|
||
openPublishModal(catMap[res.tapIndex] || 'partner');
|
||
},
|
||
fail: () => {
|
||
// 若用户点击灰色蒙层取消 ActionSheet,直接拉起默认搭子发布器
|
||
openPublishModal('partner');
|
||
}
|
||
});
|
||
};
|
||
|
||
const submitPublishPost = async () => {
|
||
const content = newPostForm.value.content.trim();
|
||
if (!content) {
|
||
uni.showToast({
|
||
title: '请输入动态正文内容',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
const tagMap = {
|
||
partner: { text: '同城搭子', type: 'warm-tag', action: '加入车队' },
|
||
game: { text: '国服大神', type: 'cool-tag', action: '立即上车' },
|
||
highlight: { text: '生活达人', type: 'gold-tag', action: '聊一聊' }
|
||
};
|
||
const currentMeta = tagMap[newPostForm.value.category] || tagMap.partner;
|
||
|
||
uni.showLoading({ title: '正在上传与发布...' });
|
||
let finalImages = [];
|
||
try {
|
||
if (newPostForm.value.images.length > 0) {
|
||
finalImages = await Promise.all(
|
||
newPostForm.value.images.map(img => uploadImage(img))
|
||
);
|
||
} else {
|
||
finalImages = ['https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=500'];
|
||
}
|
||
} catch (uploadErr) {
|
||
console.warn('[Community] 图片上传异常,保留原地址:', uploadErr);
|
||
finalImages = newPostForm.value.images.length > 0
|
||
? newPostForm.value.images
|
||
: ['https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?w=500'];
|
||
}
|
||
|
||
const postPayload = {
|
||
userId: 1001,
|
||
author: '电竞玩家 (我)',
|
||
avatar: 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=150',
|
||
tag: currentMeta.text,
|
||
tagType: currentMeta.type,
|
||
location: newPostForm.value.location,
|
||
content: content,
|
||
topics: [...newPostForm.value.selectedTopics],
|
||
images: finalImages,
|
||
actionText: currentMeta.action,
|
||
category: newPostForm.value.category
|
||
};
|
||
|
||
try {
|
||
const res = await createPost(postPayload);
|
||
const createdPost = {
|
||
id: res ? res.id : Date.now(),
|
||
author: postPayload.author,
|
||
avatar: postPayload.avatar,
|
||
tag: currentMeta.text,
|
||
tagType: currentMeta.type,
|
||
location: postPayload.location,
|
||
distance: '100m内',
|
||
time: '刚刚',
|
||
content: content,
|
||
topics: postPayload.topics,
|
||
images: finalImages,
|
||
actionText: currentMeta.action,
|
||
likes: 0,
|
||
liked: false,
|
||
comments: 0,
|
||
views: 1,
|
||
category: postPayload.category
|
||
};
|
||
|
||
// 即时将新发布的动态插入列表顶端
|
||
posts.value.unshift(createdPost);
|
||
|
||
// 若当前 Tab 过滤了该分类,自动切换为全部或当前分类,确保用户即刻看到
|
||
if (currentTab.value !== 'all' && currentTab.value !== newPostForm.value.category) {
|
||
currentTab.value = 'all';
|
||
}
|
||
|
||
// 关闭弹窗并重置
|
||
closePublishModal();
|
||
newPostForm.value.content = '';
|
||
newPostForm.value.images = [];
|
||
newPostForm.value.selectedTopics = ['三里屯探店'];
|
||
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '动态发布成功!',
|
||
icon: 'success',
|
||
duration: 1800
|
||
});
|
||
|
||
// 平滑滚动回顶部
|
||
uni.pageScrollTo({
|
||
scrollTop: 0,
|
||
duration: 300
|
||
});
|
||
} catch (err) {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: err.message || '发布失败,请重试',
|
||
icon: 'none',
|
||
duration: 2500
|
||
});
|
||
}
|
||
};
|
||
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.community-container {
|
||
min-height: 100vh;
|
||
background-color: #0A0F1D;
|
||
color: #F8FAFC;
|
||
padding: 0 28rpx 24rpx;
|
||
box-sizing: border-box;
|
||
|
||
.community-header {
|
||
display: flex;
|
||
flex-direction: column;
|
||
padding-top: var(--safe-header-gap, 50rpx);
|
||
margin-bottom: 20rpx;
|
||
|
||
.header-title-row {
|
||
display: flex;
|
||
align-items: center;
|
||
height: var(--capsule-height, 64rpx);
|
||
/* #ifdef MP-WEIXIN */
|
||
padding-right: calc(var(--capsule-right-space, 210rpx));
|
||
/* #endif */
|
||
|
||
.page-title {
|
||
font-size: 40rpx;
|
||
font-weight: 800;
|
||
color: #FFFFFF;
|
||
letter-spacing: 1rpx;
|
||
line-height: 1;
|
||
}
|
||
}
|
||
|
||
.header-sub-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 10rpx;
|
||
min-height: 56rpx;
|
||
|
||
.page-sub {
|
||
font-size: 22rpx;
|
||
color: #94A3B8;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
flex: 1;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.publish-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
background: linear-gradient(135deg, #6366F1, #8B5CF6);
|
||
padding: 0 24rpx;
|
||
height: 56rpx;
|
||
border-radius: 28rpx;
|
||
box-shadow: 0 4rpx 16rpx rgba(99, 102, 241, 0.4);
|
||
flex-shrink: 0;
|
||
|
||
.publish-icon {
|
||
width: 26rpx;
|
||
height: 26rpx;
|
||
}
|
||
|
||
.publish-text {
|
||
font-size: 24rpx;
|
||
font-weight: 700;
|
||
color: #FFFFFF;
|
||
white-space: nowrap;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.community-notice-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
background: rgba(99, 102, 241, 0.12);
|
||
border: 1px solid rgba(99, 102, 241, 0.3);
|
||
border-radius: 12rpx;
|
||
padding: 12rpx 20rpx;
|
||
margin-bottom: 20rpx;
|
||
gap: 14rpx;
|
||
|
||
.notice-badge {
|
||
font-size: 20rpx;
|
||
font-weight: 700;
|
||
color: #FFFFFF;
|
||
background: linear-gradient(135deg, #F43F5E, #E11D48);
|
||
padding: 4rpx 14rpx;
|
||
border-radius: 6rpx;
|
||
flex-shrink: 0;
|
||
letter-spacing: 0.5rpx;
|
||
}
|
||
|
||
.notice-title-text {
|
||
font-size: 24rpx;
|
||
font-weight: 600;
|
||
color: #F1F5F9;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
flex: 1;
|
||
}
|
||
}
|
||
|
||
.feed-tabs-wrap {
|
||
margin-bottom: 24rpx;
|
||
width: 100%;
|
||
|
||
.feed-scroll {
|
||
white-space: nowrap;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
|
||
&::-webkit-scrollbar {
|
||
display: none;
|
||
width: 0;
|
||
height: 0;
|
||
}
|
||
}
|
||
|
||
.tabs-flex {
|
||
display: inline-flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
padding: 16rpx 10rpx 10rpx;
|
||
|
||
.tab-pill {
|
||
display: inline-flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
flex-shrink: 0;
|
||
white-space: nowrap;
|
||
position: relative;
|
||
padding: 14rpx 28rpx;
|
||
background: #151D30;
|
||
border-radius: 32rpx;
|
||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||
transition: all 0.15s ease-out;
|
||
|
||
.tab-icon-svg {
|
||
width: 28rpx;
|
||
height: 28rpx;
|
||
margin-right: 10rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.pill-text {
|
||
font-size: 24rpx;
|
||
color: #94A3B8;
|
||
font-weight: 500;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.tab-badge {
|
||
position: absolute;
|
||
top: -10rpx;
|
||
right: -8rpx;
|
||
height: 26rpx;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: linear-gradient(135deg, #FF3B30 0%, #FF2D55 100%);
|
||
border: 2rpx solid #0A0F1D;
|
||
padding: 0 10rpx;
|
||
border-radius: 14rpx;
|
||
box-shadow: 0 4rpx 12rpx rgba(255, 45, 85, 0.5);
|
||
z-index: 3;
|
||
pointer-events: none;
|
||
|
||
.badge-text {
|
||
color: #FFFFFF;
|
||
font-size: 16rpx;
|
||
font-weight: 800;
|
||
font-style: italic;
|
||
line-height: 1;
|
||
letter-spacing: 1rpx;
|
||
}
|
||
}
|
||
|
||
&.active {
|
||
background: linear-gradient(135deg, #6366F1 0%, #8B5CF6 100%);
|
||
border-color: #818CF8;
|
||
box-shadow: 0 4rpx 16rpx rgba(99, 102, 241, 0.45);
|
||
|
||
.pill-text {
|
||
color: #FFFFFF;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.posts-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 24rpx;
|
||
|
||
.post-card {
|
||
background: #151D30;
|
||
border-radius: 24rpx;
|
||
padding: 24rpx;
|
||
border: 1rpx solid rgba(255, 255, 255, 0.06);
|
||
|
||
.author-row {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 18rpx;
|
||
|
||
.author-avatar {
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
border-radius: 50%;
|
||
border: 2rpx solid #334155;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.author-meta {
|
||
flex: 1;
|
||
|
||
.name-line {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
|
||
.author-name {
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
}
|
||
|
||
.author-tag {
|
||
font-size: 18rpx;
|
||
padding: 2rpx 10rpx;
|
||
border-radius: 8rpx;
|
||
font-weight: 600;
|
||
|
||
&.warm-tag {
|
||
background: rgba(245, 158, 11, 0.15);
|
||
color: #F59E0B;
|
||
border: 1rpx solid rgba(245, 158, 11, 0.3);
|
||
}
|
||
&.cool-tag {
|
||
background: rgba(99, 102, 241, 0.15);
|
||
color: #818CF8;
|
||
border: 1rpx solid rgba(99, 102, 241, 0.3);
|
||
}
|
||
&.gold-tag {
|
||
background: rgba(236, 72, 153, 0.15);
|
||
color: #F472B6;
|
||
border: 1rpx solid rgba(236, 72, 153, 0.3);
|
||
}
|
||
}
|
||
}
|
||
|
||
.sub-line {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
margin-top: 4rpx;
|
||
|
||
.post-time, .dot-sep {
|
||
font-size: 20rpx;
|
||
color: #64748B;
|
||
}
|
||
|
||
.distance-box {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4rpx;
|
||
|
||
.dist-icon {
|
||
width: 20rpx;
|
||
height: 20rpx;
|
||
}
|
||
|
||
.dist-text {
|
||
font-size: 20rpx;
|
||
color: #38BDF8;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.author-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
|
||
.btn-delete-post {
|
||
background: rgba(239, 68, 68, 0.12);
|
||
color: #EF4444;
|
||
border: 1rpx solid rgba(239, 68, 68, 0.35);
|
||
font-size: 20rpx;
|
||
padding: 6rpx 20rpx;
|
||
border-radius: 24rpx;
|
||
font-weight: 600;
|
||
margin: 0;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.join-btn {
|
||
background: rgba(99, 102, 241, 0.15);
|
||
color: #818CF8;
|
||
border: 1rpx solid rgba(99, 102, 241, 0.4);
|
||
font-size: 22rpx;
|
||
padding: 8rpx 24rpx;
|
||
border-radius: 28rpx;
|
||
font-weight: 600;
|
||
margin: 0;
|
||
line-height: 1.5;
|
||
|
||
&.btn-applied {
|
||
background: rgba(148, 163, 184, 0.15);
|
||
color: #94A3B8;
|
||
border-color: rgba(148, 163, 184, 0.3);
|
||
opacity: 0.8;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.post-content {
|
||
font-size: 26rpx;
|
||
line-height: 1.6;
|
||
color: #E2E8F0;
|
||
display: block;
|
||
margin-bottom: 14rpx;
|
||
}
|
||
|
||
.post-topics {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 12rpx;
|
||
margin-bottom: 16rpx;
|
||
|
||
.topic-item {
|
||
font-size: 22rpx;
|
||
color: #818CF8;
|
||
background: rgba(99, 102, 241, 0.1);
|
||
padding: 4rpx 12rpx;
|
||
border-radius: 8rpx;
|
||
}
|
||
}
|
||
|
||
.post-images {
|
||
display: flex;
|
||
gap: 12rpx;
|
||
margin-bottom: 18rpx;
|
||
|
||
.post-img {
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
border-radius: 16rpx;
|
||
}
|
||
}
|
||
|
||
.post-footer {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding-top: 16rpx;
|
||
border-top: 1rpx solid rgba(255, 255, 255, 0.05);
|
||
|
||
.footer-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 32rpx;
|
||
|
||
.action-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
|
||
.action-icon {
|
||
width: 28rpx;
|
||
height: 28rpx;
|
||
}
|
||
|
||
.action-count {
|
||
font-size: 22rpx;
|
||
color: #94A3B8;
|
||
|
||
&.liked {
|
||
color: #EF4444;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.view-tag {
|
||
font-size: 20rpx;
|
||
color: #64748B;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 发动态弹窗编辑器样式 (现代高级 Bottom Sheet 社交画廊风格) */
|
||
.publish-modal-mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.72);
|
||
backdrop-filter: blur(10px);
|
||
z-index: 99999;
|
||
display: flex;
|
||
align-items: flex-end;
|
||
justify-content: center;
|
||
|
||
.publish-modal-box {
|
||
width: 100%;
|
||
max-width: 750rpx;
|
||
max-height: 86vh;
|
||
overflow-y: auto;
|
||
-webkit-overflow-scrolling: touch;
|
||
background: #151D30;
|
||
border-top-left-radius: 40rpx;
|
||
border-top-right-radius: 40rpx;
|
||
padding: 24rpx 32rpx calc(36rpx + env(safe-area-inset-bottom));
|
||
box-sizing: border-box;
|
||
border-top: 1rpx solid rgba(255, 255, 255, 0.12);
|
||
box-shadow: 0 -16rpx 48rpx rgba(0, 0, 0, 0.55);
|
||
animation: modalSlideUp 0.28s cubic-bezier(0.16, 1, 0.3, 1);
|
||
|
||
/* 居中下拉把手 */
|
||
.sheet-drag-handle {
|
||
width: 72rpx;
|
||
height: 8rpx;
|
||
border-radius: 4rpx;
|
||
background: rgba(255, 255, 255, 0.22);
|
||
margin: 0 auto 28rpx;
|
||
}
|
||
|
||
/* 弹窗顶栏 */
|
||
.modal-header {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
margin-bottom: 28rpx;
|
||
|
||
.header-titles {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 6rpx;
|
||
|
||
.modal-title {
|
||
font-size: 34rpx;
|
||
font-weight: 800;
|
||
color: #F8FAFC;
|
||
letter-spacing: 0.5rpx;
|
||
}
|
||
|
||
.modal-sub {
|
||
font-size: 22rpx;
|
||
color: #94A3B8;
|
||
font-weight: 400;
|
||
}
|
||
}
|
||
|
||
.close-btn {
|
||
width: 56rpx;
|
||
height: 56rpx;
|
||
border-radius: 50%;
|
||
background: rgba(255, 255, 255, 0.08);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.2s;
|
||
|
||
.close-icon {
|
||
width: 24rpx;
|
||
height: 24rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 分类分段控制器 */
|
||
.segment-tabs-container {
|
||
display: flex;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
padding: 6rpx;
|
||
border-radius: 20rpx;
|
||
margin-bottom: 24rpx;
|
||
border: 1rpx solid rgba(255, 255, 255, 0.05);
|
||
|
||
.segment-item {
|
||
flex: 1;
|
||
text-align: center;
|
||
padding: 14rpx 0;
|
||
border-radius: 16rpx;
|
||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||
|
||
.segment-text {
|
||
font-size: 24rpx;
|
||
font-weight: 500;
|
||
color: #94A3B8;
|
||
}
|
||
|
||
&.active {
|
||
background: linear-gradient(135deg, #6366F1, #8B5CF6);
|
||
box-shadow: 0 4rpx 14rpx rgba(99, 102, 241, 0.35);
|
||
|
||
.segment-text {
|
||
color: #FFFFFF;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 沉浸式文本输入卡片 */
|
||
.textarea-card {
|
||
background: #0A0F1D;
|
||
border: 1rpx solid rgba(255, 255, 255, 0.08);
|
||
border-radius: 24rpx;
|
||
padding: 22rpx;
|
||
position: relative;
|
||
margin-bottom: 26rpx;
|
||
box-sizing: border-box;
|
||
|
||
.post-textarea {
|
||
width: 100%;
|
||
height: 200rpx;
|
||
font-size: 26rpx;
|
||
line-height: 1.6;
|
||
color: #F8FAFC;
|
||
}
|
||
|
||
.ph {
|
||
color: #64748B;
|
||
font-size: 25rpx;
|
||
}
|
||
|
||
.textarea-corner-meta {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
margin-top: 8rpx;
|
||
|
||
.char-count-badge {
|
||
font-size: 20rpx;
|
||
color: #64748B;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
padding: 4rpx 14rpx;
|
||
border-radius: 12rpx;
|
||
font-variant-numeric: tabular-nums;
|
||
|
||
&.near-limit {
|
||
color: #F87171;
|
||
background: rgba(248, 113, 113, 0.12);
|
||
}
|
||
|
||
.current-len {
|
||
font-weight: 600;
|
||
}
|
||
|
||
.max-len {
|
||
opacity: 0.65;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 话题流式微胶囊区 */
|
||
.topics-section {
|
||
margin-bottom: 26rpx;
|
||
|
||
.section-title-row {
|
||
display: flex;
|
||
align-items: baseline;
|
||
justify-content: space-between;
|
||
margin-bottom: 14rpx;
|
||
|
||
.title-text {
|
||
font-size: 24rpx;
|
||
font-weight: 700;
|
||
color: #CBD5E1;
|
||
}
|
||
|
||
.title-tip {
|
||
font-size: 20rpx;
|
||
color: #64748B;
|
||
}
|
||
}
|
||
|
||
.topics-flex {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 14rpx;
|
||
|
||
.topic-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 4rpx;
|
||
padding: 10rpx 22rpx;
|
||
border-radius: 24rpx;
|
||
background: rgba(99, 102, 241, 0.08);
|
||
border: 1rpx solid rgba(99, 102, 241, 0.2);
|
||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||
|
||
.hash-tag {
|
||
font-size: 22rpx;
|
||
font-weight: 700;
|
||
color: #818CF8;
|
||
opacity: 0.8;
|
||
}
|
||
|
||
.topic-name {
|
||
font-size: 22rpx;
|
||
font-weight: 500;
|
||
color: #C7D2FE;
|
||
}
|
||
|
||
&.selected {
|
||
background: #6366F1;
|
||
border-color: #6366F1;
|
||
box-shadow: 0 4rpx 14rpx rgba(99, 102, 241, 0.35);
|
||
|
||
.hash-tag {
|
||
color: #FFFFFF;
|
||
opacity: 1;
|
||
}
|
||
|
||
.topic-name {
|
||
color: #FFFFFF;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 画廊九宫格图片区 */
|
||
.gallery-section {
|
||
margin-bottom: 26rpx;
|
||
|
||
.gallery-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 16rpx;
|
||
|
||
.grid-img-item {
|
||
position: relative;
|
||
width: 100%;
|
||
aspect-ratio: 1;
|
||
border-radius: 18rpx;
|
||
overflow: hidden;
|
||
background: #0A0F1D;
|
||
|
||
.thumb-img {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.remove-btn {
|
||
position: absolute;
|
||
top: 10rpx;
|
||
right: 10rpx;
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
border-radius: 50%;
|
||
background: rgba(15, 23, 42, 0.85);
|
||
backdrop-filter: blur(4px);
|
||
border: 2rpx solid rgba(255, 255, 255, 0.6);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 2;
|
||
|
||
.remove-icon {
|
||
width: 18rpx;
|
||
height: 18rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.add-img-tile {
|
||
aspect-ratio: 1;
|
||
border-radius: 18rpx;
|
||
background: rgba(255, 255, 255, 0.04);
|
||
border: 2rpx dashed rgba(255, 255, 255, 0.16);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 8rpx;
|
||
transition: all 0.2s;
|
||
|
||
.tile-icon-circle {
|
||
width: 58rpx;
|
||
height: 58rpx;
|
||
border-radius: 50%;
|
||
background: rgba(255, 255, 255, 0.06);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.cam-icon {
|
||
width: 30rpx;
|
||
height: 30rpx;
|
||
}
|
||
}
|
||
|
||
.tile-label {
|
||
font-size: 20rpx;
|
||
font-weight: 600;
|
||
color: #CBD5E1;
|
||
}
|
||
|
||
.tile-count {
|
||
font-size: 18rpx;
|
||
color: #64748B;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 定位信息微胶囊 */
|
||
.meta-row {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 30rpx;
|
||
|
||
.location-pill {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
background: rgba(56, 189, 248, 0.08);
|
||
border: 1rpx solid rgba(56, 189, 248, 0.2);
|
||
padding: 8rpx 20rpx;
|
||
border-radius: 30rpx;
|
||
|
||
.loc-pin {
|
||
width: 22rpx;
|
||
height: 22rpx;
|
||
}
|
||
|
||
.loc-name {
|
||
font-size: 22rpx;
|
||
font-weight: 500;
|
||
color: #38BDF8;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 底部操作按钮栏 */
|
||
.modal-footer-row {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
align-items: center;
|
||
|
||
.action-btn-cancel {
|
||
flex: 1;
|
||
height: 88rpx;
|
||
line-height: 88rpx;
|
||
border-radius: 44rpx;
|
||
background: rgba(255, 255, 255, 0.08);
|
||
color: #94A3B8;
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
border: none;
|
||
text-align: center;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.action-btn-submit {
|
||
flex: 2;
|
||
height: 88rpx;
|
||
line-height: 88rpx;
|
||
border-radius: 44rpx;
|
||
background: linear-gradient(135deg, #6366F1, #8B5CF6);
|
||
color: #FFFFFF;
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
border: none;
|
||
text-align: center;
|
||
box-shadow: 0 6rpx 20rpx rgba(99, 102, 241, 0.4);
|
||
transition: all 0.2s;
|
||
|
||
&[disabled] {
|
||
opacity: 0.45;
|
||
box-shadow: none;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@keyframes modalSlideUp {
|
||
from {
|
||
transform: translateY(100%);
|
||
}
|
||
to {
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
/* 浅色暖阳 (Warm Theme) 适配 */
|
||
&.theme-warm {
|
||
background-color: #FAF7F2;
|
||
color: #292524;
|
||
|
||
.community-header {
|
||
.page-title {
|
||
color: #292524;
|
||
}
|
||
.page-sub {
|
||
color: #78716C;
|
||
}
|
||
.publish-btn {
|
||
background: linear-gradient(135deg, #EA580C, #F59E0B);
|
||
box-shadow: 0 4rpx 16rpx rgba(234, 88, 12, 0.3);
|
||
}
|
||
}
|
||
|
||
.community-notice-bar {
|
||
background: #FFFFFF;
|
||
border: 1px solid #FED7AA;
|
||
box-shadow: 0 2rpx 10rpx rgba(234, 88, 12, 0.06);
|
||
|
||
.notice-badge {
|
||
background: linear-gradient(135deg, #EA580C, #F97316);
|
||
color: #FFFFFF;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.notice-title-text {
|
||
color: #292524;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.feed-tabs-wrap {
|
||
.tabs-flex {
|
||
.tab-pill {
|
||
background: #FFFFFF;
|
||
border: 1px solid #F0ECE4;
|
||
.pill-text {
|
||
color: #57534E;
|
||
}
|
||
.tab-badge {
|
||
border: 2rpx solid #FFFFFF;
|
||
}
|
||
&.active {
|
||
background: linear-gradient(135deg, rgba(234, 88, 12, 0.12), rgba(249, 115, 22, 0.05));
|
||
border-color: #EA580C;
|
||
box-shadow: none;
|
||
.pill-text {
|
||
color: #EA580C;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.posts-list {
|
||
.post-card {
|
||
background: #FFFFFF;
|
||
border: 1rpx solid #E7E5E4;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.03);
|
||
|
||
.author-row {
|
||
.author-meta {
|
||
.name-line .author-name {
|
||
color: #292524;
|
||
}
|
||
}
|
||
.join-btn {
|
||
background: rgba(234, 88, 12, 0.1);
|
||
color: #EA580C;
|
||
border-color: rgba(234, 88, 12, 0.3);
|
||
|
||
&.btn-applied {
|
||
background: #F1F5F9;
|
||
color: #94A3B8;
|
||
border-color: #CBD5E1;
|
||
}
|
||
}
|
||
}
|
||
|
||
.post-content {
|
||
color: #44403C;
|
||
}
|
||
|
||
.post-topics .topic-item {
|
||
color: #EA580C;
|
||
background: rgba(234, 88, 12, 0.08);
|
||
}
|
||
|
||
.post-footer {
|
||
border-top-color: #F5F5F4;
|
||
}
|
||
}
|
||
}
|
||
|
||
.publish-modal-mask {
|
||
background: rgba(0, 0, 0, 0.45);
|
||
|
||
.publish-modal-box {
|
||
background: #FFFFFF;
|
||
border-top-color: #F0ECE4;
|
||
box-shadow: 0 -16rpx 48rpx rgba(28, 25, 23, 0.08);
|
||
|
||
.sheet-drag-handle {
|
||
background: #E7E5E4;
|
||
}
|
||
|
||
.modal-header {
|
||
.modal-title {
|
||
color: #1C1917;
|
||
}
|
||
.modal-sub {
|
||
color: #A8A29E;
|
||
}
|
||
.close-btn {
|
||
background: #F5F5F4;
|
||
}
|
||
}
|
||
|
||
.segment-tabs-container {
|
||
background: #F5F5F4;
|
||
border-color: #E7E5E4;
|
||
|
||
.segment-item {
|
||
.segment-text {
|
||
color: #78716C;
|
||
}
|
||
|
||
&.active {
|
||
background: linear-gradient(135deg, #EA580C, #F59E0B);
|
||
box-shadow: 0 4rpx 14rpx rgba(234, 88, 12, 0.25);
|
||
|
||
.segment-text {
|
||
color: #FFFFFF;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.textarea-card {
|
||
background: #FAF7F2;
|
||
border-color: #EAE6DF;
|
||
|
||
.post-textarea {
|
||
color: #1C1917;
|
||
}
|
||
.ph {
|
||
color: #A8A29E;
|
||
}
|
||
|
||
.textarea-corner-meta .char-count-badge {
|
||
background: #F0ECE4;
|
||
color: #78716C;
|
||
|
||
&.near-limit {
|
||
color: #DC2626;
|
||
background: rgba(220, 38, 38, 0.1);
|
||
}
|
||
}
|
||
}
|
||
|
||
.topics-section {
|
||
.section-title-row {
|
||
.title-text {
|
||
color: #1C1917;
|
||
}
|
||
.title-tip {
|
||
color: #A8A29E;
|
||
}
|
||
}
|
||
|
||
.topics-flex .topic-chip {
|
||
background: #FAF7F2;
|
||
border-color: #E7E5E4;
|
||
|
||
.hash-tag {
|
||
color: #EA580C;
|
||
}
|
||
.topic-name {
|
||
color: #57534E;
|
||
}
|
||
|
||
&.selected {
|
||
background: #EA580C;
|
||
border-color: #EA580C;
|
||
box-shadow: 0 4rpx 14rpx rgba(234, 88, 12, 0.25);
|
||
|
||
.hash-tag,
|
||
.topic-name {
|
||
color: #FFFFFF;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.gallery-section {
|
||
.gallery-grid {
|
||
.grid-img-item {
|
||
background: #FAF7F2;
|
||
|
||
.remove-btn {
|
||
background: rgba(41, 37, 36, 0.85);
|
||
border-color: #FFFFFF;
|
||
}
|
||
}
|
||
|
||
.add-img-tile {
|
||
background: #FAF7F2;
|
||
border-color: #D6D3D1;
|
||
|
||
.tile-icon-circle {
|
||
background: #F0ECE4;
|
||
}
|
||
.tile-label {
|
||
color: #57534E;
|
||
}
|
||
.tile-count {
|
||
color: #A8A29E;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.meta-row .location-pill {
|
||
background: #FAF7F2;
|
||
border-color: #E7E5E4;
|
||
|
||
.loc-name {
|
||
color: #EA580C;
|
||
}
|
||
}
|
||
|
||
.modal-footer-row {
|
||
.action-btn-cancel {
|
||
background: #F5F5F4;
|
||
color: #78716C;
|
||
}
|
||
.action-btn-submit {
|
||
background: linear-gradient(135deg, #EA580C, #F59E0B);
|
||
box-shadow: 0 6rpx 20rpx rgba(234, 88, 12, 0.35);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.comment-drawer-mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.7);
|
||
backdrop-filter: blur(8px);
|
||
z-index: 999;
|
||
display: flex;
|
||
align-items: flex-end;
|
||
justify-content: center;
|
||
}
|
||
|
||
.comment-drawer-content {
|
||
width: 100%;
|
||
max-width: 600px;
|
||
height: 65vh;
|
||
background: #151D30;
|
||
border-top-left-radius: 36rpx;
|
||
border-top-right-radius: 36rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||
border-bottom: none;
|
||
box-shadow: 0 -8rpx 32rpx rgba(0, 0, 0, 0.5);
|
||
animation: slideUp 0.25s ease-out;
|
||
|
||
.drawer-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 32rpx 36rpx 20rpx;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||
|
||
.drawer-header-left {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 12rpx;
|
||
|
||
.drawer-title {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #F8FAFC;
|
||
}
|
||
.drawer-badge {
|
||
font-size: 26rpx;
|
||
color: #94A3B8;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.drawer-close {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.close-icon {
|
||
width: 36rpx;
|
||
height: 36rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.comments-scroll {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: 24rpx 36rpx;
|
||
|
||
.comments-loading,
|
||
.comments-empty {
|
||
padding: 80rpx 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
|
||
.empty-icon {
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
opacity: 0.5;
|
||
}
|
||
|
||
.loading-text,
|
||
.empty-text {
|
||
font-size: 26rpx;
|
||
color: #94A3B8;
|
||
}
|
||
}
|
||
|
||
.comments-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 28rpx;
|
||
|
||
.comment-item {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
|
||
.comment-avatar {
|
||
width: 68rpx;
|
||
height: 68rpx;
|
||
border-radius: 50%;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.comment-body {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8rpx;
|
||
|
||
.comment-top {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
.comment-author {
|
||
font-size: 26rpx;
|
||
font-weight: 600;
|
||
color: #E2E8F0;
|
||
}
|
||
.comment-time {
|
||
font-size: 22rpx;
|
||
color: #64748B;
|
||
}
|
||
}
|
||
|
||
.comment-content {
|
||
font-size: 26rpx;
|
||
color: #CBD5E1;
|
||
line-height: 1.5;
|
||
word-break: break-all;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.comment-input-bar {
|
||
padding: 20rpx 36rpx calc(24rpx + env(safe-area-inset-bottom));
|
||
background: #0E1628;
|
||
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20rpx;
|
||
|
||
.comment-input {
|
||
flex: 1;
|
||
height: 72rpx;
|
||
background: rgba(255, 255, 255, 0.06);
|
||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||
border-radius: 36rpx;
|
||
padding: 0 28rpx;
|
||
font-size: 26rpx;
|
||
color: #F8FAFC;
|
||
}
|
||
|
||
.comment-send-btn {
|
||
width: 120rpx;
|
||
height: 72rpx;
|
||
line-height: 72rpx;
|
||
font-size: 26rpx;
|
||
font-weight: 600;
|
||
border-radius: 36rpx;
|
||
background: linear-gradient(135deg, #6366F1 0%, #4F46E5 100%);
|
||
color: #FFFFFF;
|
||
text-align: center;
|
||
padding: 0;
|
||
box-shadow: 0 4rpx 12rpx rgba(99, 102, 241, 0.35);
|
||
|
||
&:disabled {
|
||
opacity: 0.5;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.theme-warm {
|
||
.comment-drawer-content {
|
||
background: #FFFFFF;
|
||
border-color: #E7E5E4;
|
||
box-shadow: 0 -8rpx 32rpx rgba(0, 0, 0, 0.1);
|
||
|
||
.drawer-header {
|
||
border-bottom-color: #F5F2EC;
|
||
|
||
.drawer-header-left {
|
||
.drawer-title {
|
||
color: #1C1917;
|
||
}
|
||
.drawer-badge {
|
||
color: #78716C;
|
||
}
|
||
}
|
||
}
|
||
|
||
.comments-scroll {
|
||
.comments-list {
|
||
.comment-item {
|
||
.comment-body {
|
||
.comment-top {
|
||
.comment-author {
|
||
color: #1C1917;
|
||
}
|
||
.comment-time {
|
||
color: #A8A29E;
|
||
}
|
||
}
|
||
.comment-content {
|
||
color: #44403C;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.comment-input-bar {
|
||
background: #FDFBF7;
|
||
border-top-color: #E7E5E4;
|
||
|
||
.comment-input {
|
||
background: #F5F2EC;
|
||
border-color: #E7E5E4;
|
||
color: #1C1917;
|
||
}
|
||
|
||
.comment-send-btn {
|
||
background: linear-gradient(135deg, #F97316 0%, #EA580C 100%);
|
||
box-shadow: 0 4rpx 12rpx rgba(234, 88, 12, 0.35);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|