YingXingAI/pages/notes/index.vue

447 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="notes-page">
<div class="header">
<div class="title">留言板</div>
<view class="custom-tabs-box">
<u-tabs
:list="tabList"
:current="tabCurrent"
@change="onTabChange"
:is-scroll="false"
:height="80"
:font-size="28"
active-color="#4A6CF7"
inactive-color="#333333"
:bar-width="120"
:bar-height="4"
bg-color="#ffffff"
:item-width="200"
item-style="padding-left: 0; padding-right: 0;"
></u-tabs>
</view>
</div>
<!-- 内容区域包装器 -->
<div class="content-wrapper">
<!-- 留言列表 -->
<scroll-view class="message-list" scroll-y>
<view v-for="(item, index) in currentMessages" :key="index">
<u-swipe-action
:options="swipeOptions"
:show="item.show"
:index="index"
@click="handleSwipeClick"
@open="e => handleSwipeOpen(e, index)"
@close="e => handleSwipeClose(e, index)"
@content-click="() => closeOther(index)"
:btn-width="80"
:disabled="false"
>
<view class="message-item">
<view class="message-header">
<view class="user-info">
<image class="avatar" :src="item.avatar || defaultAvatar"></image>
<text class="username">{{item.username}}</text>
</view>
<view class="message-time">{{item.time}}</view>
</view>
<view class="message-content">
<view class="question">
<view class="question-icon">问</view>
<view class="question-text">{{item.question}}</view>
</view>
<view class="reply-button" @click.stop="handleReply(item)" v-if="!item.reply">
<u-icon name="chat" color="#4a6cf7" size="16"></u-icon>
<text>回复</text>
</view>
<view class="reply-content" v-if="item.reply">
<view class="reply-header">
<view class="reply-icon">答</view>
<view class="reply-info">
<text>{{item.replyUser}}</text>
</view>
</view>
<view class="reply-text" :class="{'expanded': item.expanded}">{{item.reply}}</view>
<view class="expand-button" v-if="item.reply.length > 100" @click.stop="toggleExpand(item)">
{{ item.expanded ? '收起' : '展开' }} <u-icon :name="item.expanded ? 'arrow-up' : 'arrow-down'" size="12"></u-icon>
</view>
</view>
<view class="reply-button" @click.stop="handleReply(item)" v-if="item.reply">
<u-icon name="chat" color="#4a6cf7" size="16"></u-icon>
<text>回复</text>
</view>
</view>
</view>
</u-swipe-action>
</view>
<!-- 无数据提示 -->
<view class="empty-tip" v-if="currentMessages.length === 0">
暂无留言数据
</view>
</scroll-view>
</div>
<!-- 使用TabBar组件 -->
<TabBar :currentPath="'/pages/notes/index'" @change="handleTabChange" />
<!-- 开发中提示弹窗 -->
<u-modal
v-model="showDevModal"
:show-cancel-button="false"
title="提示"
content="该功能正在开发中敬请期待"
@confirm="showDevModal = false"
></u-modal>
</div>
</template>
<script>
import TabBar from '@/components/TabBar.vue';
export default {
name: 'NotesPage',
components: {
TabBar
},
data() {
return {
tabList: [
{ name: '未回复' },
{ name: '已回复' }
],
tabCurrent: 0,
activeTab: 'unread',
showDevModal: false,
defaultAvatar: '/static/avatar/default-avatar.png',
unreadMessages: [
{
id: 1,
avatar: '',
username: '浙江理工生13024',
time: '2023/6/26 15:45:12',
question: '学校在录取时有没有一些专业会有特殊要求?',
reply: '',
expanded: false,
show: false
},
{
id: 2,
avatar: '',
username: '理工13024',
time: '2023/6/26 15:45:12',
question: '在录取时有没有一些专业会有特殊要求?',
reply: '',
expanded: false,
show: false
}
],
repliedMessages: [
{
id: 3,
avatar: '',
username: '浙江理工生13024',
time: '2023/6/26 15:45:12',
question: '学校在录取时有没有一些专业会有特殊要求?',
reply: '学生与体健康状况必须符合教育部、卫生部、中国残疾人联合会印发的《普通高等学校招生体检工作指导意见》和人力资源社会保障部、原卫生部、原教育部、原公安部、原国家人口计划生育委员会制定的有关规定。原卫生部、原教育部、原公安部、原国家人口计划生育委员会制定的有关规定。',
replyUser: '系统回复',
expanded: false,
show: false
}
],
swipeOptions: [
{
text: '删除',
style: {
backgroundColor: '#fa3534',
color: '#ffffff',
fontSize: '15px'
}
}
]
};
},
computed: {
currentMessages() {
return this.activeTab === 'unread' ? this.unreadMessages : this.repliedMessages;
}
},
methods: {
onTabChange(index) {
this.tabCurrent = index;
// 根据索引设置activeTab值
this.activeTab = index === 0 ? 'unread' : 'replied';
// 切换选项卡时关闭所有打开的滑动按钮
this.closeAllSwipe();
},
switchTab(tab) {
this.activeTab = tab;
// 更新tabCurrent以匹配activeTab
this.tabCurrent = tab === 'unread' ? 0 : 1;
// 切换选项卡时关闭所有打开的滑动按钮
this.closeAllSwipe();
},
handleTabChange(path, index) {
console.log('切换到标签页:', path, index);
},
handleReply(item) {
this.showDevModal = true;
},
toggleExpand(item) {
item.expanded = !item.expanded;
},
handleSwipeClick(e) {
const {index} = e; // 当前点击的滑动单元格索引
const btnIndex = e.index; // 点击的按钮索引
if (btnIndex === 0) { // 删除按钮
// 删除当前消息
if (this.activeTab === 'unread') {
this.unreadMessages.splice(index, 1);
} else {
this.repliedMessages.splice(index, 1);
}
}
},
handleSwipeOpen(e, index) {
// 打开滑动按钮时,关闭其他打开的滑动按钮
this.closeOther(index);
},
handleSwipeClose(e, index) {
// 处理滑动关闭事件
if (this.activeTab === 'unread') {
this.unreadMessages[index].show = false;
} else {
this.repliedMessages[index].show = false;
}
},
closeOther(index) {
// 关闭除当前外的所有滑动按钮
if (this.activeTab === 'unread') {
this.unreadMessages.forEach((item, idx) => {
if (idx !== index) {
item.show = false;
}
});
} else {
this.repliedMessages.forEach((item, idx) => {
if (idx !== index) {
item.show = false;
}
});
}
},
closeAllSwipe() {
// 关闭所有滑动按钮
this.unreadMessages.forEach(item => {
item.show = false;
});
this.repliedMessages.forEach(item => {
item.show = false;
});
}
}
}
</script>
<style scoped>
.notes-page {
height: 100vh;
background-color: #f5f6fa;
display: flex;
flex-direction: column;
position: relative;
}
.header {
background-color: #fff;
padding-top: 10px;
}
.title {
font-size: 18px;
font-weight: 500;
text-align: center;
padding: 10px 0;
}
.custom-tabs-box {
padding-left: 20px; /* 添加左侧padding使tabs位于左侧 */
position: relative;
box-sizing: border-box;
}
.custom-tabs-box >>> .u-tabs__wrapper__nav__item {
padding: 0 20px 0 0 !important; /* 调整标签项的padding */
}
.custom-tabs-box >>> .u-tabs__wrapper__nav__line {
bottom: 0 !important; /* 确保下划线位于底部 */
height: 4px !important; /* 设置下划线高度 */
border-radius: 2px !important; /* 圆角 */
}
.content-wrapper {
flex: 1;
display: flex;
flex-direction: column;
padding-bottom: 60px; /* 为底部导航栏预留空间 */
overflow-y: auto; /* 允许内容滚动 */
}
/* 留言列表样式 */
.message-list {
flex: 1;
padding: 10px;
}
.message-item {
background-color: #fff;
padding: 15px;
margin-bottom: 10px;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.message-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.user-info {
display: flex;
align-items: center;
}
.avatar {
width: 24px;
height: 24px;
border-radius: 50%;
margin-right: 8px;
background-color: #eee;
}
.username {
font-size: 12px;
color: #666;
}
.message-time {
font-size: 12px;
color: #999;
}
.message-content {
position: relative;
}
.question {
display: flex;
margin-bottom: 10px;
}
.question-icon {
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #4a6cf7;
color: #fff;
font-size: 12px;
display: flex;
justify-content: center;
align-items: center;
margin-right: 8px;
flex-shrink: 0;
}
.question-text {
font-size: 14px;
line-height: 1.5;
flex: 1;
}
.reply-button {
height: 32px;
background-color: #f0f2fd;
color: #4a6cf7;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
margin-top: 10px;
cursor: pointer;
}
.reply-button text {
margin-left: 5px;
}
.reply-content {
background-color: #f8f8f8;
border-radius: 4px;
padding: 10px;
margin-top: 10px;
}
.reply-header {
display: flex;
align-items: center;
margin-bottom: 5px;
}
.reply-icon {
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #ff9500;
color: #fff;
font-size: 12px;
display: flex;
justify-content: center;
align-items: center;
margin-right: 8px;
}
.reply-info {
font-size: 12px;
color: #666;
}
.reply-text {
font-size: 14px;
line-height: 1.5;
color: #333;
margin-left: 28px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
.reply-text.expanded {
-webkit-line-clamp: unset;
}
.expand-button {
text-align: right;
font-size: 12px;
color: #4a6cf7;
margin-top: 5px;
cursor: pointer;
}
.empty-tip {
text-align: center;
padding: 20px;
color: #999;
font-size: 14px;
}
</style>