793 lines
19 KiB
Vue
793 lines
19 KiB
Vue
<template>
|
||
<div class="comments-content">
|
||
<h4>评论</h4>
|
||
|
||
<!-- 评论列表 -->
|
||
<div class="comment-list" v-if="displayComments.length > 0">
|
||
<div class="comment-item" v-for="comment in displayComments" :key="comment.id">
|
||
<div class="comment-avatar">
|
||
<img :src="comment.avatar" :alt="comment.username" />
|
||
</div>
|
||
<div class="comment-content">
|
||
<div class="comment-header">
|
||
<span class="comment-username">{{ comment.username }}</span>
|
||
<span v-if="comment.userType === 'instructor'" class="instructor-badge">{{ comment.userBadge }}</span>
|
||
<span v-else-if="comment.userType === 'student'" class="student-badge">{{ comment.userBadge }}</span>
|
||
</div>
|
||
<div class="comment-text">{{ comment.content }}</div>
|
||
<div class="comment-actions">
|
||
<button v-if="comment.isPinned" class="action-btn">
|
||
<span class="top">置顶评论</span>
|
||
</button>
|
||
<button class="action-btn">
|
||
<span>{{ comment.time }}</span>
|
||
</button>
|
||
<button class="action-btn" @click="likeComment(comment)">
|
||
<span>{{ comment.isLiked ? '已点赞' : '点赞' }} ({{ comment.likeCount }})</span>
|
||
</button>
|
||
<button v-if="!comment.replies || comment.replies.length === 0" class="action-btn"
|
||
@click="startReply(comment.id, comment.username)">
|
||
回复
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 回复区域 -->
|
||
<div class="comment-replies" v-if="comment.replies && comment.replies.length > 0">
|
||
<div class="reply-item instructor-reply" v-for="reply in comment.replies" :key="reply.id">
|
||
<div class="reply-avatar">
|
||
<img :src="reply.avatar" :alt="reply.username" />
|
||
</div>
|
||
<div class="reply-content">
|
||
<div class="reply-main">
|
||
<div class="reply-header">
|
||
<span class="reply-username">{{ reply.username }}</span>
|
||
<span class="reply-badge instructor">{{ reply.badge }}</span>
|
||
</div>
|
||
<div class="reply-text">{{ reply.content }}</div>
|
||
</div>
|
||
<div class="reply-footer">
|
||
<span class="reply-time">{{ reply.time }}</span>
|
||
<div class="reply-actions">
|
||
<button class="reply-action-btn">回复</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 回复输入框 -->
|
||
<div v-if="replyingTo === comment.id" class="reply-input-section">
|
||
<div class="reply-input-header">
|
||
<span>回复 @{{ replyToUsername }}:</span>
|
||
</div>
|
||
<div class="reply-input-content">
|
||
<textarea v-model="replyContent" class="reply-textarea" placeholder="请输入回复内容..." :maxlength="500"
|
||
rows="3"></textarea>
|
||
<div class="reply-input-actions">
|
||
<button class="reply-cancel-btn" @click="cancelReply">取消</button>
|
||
<button class="reply-submit-btn" @click="submitReply">发送</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 空状态 -->
|
||
<div v-else-if="!loading && !error" class="empty-state">
|
||
<div class="empty-content">
|
||
<h3 class="empty-title">暂无评论</h3>
|
||
<p class="empty-description">还没有人发表评论,快来抢沙发吧!</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 加载状态 -->
|
||
<div v-if="loading" class="loading-container">
|
||
<div class="loading-content">
|
||
<p>正在加载评论...</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 错误状态 -->
|
||
<div v-if="error" class="error-container">
|
||
<div class="error-content">
|
||
<p>{{ error }}</p>
|
||
<button @click="loadComments" class="retry-btn">重试</button>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, onMounted, computed } from 'vue'
|
||
import { useRoute } from 'vue-router'
|
||
import { useMessage } from 'naive-ui'
|
||
import { CommentApi } from '@/api/modules/comment'
|
||
|
||
// 路由和消息
|
||
const route = useRoute()
|
||
const message = useMessage()
|
||
|
||
// 课程ID
|
||
const courseId = computed(() => route.params.id as string)
|
||
|
||
// 评论数据
|
||
const displayComments = ref<any[]>([])
|
||
|
||
const loading = ref(false)
|
||
const error = ref('')
|
||
|
||
// 回复相关
|
||
const replyingTo = ref<number | null>(null)
|
||
const replyToUsername = ref('')
|
||
const replyContent = ref('')
|
||
|
||
// 时间格式化函数
|
||
const formatTime = (timeStr: string) => {
|
||
try {
|
||
const date = new Date(timeStr)
|
||
const now = new Date()
|
||
const diff = now.getTime() - date.getTime()
|
||
|
||
// 小于1分钟
|
||
if (diff < 60000) {
|
||
return '刚刚'
|
||
}
|
||
|
||
// 小于1小时
|
||
if (diff < 3600000) {
|
||
return `${Math.floor(diff / 60000)}分钟前`
|
||
}
|
||
|
||
// 小于1天
|
||
if (diff < 86400000) {
|
||
return `${Math.floor(diff / 3600000)}小时前`
|
||
}
|
||
|
||
// 小于7天
|
||
if (diff < 604800000) {
|
||
return `${Math.floor(diff / 86400000)}天前`
|
||
}
|
||
|
||
// 超过7天显示具体日期
|
||
return date.toLocaleDateString('zh-CN', {
|
||
year: 'numeric',
|
||
month: '2-digit',
|
||
day: '2-digit',
|
||
hour: '2-digit',
|
||
minute: '2-digit'
|
||
}).replace(/\//g, '.')
|
||
} catch (error) {
|
||
return timeStr
|
||
}
|
||
}
|
||
|
||
// 加载评论数据
|
||
const loadComments = async () => {
|
||
if (!courseId.value) {
|
||
console.error('❌ 课程ID不存在')
|
||
return
|
||
}
|
||
|
||
try {
|
||
loading.value = true
|
||
error.value = ''
|
||
|
||
console.log('🚀 开始加载课程评论:', courseId.value)
|
||
|
||
// 调用评论API - 使用正确的接口路径
|
||
const response = await CommentApi.getCourseComments(Number(courseId.value), {
|
||
page: 1,
|
||
pageSize: 20,
|
||
sortBy: 'newest'
|
||
})
|
||
|
||
console.log('📊 评论API响应:', response)
|
||
|
||
if (response.data && response.data.code === 200) {
|
||
const comments = response.data.result || []
|
||
|
||
// 转换API数据格式
|
||
const apiComments = comments.map((comment: any) => {
|
||
// 调试:打印原始评论数据
|
||
console.log('🔍 原始评论数据:', comment)
|
||
console.log('🔍 用户身份相关字段:', {
|
||
userType: comment.userType,
|
||
user_type: comment.user_type,
|
||
role: comment.role,
|
||
isTeacher: comment.isTeacher,
|
||
is_teacher: comment.is_teacher,
|
||
userRole: comment.userRole,
|
||
user_role: comment.user_role,
|
||
type: comment.type,
|
||
userCategory: comment.userCategory,
|
||
user_category: comment.user_category
|
||
})
|
||
|
||
// 根据接口数据判断用户身份
|
||
let userType = 'user'
|
||
let userBadge = '用户'
|
||
|
||
// 检查是否是讲师/教师 - 扩展更多可能的字段
|
||
if (comment.userType === 'teacher' || comment.user_type === 'teacher' ||
|
||
comment.role === 'teacher' || comment.role === 'instructor' ||
|
||
comment.isTeacher === true || comment.is_teacher === true ||
|
||
comment.userRole === 'teacher' || comment.user_role === 'teacher' ||
|
||
comment.type === 'teacher' || comment.type === 'instructor' ||
|
||
comment.userCategory === 'teacher' || comment.user_category === 'teacher') {
|
||
userType = 'instructor'
|
||
userBadge = '讲师'
|
||
console.log('✅ 识别为讲师')
|
||
}
|
||
// 检查是否是学生
|
||
else if (comment.userType === 'student' || comment.user_type === 'student' ||
|
||
comment.role === 'student' || comment.isStudent === true ||
|
||
comment.is_student === true ||
|
||
comment.userRole === 'student' || comment.user_role === 'student' ||
|
||
comment.type === 'student' ||
|
||
comment.userCategory === 'student' || comment.user_category === 'student') {
|
||
userType = 'student'
|
||
userBadge = '学生'
|
||
console.log('✅ 识别为学生')
|
||
} else {
|
||
console.log('❌ 未识别用户身份,默认为用户')
|
||
}
|
||
|
||
return {
|
||
id: comment.id,
|
||
username: comment.userName || comment.username || '匿名用户',
|
||
avatar: comment.userAvatar || comment.avatar || '/images/activity/1.png',
|
||
time: formatTime(comment.createTime || comment.create_time),
|
||
content: comment.content,
|
||
isPinned: comment.isPinned || comment.izTop === 1,
|
||
type: comment.isPinned ? 'pinned' : 'comment',
|
||
likeCount: comment.likeCount || 0,
|
||
isLiked: comment.isLiked || false,
|
||
userType: userType,
|
||
userBadge: userBadge,
|
||
replies: (comment.replies || []).map((reply: any) => {
|
||
// 调试:打印原始回复数据
|
||
console.log('🔍 原始回复数据:', reply)
|
||
console.log('🔍 回复用户身份相关字段:', {
|
||
userType: reply.userType,
|
||
user_type: reply.user_type,
|
||
role: reply.role,
|
||
isTeacher: reply.isTeacher,
|
||
is_teacher: reply.is_teacher,
|
||
userRole: reply.userRole,
|
||
user_role: reply.user_role,
|
||
type: reply.type,
|
||
userCategory: reply.userCategory,
|
||
user_category: reply.user_category
|
||
})
|
||
|
||
// 根据接口数据判断用户身份
|
||
let userType = 'user'
|
||
let userBadge = '用户'
|
||
|
||
// 检查是否是讲师/教师 - 扩展更多可能的字段
|
||
if (reply.userType === 'teacher' || reply.user_type === 'teacher' ||
|
||
reply.role === 'teacher' || reply.role === 'instructor' ||
|
||
reply.isTeacher === true || reply.is_teacher === true ||
|
||
reply.userRole === 'teacher' || reply.user_role === 'teacher' ||
|
||
reply.type === 'teacher' || reply.type === 'instructor' ||
|
||
reply.userCategory === 'teacher' || reply.user_category === 'teacher') {
|
||
userType = 'instructor'
|
||
userBadge = '讲师'
|
||
console.log('✅ 回复识别为讲师')
|
||
}
|
||
// 检查是否是学生
|
||
else if (reply.userType === 'student' || reply.user_type === 'student' ||
|
||
reply.role === 'student' || reply.isStudent === true ||
|
||
reply.is_student === true ||
|
||
reply.userRole === 'student' || reply.user_role === 'student' ||
|
||
reply.type === 'student' ||
|
||
reply.userCategory === 'student' || reply.user_category === 'student') {
|
||
userType = 'student'
|
||
userBadge = '学生'
|
||
console.log('✅ 回复识别为学生')
|
||
} else {
|
||
console.log('❌ 回复未识别用户身份,默认为用户')
|
||
}
|
||
|
||
return {
|
||
id: reply.id || `reply_${Date.now()}`,
|
||
username: reply.userName || reply.username || reply.user_name || '匿名用户',
|
||
avatar: reply.userAvatar || reply.avatar || reply.user_avatar || '/images/activity/1.png',
|
||
time: formatTime(reply.createTime || reply.create_time || reply.time),
|
||
content: reply.content || reply.text || '',
|
||
type: userType,
|
||
badge: userBadge
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
// 只使用API返回的真实数据
|
||
displayComments.value = apiComments
|
||
|
||
console.log('✅ API评论数据:', apiComments.length, '条')
|
||
console.log('✅ 转换后的评论数据:', displayComments.value)
|
||
|
||
// 调试:查看API返回的原始回复数据
|
||
if (comments.length > 0 && comments[0].replies) {
|
||
console.log('🔍 API原始回复数据:', comments[0].replies)
|
||
}
|
||
} else {
|
||
console.warn('⚠️ 评论API返回数据为空或失败')
|
||
// 显示空状态
|
||
displayComments.value = []
|
||
}
|
||
} catch (err: any) {
|
||
console.error('❌ 加载评论失败:', err)
|
||
console.error('❌ 错误详情:', {
|
||
message: err.message,
|
||
status: err.response?.status,
|
||
statusText: err.response?.statusText,
|
||
data: err.response?.data,
|
||
url: err.config?.url
|
||
})
|
||
error.value = `加载评论失败: ${err.response?.status || err.message}`
|
||
|
||
// 显示空状态
|
||
displayComments.value = []
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
// 开始回复
|
||
const startReply = (commentId: number, username: string) => {
|
||
replyingTo.value = commentId
|
||
replyToUsername.value = username
|
||
}
|
||
|
||
// 提交回复
|
||
const submitReply = async () => {
|
||
if (!replyContent.value.trim()) {
|
||
message.warning('请输入回复内容')
|
||
return
|
||
}
|
||
|
||
try {
|
||
console.log('🚀 发送回复请求:', {
|
||
content: replyContent.value,
|
||
targetType: 'comment',
|
||
targetId: replyingTo.value
|
||
})
|
||
|
||
// 使用专门的回复接口
|
||
const response = await CommentApi.replyComment({
|
||
content: replyContent.value,
|
||
targetType: 'comment',
|
||
targetId: String(replyingTo.value),
|
||
parentId: replyingTo.value || undefined
|
||
})
|
||
|
||
console.log('📊 回复API响应:', response)
|
||
|
||
if (response.data && response.data.code === 200) {
|
||
message.success('回复成功')
|
||
replyContent.value = ''
|
||
replyingTo.value = null
|
||
replyToUsername.value = ''
|
||
|
||
// 重新加载评论
|
||
await loadComments()
|
||
} else {
|
||
message.error(response.data?.message || '回复失败')
|
||
}
|
||
} catch (err) {
|
||
console.error('❌ 回复失败:', err)
|
||
message.error('回复失败,请重试')
|
||
}
|
||
}
|
||
|
||
// 点赞评论
|
||
const likeComment = async (comment: any) => {
|
||
try {
|
||
console.log('🚀 发送点赞请求:', comment.id)
|
||
|
||
const response = await CommentApi.likeComment(comment.id)
|
||
|
||
console.log('📊 点赞API响应:', response)
|
||
|
||
if (response.data && response.data.code === 200) {
|
||
comment.isLiked = !comment.isLiked
|
||
comment.likeCount += comment.isLiked ? 1 : -1
|
||
message.success(comment.isLiked ? '点赞成功' : '取消点赞')
|
||
} else {
|
||
message.error(response.data?.message || '操作失败')
|
||
}
|
||
} catch (err) {
|
||
console.error('❌ 点赞失败:', err)
|
||
message.error('点赞失败,请重试')
|
||
}
|
||
}
|
||
|
||
// 取消回复
|
||
const cancelReply = () => {
|
||
replyContent.value = ''
|
||
replyingTo.value = null
|
||
replyToUsername.value = ''
|
||
}
|
||
|
||
// 组件挂载时加载数据
|
||
onMounted(() => {
|
||
loadComments()
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
.comments-content h4 {
|
||
font-size: 18px;
|
||
font-weight: 500;
|
||
color: #333;
|
||
margin: 0 0 12px 0;
|
||
}
|
||
|
||
.comment-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 20px;
|
||
}
|
||
|
||
.comment-item {
|
||
display: flex;
|
||
gap: 12px;
|
||
}
|
||
|
||
.comment-avatar img {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
.comment-content {
|
||
flex: 1;
|
||
}
|
||
|
||
.comment-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.comment-username {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
.instructor-badge {
|
||
display: inline-block;
|
||
padding: 2px 6px;
|
||
background: #EEF9FF;
|
||
color: #008BD7;
|
||
font-size: 10px;
|
||
border-radius: 2px;
|
||
margin-left: 8px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.student-badge {
|
||
display: inline-block;
|
||
padding: 2px 6px;
|
||
background: #fff7e6;
|
||
color: #fa8c16;
|
||
font-size: 10px;
|
||
border-radius: 2px;
|
||
margin-left: 8px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.comment-text {
|
||
font-size: 14px;
|
||
line-height: 1.6;
|
||
color: #333;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.comment-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16px;
|
||
}
|
||
|
||
.action-btn {
|
||
background: none;
|
||
border: none;
|
||
font-size: 12px;
|
||
color: #999;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 14px;
|
||
transition: color 0.3s;
|
||
}
|
||
|
||
.action-btn:hover {
|
||
color: #1890ff;
|
||
}
|
||
|
||
.action-btn .top {
|
||
background: #FFF4F4;
|
||
color: #FF304B;
|
||
padding: 4px 6px;
|
||
border-radius: 20px;
|
||
font-size: 10px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* 回复和二级评论样式 */
|
||
.comment-replies {
|
||
margin-top: 12px;
|
||
}
|
||
|
||
.reply-item {
|
||
display: flex;
|
||
gap: 12px;
|
||
margin-bottom: 16px;
|
||
position: relative;
|
||
}
|
||
|
||
.reply-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.reply-avatar {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.reply-avatar img {
|
||
width: 24px;
|
||
height: 24px;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
.reply-content {
|
||
flex: 1;
|
||
}
|
||
|
||
.reply-main {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 12px;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.reply-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.reply-username {
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
.reply-badge {
|
||
width: 32px;
|
||
height: 20px;
|
||
text-align: center;
|
||
line-height: 20px;
|
||
font-size: 10px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.reply-badge.instructor {
|
||
background: #EEF9FF;
|
||
color: #008BD7;
|
||
}
|
||
|
||
.reply-badge.user {
|
||
background: #f6ffed;
|
||
color: #52c41a;
|
||
}
|
||
|
||
.reply-badge.student {
|
||
background: #fff7e6;
|
||
color: #fa8c16;
|
||
}
|
||
|
||
.reply-badge.teacher {
|
||
background: #f6ffed;
|
||
color: #52c41a;
|
||
}
|
||
|
||
.reply-time {
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
|
||
.reply-text {
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
color: #333;
|
||
flex: 1;
|
||
}
|
||
|
||
.reply-footer {
|
||
display: flex;
|
||
justify-content: left;
|
||
align-items: center;
|
||
margin-top: 8px;
|
||
gap: 15px;
|
||
}
|
||
|
||
.reply-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
|
||
.reply-action-btn {
|
||
background: none;
|
||
border: none;
|
||
font-size: 12px;
|
||
color: #999;
|
||
cursor: pointer;
|
||
transition: color 0.3s;
|
||
}
|
||
|
||
.reply-action-btn:hover {
|
||
color: #1890ff;
|
||
}
|
||
|
||
/* 空状态样式 */
|
||
.empty-state {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding: 60px 20px;
|
||
min-height: 200px;
|
||
}
|
||
|
||
.empty-content {
|
||
text-align: center;
|
||
max-width: 300px;
|
||
}
|
||
|
||
|
||
.empty-title {
|
||
font-size: 18px;
|
||
font-weight: 500;
|
||
color: #374151;
|
||
margin: 0 0 8px 0;
|
||
}
|
||
|
||
.empty-description {
|
||
font-size: 14px;
|
||
color: #6B7280;
|
||
margin: 0 0 24px 0;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
|
||
/* 加载和错误状态样式 */
|
||
.loading-container,
|
||
.error-container {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding: 40px 20px;
|
||
}
|
||
|
||
.loading-content,
|
||
.error-content {
|
||
text-align: center;
|
||
}
|
||
|
||
.loading-content p,
|
||
.error-content p {
|
||
color: #666;
|
||
font-size: 14px;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.retry-btn {
|
||
background: #1890ff;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 16px;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.retry-btn:hover {
|
||
background: #40a9ff;
|
||
}
|
||
|
||
/* 回复输入框样式 */
|
||
.reply-input-section {
|
||
margin-top: 16px;
|
||
padding: 16px;
|
||
background: #f8f9fa;
|
||
border-radius: 8px;
|
||
border: 1px solid #e9ecef;
|
||
}
|
||
|
||
.reply-input-header {
|
||
margin-bottom: 12px;
|
||
font-size: 14px;
|
||
color: #666;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.reply-input-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
}
|
||
|
||
.reply-textarea {
|
||
width: 100%;
|
||
min-height: 80px;
|
||
padding: 12px;
|
||
border: 1px solid #d9d9d9;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
resize: vertical;
|
||
outline: none;
|
||
transition: border-color 0.3s;
|
||
}
|
||
|
||
.reply-textarea:focus {
|
||
border-color: #1890ff;
|
||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
||
}
|
||
|
||
.reply-textarea::placeholder {
|
||
color: #bfbfbf;
|
||
}
|
||
|
||
.reply-input-actions {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
gap: 12px;
|
||
}
|
||
|
||
.reply-cancel-btn {
|
||
padding: 6px 16px;
|
||
border: 1px solid #d9d9d9;
|
||
background: white;
|
||
color: #666;
|
||
border-radius: 4px;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.reply-cancel-btn:hover {
|
||
border-color: #40a9ff;
|
||
color: #40a9ff;
|
||
}
|
||
|
||
.reply-submit-btn {
|
||
padding: 6px 16px;
|
||
border: none;
|
||
background: #1890ff;
|
||
color: white;
|
||
border-radius: 4px;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: background 0.3s;
|
||
}
|
||
|
||
.reply-submit-btn:hover {
|
||
background: #40a9ff;
|
||
}
|
||
|
||
.reply-submit-btn:active {
|
||
background: #096dd9;
|
||
}
|
||
</style>
|