feat:完成评论功能搭建
15
Yi.BBS.Vue3/src/apis/commentApi.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import myaxios from '@/utils/request'
|
||||||
|
export function getListByDiscussId(discussId,data){
|
||||||
|
return myaxios({
|
||||||
|
url: `/comment/discuss-id/${discussId}`,
|
||||||
|
method: 'get',
|
||||||
|
params:data
|
||||||
|
})
|
||||||
|
};
|
||||||
|
export function add(data){
|
||||||
|
return myaxios({
|
||||||
|
url: `/comment`,
|
||||||
|
method: 'post',
|
||||||
|
data:data
|
||||||
|
})
|
||||||
|
};
|
||||||
46
Yi.BBS.Vue3/src/components/CommentInfo.vue
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<div v-for="item in commentList" :key="item.id">
|
||||||
|
第一级:{{ item.content }},id{{ item.id }} <el-button @click="replay(item.id,item.id)">回复</el-button>
|
||||||
|
<div v-for="children in item.children" :key="children.id">
|
||||||
|
-->> 第二级 {{ children.content }}, 评论者{{ children.createUser.nick }},
|
||||||
|
被回复者{{ children.commentedUser.nick }},id{{ children.id }}
|
||||||
|
<el-button @click="replay(children.id,item.id)">回复</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-input v-model="form.content"></el-input>
|
||||||
|
<el-button @click="addComment">发布</el-button>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, reactive, ref } from "vue";
|
||||||
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
import { getListByDiscussId, add } from "@/apis/commentApi.js";
|
||||||
|
//数据定义
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const commentList = ref([]);
|
||||||
|
const query = reactive({});
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
content: "",
|
||||||
|
discussId: route.params.discussId,
|
||||||
|
query,
|
||||||
|
parentId: 0,
|
||||||
|
rootId: 0,
|
||||||
|
});
|
||||||
|
onMounted(async () => {
|
||||||
|
await loadComment();
|
||||||
|
});
|
||||||
|
const loadComment = async () => {
|
||||||
|
const response = await getListByDiscussId(route.params.discussId, query);
|
||||||
|
commentList.value = response.data.items;
|
||||||
|
};
|
||||||
|
const addComment = async () => {
|
||||||
|
await add(form);
|
||||||
|
await loadComment();
|
||||||
|
};
|
||||||
|
const replay= async(parentId,rootId)=>{
|
||||||
|
form.parentId=parentId;
|
||||||
|
form.rootId=rootId;
|
||||||
|
await addComment();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -53,7 +53,11 @@
|
|||||||
</el-space>
|
</el-space>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="24" class="comment"> 文章评论 </el-col>
|
<el-col :span="24" class="comment">
|
||||||
|
|
||||||
|
<CommentInfo/>
|
||||||
|
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
@@ -121,6 +125,7 @@ import { h, ref, onMounted } from "vue";
|
|||||||
import AvatarInfo from "@/components/AvatarInfo.vue";
|
import AvatarInfo from "@/components/AvatarInfo.vue";
|
||||||
import InfoCard from "@/components/InfoCard.vue";
|
import InfoCard from "@/components/InfoCard.vue";
|
||||||
import ArticleContentInfo from "@/components/ArticleContentInfo.vue";
|
import ArticleContentInfo from "@/components/ArticleContentInfo.vue";
|
||||||
|
import CommentInfo from "@/components/CommentInfo.vue";
|
||||||
|
|
||||||
import TreeArticleInfo from "@/components/TreeArticleInfo.vue";
|
import TreeArticleInfo from "@/components/TreeArticleInfo.vue";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
<template #content >
|
<template #content >
|
||||||
<div class="introduce">
|
<div class="introduce">
|
||||||
|
|
||||||
没有什么能够阻挡,人类对代码<span style="color: #1890ff;">优雅</span>的最求
|
没有什么能够阻挡,人类对代码<span style="color: #1890ff;">优雅</span>的追求
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Yi.BBS.Application.Contracts.Exhibition.Dtos.Argee
|
||||||
|
{
|
||||||
|
public class ArgeeDto
|
||||||
|
{
|
||||||
|
public ArgeeDto(bool isArgee)
|
||||||
|
{
|
||||||
|
IsArgee = isArgee;
|
||||||
|
if (isArgee)
|
||||||
|
{
|
||||||
|
|
||||||
|
Message = "点赞成功,点赞+1";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
Message = "取消点赞,点赞-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsArgee { get; set; }
|
||||||
|
public string Message { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Cike.AutoWebApi.Setting;
|
||||||
|
using Yi.BBS.Application.Contracts.Exhibition.Dtos.Argee;
|
||||||
|
using Yi.BBS.Domain.Exhibition.Entities;
|
||||||
|
using Yi.BBS.Domain.Forum.Entities;
|
||||||
|
using Yi.Framework.Core.CurrentUsers;
|
||||||
|
using Yi.Framework.Ddd.Repositories;
|
||||||
|
using Yi.Framework.Ddd.Services;
|
||||||
|
using Yi.Framework.Ddd.Services.Abstract;
|
||||||
|
using Yi.Framework.Uow;
|
||||||
|
|
||||||
|
namespace Yi.BBS.Application.Exhibition
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 点赞功能
|
||||||
|
/// </summary>
|
||||||
|
[AppService]
|
||||||
|
public class AgreeService : ApplicationService, IApplicationService, IAutoApiService
|
||||||
|
{
|
||||||
|
|
||||||
|
[Autowired]
|
||||||
|
private IRepository<AgreeEntity> _repository { get; set; }
|
||||||
|
|
||||||
|
[Autowired]
|
||||||
|
private IRepository<DiscussEntity> _discssRepository { get; set; }
|
||||||
|
[Autowired]
|
||||||
|
private ICurrentUser _currentUser { get; set; }
|
||||||
|
|
||||||
|
[Autowired]
|
||||||
|
private IUnitOfWorkManager _unitOfWorkManager { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 点赞,返回true为点赞+1,返回false为点赞-1
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<ArgeeDto> PostOperateAsync(long discussId)
|
||||||
|
{
|
||||||
|
var entity = await _repository.GetFirstAsync(x => x.DiscussId == discussId && x.CreatorId == _currentUser.Id);
|
||||||
|
//判断是否已经点赞过
|
||||||
|
if (entity is null)
|
||||||
|
{
|
||||||
|
using (var uow = _unitOfWorkManager.CreateContext())
|
||||||
|
{
|
||||||
|
//没点赞过,添加记录即可,,修改总点赞数量
|
||||||
|
await _repository.InsertAsync(new AgreeEntity(discussId));
|
||||||
|
var discussEntity = await _discssRepository.GetByIdAsync(discussId);
|
||||||
|
if (discussEntity is null)
|
||||||
|
{
|
||||||
|
throw new UserFriendlyException("主题为空");
|
||||||
|
}
|
||||||
|
discussEntity.AgreeNum += 1;
|
||||||
|
await _discssRepository.UpdateAsync(discussEntity);
|
||||||
|
uow.Commit();
|
||||||
|
}
|
||||||
|
return new ArgeeDto(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using (var uow = _unitOfWorkManager.CreateContext())
|
||||||
|
{
|
||||||
|
//点赞过,删除即可,修改总点赞数量
|
||||||
|
await _repository.DeleteByIdAsync(entity.Id);
|
||||||
|
var discussEntity = await _discssRepository.GetByIdAsync(discussId);
|
||||||
|
if (discussEntity is null)
|
||||||
|
{
|
||||||
|
throw new UserFriendlyException("主题为空");
|
||||||
|
}
|
||||||
|
discussEntity.AgreeNum -= 1;
|
||||||
|
await _discssRepository.UpdateAsync(discussEntity);
|
||||||
|
uow.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArgeeDto(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SqlSugar;
|
||||||
|
using Yi.Framework.Data.Auditing;
|
||||||
|
using Yi.Framework.Data.Entities;
|
||||||
|
using Yi.Framework.Ddd.Entities;
|
||||||
|
|
||||||
|
namespace Yi.BBS.Domain.Exhibition.Entities
|
||||||
|
{
|
||||||
|
[SugarTable("Agree")]
|
||||||
|
public class AgreeEntity : IEntity<long>, ICreationAuditedObject
|
||||||
|
{
|
||||||
|
public AgreeEntity()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public AgreeEntity(long discussId)
|
||||||
|
{
|
||||||
|
DiscussId = discussId;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SugarColumn(IsPrimaryKey = true)]
|
||||||
|
public long Id { get; set; } = SnowflakeHelper.NextId;
|
||||||
|
public DateTime CreationTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主题id
|
||||||
|
/// </summary>
|
||||||
|
public long DiscussId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建者
|
||||||
|
/// </summary>
|
||||||
|
public long? CreatorId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 5.4 KiB |