文章详情组件
parent
a747231358
commit
40c4bb38ce
|
|
@ -0,0 +1,257 @@
|
||||||
|
<template>
|
||||||
|
<div class="pageContainer">
|
||||||
|
<div class="breadNav" v-if="props.breadNav.length > 0">
|
||||||
|
<template :key="item.path" v-for="item in props.breadNav">
|
||||||
|
<router-link :to="item.path">{{item.name}}</router-link><span>></span>
|
||||||
|
</template>
|
||||||
|
<span>详情</span>
|
||||||
|
</div>
|
||||||
|
<div class="article">
|
||||||
|
<template v-if="detail">
|
||||||
|
<h1 class="title">{{ detail.title }}</h1>
|
||||||
|
<div class="props">
|
||||||
|
<span>作者:{{ detail.author }}</span>
|
||||||
|
<span>责编:{{ detail.editor }}</span>
|
||||||
|
<span>{{ DateFormat(new Date(detail.published_at * 1000), 'yyyy.MM.dd') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<div v-html="detail.content"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="loadingBox" v-else>{{ placeholder }}</div>
|
||||||
|
<div class="recommend" v-if="recommend.length > 0">
|
||||||
|
<div class="blockTitle">推荐文章</div>
|
||||||
|
<ul>
|
||||||
|
<li :key="item.id" v-for="item in recommend" @click="goDetail(item.id)">
|
||||||
|
<div class="img"><img :src="item.cover" :alt="item.title"></div>
|
||||||
|
<div class="info">
|
||||||
|
<h3>{{ item.title }}</h3>
|
||||||
|
<p>{{ item.description }}1</p>
|
||||||
|
<span>{{ DateFormat(new Date(item.published_at * 1000), 'yyyy.MM.dd') }}</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <AiAssistant></AiAssistant> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onBeforeMount, onMounted } from 'vue';
|
||||||
|
import http from '@/io/http';
|
||||||
|
import { showToast } from 'vant';
|
||||||
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
|
import { DateFormat } from '@/utils/format.js';
|
||||||
|
// import AiAssistant from '@/views/chat/components/ai-assistant.vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {type: [Number, String], required: true },
|
||||||
|
breadNav: {type: Array, default: []},
|
||||||
|
type: String,
|
||||||
|
isRecommend: {type: Boolean, default: false }
|
||||||
|
});
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const id = ref(props.id || route.params.id);
|
||||||
|
const detail = ref();
|
||||||
|
const recommend = ref([]);
|
||||||
|
const placeholder = ref('数据加载中...');
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getDetail();
|
||||||
|
props.isRecommend && getRecommendList();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const getDetail = () => {
|
||||||
|
http(`/api/article/${id.value}`, {}, 'get').then(res => {
|
||||||
|
detail.value = res.data;
|
||||||
|
}).catch(err => {
|
||||||
|
showToast(err.message);
|
||||||
|
if(err.status == 1001){
|
||||||
|
placeholder.value = '无权限阅读,或会员已过期,请先订阅会员';
|
||||||
|
}else{
|
||||||
|
placeholder.value = '内容获取失败';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getRecommendList = () => {
|
||||||
|
let params = {
|
||||||
|
recommend: 1,
|
||||||
|
type: props.type, // policy
|
||||||
|
per_page: 4,
|
||||||
|
page: 1
|
||||||
|
};
|
||||||
|
http('/api/article', params, 'get').then(res => {
|
||||||
|
recommend.value = res.data.data || [];
|
||||||
|
}).catch(err => {
|
||||||
|
message.error(err.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const goDetail = (id) => {
|
||||||
|
const urlOptions = {
|
||||||
|
policy: `/business/legal/policy/detail/${id}`,
|
||||||
|
insight: '',
|
||||||
|
};
|
||||||
|
if(urlOptions[props.type]){
|
||||||
|
router.push(urlOptions[props.type]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.pageContainer {
|
||||||
|
color: #FFF;
|
||||||
|
padding: 25px;
|
||||||
|
background-color: #242527;
|
||||||
|
|
||||||
|
.breadNav {
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
color: #999;
|
||||||
|
font-size: 22px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #999;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.loadingBox {
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article {
|
||||||
|
padding: 20px 0;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 26px;
|
||||||
|
line-height: 30px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FFF;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.props {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
color: #999;
|
||||||
|
font-size: 23px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
line-height: 1.5;
|
||||||
|
font-size: 23px;
|
||||||
|
|
||||||
|
:deep(p) {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(strong) {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(b) {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(h1) {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(img) {
|
||||||
|
max-width: 100%;
|
||||||
|
display: block;
|
||||||
|
margin: 10px auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommend {
|
||||||
|
padding: 30px 0;
|
||||||
|
|
||||||
|
.blockTitle {
|
||||||
|
height: 80px;
|
||||||
|
line-height: 80px;
|
||||||
|
border-bottom: 1px solid #666;
|
||||||
|
font-size: 39px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
li {
|
||||||
|
width: 100%;
|
||||||
|
padding-right: 30px;
|
||||||
|
display: flex;
|
||||||
|
margin-top: 30px;
|
||||||
|
|
||||||
|
.img {
|
||||||
|
width: 260px;
|
||||||
|
height: 360px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 260px;
|
||||||
|
height: 360px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 15px;
|
||||||
|
height: 360px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding: 10px 0;
|
||||||
|
font-size: 26px;
|
||||||
|
line-height: 30px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #999;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,71 +1,44 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="pageContainer">
|
<ArticleDetail :id="id" :breadNav="breadNav" type="insight" :isRecommend="false" />
|
||||||
<div class="breadNav">
|
|
||||||
<router-link to="/">首页</router-link><span>></span>
|
|
||||||
<router-link to="/business">AI商情</router-link><span>></span>
|
|
||||||
<router-link to="/business/insight">行业洞察</router-link><span>></span>
|
|
||||||
<router-link :to="`/business/insight/category/${category.id}`" v-if="category.id">{{category.name}}</router-link><span v-if="category.id">></span>
|
|
||||||
<span>详情</span>
|
|
||||||
</div>
|
|
||||||
<div class="article" v-if="detail">
|
|
||||||
<h1 class="title">{{detail.title}}</h1>
|
|
||||||
<div class="props">
|
|
||||||
<span>作者:{{detail.author }}</span>
|
|
||||||
<span>责编:{{detail.editor }}</span>
|
|
||||||
<span>{{DateFormat(new Date(detail.published_at * 1000), 'yyyy.MM.dd')}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info">
|
|
||||||
<div v-html="detail.content"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="loadingBox" v-else>数据加载中...</div>
|
|
||||||
<!-- <AiAssistant></AiAssistant> -->
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onBeforeMount, onMounted } from 'vue';
|
import { ref, onBeforeMount, onMounted } from 'vue';
|
||||||
import http from '@/io/http';
|
import http from '@/io/http';
|
||||||
import { showToast } from 'vant';
|
import { showToast } from 'vant';
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { DateFormat } from '@/utils/format.js';
|
import ArticleDetail from '@/components/ArticleDetail/index.vue';
|
||||||
// import AiAssistant from '@/views/chat/components/ai-assistant.vue';
|
|
||||||
|
const breadNav = [
|
||||||
|
{ path: '/', name: '首页' },
|
||||||
|
{ path: '/business', name: 'AI商情' },
|
||||||
|
{ path: '/business/insight', name: '行业洞察' },
|
||||||
|
];
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const cid = ref(route.params.cid);
|
|
||||||
const id = ref(route.params.id);
|
const id = ref(route.params.id);
|
||||||
const category = ref({});
|
|
||||||
const detail = ref();
|
|
||||||
|
|
||||||
onBeforeMount(()=>{
|
onBeforeMount(()=>{
|
||||||
getCategories();
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(()=>{
|
|
||||||
getDetail();
|
getDetail();
|
||||||
});
|
});
|
||||||
|
|
||||||
const getCategories = () => {
|
// const getCategories = () => {
|
||||||
let params = { type_key: 'business' };
|
// let params = { type_key: 'business' };
|
||||||
http('/api/keywords', params, 'get').then(res => {
|
// http('/api/keywords', params, 'get').then(res => {
|
||||||
category.value = res.data.filter(v => v.id == cid.value)[0];
|
// category.value = res.data.filter(v => v.id == cid.value)[0];
|
||||||
}).catch(err => {
|
// }).catch(err => {
|
||||||
showToast(err.message);
|
// showToast(err.message);
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
|
|
||||||
const getDetail = ()=>{
|
const getDetail = () => {
|
||||||
http(`/api/article/${id.value}`, {}, 'get').then(res => {
|
http(`/api/article/${id.value}`, {}, 'get').then(res => {
|
||||||
detail.value = res.data;
|
console.log(res.data);
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
showToast(err.message);
|
// showToast(err.message);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const goBack = () => {
|
|
||||||
router.back();
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,216 +1,19 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="pageContainer">
|
<ArticleDetail :id="id" :breadNav="breadNav" type="policy" :isRecommend="true" />
|
||||||
<div class="breadNav">
|
|
||||||
<router-link to="/">首页</router-link><span>></span>
|
|
||||||
<router-link to="/business">AI商情</router-link><span>></span>
|
|
||||||
<router-link to="/business/legal">法律法规</router-link><span>></span>
|
|
||||||
<router-link to="/business/legal/policy">政策解读</router-link><span>></span>
|
|
||||||
<span>详情</span>
|
|
||||||
</div>
|
|
||||||
<div class="article">
|
|
||||||
<template v-if="detail">
|
|
||||||
<h1 class="title">{{detail.title}}</h1>
|
|
||||||
<div class="props">
|
|
||||||
<span>作者:{{detail.author }}</span>
|
|
||||||
<span>责编:{{detail.editor }}</span>
|
|
||||||
<span>{{DateFormat(new Date(detail.published_at * 1000), 'yyyy.MM.dd')}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info">
|
|
||||||
<div v-html="detail.content"></div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="loadingBox" v-else>数据加载中...</div>
|
|
||||||
<div class="recommend" v-if="recommend.length > 0">
|
|
||||||
<div class="blockTitle">推荐文章</div>
|
|
||||||
<ul>
|
|
||||||
<li :key="item.id" v-for="item in recommend" @click="goDetail(item.id)">
|
|
||||||
<div class="img"><img :src="item.cover" :alt="item.title"></div>
|
|
||||||
<div class="info">
|
|
||||||
<h3>{{ item.title }}</h3>
|
|
||||||
<p>{{ item.description }}1</p>
|
|
||||||
<span>{{ DateFormat(new Date(item.published_at * 1000), 'yyyy.MM.dd') }}</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- <AiAssistant></AiAssistant> -->
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onBeforeMount, onMounted } from 'vue';
|
import { ref, onBeforeMount, onMounted } from 'vue';
|
||||||
import http from '@/io/http';
|
import { useRoute } from 'vue-router';
|
||||||
import { showToast } from 'vant';
|
import ArticleDetail from '@/components/ArticleDetail/index.vue';
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
|
||||||
import { DateFormat } from '@/utils/format.js';
|
const breadNav = [
|
||||||
// import AiAssistant from '@/views/chat/components/ai-assistant.vue';
|
{path: '/', name: '首页'},
|
||||||
|
{path: '/business', name: 'AI商情'},
|
||||||
|
{path: '/business/legal', name: '法律法规'},
|
||||||
|
{path: '/business/legal/policy', name: '政策解读'},
|
||||||
|
];
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const id = ref(route.params.id);
|
const id = ref(route.params.id);
|
||||||
const category = ref({});
|
|
||||||
const detail = ref();
|
|
||||||
const recommend = ref([]);
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(()=>{
|
|
||||||
getDetail();
|
|
||||||
getRecommendList();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
const getDetail = ()=>{
|
|
||||||
http(`/api/article/${id.value}`, {}, 'get').then(res => {
|
|
||||||
detail.value = res.data;
|
|
||||||
category.value = res.data.category;
|
|
||||||
}).catch(err => {
|
|
||||||
showToast(err.message);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getRecommendList = () => {
|
|
||||||
let params = {
|
|
||||||
recommend: 1,
|
|
||||||
type: 'policy',
|
|
||||||
per_page: 4,
|
|
||||||
page: 1
|
|
||||||
};
|
|
||||||
http('/api/article', params, 'get').then(res => {
|
|
||||||
recommend.value = res.data.data || [];
|
|
||||||
}).catch(err => {
|
|
||||||
message.error(err.message);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const goDetail = (id) => {
|
|
||||||
router.push(`/business/legal/policy/detail/${id}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.pageContainer{
|
|
||||||
color: #FFF;
|
|
||||||
padding: 25px;
|
|
||||||
background-color: #242527;
|
|
||||||
.breadNav{
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
color: #999;
|
|
||||||
font-size: 22px;
|
|
||||||
span{
|
|
||||||
padding: 0 5px;
|
|
||||||
}
|
|
||||||
a{
|
|
||||||
color: #999;
|
|
||||||
&:hover{
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.loadingBox{
|
|
||||||
width: 100%;
|
|
||||||
height: 400px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
.article{
|
|
||||||
padding: 20px 0;
|
|
||||||
.title{
|
|
||||||
font-size: 26px;
|
|
||||||
line-height: 30px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #FFF;
|
|
||||||
text-align: center;
|
|
||||||
padding: 10px 0;
|
|
||||||
}
|
|
||||||
.props{
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 30px;
|
|
||||||
color: #999;
|
|
||||||
font-size: 23px;
|
|
||||||
span{
|
|
||||||
display: inline-block;
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.info{
|
|
||||||
line-height: 1.5;
|
|
||||||
font-size: 23px;
|
|
||||||
:deep(p){
|
|
||||||
padding: 10px 0;
|
|
||||||
}
|
|
||||||
:deep(strong){
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
:deep(b){
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
:deep(h1){
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
:deep(img){
|
|
||||||
max-width: 100%;
|
|
||||||
display: block;
|
|
||||||
margin: 10px auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.recommend{
|
|
||||||
padding: 30px 0;
|
|
||||||
.blockTitle{
|
|
||||||
height: 80px;
|
|
||||||
line-height: 80px;
|
|
||||||
border-bottom: 1px solid #666;
|
|
||||||
font-size: 39px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
ul{
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
li{
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 30px;
|
|
||||||
display: flex;
|
|
||||||
margin-top: 30px;
|
|
||||||
.img{
|
|
||||||
width: 260px;
|
|
||||||
height: 360px;
|
|
||||||
overflow: hidden;
|
|
||||||
img{
|
|
||||||
width: 260px;
|
|
||||||
height: 360px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.info{
|
|
||||||
flex: 1;
|
|
||||||
margin-left: 15px;
|
|
||||||
height: 360px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
h3{
|
|
||||||
font-size: 32px;
|
|
||||||
font-weight: bold;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
p{
|
|
||||||
padding: 10px 0;
|
|
||||||
font-size: 26px;
|
|
||||||
line-height: 30px;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
span{
|
|
||||||
color: #999;
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Loading…
Reference in New Issue