parent
4c504f76d4
commit
3a6254d1cc
13 changed files with 366 additions and 253 deletions
After Width: | Height: | Size: 1.1 KiB |
@ -1,8 +1,9 @@ |
|||||||
|
import defaultImage from '@/assets/images/item.png'; |
||||||
export default { |
export default { |
||||||
mounted(el: any, binding: any) { |
mounted(el: any, binding: any) { |
||||||
el.onerror = () => { |
el.onerror = () => { |
||||||
// 当图片加载失败时,设置默认图片
|
// 当图片加载失败时,设置默认图片
|
||||||
el.src = binding.value || '/student/src/assets/images/item.png' // 默认图片
|
el.src = binding.value || defaultImage // 默认图片
|
||||||
} |
} |
||||||
}, |
}, |
||||||
} |
} |
||||||
|
@ -0,0 +1,19 @@ |
|||||||
|
import { defineStore } from 'pinia' |
||||||
|
import { getLogo } from '@/api/setting' |
||||||
|
const settingStore = defineStore('setting', { |
||||||
|
state: () => ({ |
||||||
|
logo: '', |
||||||
|
}), |
||||||
|
actions: { |
||||||
|
setLogo() { |
||||||
|
getLogo().then((res: any) => { |
||||||
|
console.log(res, 'this.logo') |
||||||
|
this.logo = res.result.logo |
||||||
|
|
||||||
|
|
||||||
|
document.querySelector("link[rel~='icon']").href = import.meta.env.VITE_APP_BASE_API + '/' + this.logo |
||||||
|
}) |
||||||
|
}, |
||||||
|
}, |
||||||
|
}) |
||||||
|
export default settingStore |
@ -1,183 +1,161 @@ |
|||||||
<template> |
<template> |
||||||
<div class="main"> |
<div class="container"> |
||||||
<el-tabs |
<div class="news-list"> |
||||||
v-model="activeName" |
<div class="item" v-for="(item,index) in newsList" :key="item.id"> |
||||||
style="max-width: 70%; margin: auto" |
<div class="news-title" :id="index.toString()">{{ item.name }}</div> |
||||||
class="container" |
<div class="children"> |
||||||
@tab-click="handleTabClick" |
<div class="son-item" v-for="obj in item.cmsArticleList" :key="obj.id" @click="toNewsDetail(obj.id)"> |
||||||
> |
<div class="left"> |
||||||
<el-tab-pane |
<div class="title">{{ obj.title }}</div> |
||||||
v-for="category in categories" |
<div class="content"> |
||||||
:key="category.id" |
{{ obj.info }} |
||||||
:label="category.name" |
|
||||||
:name="category.id" |
|
||||||
> |
|
||||||
<ul> |
|
||||||
<li |
|
||||||
v-for="newsItem in getNewsItemsForCategory(category)" |
|
||||||
:key="newsItem.id" |
|
||||||
> |
|
||||||
<div class="box-list" @click.stop="handleNewsClick(newsItem)"> |
|
||||||
<div class="left-box-list"> |
|
||||||
<p class="list-title">{{ newsItem.title }}</p> |
|
||||||
<p class="list-summary"> |
|
||||||
{{ stripHtmlTags(newsItem.summary) }} |
|
||||||
</p> |
|
||||||
<p class="list-time">{{ newsItem.date }}</p> |
|
||||||
</div> |
</div> |
||||||
<img |
<div class="time"><div>{{ obj.publishTime }}</div> <div style="margin-left: 20px;">发布人:{{ obj.createBy }}</div></div> |
||||||
class="news-image" |
|
||||||
:src="newsItem.imageUrl" |
|
||||||
alt="News Image" |
|
||||||
|
|
||||||
/> |
|
||||||
</div> |
</div> |
||||||
<el-divider /> |
<div class="right"> |
||||||
</li> |
<img :src="setImageUrl(obj.comimg)" alt="" v-default-image/> |
||||||
</ul> |
</div> |
||||||
</el-tab-pane> |
</div> |
||||||
</el-tabs> |
<el-empty description="无新闻" v-if="item.cmsArticleList.length === 0" style="height: 200px;"/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<!-- 右侧栏目 --> |
||||||
|
</div> |
||||||
|
<div class="right-coulom"> |
||||||
|
<div :class="active === index ? 'item active' : 'item' " @click="scrollById(index)" v-for="(item,index) in columnList" :key="item">{{ item }}</div> |
||||||
|
|
||||||
</div> |
</div> |
||||||
</template> |
</template> |
||||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||||
import { ref, onMounted } from 'vue' |
import { ref, onMounted } from 'vue' |
||||||
import { useRouter } from 'vue-router' |
import { useRouter } from 'vue-router' |
||||||
import { getColumnListApi, queryEssayListApi } from '@/api/news' |
import { getNewsListApi } from '@/api/news' |
||||||
let categories = ref([]) |
|
||||||
let newsItems = ref({}) |
|
||||||
let activeName = ref('') |
|
||||||
const router = useRouter() |
|
||||||
|
|
||||||
//使用正则表达式转换html标签文本 |
|
||||||
function stripHtmlTags(html) { |
|
||||||
return html.replace(/<[^>]*>/g, '') |
|
||||||
} |
|
||||||
|
|
||||||
// 获取栏目信息 |
|
||||||
const fetchColumnList = async () => { |
|
||||||
const response = await getColumnListApi() |
|
||||||
if (response.success && response.result) { |
|
||||||
categories.value = response.result.filter( |
|
||||||
(category) => category.isShow === '1', |
|
||||||
) |
|
||||||
// 尝试立即加载第一个栏目的新闻列表 |
|
||||||
if (categories.value.length > 0) { |
|
||||||
await fetchNewsList(categories.value[0].id) |
|
||||||
activeName.value = categories.value[0].id |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// 栏目新闻列表查询 |
const router = useRouter() |
||||||
const fetchNewsList = async (categoryId) => { |
const newsList = ref<any>([]) |
||||||
try { |
const columnList = ref<any>([]) |
||||||
const response = await queryEssayListApi(categoryId) |
const active = ref(0) |
||||||
// console.log(response.success,'是否有响应') |
const getNewsListApiEvent = async () => { |
||||||
// console.log(response.result.records,'获取的响应数据') |
const res:any = await getNewsListApi() |
||||||
if (response.success && response.result.records) { |
console.log(res, '212121') |
||||||
newsItems.value[categoryId] = response.result.records.map((data) => ({ |
columnList.value = res.result.map(item => item.name) |
||||||
id: data.id, |
newsList.value = res.result |
||||||
title: data.title, |
} |
||||||
date: data.publishTime, |
getNewsListApiEvent() |
||||||
summary: data.content, |
const scrollById = (index: number) => { |
||||||
imageUrl: data.comimg ? getAbsoluteImagePath(data.comimg) : '', |
active.value = index |
||||||
})) |
const targetPosition = (document.getElementById(index.toString()) as HTMLElement).offsetTop - 120; |
||||||
} |
window.scrollTo({ |
||||||
} catch (error) { |
top: targetPosition, |
||||||
console.error('获取新闻列表失败', error) |
behavior: 'smooth', // 平滑滚动 |
||||||
} |
}); |
||||||
} |
} |
||||||
|
const toNewsDetail = (id: number) => { |
||||||
//获取图片完整地址 |
|
||||||
const getAbsoluteImagePath = (relativePath) => { |
|
||||||
const baseImageUrl = 'https://localhost:18085/jeecg-boot/' // 替换为实际的服务器地址 |
|
||||||
return baseImageUrl + relativePath |
|
||||||
} |
|
||||||
|
|
||||||
// 获取指定栏目的新闻列表 |
|
||||||
const getNewsItemsForCategory = (category) => { |
|
||||||
return newsItems.value[category.id] || [] |
|
||||||
} |
|
||||||
|
|
||||||
// 初始化加载栏目列表 |
|
||||||
onMounted(() => { |
|
||||||
fetchColumnList() |
|
||||||
}) |
|
||||||
|
|
||||||
// 当选项卡改变时更新当前显示的新闻列表 |
|
||||||
const handleTabClick = async (tab) => { |
|
||||||
const categoryId = tab.props.name |
|
||||||
if (!newsItems.value[categoryId]?.length) { |
|
||||||
await fetchNewsList(categoryId) |
|
||||||
} |
|
||||||
activeName.value = categoryId |
|
||||||
} |
|
||||||
|
|
||||||
// 处理新闻条目的点击事件 |
|
||||||
const handleNewsClick = (newsItem) => { |
|
||||||
router.push({ |
router.push({ |
||||||
name: 'newsDetail', |
path: '/detail/' + id |
||||||
params: { id: newsItem.id.toString() }, |
|
||||||
}) |
}) |
||||||
} |
} |
||||||
</script> |
const setImageUrl = (url: string) => { |
||||||
<style scoped> |
return import.meta.env.VITE_APP_BASE_API + '/sys/common/static/' + url |
||||||
.main { |
|
||||||
margin-top: 100px; |
|
||||||
} |
} |
||||||
|
</script> |
||||||
|
<style scoped lang="scss"> |
||||||
.container { |
.container { |
||||||
|
width: 1200px; |
||||||
margin: auto; |
margin: auto; |
||||||
height: 98vh; |
margin-top: 100px; |
||||||
overflow-y: scroll; |
.news-list { |
||||||
padding: 0; |
width: 100%; |
||||||
display: block; |
// height: 900px; |
||||||
} |
// background-color: #f2f3f5; |
||||||
.container::-webkit-scrollbar { |
padding: 15px; |
||||||
width: 0; |
border: 1px solid #f2f3f5; |
||||||
} |
border-radius: 5px; |
||||||
.box-list { |
.item { |
||||||
display: flex; |
.news-title { |
||||||
width: 95%; |
font-size: 24px; |
||||||
height: 100px; |
font-weight: 700; |
||||||
margin-left: 30px; |
} |
||||||
margin-bottom: 10px; |
.children { |
||||||
align-items: center; |
margin: 20px 0; |
||||||
cursor: pointer; /* 默认鼠标指针形状 */ |
.son-item { |
||||||
} |
width: 100%; |
||||||
.box-list:hover { |
height: 100px; |
||||||
background-color: lightgrey; /* 鼠标悬停时改变背景颜色 */ |
background-color: #fff; |
||||||
} |
padding: 15px; |
||||||
.left-box-list { |
display: flex; |
||||||
display: flex; |
border-bottom: 1px solid rgba(228, 230, 235, 0.5); |
||||||
flex-direction: column; |
justify-content: space-between; |
||||||
justify-content: space-between; |
cursor: pointer; |
||||||
flex: 1; |
.left { |
||||||
padding-right: 10px; |
width: 1000px; |
||||||
} |
.title { |
||||||
.list-title { |
font-size: 18px; |
||||||
font-size: 22px; |
font-weight: 700; |
||||||
margin-left: 60px; |
color: #4f5153; |
||||||
} |
} |
||||||
.list-summary { |
.content { |
||||||
font-size: 16px; |
margin-top: 8px; |
||||||
margin-left: 60px; |
font-size: 13px; |
||||||
margin-top: 15px; |
color: #8a919f; |
||||||
color: #999999; |
display: -webkit-box; |
||||||
display: -webkit-box; |
-webkit-line-clamp: 1; |
||||||
-webkit-box-orient: vertical; |
-webkit-box-orient: vertical; |
||||||
-webkit-line-clamp: 1; |
overflow: hidden; |
||||||
overflow: hidden; |
} |
||||||
text-overflow: ellipsis; /* 溢出部分显示为省略号 */ |
.time { |
||||||
max-width: calc(100% - 130px); /* 减去右侧图片宽度和内边距 */ |
margin-top: 8px; |
||||||
} |
font-size: 12px; |
||||||
.list-time { |
color: #8a919f; |
||||||
margin-left: 60px; |
display: flex; |
||||||
margin-top: 20px; |
} |
||||||
color: #999999; |
} |
||||||
|
.right { |
||||||
|
display: flex; |
||||||
|
flex: 1; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
img { |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
} |
||||||
|
&:hover { |
||||||
|
background-color: #f7f8fa; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
} |
} |
||||||
.news-image { |
.right-coulom { |
||||||
width: 100px; |
position: fixed; |
||||||
height: 80px; |
left: 200px; |
||||||
margin-right: 30px; |
top: 100px; |
||||||
|
z-index: 999; |
||||||
|
width: 150px; |
||||||
|
// height: 300px; |
||||||
|
background-color: #f2f3f5; |
||||||
|
padding: 10px; |
||||||
|
border-radius: 5px; |
||||||
|
.item { |
||||||
|
height: 45px; |
||||||
|
// text-align: center; |
||||||
|
line-height: 22px; |
||||||
|
font-size: 16px; |
||||||
|
padding: 10px; |
||||||
|
border-radius: 5px; |
||||||
|
cursor: pointer; |
||||||
|
margin: 5px 0; |
||||||
|
&:hover { |
||||||
|
background-color: #0bd7c628; |
||||||
|
color: #0bd7c6; |
||||||
|
} |
||||||
|
} |
||||||
|
.active { |
||||||
|
background-color: #0bd7c628; |
||||||
|
color: #0bd7c6; |
||||||
|
} |
||||||
} |
} |
||||||
</style> |
</style> |
||||||
|
Loading…
Reference in new issue