v0.0.4 帖子内容集成

This commit is contained in:
zpc 2025-11-16 21:28:05 +08:00
parent b829eb35ad
commit 89d620dd91
7 changed files with 300 additions and 17 deletions

View File

@ -1,6 +1,8 @@
using Microsoft.AspNetCore.Mvc;
using ZR.LiveForum.Model.Liveforum.Dto;
using Microsoft.AspNetCore.Mvc;
using ZR.LiveForum.Model.Liveforum;
using ZR.LiveForum.Model.Liveforum.Dto;
using ZR.Model;
using ZR.Service.Liveforum.ILiveforumService;
//创建时间2025-11-16
@ -16,10 +18,14 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum
/// 论坛帖子接口
/// </summary>
private readonly IT_PostsService _T_PostsService;
private readonly IT_LikesService _T_LikesService;
private readonly IT_CommentsService _T_CommentsService;
public T_PostsController(IT_PostsService T_PostsService)
public T_PostsController(IT_PostsService T_PostsService, IT_LikesService T_LikesService, IT_CommentsService T_CommentsService)
{
_T_PostsService = T_PostsService;
_T_LikesService = T_LikesService;
_T_CommentsService = T_CommentsService;
}
/// <summary>
@ -124,5 +130,41 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum
return ExportExcel(result.Item2, result.Item1);
}
/// <summary>
/// 获取帖子的点赞列表
/// </summary>
/// <param name="postId">帖子ID</param>
/// <param name="parm">分页参数</param>
/// <returns></returns>
[HttpGet("{postId}/likes")]
[ActionPermissionFilter(Permission = "tposts:query")]
public IActionResult GetPostLikes([FromRoute] long postId, [FromQuery] PagerInfo parm)
{
var response = _T_LikesService.GetLikesByPostId(postId, parm);
return SUCCESS(response);
}
/// <summary>
/// 获取帖子的评论列表
/// </summary>
/// <param name="postId">帖子ID</param>
/// <param name="parm">分页参数</param>
/// <returns></returns>
[HttpGet("{postId}/comments")]
[ActionPermissionFilter(Permission = "tposts:query")]
public IActionResult GetPostComments([FromRoute] long postId, [FromQuery] PagerInfo parm)
{
var queryDto = new T_CommentsQueryDto
{
PostId = postId,
PageNum = parm.PageNum,
PageSize = parm.PageSize,
Sort = parm.Sort,
SortType = parm.SortType
};
var response = _T_CommentsService.GetList(queryDto);
return SUCCESS(response);
}
}
}

View File

@ -12,6 +12,13 @@ namespace ZR.Service.Liveforum.ILiveforumService
T_Likes GetInfo(long Id);
/// <summary>
/// 根据帖子ID查询该帖子的所有点赞记录
/// </summary>
/// <param name="postId">帖子ID</param>
/// <param name="parm">分页参数</param>
/// <returns></returns>
PagedInfo<T_LikesDto> GetLikesByPostId(long postId, PagerInfo parm);
T_Likes AddT_Likes(T_Likes parm);
int UpdateT_Likes(T_Likes parm);

View File

@ -98,6 +98,36 @@ namespace ZR.Service.Liveforum
return Update(model, true);
}
/// <summary>
/// 根据帖子ID查询该帖子的所有点赞记录
/// </summary>
/// <param name="postId">帖子ID</param>
/// <param name="parm">分页参数</param>
/// <returns></returns>
public PagedInfo<T_LikesDto> GetLikesByPostId(long postId, PagerInfo parm)
{
var query = Queryable()
.Where(l => l.TargetType == 1 && l.TargetId == postId)
.LeftJoin<T_Users>((l, u) => l.UserId == u.Id);
// 默认按创建时间倒序
query = query.OrderBy((l, u) => l.CreatedAt, OrderByType.Desc);
var response = query.Select((l, u) => new T_LikesDto()
{
Id = l.Id,
UserId = l.UserId,
TargetType = l.TargetType,
TargetId = l.TargetId,
CreatedAt = l.CreatedAt,
UserName = u.NickName,
TargetInfo = null, // 帖子点赞时不需要显示目标信息
}, true);
var resp = ToPage(response, parm);
return resp;
}
/// <summary>
/// 查询导出表达式
/// </summary>

View File

@ -60,3 +60,29 @@ export function deltposts(pid) {
export async function exporttposts(query) {
await downFile('liveforum/tposts/export', { ...query })
}
/**
* 获取帖子的点赞列表
* @param {帖子ID} postId
* @param {查询条件} query
*/
export function getPostLikes(postId, query) {
return request({
url: 'liveforum/tposts/' + postId + '/likes',
method: 'get',
params: query,
})
}
/**
* 获取帖子的评论列表
* @param {帖子ID} postId
* @param {查询条件} query
*/
export function getPostComments(postId, query) {
return request({
url: 'liveforum/tposts/' + postId + '/comments',
method: 'get',
params: query,
})
}

View File

@ -56,7 +56,7 @@
<el-dialog :title="title" :lock-scroll="false" v-model="open" >
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="20">
<el-col :lg="12">
<el-form-item label="协议标题" prop="title">
@ -69,14 +69,14 @@
<editor v-model="form.content" :min-height="200" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="协议类型" prop="agreementType">
<el-select v-model="form.agreementType" placeholder="请选择协议类型">
<el-option
v-for="item in options.liveforum_agreements_type"
:key="item.dictValue"
:label="item.dictLabel"
v-for="item in options.liveforum_agreements_type"
:key="item.dictValue"
:label="item.dictLabel"
:value="parseInt(item.dictValue)"></el-option>
</el-select>
</el-form-item>
@ -118,9 +118,9 @@
<script setup name="tagreements">
import { listtagreements,
addtagreements, deltagreements,
updatetagreements,gettagreements,
}
addtagreements, deltagreements,
updatetagreements,gettagreements,
}
from '@/api/liveforum/tagreements.js'
import Editor from '@/components/Editor'
const { proxy } = getCurrentInstance()
@ -331,4 +331,4 @@ function handleDelete(row) {
handleQuery()
</script>
</script>

View File

@ -92,8 +92,32 @@
<el-table-column prop="content" label="正文内容" align="center" width="250" :show-overflow-tooltip="true" v-if="columns.showColumn('content')"/>
<el-table-column prop="categoryId" label="分类ID" align="center" width="100" v-if="columns.showColumn('categoryId')"/>
<el-table-column prop="viewCount" label="浏览次数" align="center" width="100" v-if="columns.showColumn('viewCount')"/>
<el-table-column prop="likeCount" label="点赞数量" align="center" width="100" v-if="columns.showColumn('likeCount')"/>
<el-table-column prop="commentCount" label="评论数量" align="center" width="100" v-if="columns.showColumn('commentCount')"/>
<el-table-column prop="likeCount" label="点赞数量" align="center" width="100" v-if="columns.showColumn('likeCount')">
<template #default="scope">
<el-link
v-if="scope.row.likeCount > 0"
type="primary"
:underline="false"
@click="handleViewLikes(scope.row)"
style="cursor: pointer;">
{{ scope.row.likeCount }}
</el-link>
<span v-else style="color: #999;">{{ scope.row.likeCount || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="commentCount" label="评论数量" align="center" width="100" v-if="columns.showColumn('commentCount')">
<template #default="scope">
<el-link
v-if="scope.row.commentCount > 0"
type="primary"
:underline="false"
@click="handleViewComments(scope.row)"
style="cursor: pointer;">
{{ scope.row.commentCount }}
</el-link>
<span v-else style="color: #999;">{{ scope.row.commentCount || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="shareCount" label="分享次数" align="center" width="100" v-if="columns.showColumn('shareCount')"/>
<el-table-column prop="isTop" label="是否置顶" align="center" width="100" v-if="columns.showColumn('isTop')">
<template #default="scope">
@ -133,7 +157,7 @@
</template>
</el-table-column>
</el-table>
<pagination :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="title" :lock-scroll="false" v-model="open" >
@ -292,7 +316,7 @@
</template>
</el-table-column>
</el-table>
<pagination :total="imageTotal" :page="imageQueryParams.pageNum" :limit="imageQueryParams.pageSize" @pagination="getImageList" />
<pagination :total="imageTotal" v-model:page="imageQueryParams.pageNum" v-model:limit="imageQueryParams.pageSize" @pagination="getImageList" />
<!-- 添加图片表单对话框 -->
<el-dialog
@ -346,6 +370,68 @@
</template>
</el-dialog>
</el-dialog>
<!-- 点赞列表弹窗 -->
<el-dialog
:title="'点赞列表 - ' + currentPostForLikes.title"
v-model="likeDialogOpen"
width="60%"
:lock-scroll="false"
@close="closeLikeDialog">
<el-table
:data="likeList"
v-loading="likeLoading"
border
header-cell-class-name="el-table-header-cell"
highlight-current-row>
<el-table-column prop="id" label="ID" align="center" width="80"/>
<el-table-column prop="userName" label="用户昵称" align="center" width="150" :show-overflow-tooltip="true"/>
<el-table-column prop="userId" label="用户ID" align="center" width="100"/>
<el-table-column prop="createdAt" label="点赞时间" :show-overflow-tooltip="true" width="180"/>
</el-table>
<pagination :total="likeTotal" v-model:page="likeQueryParams.pageNum" :limit="likeQueryParams.pageSize" @pagination="getLikeList" />
</el-dialog>
<!-- 评论列表弹窗 -->
<el-dialog
:title="'评论列表 - ' + currentPostForComments.title"
v-model="commentDialogOpen"
width="80%"
:lock-scroll="false"
@close="closeCommentDialog">
<el-table
:data="commentList"
v-loading="commentLoading"
border
header-cell-class-name="el-table-header-cell"
highlight-current-row>
<el-table-column prop="id" label="ID" align="center" width="80"/>
<el-table-column prop="userName" label="评论者" align="center" width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="replyToUserName" label="被回复用户" align="center" width="120" :show-overflow-tooltip="true">
<template #default="scope">
<span v-if="scope.row.replyToUserName">{{ scope.row.replyToUserName }}</span>
<span v-else style="color: #999;">-</span>
</template>
</el-table-column>
<el-table-column prop="content" label="评论内容" align="left" width="300" :show-overflow-tooltip="true">
<template #default="scope">
<div :style="{ paddingLeft: scope.row.parentCommentId ? '30px' : '0', position: 'relative' }">
<span v-if="scope.row.parentCommentId" style="color: #409eff; font-weight: bold;">回复</span>
<span>{{ scope.row.content }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="likeCount" label="点赞数" align="center" width="80"/>
<el-table-column prop="replyCount" label="回复数" align="center" width="80"/>
<el-table-column prop="status" label="状态" align="center" width="100">
<template #default="scope">
<dict-tag :options="options.liveforum_posts_comments" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column prop="createdAt" label="创建时间" :show-overflow-tooltip="true" width="180"/>
</el-table>
<pagination :total="commentTotal" v-model:page="commentQueryParams.pageNum" v-model:limit="commentQueryParams.pageSize" @pagination="getCommentList" />
</el-dialog>
</div>
</template>
@ -353,6 +439,7 @@
import { listtposts,
addtposts, deltposts,
updatetposts,gettposts,
getPostLikes, getPostComments,
}
from '@/api/liveforum/tposts.js'
import { listtpostimages,
@ -442,6 +529,7 @@ const imageFormRules = {
var dictParams = [
"liveforum_action_bool",
"liveforum_posts_status",
"liveforum_posts_comments",
]
proxy.getDicts(dictParams).then((response) => {
@ -812,5 +900,95 @@ function closeImageManageDialog() {
imageIds.value = []
}
/*************** 点赞列表相关方法 ***************/
//
const likeDialogOpen = ref(false)
const currentPostForLikes = ref({ id: null, title: '' })
const likeList = ref([])
const likeTotal = ref(0)
const likeLoading = ref(false)
const likeQueryParams = reactive({
pageNum: 1,
pageSize: 10,
})
//
function handleViewLikes(row) {
currentPostForLikes.value = {
id: row.id,
title: row.title || '未命名帖子'
}
likeQueryParams.pageNum = 1
likeDialogOpen.value = true
getLikeList()
}
//
function getLikeList() {
likeLoading.value = true
getPostLikes(currentPostForLikes.value.id, likeQueryParams).then(res => {
const { code, data } = res
if (code == 200) {
likeList.value = data.result
likeTotal.value = data.totalNum
likeLoading.value = false
}
})
}
//
function closeLikeDialog() {
likeDialogOpen.value = false
currentPostForLikes.value = { id: null, title: '' }
likeList.value = []
likeTotal.value = 0
likeQueryParams.pageNum = 1
}
/*************** 评论列表相关方法 ***************/
//
const commentDialogOpen = ref(false)
const currentPostForComments = ref({ id: null, title: '' })
const commentList = ref([])
const commentTotal = ref(0)
const commentLoading = ref(false)
const commentQueryParams = reactive({
pageNum: 1,
pageSize: 10,
})
//
function handleViewComments(row) {
currentPostForComments.value = {
id: row.id,
title: row.title || '未命名帖子'
}
commentQueryParams.pageNum = 1
commentDialogOpen.value = true
getCommentList()
}
//
function getCommentList() {
commentLoading.value = true
getPostComments(currentPostForComments.value.id, commentQueryParams).then(res => {
const { code, data } = res
if (code == 200) {
commentList.value = data.result
commentTotal.value = data.totalNum
commentLoading.value = false
}
})
}
//
function closeCommentDialog() {
commentDialogOpen.value = false
currentPostForComments.value = { id: null, title: '' }
commentList.value = []
commentTotal.value = 0
commentQueryParams.pageNum = 1
}
handleQuery()
</script>

View File

@ -64,7 +64,7 @@
</template>
</el-table-column>
</el-table>
<pagination :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="title" :lock-scroll="false" v-model="open">