347 lines
8.2 KiB
Vue
347 lines
8.2 KiB
Vue
<template>
|
|
<view class="message-board-component">
|
|
<!-- 一个列表一个swipe-action容器更符合官方推荐用法 -->
|
|
<view v-for="(item, index) in answerList" :key="item.id">
|
|
<uni-swipe-action>
|
|
<!-- :right-options="swipeOptions" -->
|
|
<uni-swipe-action-item
|
|
:disabled="!canSwipe"
|
|
:threshold="0.3"
|
|
:auto-close="false"
|
|
@change="(e) => handleSwipeChange(e, index)"
|
|
>
|
|
<template #right>
|
|
<view class="right-btn-box" @click.stop="handleSwipeClick(item, index, e)">
|
|
<image
|
|
class="right-btn"
|
|
src="/static/common/images/icon_delete.png"
|
|
></image>
|
|
<text>撤回</text>
|
|
</view>
|
|
</template>
|
|
|
|
<view class="answer-item-box">
|
|
<view
|
|
class="answer-item"
|
|
:class="{
|
|
'no-right-radius': openedItems[index] === 'right',
|
|
'is-web-mode': isWebMode,
|
|
}"
|
|
>
|
|
<view class="student-info">
|
|
<image
|
|
class="student-avatar"
|
|
:src="item.studentAvatar || AvatarDefault"
|
|
></image>
|
|
|
|
<view class="student-info-content">
|
|
<text class="student-name">{{ item.studentName }}</text>
|
|
<text class="answer-time">{{ item.time }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="question">
|
|
<image
|
|
class="question-tag"
|
|
src="/static/common/images/icon_ask.png"
|
|
></image>
|
|
<view class="question-content">{{ item.question }}</view>
|
|
</view>
|
|
|
|
<view v-if="item.isReply">
|
|
<view class="line"></view>
|
|
|
|
<view class="student-info">
|
|
<image
|
|
class="student-avatar"
|
|
:src="item.teacherAvatar || AvatarDefault"
|
|
></image>
|
|
|
|
<view class="student-info-content">
|
|
<text class="student-name">{{ item.teacherName }}</text>
|
|
<text class="answer-time">{{ item.replyTime }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="answer">
|
|
<image
|
|
class="answer-tag"
|
|
src="/static/common/images/icon_answer.png"
|
|
></image>
|
|
<view class="answer-content">
|
|
<view class="answer-text">{{ item.fullAnswer }}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 回复按钮-老师 -->
|
|
<view class="reply-btn-box" v-if="isTeacher">
|
|
<button class="reply-btn">
|
|
<image
|
|
class="reply-btn-icon"
|
|
src="/static/common/images/icon_reply.png"
|
|
></image
|
|
>回复
|
|
</button>
|
|
</view>
|
|
</view>
|
|
|
|
<view
|
|
v-if="isWebMode"
|
|
class="right-btn-box"
|
|
:class="{
|
|
'web-mode-cursor': isWebMode,
|
|
}"
|
|
@click.stop="handleWebModeClick(item)"
|
|
>
|
|
<image
|
|
class="right-btn"
|
|
src="/static/common/images/icon_delete.png"
|
|
></image>
|
|
<text>撤回</text>
|
|
</view>
|
|
</view>
|
|
</uni-swipe-action-item>
|
|
</uni-swipe-action>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import AvatarDefault from "@/static/common/images/avatar_default.jpg";
|
|
import UniSwipeAction from "@/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue";
|
|
|
|
export default {
|
|
name: "MessageBoard",
|
|
components: {
|
|
UniSwipeAction,
|
|
},
|
|
props: {
|
|
answerList: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
isTeacher: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
// 是否允许左滑
|
|
canSwipe: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
AvatarDefault, // 默认头像
|
|
openedItems: {}, // 记录每个项目的滑动状态
|
|
isWebMode: false, // 是否是web模式
|
|
};
|
|
},
|
|
mounted() {
|
|
// #ifdef H5
|
|
const userAgent = navigator.userAgent.toLowerCase();
|
|
this.isWebMode = !/mobile|android|iphone|ipod|ipad/.test(userAgent);
|
|
// #endif
|
|
|
|
console.log("isWebMode", this.isWebMode);
|
|
},
|
|
methods: {
|
|
// 处理左滑按钮点击
|
|
handleSwipeClick(item, index, e) {
|
|
console.log("按钮点击", item, index, e);
|
|
},
|
|
|
|
// 处理web模式点击
|
|
handleWebModeClick(item) {
|
|
console.log("web模式点击", item);
|
|
},
|
|
|
|
// 监听滑动状态变化
|
|
handleSwipeChange(isOpened, index) {
|
|
// 使用Vue的响应式更新方法来更新对象
|
|
this.$set(this.openedItems, index, isOpened);
|
|
console.log("滑动状态", this.openedItems);
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.message-board-component {
|
|
.right-btn-box {
|
|
width: 120rpx;
|
|
// height: inherit;
|
|
color: #ffffff;
|
|
background-color: #ff5252;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10rpx;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 0 16rpx 16rpx 0;
|
|
margin-bottom: 32rpx;
|
|
.right-btn {
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
}
|
|
}
|
|
|
|
.answer-item-box {
|
|
display: flex;
|
|
}
|
|
|
|
.answer-item {
|
|
flex: 1;
|
|
background-color: #ffffff;
|
|
border-radius: 16rpx;
|
|
padding: 32rpx;
|
|
margin-bottom: 32rpx;
|
|
position: relative;
|
|
/* 删除 overflow: hidden; 可能妨碍滑动 */
|
|
transition: border-radius 0.3s; /* 添加过渡效果使圆角变化更平滑 */
|
|
|
|
/* 滑动时移除右侧圆角 */
|
|
&.no-right-radius {
|
|
border-top-right-radius: 0;
|
|
border-bottom-right-radius: 0;
|
|
}
|
|
}
|
|
|
|
.is-web-mode {
|
|
cursor: default;
|
|
}
|
|
|
|
.web-mode-cursor {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.student-info {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 32rpx;
|
|
|
|
.student-avatar {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
border-radius: 50%;
|
|
margin-right: 16rpx;
|
|
}
|
|
|
|
.student-info-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
.student-name {
|
|
font-size: 28rpx;
|
|
color: #333333;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.answer-time {
|
|
font-size: 24rpx;
|
|
color: #666666;
|
|
}
|
|
}
|
|
}
|
|
|
|
.line {
|
|
width: 100%;
|
|
height: 1rpx;
|
|
background-color: rgba(238, 238, 238, 0.8);
|
|
margin: 28rpx 0;
|
|
}
|
|
|
|
.question {
|
|
display: flex;
|
|
margin-bottom: 24rpx;
|
|
|
|
.question-tag {
|
|
width: 42rpx;
|
|
height: 42rpx;
|
|
margin-right: 32rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.question-content {
|
|
font-size: 32rpx;
|
|
color: #333333;
|
|
flex: 1;
|
|
}
|
|
}
|
|
|
|
.answer {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
|
|
.answer-tag {
|
|
width: 42rpx;
|
|
height: 42rpx;
|
|
margin-right: 32rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.answer-content {
|
|
font-size: 24rpx;
|
|
line-height: 40rpx;
|
|
color: #666666;
|
|
flex: 1;
|
|
position: relative;
|
|
|
|
.answer-text {
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 3;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
}
|
|
}
|
|
|
|
.reply-btn-box {
|
|
width: 100%;
|
|
margin-top: 28rpx;
|
|
|
|
.reply-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 280rpx;
|
|
height: 64rpx;
|
|
background: #4f6aff;
|
|
border-radius: 16rpx;
|
|
font-size: 28rpx;
|
|
color: #ffffff;
|
|
margin-right: 0;
|
|
|
|
.reply-btn-icon {
|
|
width: 28rpx;
|
|
height: 28rpx;
|
|
margin-right: 12rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 自定义滑动按钮样式,保持简洁 */
|
|
::v-deep .uni-swipe-action__button {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
padding: 0 32rpx;
|
|
}
|
|
|
|
/* 自定义图标样式 - 如果使用默认图标系统 */
|
|
::v-deep .uni-swipe-action__button-icon {
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
}
|
|
|
|
/* 如果需要使用自定义图标 */
|
|
::v-deep .uni-swipe-action__button-image {
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
margin-right: 8rpx;
|
|
}
|
|
</style>
|