暂时实现功能,代码冗余
This commit is contained in:
parent
8cb632f53a
commit
ae691c6db9
|
|
@ -1,21 +1,22 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, onMounted} from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { useArticleApi } from '~/composables/useArticleApi'
|
||||||
|
|
||||||
// 类型定义
|
// 类型定义
|
||||||
interface Article {
|
interface Article {
|
||||||
id: number
|
id: string
|
||||||
title: string
|
title: string
|
||||||
time: number
|
brief: string | null
|
||||||
|
content: string | null
|
||||||
|
createTime: string
|
||||||
|
code: string
|
||||||
|
status: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NewsCategory {
|
interface NewsCategory {
|
||||||
name: string
|
name: string
|
||||||
articleList: Article[]
|
|
||||||
}
|
|
||||||
|
|
||||||
interface NewsApiResponse {
|
|
||||||
code: string
|
code: string
|
||||||
data: NewsCategory[]
|
articleList: Article[]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
|
|
@ -23,9 +24,16 @@ const newsData = ref<NewsCategory[]>([])
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const error = ref('')
|
const error = ref('')
|
||||||
|
|
||||||
// 计算属性 - 格式化时间
|
// 文章类型配置
|
||||||
const formatTime = (timestamp: number): string => {
|
const articleTypes = [
|
||||||
const date = new Date(timestamp * 1000)
|
{ name: '解决方案', code: 'solution' },
|
||||||
|
{ name: '开发知识', code: 'developKnowledge' },
|
||||||
|
{ name: '行业动态', code: 'industryTrend' }
|
||||||
|
]
|
||||||
|
|
||||||
|
// 格式化时间
|
||||||
|
const formatTime = (timeString: string): string => {
|
||||||
|
const date = new Date(timeString)
|
||||||
const Y = date.getFullYear()
|
const Y = date.getFullYear()
|
||||||
const M = String(date.getMonth() + 1).padStart(2, '0')
|
const M = String(date.getMonth() + 1).padStart(2, '0')
|
||||||
const D = String(date.getDate()).padStart(2, '0')
|
const D = String(date.getDate()).padStart(2, '0')
|
||||||
|
|
@ -34,31 +42,47 @@ const formatTime = (timestamp: number): string => {
|
||||||
return `${Y}-${M}-${D} ${h}:${m}`
|
return `${Y}-${M}-${D} ${h}:${m}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取文章链接
|
||||||
|
const getArticleLink = (articleId: string): string => {
|
||||||
|
return `/article/${articleId}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取显示的文章列表(每个分类显示前2篇文章)
|
||||||
|
const getDisplayArticles = (articles: Article[]): Article[] => {
|
||||||
|
return articles.slice(0, 2)
|
||||||
|
}
|
||||||
|
|
||||||
// 获取新闻数据
|
// 获取新闻数据
|
||||||
const fetchNewsData = async (): Promise<void> => {
|
const fetchNewsData = async (): Promise<void> => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
error.value = ''
|
error.value = ''
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('https://article.yuxiit.com/Home/Article/articleList.html', {
|
// 并发获取所有类型的文章数据
|
||||||
method: 'POST',
|
const promises = articleTypes.map(async (type) => {
|
||||||
headers: {
|
try {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
const articles = await useArticleApi().getArticles({
|
||||||
},
|
code: type.code,
|
||||||
body: 'p1_Num=10'
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
name: type.name,
|
||||||
|
code: type.code,
|
||||||
|
articleList: articles || []
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error fetching ${type.name} articles:`, err)
|
||||||
|
return {
|
||||||
|
name: type.name,
|
||||||
|
code: type.code,
|
||||||
|
articleList: []
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!response.ok) {
|
const results = await Promise.all(promises)
|
||||||
throw new Error(`HTTP error! status: ${response.status}`)
|
newsData.value = results.filter(category => category.articleList.length > 0)
|
||||||
}
|
|
||||||
|
|
||||||
const result: NewsApiResponse = await response.json()
|
|
||||||
|
|
||||||
if (result.code === '10000') {
|
|
||||||
newsData.value = result.data
|
|
||||||
} else {
|
|
||||||
throw new Error('API returned error code: ' + result.code)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error.value = err instanceof Error ? err.message : '获取新闻数据失败'
|
error.value = err instanceof Error ? err.message : '获取新闻数据失败'
|
||||||
console.error('Error fetching news data:', err)
|
console.error('Error fetching news data:', err)
|
||||||
|
|
@ -67,16 +91,6 @@ const fetchNewsData = async (): Promise<void> => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取文章链接
|
|
||||||
const getArticleLink = (articleId: number): string => {
|
|
||||||
return `http://www.yuxiit.com/news/news_${articleId}.html`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取显示的文章列表(每个分类显示前2篇文章)
|
|
||||||
const getDisplayArticles = (articles: Article[]): Article[] => {
|
|
||||||
return articles.slice(0, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchNewsData()
|
fetchNewsData()
|
||||||
})
|
})
|
||||||
|
|
@ -148,7 +162,7 @@ onMounted(() => {
|
||||||
:title="article.title"
|
:title="article.title"
|
||||||
class="cGray f_14"
|
class="cGray f_14"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
<span class="pull-right">{{ formatTime(article.time) }}</span>
|
<span class="pull-right">{{ formatTime(article.createTime) }}</span>
|
||||||
<span class="oneIn oneIn_1">{{ article.title }}</span>
|
<span class="oneIn oneIn_1">{{ article.title }}</span>
|
||||||
<div class="blank20"/>
|
<div class="blank20"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,50 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {onMounted, ref} from "vue";
|
import {onMounted, ref, watch} from "vue";
|
||||||
|
|
||||||
|
// 组件属性
|
||||||
|
interface Props {
|
||||||
|
articleData?: {
|
||||||
|
title: string
|
||||||
|
publishDate: string
|
||||||
|
category: string
|
||||||
|
content: string
|
||||||
|
prevArticle: {
|
||||||
|
title: string
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
nextArticle: {
|
||||||
|
title: string
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loading?: boolean
|
||||||
|
error?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
articleData: () => ({
|
||||||
|
title: '',
|
||||||
|
publishDate: '',
|
||||||
|
category: '',
|
||||||
|
content: '',
|
||||||
|
prevArticle: {
|
||||||
|
title: '',
|
||||||
|
url: '#'
|
||||||
|
},
|
||||||
|
nextArticle: {
|
||||||
|
title: '',
|
||||||
|
url: '#'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
loading: true,
|
||||||
|
error: ''
|
||||||
|
})
|
||||||
|
|
||||||
// API基础地址
|
// API基础地址
|
||||||
const API_BASE_URL = 'http://192.168.2.26:4101'
|
const API_BASE_URL = 'http://192.168.2.26:4101'
|
||||||
|
|
||||||
// 文章数据
|
// 内部文章数据(当没有外部传入时使用)
|
||||||
const articleData = ref({
|
const internalArticleData = ref({
|
||||||
title: '',
|
title: '',
|
||||||
publishDate: '',
|
publishDate: '',
|
||||||
category: '',
|
category: '',
|
||||||
|
|
@ -20,15 +59,20 @@ const articleData = ref({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 加载状态
|
// 内部加载状态
|
||||||
const loading = ref(true)
|
const internalLoading = ref(true)
|
||||||
const error = ref('')
|
const internalError = ref('')
|
||||||
|
|
||||||
|
// 使用外部传入的数据或内部数据
|
||||||
|
const articleData = computed(() => props.articleData || internalArticleData.value)
|
||||||
|
const loading = computed(() => props.loading !== undefined ? props.loading : internalLoading.value)
|
||||||
|
const error = computed(() => props.error || internalError.value)
|
||||||
|
|
||||||
// 获取文章详情
|
// 获取文章详情
|
||||||
const fetchArticle = async (id: number) => {
|
const fetchArticle = async (id: number) => {
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
internalLoading.value = true
|
||||||
error.value = ''
|
internalError.value = ''
|
||||||
|
|
||||||
const response = await fetch(`${API_BASE_URL}/app/owArticle/get/${id}`)
|
const response = await fetch(`${API_BASE_URL}/app/owArticle/get/${id}`)
|
||||||
|
|
||||||
|
|
@ -41,19 +85,18 @@ const fetchArticle = async (id: number) => {
|
||||||
|
|
||||||
console.log('api请求数据', data)
|
console.log('api请求数据', data)
|
||||||
|
|
||||||
|
|
||||||
// 分类映射配置
|
// 分类映射配置
|
||||||
const categoryMapping: Record<string, string> = {
|
const categoryMapping: Record<string, string> = {
|
||||||
'solution': '解决方案',
|
'solution': '解决方案',
|
||||||
'developKnowledge': '开发知识',
|
'developKnowledge': '开发知识',
|
||||||
'industryTrend': '行业动态',
|
'industryTrend': '行业动态',
|
||||||
'aboutUs': '关于我们'
|
'aboutUs': '关于我们'
|
||||||
};
|
}
|
||||||
|
|
||||||
data.code = categoryMapping[data.code] || '暂无分类';
|
data.code = categoryMapping[data.code] || '暂无分类'
|
||||||
|
|
||||||
// 更新文章数据
|
// 更新内部文章数据
|
||||||
articleData.value = {
|
internalArticleData.value = {
|
||||||
title: data.title || '暂无标题',
|
title: data.title || '暂无标题',
|
||||||
publishDate: data.createTime || '暂无日期',
|
publishDate: data.createTime || '暂无日期',
|
||||||
category: data.code || '暂无分类',
|
category: data.code || '暂无分类',
|
||||||
|
|
@ -69,9 +112,9 @@ const fetchArticle = async (id: number) => {
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('获取文章失败:', err)
|
console.error('获取文章失败:', err)
|
||||||
error.value = '获取文章失败,请稍后重试'
|
internalError.value = '获取文章失败,请稍后重试'
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
internalLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,50 +130,50 @@ const recommendedArticles = ref({
|
||||||
{
|
{
|
||||||
title: '创特景区SaaS平台 打造专业景区共享出行综合解决方案',
|
title: '创特景区SaaS平台 打造专业景区共享出行综合解决方案',
|
||||||
date: '2025-07-08',
|
date: '2025-07-08',
|
||||||
url: 'http://www.yuxiit.com/news/news_437.html'
|
url: '/article/437'
|
||||||
},
|
},
|
||||||
{title: '景区共享自行车运营方案都有哪些?', date: '2023-05-12', url: 'http://www.yuxiit.com/news/news_407.html'},
|
{title: '景区共享自行车运营方案都有哪些?', date: '2023-05-12', url: '/article/407'},
|
||||||
{
|
{
|
||||||
title: '为什么说景区共享代步车的未来发展空间巨大?',
|
title: '为什么说景区共享代步车的未来发展空间巨大?',
|
||||||
date: '2023-05-08',
|
date: '2023-05-08',
|
||||||
url: 'http://www.yuxiit.com/news/news_401.html'
|
url: '/article/401'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '景区共享单车具备什么功能特点和收费标准?',
|
title: '景区共享单车具备什么功能特点和收费标准?',
|
||||||
date: '2023-04-14',
|
date: '2023-04-14',
|
||||||
url: 'http://www.yuxiit.com/news/news_394.html'
|
url: '/article/394'
|
||||||
},
|
},
|
||||||
{title: '新冠疫情成为共享电单车行业新契机!', date: '2020-09-08', url: 'http://www.yuxiit.com/news/news_300.html'}
|
{title: '新冠疫情成为共享电单车行业新契机!', date: '2020-09-08', url: '/article/300'}
|
||||||
],
|
],
|
||||||
knowledge: [
|
knowledge: [
|
||||||
{
|
{
|
||||||
title: '共享电动车为何能在共享经济中独树一帜?',
|
title: '共享电动车为何能在共享经济中独树一帜?',
|
||||||
date: '2023-06-29',
|
date: '2023-06-29',
|
||||||
url: 'http://www.yuxiit.com/news/news_426.html'
|
url: '/article/426'
|
||||||
},
|
},
|
||||||
{title: '共享经济项目为何能受到大众的青睐?', date: '2023-05-16', url: 'http://www.yuxiit.com/news/news_409.html'},
|
{title: '共享经济项目为何能受到大众的青睐?', date: '2023-05-16', url: '/article/409'},
|
||||||
{title: '景区共享智能代步车运营方案有哪些?', date: '2023-05-10', url: 'http://www.yuxiit.com/news/news_402.html'},
|
{title: '景区共享智能代步车运营方案有哪些?', date: '2023-05-10', url: '/article/402'},
|
||||||
{
|
{
|
||||||
title: '创特景区共享代步车系统具备什么样的优势?',
|
title: '创特景区共享代步车系统具备什么样的优势?',
|
||||||
date: '2023-04-07',
|
date: '2023-04-07',
|
||||||
url: 'http://www.yuxiit.com/news/news_391.html'
|
url: '/article/391'
|
||||||
},
|
},
|
||||||
{title: '做共享电动车能赚到钱吗', date: '2020-03-07', url: 'http://www.yuxiit.com/news/news_308.html'}
|
{title: '做共享电动车能赚到钱吗', date: '2020-03-07', url: '/article/308'}
|
||||||
],
|
],
|
||||||
industry: [
|
industry: [
|
||||||
{
|
{
|
||||||
title: '景区共享电动代步车如何引领景区发展趋势?',
|
title: '景区共享电动代步车如何引领景区发展趋势?',
|
||||||
date: '2024-12-11',
|
date: '2024-12-11',
|
||||||
url: 'http://www.yuxiit.com/news/news_432.html'
|
url: '/article/432'
|
||||||
},
|
},
|
||||||
{title: '景区共享电动代步车有几种合作模式?', date: '2023-07-19', url: 'http://www.yuxiit.com/news/news_431.html'},
|
{title: '景区共享电动代步车有几种合作模式?', date: '2023-07-19', url: '/article/431'},
|
||||||
{title: '景区共享观光代步车为何如此火爆?', date: '2023-07-13', url: 'http://www.yuxiit.com/news/news_430.html'},
|
{title: '景区共享观光代步车为何如此火爆?', date: '2023-07-13', url: '/article/430'},
|
||||||
{
|
{
|
||||||
title: '2023年了,共享电动车项目还具备投资价值吗?',
|
title: '2023年了,共享电动车项目还具备投资价值吗?',
|
||||||
date: '2023-07-04',
|
date: '2023-07-04',
|
||||||
url: 'http://www.yuxiit.com/news/news_428.html'
|
url: '/article/428'
|
||||||
},
|
},
|
||||||
{title: '共享电动车项目投资大吗?', date: '2023-07-03', url: 'http://www.yuxiit.com/news/news_427.html'}
|
{title: '共享电动车项目投资大吗?', date: '2023-07-03', url: '/article/427'}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -141,8 +184,10 @@ onMounted(() => {
|
||||||
// 加载JavaScript文件
|
// 加载JavaScript文件
|
||||||
loadJSFiles()
|
loadJSFiles()
|
||||||
|
|
||||||
// 获取文章详情,使用id=1进行测试
|
// 如果没有外部传入的文章数据,则获取文章详情(使用id=1进行测试)
|
||||||
fetchArticle(1)
|
if (!props.articleData || !props.articleData.title) {
|
||||||
|
fetchArticle(1)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const loadJSFiles = () => {
|
const loadJSFiles = () => {
|
||||||
|
|
@ -224,7 +269,7 @@ const loadCSSFiles = () => {
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a
|
<a
|
||||||
aria-expanded="false" aria-haspopup="true" class="dropdown-toggle"
|
aria-expanded="false" aria-haspopup="true" class="dropdown-toggle"
|
||||||
data-toggle="dropdown" href="https://www.yuxiit.com/news/news_437.html#" role="button">定制开发 <span
|
data-toggle="dropdown" href="/article/437#" role="button">定制开发 <span
|
||||||
class="caret"/></a>
|
class="caret"/></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
|
|
||||||
|
|
@ -262,7 +307,7 @@ const loadCSSFiles = () => {
|
||||||
<p>{{ error }}</p>
|
<p>{{ error }}</p>
|
||||||
<button
|
<button
|
||||||
style="margin-top: 20px; padding: 10px 20px; background: #ff8200; color: white; border: none; border-radius: 4px; cursor: pointer;"
|
style="margin-top: 20px; padding: 10px 20px; background: #ff8200; color: white; border: none; border-radius: 4px; cursor: pointer;"
|
||||||
@click="fetchArticle(1)">
|
@click="() => { if (!props.articleData || !props.articleData.title) fetchArticle(1) }">
|
||||||
重新加载
|
重新加载
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -120,3 +120,43 @@ export const ARTICLE_TYPE_MAP: Record<string, string> = {
|
||||||
export const getArticleTypeName = (code: string): string => {
|
export const getArticleTypeName = (code: string): string => {
|
||||||
return ARTICLE_TYPE_MAP[code] || '未知类型'
|
return ARTICLE_TYPE_MAP[code] || '未知类型'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文章API Composable
|
||||||
|
* @returns 文章API相关方法
|
||||||
|
*/
|
||||||
|
export const useArticleApi = () => {
|
||||||
|
/**
|
||||||
|
* 获取文章列表
|
||||||
|
* @param params 查询参数
|
||||||
|
* @returns Promise<Article[]>
|
||||||
|
*/
|
||||||
|
const getArticles = async (params: ArticleListParams = {}): Promise<Article[]> => {
|
||||||
|
try {
|
||||||
|
const response = await fetchArticleList(params)
|
||||||
|
return response.data || []
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取文章列表失败:', error)
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取推荐文章(按类型分组)
|
||||||
|
* @param types 文章类型数组
|
||||||
|
* @param pageSize 每页数量
|
||||||
|
* @returns Promise<Record<string, Article[]>>
|
||||||
|
*/
|
||||||
|
const getRecommendedArticles = async (
|
||||||
|
types: string[] = ['solution', 'developKnowledge', 'industryTrend'],
|
||||||
|
pageSize: number = 5
|
||||||
|
): Promise<Record<string, Article[]>> => {
|
||||||
|
return await fetchRecommendedArticles(types, pageSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
getArticles,
|
||||||
|
getRecommendedArticles,
|
||||||
|
getArticleTypeName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
106
app/pages/article/[id].vue
Normal file
106
app/pages/article/[id].vue
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
// 设置页面布局
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'no-navigation'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取路由参数
|
||||||
|
const route = useRoute()
|
||||||
|
const articleId = route.params.id as string
|
||||||
|
|
||||||
|
// 文章数据
|
||||||
|
const articleData = ref({
|
||||||
|
title: '',
|
||||||
|
publishDate: '',
|
||||||
|
category: '',
|
||||||
|
content: '',
|
||||||
|
prevArticle: {
|
||||||
|
title: '',
|
||||||
|
url: '#'
|
||||||
|
},
|
||||||
|
nextArticle: {
|
||||||
|
title: '',
|
||||||
|
url: '#'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(true)
|
||||||
|
const error = ref('')
|
||||||
|
|
||||||
|
// API基础地址
|
||||||
|
const API_BASE_URL = 'http://192.168.2.26:4101'
|
||||||
|
|
||||||
|
// 获取文章详情
|
||||||
|
const fetchArticle = async (id: string) => {
|
||||||
|
try {
|
||||||
|
loading.value = true
|
||||||
|
error.value = ''
|
||||||
|
|
||||||
|
const response = await fetch(`${API_BASE_URL}/app/owArticle/get/${id}`)
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await response.json()
|
||||||
|
const data = res.data
|
||||||
|
|
||||||
|
console.log('api请求数据', data)
|
||||||
|
|
||||||
|
// 分类映射配置
|
||||||
|
const categoryMapping: Record<string, string> = {
|
||||||
|
'solution': '解决方案',
|
||||||
|
'developKnowledge': '开发知识',
|
||||||
|
'industryTrend': '行业动态',
|
||||||
|
'aboutUs': '关于我们'
|
||||||
|
}
|
||||||
|
|
||||||
|
data.code = categoryMapping[data.code] || '暂无分类'
|
||||||
|
|
||||||
|
// 更新文章数据
|
||||||
|
articleData.value = {
|
||||||
|
title: data.title || '暂无标题',
|
||||||
|
publishDate: data.createTime || '暂无日期',
|
||||||
|
category: data.code || '暂无分类',
|
||||||
|
content: data.content || '暂无内容',
|
||||||
|
prevArticle: data.prevArticle || {
|
||||||
|
title: '暂无上一篇',
|
||||||
|
url: '#'
|
||||||
|
},
|
||||||
|
nextArticle: data.nextArticle || {
|
||||||
|
title: '暂无下一篇',
|
||||||
|
url: '#'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('获取文章失败:', err)
|
||||||
|
error.value = '获取文章失败,请稍后重试'
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件挂载时获取文章详情
|
||||||
|
onMounted(() => {
|
||||||
|
if (articleId) {
|
||||||
|
fetchArticle(articleId)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听路由变化
|
||||||
|
watch(() => route.params.id, (newId) => {
|
||||||
|
if (newId) {
|
||||||
|
fetchArticle(newId as string)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<NewsNew :article-data="articleData" :loading="loading" :error="error" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
88
app/pages/articles.vue
Normal file
88
app/pages/articles.vue
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
// 设置页面布局
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'default'
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="articles-page">
|
||||||
|
<div class="container" style="padding: 40px 0;">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h1 class="page-title">文章中心</h1>
|
||||||
|
<p class="page-subtitle">探索最新的技术文章和行业动态</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 推荐文章 -->
|
||||||
|
<div class="row" style="margin-top: 40px;">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<RecommendedArticles
|
||||||
|
:show-types="['solution', 'developKnowledge', 'industryTrend']"
|
||||||
|
:articles-per-type="6"
|
||||||
|
title="推荐文章"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 按类型分类的文章 -->
|
||||||
|
<div class="row" style="margin-top: 60px;">
|
||||||
|
<div class="col-xs-12 col-md-4">
|
||||||
|
<RecommendedArticles
|
||||||
|
:show-types="['solution']"
|
||||||
|
:articles-per-type="8"
|
||||||
|
title="解决方案"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 col-md-4">
|
||||||
|
<RecommendedArticles
|
||||||
|
:show-types="['developKnowledge']"
|
||||||
|
:articles-per-type="8"
|
||||||
|
title="开发知识"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 col-md-4">
|
||||||
|
<RecommendedArticles
|
||||||
|
:show-types="['industryTrend']"
|
||||||
|
:articles-per-type="8"
|
||||||
|
title="行业动态"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.articles-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式设计 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.page-title {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-subtitle {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user