perf: 优化bbs前端整体显示

This commit is contained in:
橙子
2025-02-04 15:23:20 +08:00
parent 9a73789788
commit bce9b58265
10 changed files with 138 additions and 52 deletions

View File

@@ -77,6 +77,56 @@ namespace Yi.Framework.Bbs.Application.Services.Analyses
return output;
}
/// <summary>
/// 作者主题,返回当前作者最新的主题
/// </summary>
/// <returns></returns>
[HttpGet("analyse/bbs-discuss/author/{userId}")]
public async Task<List<DiscussGetListOutputDto>> GetAuthorDiscussAsync(
[FromRoute] Guid userId,
[FromQuery] PagedResultRequestDto input)
{
var output = await _forumManager._discussRepository._DbQueryable.Where(discuss=>discuss.CreatorId==userId)
.Where(discuss=>discuss.PermissionType== DiscussPermissionTypeEnum.Public)
.LeftJoin<UserAggregateRoot>((discuss, user) => discuss.CreatorId == user.Id)
.LeftJoin<BbsUserExtraInfoEntity>((discuss, user, info) => user.Id == info.UserId)
.OrderByDescending(discuss => discuss.CreationTime)
.Select((discuss, user, info) => new DiscussGetListOutputDto
{
Id = discuss.Id,
User = new BbsUserGetListOutputDto()
{
Id = user.Id,
UserName = user.UserName,
Nick = user.Nick,
Icon = user.Icon,
Level = info.Level,
UserLimit = info.UserLimit
}
}, true)
.ToPageListAsync(input.SkipCount, input.MaxResultCount);
var discussId = output.Select(x => x.Id);
//点赞字典key为主题idy为用户ids
var agreeDic =
(await _agreeRepository._DbQueryable.Where(x => discussId.Contains(x.DiscussId)).ToListAsync())
.GroupBy(x => x.DiscussId)
.ToDictionary(x => x.Key, y => y.Select(y => y.CreatorId).ToList());
//等级、是否点赞赋值
output?.ForEach(x =>
{
if (CurrentUser.Id is not null)
{
//默认fasle
if (agreeDic.TryGetValue(x.Id,out var userIds))
{
x.IsAgree = userIds.Contains(CurrentUser.Id);
}
}
});
return output;
}
}
}

View File

@@ -1,5 +1,20 @@
import request from "@/config/axios/service";
/**
* 获取作者主题
* @param userId
* @param {*} data
* @returns
*/
export function getAuthorTopic(userId,data) {
return request({
url: `/analyse/bbs-discuss/author/${userId}`,
method: "get",
data,
});
}
/**
* 获取推荐主题
* @param {*} data

View File

@@ -1,6 +1,7 @@
<template>
<el-badge class="box-card">
<el-card shadow="never" :style="{ 'border-color': discuss.color }">
<el-card shadow="never" :style="{ 'border-color': discuss.color }"
>
<div class="card-header">
<AvatarInfo :userInfo="discuss.user" />
</div>
@@ -157,8 +158,8 @@ onMounted(() => {
font-size: 14px;
margin: 5px 0;
}
.box-card {
position: relative;
width: 100%;
/* right: calc(1px + var(--el-badge-size)/ 2) !important; */

View File

@@ -1,7 +1,7 @@
<script setup>
import { ref } from "vue";
const props = defineProps(["items", "header", "text", "hideDivider", "height"]);
const props = defineProps(["items", "header", "text", "hideDivider", "height","isPadding"]);
const emit = defineEmits(['onClickText'])
const height = ref(props.height + "px");
@@ -11,7 +11,7 @@ const onClickText=()=>{
</script>
<template>
<el-card class="box-card" shadow="never">
<el-card class="box-card" shadow="never" :body-style="{padding: isPadding===false?'0px 20px':'20px 20px'}">
<template #header>
<div class="card-header">
<span>{{ props.header }}</span>
@@ -50,7 +50,6 @@ const onClickText=()=>{
justify-content: space-between;
align-items: center;
}
.text {
font-size: 14px;
}

View File

@@ -2,16 +2,16 @@
<el-scrollbar>
<div class="scrollbar-flex-content">
<div v-for="item in recommendList" :key="item.id" class="scrollbar-item">
<el-tooltip
class="box-item"
effect="dark"
:content="item.dictLabel"
placement="top"
v-if="item.dictLabel.length > 5"
>
{{ item.dictLabel.slice(0, 5) + "..." }}
</el-tooltip>
<span v-else>
<!-- <el-tooltip-->
<!-- class="box-item"-->
<!-- effect="dark"-->
<!-- :content="item.dictLabel"-->
<!-- placement="top"-->
<!-- v-if="item.dictLabel.length > 5"-->
<!-- >-->
<!-- {{ item.dictLabel.slice(0, 5) + "..." }}-->
<!-- </el-tooltip>-->
<span >
{{ item.dictLabel }}
</span>
</div>
@@ -35,12 +35,13 @@ onMounted(async () => {
display: flex;
}
.scrollbar-item {
padding: 0 15px;
cursor: pointer;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
width: 4rem;
//width: 4rem;
height: 2.6rem;
margin: 0 0.2rem;
text-align: center;

View File

@@ -1,5 +1,6 @@
<template>
<el-tree
<el-tree
empty-text="无子文章"
:data="props.data == '' ? [] : props.data"
:props="defaultProps"
@node-click="handleNodeClick"

View File

@@ -100,7 +100,7 @@ const router = createRouter({
path: "/article/:discussId",
component: () => import("../views/Article.vue"),
meta: {
title: "主题封面",
title: "主题首页",
},
},
{

View File

@@ -9,7 +9,7 @@
<el-button
style="width: 100%; margin-bottom: 0.8rem"
@click="loadDiscuss(true)"
>主题封面</el-button
>主题首页</el-button
>
<el-button
v-if="isAddArticle && isArticleUser"
@@ -19,7 +19,7 @@
>添加子文章</el-button
>
<!--目录在这里 -->
<el-scrollbar height="410px">
<el-scrollbar style="min-height: 410px">
<TreeArticleInfo
:data="articleData"
@remove="delArticle"
@@ -34,19 +34,19 @@
</InfoCard>
</el-col>
<el-col :span="24">
<InfoCard :items="items" header="作者分享" text="更多">
<InfoCard :items="authorList" :isPadding="false" header="作者分享" height="410" text="更多">
<template #item="temp">
<AvatarInfo />
</template>
</InfoCard>
</el-col>
<el-col :span="24">
<InfoCard :items="items" header="内容推荐" text="更多">
<template #item="temp">
<AvatarInfo />
<ThemeData :themeData="temp"/>
</template>
</InfoCard>
</el-col>
<!-- <el-col :span="24">-->
<!-- <InfoCard :items="items" header="内容推荐" text="更多">-->
<!-- <template #item="temp">-->
<!-- <AvatarInfo />-->
<!-- </template>-->
<!-- </InfoCard>-->
<!-- </el-col>-->
</el-row>
</el-col>
@@ -155,19 +155,24 @@
</InfoCard>
</el-col>
<el-col :span="24">
<InfoCard :items="items" header="其他" text="更多">
<InfoCard :items="themeList" :isPadding="false" header="推荐主题" text="更多" height="500">
<template #item="temp">
<AvatarInfo />
</template>
</InfoCard>
</el-col>
<el-col :span="24">
<InfoCard :items="items" header="其他" text="更多">
<template #item="temp">
<AvatarInfo />
<ThemeData :themeData="temp"/>
</template>
</InfoCard>
<!-- <InfoCard :items="items" header="其他" text="更多">-->
<!-- <template #item="temp">-->
<!-- <AvatarInfo />-->
<!-- </template>-->
<!-- </InfoCard>-->
</el-col>
<!-- <el-col :span="24">-->
<!-- <InfoCard :items="items" header="其他" text="更多">-->
<!-- <template #item="temp">-->
<!-- <AvatarInfo />-->
<!-- </template>-->
<!-- </InfoCard>-->
<!-- </el-col>-->
</el-row>
</el-col>
</el-row>
@@ -192,17 +197,20 @@ import {
import Breadcrumb from "@/components/Breadcrumb/index.vue";
import { getPermission } from "@/utils/auth";
import useUserStore from "@/stores/user.js";
import ThemeData from "@/views/home/components/RecommendTheme/index.vue";
import {getRecommendedTopic,getAuthorTopic} from "@/apis/analyseApi";
//数据定义
const route = useRoute();
const router = useRouter();
const spacer = h(ElDivider, { direction: "vertical" });
const items = [{ user: "用户1" }, { user: "用户2" }, { user: "用户3" }];
//子文章数据
const articleData = ref([]);
//主题内容
const discuss = ref({});
//推荐主题
const themeList=ref([]);
//作者主题
const authorList=ref([]);
//封面url
const getUrl = (str) => {
return `${import.meta.env.VITE_APP_BASEAPI}/file/${str}`;
@@ -369,11 +377,22 @@ const delArticle = (node, data) => {
});
});
};
const loadThemeData =async () => {
const {data: themeData} = await getRecommendedTopic();
themeList.value = themeData;
}
const loadAuthorData=async () => {
const {data: authorData} = await getAuthorTopic(discuss.value.user.id);
authorList.value = authorData;
}
onMounted(async () => {
await loadDiscuss();
await loadArticleData();
await loadAuthorData();
await loadThemeData();
});
watch(
() => currentArticle.value,
(val) => {
@@ -406,7 +425,7 @@ watch(
}
.article-box {
width: 1400px;
width: 1500px;
height: 100%;
.comment {
min-height: 40rem;

View File

@@ -65,7 +65,7 @@
:codeStyle="codeStyle"
/>
</el-form-item>
<el-form-item label="封面" v-if="radio == 'discuss'">
<el-form-item label="首页" v-if="radio == 'discuss'">
<el-image
v-if="dialogImageUrl"
@@ -74,7 +74,7 @@
class="avatar"
/>
<!-- 主题封面选择 -->
<!-- 主题首页选择 -->
<el-upload
class="avatar-uploader"
:action="fileUploadUrl"

View File

@@ -107,7 +107,7 @@ margin: 10px auto;">
<el-col v-if="!isIcp" :span="24">
<InfoCard header="活动">
<template #content>
<div class="top">你好很高兴今天又遇到你呀~</div>
<div class="top">祝各位蛇年大吉~</div>
<el-row class="active">
<el-col v-for="item in activeList" :span="6" @click="handleToRouter(item.path)">
@@ -160,7 +160,7 @@ margin: 10px auto;">
<el-col v-if="!isIcp" :span="24">
<template v-if="isPointFinished">
<InfoCard :items="pointList" header="财富排行榜" text="查看我的位置" height="400"
<InfoCard :isPadding="false" :items="pointList" header="财富排行榜" text="查看我的位置" height="410"
@onClickText="onClickMoneyTop">
<template #item="temp">
<PointsRanking :pointsData="temp"/>
@@ -168,7 +168,7 @@ margin: 10px auto;">
</InfoCard>
</template>
<template v-else>
<InfoCard header="本月排行" text="更多">
<InfoCard :isPadding="false" header="财富排行" text="查看我的位置">
<template #content>
<Skeleton/>
</template>
@@ -178,14 +178,14 @@ margin: 10px auto;">
<el-col v-if="!isIcp" :span="24">
<template v-if="isFriendFinished">
<InfoCard :items="friendList" header="推荐好友" text="更多" height="400">
<InfoCard :isPadding="false" :items="friendList" header="推荐好友" text="更多" height="400">
<template #item="temp">
<RecommendFriend :friendData="temp"/>
</template>
</InfoCard>
</template>
<template v-else>
<InfoCard header="推荐好友" text="更多">
<InfoCard :isPadding="false" header="推荐好友" text="更多">
<template #content>
<Skeleton/>
</template>
@@ -194,14 +194,14 @@ margin: 10px auto;">
</el-col>
<el-col v-if="!isIcp" :span="24">
<template v-if="isThemeFinished">
<InfoCard :items="themeList" header="推荐主题" text="更多" height="400">
<InfoCard :isPadding="false" :items="themeList" header="推荐主题" text="更多" height="400">
<template #item="temp">
<ThemeData :themeData="temp"/>
</template>
</InfoCard>
</template>
<template v-else>
<InfoCard header="推荐主题" text="更多">
<InfoCard :isPadding="false" header="推荐主题" text="更多">
<template #content>
<Skeleton/>
</template>
@@ -243,6 +243,7 @@ import {onMounted, ref, reactive, computed, nextTick, watch} from "vue";
import {useRouter} from "vue-router";
import DisscussCard from "@/components/DisscussCard.vue";
import InfoCard from "@/components/InfoCard.vue";
import ThemeData from "@/views/home/components/RecommendTheme/index.vue";
import PlateCard from "@/components/PlateCard.vue";
import ScrollbarInfo from "@/components/ScrollbarInfo.vue";
import BottomInfo from "@/components/BottomInfo.vue";
@@ -263,7 +264,6 @@ import {
import {getList as getAllDiscussList} from "@/apis/discussApi.js";
import PointsRanking from "./components/PointsRanking/index.vue";
import RecommendFriend from "./components/RecommendFriend/index.vue";
import ThemeData from "./components/RecommendTheme/index.vue";
import Skeleton from "@/components/Skeleton/index.vue";
import useSocketStore from "@/stores/socket";