ct/app/components/news/new.vue
2025-10-13 10:37:09 +08:00

455 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script lang="ts" setup>
import {computed} 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 = defineProps<Props>()
// 使用传入的数据
const articleData = computed(() => props.articleData)
const loading = computed(() => props.loading)
const error = computed(() => props.error)
// 热门标签
const hotTags = ref([
'景区单车', '政务平台', '共享经济', '共享汽车APP开发', '共享类',
'共享汽车软件开发', '共享雨伞APP开发', '共享雨伞软件开发', '共享货车开发'
])
// 重新加载页面方法
const reloadPage = () => {
if (typeof window !== 'undefined') {
window.location.reload()
}
}
onMounted(() => {
// 加载CSS样式文件
loadCSSFiles()
// 加载JavaScript文件
loadJSFiles()
// 强制处理图片样式
nextTick(() => {
forceImageStyles()
})
})
// 强制处理图片样式的方法
const forceImageStyles = () => {
if (typeof document !== 'undefined') {
const images = document.querySelectorAll('.article-content img')
images.forEach((img: any) => {
// 强制设置样式
img.style.maxWidth = 'calc(50% - 20px)'
img.style.height = 'auto'
img.style.width = 'auto'
img.style.display = 'block'
img.style.margin = '15px 0'
img.style.boxSizing = 'border-box'
})
}
}
// 监听内容变化,重新处理图片样式
watch(() => props.articleData.content, () => {
nextTick(() => {
forceImageStyles()
})
}, {deep: true})
const loadJSFiles = () => {
const jsFiles = [
'/news/jquery.1.11.3.min.js',
'/news/bootstrap.min.js',
'/news/float.js',
]
jsFiles.forEach(src => {
// 检查是否已经加载过该JS文件
const existingScript = document.querySelector(`script[src="${src}"]`)
if (!existingScript) {
const script = document.createElement('script')
script.src = src
script.type = 'text/javascript'
document.head.appendChild(script)
}
})
}
const loadCSSFiles = () => {
const cssFiles = [
'/news/bootstrap.min.css',
'/news/main22.css',
'/news/new_index.css',
'/news/float.css',
'/news/animate.min.css'
]
cssFiles.forEach(href => {
// 检查是否已经加载过该CSS文件
const existingLink = document.querySelector(`link[href="${href}"]`)
if (!existingLink) {
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = href
link.type = 'text/css'
document.head.appendChild(link)
}
})
}
</script>
<template>
<view>
<!-- 顶部 -->
<nav class="navbar navbar-default navbar-fixed-top" style="background: rgba(255,255,255,1);">
<div class="container">
<div class="navbar-header">
<button class="navbar-toggle" data-target="#mynav" data-toggle="collapse">
<span>创特科技</span>
</button>
<a href="/"><img
alt="logo"
class="img-responsive"
src="/news/top_logo.png" style='margin-top:4px'></a>
</div>
<div id="mynav" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="hidden-xs hidden-sm"><a href="/">首页 <span class="sr-only">(current)</span></a>
</li>
<li class="dropdown">
<a data-toggle="dropdown" role="button">解决方案 <span class="caret"/></a>
<ul class="dropdown-menu">
<li><a class="menu-group" href="javascript:void(0);">共享</a></li>
<li><a href="/sharedSolutions/bike">共享单车</a></li>
<li><a href="/sharedSolutions/carShare">共享汽车</a></li>
<li><a href="/sharedSolutions/sharedbed">共享陪护床</a></li>
<li><a href="/sharedSolutions/scooter">共享滑板车</a></li>
<li><a href="/sharedSolutions/eBike">共享助力车</a></li>
</ul>
</li>
<li class="dropdown">
<a
aria-expanded="false" aria-haspopup="true" class="dropdown-toggle"
data-toggle="dropdown" href="/article/437#" role="button">定制开发 <span
class="caret"/></a>
<ul class="dropdown-menu">
<li><a href="/softwareDevelopment/app">APP开发</a></li>
<li class="divider" role="separator"/>
<li><a href="/softwareDevelopment/miniprogram">小程序开发</a></li>
</ul>
</li>
<li><a href="/about">关于创特 </a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="/">电话0755-85225123
<!-- <span class="hidden-xs hidden-sm"> 0755-85225123 / </span> 18123752516 --></a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div>
</nav>
<!-- 文章正文 -->
<section class="container" style="margin-top: 88px;">
<div class="row">
<!-- 左边部分 -->
<div class="col-md-8 wow fadeInLeft animated" style="visibility: visible; animation-name: fadeInLeft;">
<!-- 加载状态 -->
<div v-if="loading" class="loading-container" style="text-align: center; padding: 50px;">
<div
class="loading-spinner"
style="border: 4px solid #f3f3f3; border-top: 4px solid #ff8200; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 0 auto;"/>
<p style="margin-top: 20px; color: #666;">正在加载文章...</p>
</div>
<!-- 错误提示 -->
<div v-else-if="error" class="error-container" style="text-align: center; padding: 50px; color: #ff6b6b;">
<p>{{ error }}</p>
<button
style="margin-top: 20px; padding: 10px 20px; background: #ff8200; color: white; border: none; border-radius: 4px; cursor: pointer;"
@click="reloadPage">
重新加载
</button>
</div>
<!-- 文章内容 -->
<div v-else class="row">
<div class="col-xs-12">
<h2>{{ articleData.title }}</h2>
<p id="label" style="border-bottom: 1px solid #ddd; margin-top: 20px;">
<span>{{ articleData.publishDate }}</span>
<span class="pull-right">分类:{{ articleData.category }}</span>
</p>
<div class="article-content" v-html="articleData.content"/>
</div>
</div>
<!-- 上一篇/下一篇 -->
<div class="nextorpre" style="margin-top: 38px; border-top: 1px solid #ddd; padding-top: 8px;">
<li class="pull-left">上一篇:
<a :href="articleData.prevArticle.url">{{ articleData.prevArticle.title }}</a>
</li>
<li class="pull-right">下一篇:
<a :href="articleData.nextArticle.url">{{ articleData.nextArticle.title }}</a>
</li>
</div>
<br><br><br><br>
</div><!--左边部分-->
<!-- 右边部分 -->
<aside class="col-md-4" style="border-left: 1px solid #eee; background: #fefefe;">
<!-- 热门标签 -->
<div
class="widget tags wow fadeInRight animated"
style="margin-bottom: 30px !important; visibility: visible; animation-name: fadeInRight;">
<h4>热门标签</h4>
<ul class="tag-cloud">
<li v-for="tag in hotTags" :key="tag">
<a class="btn btn-xs" href="#" @click.prevent>{{ tag }}</a>
</li>
</ul>
</div><!-- 热门标签 -->
<!-- 推荐文章 -->
<div
class="sy_news animated" data-wow-delay="200ms"
style="visibility: visible; animation-delay: 200ms; animation-name: fadeInDown;">
<RecommendedArticles
:articles-per-type="3"
:show-title="false"
:show-types="['solution', 'developKnowledge', 'industryTrend']"
/>
</div>
</aside><!-- 右边部分 -->
</div><!--/.row-->
</section><!--/#blog-->
</view>
</template>
<style scoped>
/* 文章内容样式 */
.article-content {
margin-top: 20px;
line-height: 1.8;
font-size: 14px;
color: #333;
overflow: hidden; /* 防止内容溢出 */
word-wrap: break-word; /* 长单词换行 */
}
.article-content p {
margin-bottom: 15px;
}
/* v-html 内容中的图片样式控制 */
.article-content img {
max-width: calc(50% - 20px) !important; /* 确保不超过容器宽度,留出边距 */
height: auto !important; /* 高度自动调整,保持比例 */
width: auto !important; /* 宽度自动配合max-width使用 */
display: block !important;
margin: 15px 0 !important;
box-sizing: border-box !important; /* 包含边框和内边距 */
/* 完全避免裁剪,确保图片完整显示 */
/* 使用 !important 确保覆盖内联样式 */
}
/* 针对 v-html 内容中可能存在的其他图片元素 */
.article-content img[style*="width"],
.article-content img[style*="height"] {
max-width: calc(50% - 20px) !important;
height: auto !important;
width: auto !important;
}
/* 确保所有图片元素都被控制 */
.article-content * img {
max-width: calc(50% - 20px) !important;
height: auto !important;
width: auto !important;
display: block !important;
margin: 15px 0 !important;
}
/* 针对被包裹在span中的图片 */
.article-content span img {
max-width: calc(50% - 20px) !important;
height: auto !important;
width: auto !important;
display: block !important;
margin: 15px 0 !important;
}
/* 强制覆盖所有可能的图片样式 */
.article-content img[src] {
max-width: calc(50% - 20px) !important;
height: auto !important;
width: auto !important;
display: block !important;
margin: 15px 0 !important;
}
/* 响应式调整 */
@media (max-width: 1024px) {
.col-md-8, .col-md-4 {
width: 100%;
margin-bottom: 20px;
}
/* 移动端图片控制 */
.article-content img,
.article-content img[style*="width"],
.article-content img[style*="height"],
.article-content * img,
.article-content span img,
.article-content img[src] {
max-width: calc(50% - 10px) !important;
margin: 10px 0 !important;
height: auto !important; /* 移动端保持比例 */
width: auto !important; /* 移动端宽度自动 */
}
}
/* 桌面端图片控制 */
@media (min-width: 1025px) {
.article-content img,
.article-content img[style*="width"],
.article-content img[style*="height"],
.article-content * img,
.article-content span img,
.article-content img[src] {
max-width: calc(50% - 30px) !important; /* 桌面端留更多边距 */
height: auto !important; /* 桌面端保持比例 */
width: auto !important; /* 桌面端宽度自动 */
}
}
/* 标签云样式 */
.tag-cloud li {
display: inline-block;
margin: 2px;
}
.tag-cloud a {
display: inline-block;
padding: 4px 8px;
background-color: #f5f5f5;
color: #666;
text-decoration: none;
border-radius: 3px;
font-size: 12px;
transition: all 0.3s ease;
}
.tag-cloud a:hover {
background-color: #ff8200;
color: #fff;
}
/* 推荐文章样式 */
.sy_news ul li {
padding: 8px 0;
border-bottom: 1px solid #f0f0f0;
}
.sy_news ul li:last-child {
border-bottom: none;
}
.sy_news ul li a {
color: #333;
text-decoration: none;
font-size: 13px;
line-height: 1.4;
display: block;
transition: color 0.3s ease;
}
.sy_news ul li a:hover {
color: #ff8200;
}
.sy_news ul li a span {
color: #999;
font-size: 12px;
}
/* 上一篇下一篇样式 */
.nextorpre {
display: flex;
justify-content: space-between;
align-items: center;
}
.nextorpre li {
list-style: none;
margin: 0;
}
.nextorpre a {
color: #ff8200;
text-decoration: none;
}
.nextorpre a:hover {
text-decoration: underline;
}
/* 加载动画 */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* 加载状态样式 */
.loading-container {
min-height: 200px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
/* 错误状态样式 */
.error-container {
min-height: 200px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
</style>