package com.example.job.controller.api;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.job.entity.Comment;
import com.example.job.entity.FavoritePost;
import com.example.job.entity.Post;
import com.example.job.entity.ReplyComment;
import com.example.job.entity.Student;
import com.example.job.service.ICommentService;
import com.example.job.service.IFavoritePostService;
import com.example.job.service.IPostService;
import com.example.job.service.IReplyCommentService;
import com.example.job.service.IStudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 小程序端 - 论坛帖子接口
*/
@RestController
@RequestMapping("/api/posts")
public class PostApiController {
@Autowired
private IPostService postService;
@Autowired
private ICommentService commentService;
@Autowired
private IReplyCommentService replyCommentService;
@Autowired
private IFavoritePostService favoritePostService;
@Autowired
private IStudentService studentService;
/**
* 获取帖子列表 (分页 + 搜索)
* @param page 页码
* @param size 每页数量
* @param keyword 搜索关键词 (匹配标题或内容, 可选)
* @return 分页后的帖子列表
*/
@GetMapping
public ResponseEntity<?> getPosts(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(required = false) String keyword) {
Page<Post> postPage = new Page<>(page, size);
QueryWrapper<Post> queryWrapper = new QueryWrapper<>();
// 只查询已发布的帖子
queryWrapper.eq("show_state", "已发布");
// 添加关键词搜索
if (StringUtils.hasText(keyword)) {
queryWrapper.and(qw -> qw.like("title", keyword).or().like("content", keyword));
}
// 按发布日期降序排列
queryWrapper.orderByDesc("publish_date");
Page<Post> resultPage = postService.page(postPage, queryWrapper);
// 批量查发帖人信息,防止IN ()报错
Set<Integer> stuidSet = resultPage.getRecords().stream()
.map(Post::getStuid)
.filter(java.util.Objects::nonNull)
.collect(java.util.stream.Collectors.toSet());
Map<Integer, Student> studentMap = stuidSet.isEmpty() ? new HashMap<>() :
studentService.listByIds(stuidSet)
.stream().collect(java.util.stream.Collectors.toMap(Student::getStuid, s -> s));
// 组装DTO
List<Map<String, Object>> dtoList = resultPage.getRecords().stream().map(post -> {
Map<String, Object> dto = new HashMap<>();
dto.put("post", post);
Student stu = studentMap.get(post.getStuid());
dto.put("userName", stu != null ? stu.getName() : "未知用户");
dto.put("userAvatar", "/static/avatar/default.png"); // 默认头像
return dto;
}).collect(java.util.stream.Collectors.toList());
Map<String, Object> pageResult = new HashMap<>();
pageResult.put("records", dtoList);
pageResult.put("total", resultPage.getTotal());
pageResult.put("size", resultPage.getSize());
pageResult.put("current", resultPage.getCurrent());
return ResponseEntity.ok(pageResult);
}
/**
* 获取帖子详情
* @param postid 帖子ID
* @param stuid 学生ID (可选),用于判断是否已收藏
* @return 帖子详情
*/
@GetMapping("/{postid}")
public ResponseEntity<?> getPostDetail(@PathVariable Integer postid, @RequestParam(required = false) Integer stuid) {
Post post = postService.getById(postid);
if (post != null && "已发布".equals(post.getShowState())) {
Student student = studentService.getById(post.getStuid());
Map<String, Object> result = new HashMap<>();
result.put("post", post);
result.put("userName", student != null ? student.getName() : "未知用户");
result.put("userAvatar", "/static/avatar/default.png"); // 默认头像
// 检查当前用户是否已收藏该帖子
if (stuid != null) {
QueryWrapper<FavoritePost> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("postid", postid).eq("stuid", stuid);
boolean isFavorited = favoritePostService.count(queryWrapper) > 0;
result.put("isFavorited", isFavorited);
} else {
result.put("isFavorited", false);
}
return ResponseEntity.ok(result);
} else {
return ResponseEntity.notFound().build();
}
}
/**
* 发布新帖子
* @param post 帖子内容 (需要包含 title, content)
* @param stuid 学生ID (实际应用中应从认证信息获取)
* @return 创建的帖子信息
*/
@PostMapping
public ResponseEntity<?> createPost(@RequestBody Post post, @RequestParam Integer stuid) {
if (!StringUtils.hasText(post.getTitle()) || !StringUtils.hasText(post.getContent())) {
return ResponseEntity.badRequest().body("标题和内容不能为空");
}
post.setStuid(stuid);
post.setPublishDate(LocalDate.now());
post.setShowState("已发布"); // 默认直接发布
// post.setAdminid(null); // 管理员ID默认为空
// post.setHideDate(null);
boolean success = postService.save(post);
// 返回创建后的帖子,包含生成的 postid
return success ? ResponseEntity.ok(post) : ResponseEntity.internalServerError().body("发布失败");
}
// --- 收藏相关 ---
/**
* 收藏帖子
* @param postid 帖子ID
* @param stuid 学生ID
* @return 操作结果
*/
@PostMapping("/{postid}/favorite")
public ResponseEntity<?> favoritePost(@PathVariable Integer postid, @RequestParam Integer stuid) {
QueryWrapper<FavoritePost> checkWrapper = new QueryWrapper<>();
checkWrapper.eq("postid", postid).eq("stuid", stuid);
if (favoritePostService.count(checkWrapper) > 0) {
return ResponseEntity.badRequest().body("已收藏该帖子");
}
FavoritePost favoritePost = new FavoritePost();
favoritePost.setPostid(postid);
favoritePost.setStuid(stuid);
favoritePost.setFavoriteDate(LocalDate.now());
boolean success = favoritePostService.save(favoritePost);
return success ? ResponseEntity.ok("收藏成功") : ResponseEntity.internalServerError().body("收藏失败");
}
/**
* 取消收藏帖子
* @param postid 帖子ID
* @param stuid 学生ID
* @return 操作结果
*/
@DeleteMapping("/{postid}/favorite")
public ResponseEntity<?> unfavoritePost(@PathVariable Integer postid, @RequestParam Integer stuid) {
QueryWrapper<FavoritePost> deleteWrapper = new QueryWrapper<>();
deleteWrapper.eq("postid", postid).eq("stuid", stuid);
boolean success = favoritePostService.remove(deleteWrapper);
return success ? ResponseEntity.ok("取消收藏成功") : ResponseEntity.internalServerError().body("取消收藏失败");
}
// --- 评论相关 ---
/**
* 获取帖子的评论列表 (分页)
* @param postid 帖子ID
* @param page 页码
* @param size 每页数量
* @return 评论列表
*/
@GetMapping("/{postid}/comments")
public ResponseEntity<?> getComments(
@PathVariable Integer postid,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
Page<Comment> commentPage = new Page<>(page, size);
QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("postid", postid);
queryWrapper.eq("show_state", "已发布"); // 只显示已发布的评论
queryWrapper.orderByAsc("publish_date"); // 按发布时间升序
Page<Comment> resultPage = commentService.page(commentPage, queryWrapper);
// 批量查评论人信息,防止IN ()报错
Set<Integer> stuidSet = resultPage.getRecords().stream()
.map(Comment::getStuid)
.filter(java.util.Objects::nonNull)
.collect(java.util.stream.Collectors.toSet());
Map<Integer, Student> studentMap = stuidSet.isEmpty() ? new HashMap<>() :
studentService.listByIds(stuidSet)
.stream().collect(java.util.stream.Collectors.toMap(Student::getStuid, s -> s));
// 组装DTO
List<Map<String, Object>> dtoList = resultPage.getRecords().stream().map(comment -> {
Map<String, Object> dto = new HashMap<>();
dto.put("comment", comment);
Student stu = studentMap.get(comment.getStuid());
dto.put("userName", stu != null ? stu.getName() : "匿名用户");
dto.put("userAvatar", "/static/avatar/default.png"); // 默认头像
return dto;
}).collect(java.util.stream.Collectors.toList());
Map<String, Object> pageResult = new HashMap<>();
pageResult.put("records", dtoList);
pageResult.put("total", resultPage.getTotal());
pageResult.put("size", resultPage.getSize());
pageResult.put("current", resultPage.getCurrent());
return ResponseEntity.ok(pageResult);
}
/**
* 发布评论
* @param postid 帖子ID
* @param comment 评论内容 (需要包含 content)
* @param stuid 学生ID
* @return 创建的评论信息
*/
@PostMapping("/{postid}/comments")
public ResponseEntity<?> createComment(@PathVariable Integer postid, @RequestBody Comment comment, @RequestParam Integer stuid) {
if (!StringUtils.hasText(comment.getContent())) {
return ResponseEntity.badRequest().body("评论内容不能为空");
}
comment.setPostid(postid);
comment.setStuid(stuid);
comment.setPublishDate(LocalDate.now());
comment.setShowState("已发布");
boolean success = commentService.save(comment);
return success ? ResponseEntity.ok(comment) : ResponseEntity.internalServerError().body("评论失败");
}
// --- 回复评论相关 ---
/**
* 获取评论的回复列表 (分页)
* @param commentid 评论ID
* @param page 页码
* @param size 每页数量
* @return 回复列表
*/
@GetMapping("/comments/{commentid}/replies")
public ResponseEntity<?> getReplies(
@PathVariable Integer commentid,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
Page<ReplyComment> replyPage = new Page<>(page, size);
QueryWrapper<ReplyComment> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("comid", commentid);
queryWrapper.eq("show_state", "已发布");
queryWrapper.orderByAsc("reply_date");
Page<ReplyComment> resultPage = replyCommentService.page(replyPage, queryWrapper);
// 批量查学生信息,防止IN ()报错
Set<Integer> stuidSet = resultPage.getRecords().stream()
.map(ReplyComment::getStuid)
.filter(java.util.Objects::nonNull)
.collect(java.util.stream.Collectors.toSet());
Map<Integer, Student> studentMap = stuidSet.isEmpty() ? new HashMap<>() :
studentService.listByIds(stuidSet)
.stream().collect(java.util.stream.Collectors.toMap(Student::getStuid, s -> s));
// 组装DTO
List<Map<String, Object>> dtoList = resultPage.getRecords().stream().map(reply -> {
Map<String, Object> dto = new HashMap<>();
dto.put("replyid", reply.getStuid());
dto.put("content", reply.getContent());
dto.put("replyDate", reply.getReplyDate());
Student stu = studentMap.get(reply.getStuid());
dto.put("userName", stu != null ? stu.getName() : "匿名用户");
return dto;
}).collect(java.util.stream.Collectors.toList());
Map<String, Object> pageResult = new HashMap<>();
pageResult.put("records", dtoList);
pageResult.put("total", resultPage.getTotal());
pageResult.put("size", resultPage.getSize());
pageResult.put("current", resultPage.getCurrent());
return ResponseEntity.ok(pageResult);
}
/**
* 回复评论
* @param commentid 评论ID
* @param reply 回复内容 (需要包含 content)
* @param stuid 学生ID
* @return 创建的回复信息
*/
@PostMapping("/comments/{commentid}/replies")
public ResponseEntity<?> createReply(@PathVariable Integer commentid, @RequestBody ReplyComment reply, @RequestParam Integer stuid) {
if (!StringUtils.hasText(reply.getContent())) {
return ResponseEntity.badRequest().body("回复内容不能为空");
}
// 检查父评论是否存在且可见
Comment parentComment = commentService.getById(commentid);
if (parentComment == null || !"已发布".equals(parentComment.getShowState())) {
return ResponseEntity.badRequest().body("评论不存在或已被隐藏");
}
reply.setComid(commentid);
reply.setStuid(stuid);
reply.setReplyDate(LocalDate.now());
reply.setShowState("已发布");
boolean success = replyCommentService.save(reply);
return success ? ResponseEntity.ok(reply) : ResponseEntity.internalServerError().body("回复失败");
}
/**
* 获取当前学生发布的帖子列表(分页)
* @param stuid 学生ID
* @param page 页码
* @param size 每页数量
* @return 分页后的帖子列表(带userName、userAvatar等)
*/
@GetMapping("/my")
public ResponseEntity<?> getMyPosts(
@RequestParam Integer stuid,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
Page<Post> postPage = new Page<>(page, size);
QueryWrapper<Post> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("stuid", stuid);
queryWrapper.eq("show_state", "已发布");
queryWrapper.orderByDesc("publish_date");
Page<Post> resultPage = postService.page(postPage, queryWrapper);
// 查学生信息
Student stu = studentService.getById(stuid);
String userName = stu != null ? stu.getName() : "未知用户";
String userAvatar = "/static/avatar/default.png";
// 组装DTO
List<Map<String, Object>> dtoList = resultPage.getRecords().stream().map(post -> {
Map<String, Object> dto = new HashMap<>();
dto.put("postid", post.getPostid());
dto.put("title", post.getTitle());
dto.put("content", post.getContent());
dto.put("publishTime", post.getPublishDate());
dto.put("stuid", post.getStuid());
dto.put("showState", post.getShowState());
dto.put("adminid", post.getAdminid());
dto.put("hideDate", post.getHideDate());
dto.put("userName", userName);
dto.put("userAvatar", userAvatar);
return dto;
}).collect(java.util.stream.Collectors.toList());
Map<String, Object> pageResult = new HashMap<>();
pageResult.put("records", dtoList);
pageResult.put("total", resultPage.getTotal());
pageResult.put("size", resultPage.getSize());
pageResult.put("current", resultPage.getCurrent());
return ResponseEntity.ok(pageResult);
}
}
<template>
<view class="container">
<view class="post-detail-card">
<!-- 头部:文字头像、用户名、发布时间 -->
<view class="card-header">
<TextAvatar :userName="post.userName" class="main-avatar" />
<view class="user-info">
<text class="username">{{ post.userName }}</text>
<text class="publish-time">{{ post.publishTime }}</text>
</view>
</view>
<!-- 帖子标题 -->
<text class="post-title">{{ post.title }}</text>
<!-- 内容 -->
<view class="card-content">
<text class="content-text">{{ post.content }}</text>
</view>
<!-- 图片 -->
<view class="card-images" v-if="post.images && post.images.length > 0">
<image v-for="(img, idx) in post.images" :key="idx" :src="img" mode="aspectFill" class="post-image"></image>
</view>
</view>
<!-- 操作栏:只保留收藏和评论,图标样式 -->
<view class="icon-action-bar">
<uni-icons type="star" size="28" :color="isFavorited ? '#ffc107' : '#bbb'" @click="toggleFavorite" class="icon-btn"></uni-icons>
<uni-icons type="chatbubble" size="28" color="#9BC6FC" class="icon-btn" @click="onToggleCommentInput"></uni-icons>
</view>
<!-- 评论列表 -->
<view class="comment-section">
<view v-for="item in commentList" :key="item.comment.comid" class="comment-item">
<TextAvatar :userName="item.userName" :isSmall="true" class="comment-avatar" />
<view class="comment-content" @click="onCommentClick(item)">
<text class="comment-username">{{ item.userName }}</text>
<text class="comment-text">{{ item.comment.content }}</text>
<text class="comment-time">{{ item.comment.publishDate }}</text>
<!-- 回复区 -->
<view v-if="item.replies && item.replies.length" class="reply-list">
<view v-for="reply in item.replies" :key="reply.replyid" class="reply-item">
<TextAvatar :userName="reply.userName" :isSmall="true" class="reply-avatar" />
<text class="reply-username">{{ reply.userName }}</text>
<text class="reply-content">{{ reply.content }}</text>
<text class="reply-time">{{ reply.replyDate }}</text>
</view>
</view>
</view>
</view>
<view v-if="!commentList.length && !loadingComments" class="no-comment">暂无评论</view>
</view>
<!-- 评论输入框 -->
<view class="comment-input-bar" v-if="showCommentInput">
<input v-model="commentContent" placeholder="写下你的评论..." class="comment-input"/>
<button class="send-btn" @click="submitComment">发送</button>
</view>
<!-- 回复输入框,仅发帖人可见 -->
<view class="reply-input-bar" v-if="showReplyInput">
<input v-model="replyContent" placeholder="回复内容..." class="reply-input" />
<button class="send-btn" @click="submitReply">发送</button>
</view>
</view>
</template>
<script>
import { getPostDetail, favoritePost, unfavoritePost, getComments, createComment, getReplies } from '@/api/index.js';
import uniIcons from '@/uni_modules/uni-icons/components/uni-icons/uni-icons.vue';
import TextAvatar from '@/components/TextAvatar.vue';
export default {
components: {
uniIcons,
TextAvatar
},
data() {
return {
postId: null,
post: {},
defaultAvatar: '/static/avatar/default.png',
isFavorited: false,
commentList: [],
commentContent: '',
loadingComments: false,
showCommentInput: false,
replyToCommentId: null, // 当前要回复的评论ID
replyContent: '', // 回复内容
showReplyInput: false // 是否显示回复输入框
};
},
onLoad(options) {
this.postId = options.id;
this.fetchPostDetail(this.postId);
},
methods: {
async fetchPostDetail(id) {
try {
const stuid = uni.getStorageSync('stuid');
const res = await getPostDetail(id, stuid);
// 适配后端返回结构
this.post = {
id: res.post?.postid || res.postid || res.id,
stuid: res.post?.stuid || res.stuid || '',
title: res.post?.title || res.title || '',
userName: res.userName || res.username || '匿名用户',
publishTime: res.post?.publishDate || res.publishDate || res.publishTime || '',
content: res.post?.content || res.content,
images: res.post?.images || res.images || []
};
// 明确处理收藏状态
this.isFavorited = res.isFavorited === true;
this.fetchComments();
if (this.post.userName) {
uni.setNavigationBarTitle({ title: this.post.userName + '的帖子' });
}
} catch (err) {
uni.showToast({ title: '获取帖子详情失败', icon: 'none' });
}
},
async toggleFavorite() {
const stuid = uni.getStorageSync('stuid') || 10001;
try {
if (!this.isFavorited) {
await favoritePost(this.postId, stuid);
this.isFavorited = true;
uni.showToast({ title: '收藏成功', icon: 'none' });
} else {
await unfavoritePost(this.postId, stuid);
this.isFavorited = false;
uni.showToast({ title: '取消收藏', icon: 'none' });
}
} catch (err) {
uni.showToast({ title: '操作失败', icon: 'none' });
}
},
async fetchComments() {
this.loadingComments = true;
try {
const res = await getComments(this.postId, { page: 1, size: 20 });
const commentArr = res.records || res.data || [];
// 并发获取每条评论的回复
await Promise.all(commentArr.map(async (item) => {
const replyRes = await getReplies(item.comment.comid, { page: 1, size: 10 });
item.replies = (replyRes.records || replyRes.data || []).map(r => ({
...r,
userName: r.userName || '匿名用户'
}));
}));
this.commentList = commentArr;
} catch (err) {
uni.showToast({ title: '获取评论失败', icon: 'none' });
} finally {
this.loadingComments = false;
}
},
async submitComment() {
if (!this.commentContent.trim()) {
uni.showToast({ title: '评论不能为空', icon: 'none' });
return;
}
const stuid = uni.getStorageSync('stuid') || 10001;
try {
await createComment(this.postId, { content: this.commentContent, stuid });
this.commentContent = '';
this.fetchComments();
uni.showToast({ title: '评论成功', icon: 'success' });
} catch (err) {
uni.showToast({ title: '评论失败', icon: 'none' });
}
},
// 点击评论图标
onToggleCommentInput() {
if (this.showReplyInput) {
// 如果回复框已显示,先关闭回复框
this.showReplyInput = false;
this.replyContent = '';
}
// 切换评论框显示状态
this.showCommentInput = !this.showCommentInput;
},
// 点击评论内容,显示回复输入框
onCommentClick(item) {
console.log('点击了评论内容', item);
// 只有发帖人才可以回复
const stuid = uni.getStorageSync('stuid');
console.log('当前登录stuid:', stuid, '帖子stuid:', this.post.stuid);
if (stuid && String(stuid) === String(this.post.stuid)) {
console.log('允许回复,显示回复输入框');
// 如果评论框已显示,先关闭评论框
if (this.showCommentInput) {
this.showCommentInput = false;
this.commentContent = '';
}
this.replyToCommentId = item.comment.comid;
this.showReplyInput = true;
this.replyContent = '';
} else {
console.log('非发帖人点击,不做任何操作');
// 非发帖人点击不做任何操作
return;
}
},
// 发送回复
async submitReply() {
if (!this.replyContent.trim()) {
uni.showToast({ title: '回复不能为空', icon: 'none' });
return;
}
const stuid = uni.getStorageSync('stuid');
try {
await this.$api.createReply(this.replyToCommentId, { content: this.replyContent, stuid });
this.replyContent = '';
this.showReplyInput = false;
this.fetchComments();
uni.showToast({ title: '回复成功', icon: 'success' });
} catch (err) {
uni.showToast({ title: '回复失败', icon: 'none' });
}
}
}
}
</script>
<style lang="scss" scoped>
.container {
background-color: #f8f8f8;
min-height: 100vh;
padding-bottom: 70px;
}
.post-detail-card {
background-color: #fff;
border-radius: 8px;
padding: 15px;
margin: 15px;
margin-bottom: 20px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.post-title {
display: block;
font-size: 17px;
font-weight: bold;
color: #222;
margin-bottom: 10px;
letter-spacing: 1px;
margin-top: 2px;
}
.card-header {
display: flex;
align-items: center;
margin-bottom: 6px;
.main-avatar {
width: 40px;
height: 40px;
font-size: 18px;
margin-right: 10px;
}
.user-info {
flex: 1;
display: flex;
flex-direction: column;
}
.username {
font-size: 14px;
font-weight: bold;
color: #333;
margin-bottom: 2px;
}
.publish-time {
font-size: 12px;
color: #999;
}
}
.card-content {
margin-bottom: 10px;
.content-text {
display: block;
font-size: 15px;
color: #333;
line-height: 1.6;
}
}
.card-images {
margin-bottom: 10px;
display: flex;
flex-wrap: wrap;
.post-image {
max-width: 48%;
margin-right: 2%;
margin-bottom: 8px;
max-height: 200px;
border-radius: 6px;
background-color: #f0f0f0;
}
.post-image:nth-child(2n) {
margin-right: 0;
}
}
.icon-action-bar {
display: flex;
justify-content: flex-start;
align-items: center;
margin: 10px 20px 10px 20px;
.icon-btn {
margin-right: 28px;
cursor: pointer;
transition: color 0.2s;
}
.icon-btn:active {
color: #9BC6FC;
}
}
.comment-section {
margin: 10px 0;
padding: 0 16px;
.comment-item {
display: flex;
align-items: flex-start;
margin-bottom: 14px;
padding-left: 2px;
padding-right: 2px;
.comment-avatar {
/* 由TextAvatar的small类控制尺寸 */
}
.comment-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
.comment-username {
font-size: 12px;
font-weight: bold;
color: #333;
margin-bottom: 2px;
}
.comment-text {
font-size: 12px;
color: #444;
margin-bottom: 2px;
display: block;
margin-top: 4px;
margin-left: 2px;
}
.comment-time {
font-size: 10px;
color: #aaa;
margin-top: 2px;
}
}
}
.no-comment {
color: #aaa;
text-align: center;
padding: 20px 0;
}
}
.comment-input-bar {
display: flex;
align-items: center;
padding: 10px 15px;
background-color: #ffffff;
border-top: 1px solid #eeeeee;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 100;
.comment-input {
flex: 1;
border: 1px solid #eee;
border-radius: 16px;
padding: 6px 12px;
margin-right: 8px;
}
.send-btn {
background: #9BC6FC;
color: #fff;
border-radius: 16px;
padding: 0 20px;
height: 36px;
line-height: 36px;
border: none;
font-weight: bold;
box-shadow: 0 1px 3px rgba(155,198,252,0.08);
transition: background 0.2s;
}
.send-btn:active {
background: #7bb0f7;
}
}
.reply-input-bar {
display: flex;
align-items: center;
padding: 8px 16px;
background: #f7f7f7;
border-top: 1px solid #eee;
.reply-input {
flex: 1;
height: 32px;
border: 1px solid #ddd;
border-radius: 16px;
padding: 0 12px;
font-size: 14px;
margin-right: 8px;
background: #fff;
}
.send-btn {
background: #9BC6FC;
color: #fff;
border: none;
border-radius: 16px;
padding: 0 16px;
height: 32px;
font-size: 14px;
}
}
.reply-list {
margin-top: 6px;
padding-left: 32px;
border-left: 2px solid #f0f0f0;
}
.reply-item {
display: flex;
align-items: center;
margin-bottom: 4px;
.reply-avatar {
width: 20px;
height: 20px;
font-size: 10px;
margin-right: 6px;
}
.reply-username {
font-size: 11px;
color: #6a8bad;
font-weight: bold;
margin-right: 4px;
}
.reply-content {
font-size: 11px;
color: #666;
margin-right: 4px;
}
.reply-time {
font-size: 10px;
color: #bbb;
}
}
</style> 回复失败,什么原因,怎么解决