新版本官网优化完成
This commit is contained in:
131
pages/m/article/[id].vue
Normal file
131
pages/m/article/[id].vue
Normal file
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
|
||||
<Banner :layout="layout" />
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="p-5">
|
||||
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>
|
||||
{{ page.title }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="content">
|
||||
|
||||
<!-- 文章模型 -->
|
||||
<ul class="news_listn clearfix pt-2">
|
||||
<template v-for="(item,index) in list" key="index">
|
||||
<li class="clearfix">
|
||||
<a :href="mDetail(item)" class=" fl mr-1">
|
||||
<el-image :src="item.image" :fit="`scale-down`" class="w-[120px] h-[80px]" :alt="item.title" />
|
||||
</a>
|
||||
<div class="list">
|
||||
<h3 class="text-lg"><a :href="mDetail(item)" :title="item.title" class="line-clamp-1 text-left">{{ item.title }}</a></h3>
|
||||
<div v-html="item.comments" class="line-clamp-2"></div>
|
||||
<!-- <div class="date">发布日期:{{ dayjs(item.createTime).format('YYYY-MM-DD') }}</div>-->
|
||||
<!-- <div class="n-more" ><a :href="detail(item)" >查看更多>></a></div>-->
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
<div class="clearboth"></div>
|
||||
</ul>
|
||||
|
||||
<Pagination :total="total" @done="search" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Banner from "@/components/Banner.vue";
|
||||
import {useLayout, usePage} from "~/composables/configState";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import type {CmsArticle, CmsArticleParam} from "~/api/cms/cmsArticle/model";
|
||||
import dayjs from "dayjs";
|
||||
import type { ComponentSize } from 'element-plus'
|
||||
import {mDetail, paramsId} from "~/utils/common";
|
||||
import {getCmsNavigation, listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
import {pageCmsArticle} from "~/api/cms/cmsArticle";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
// 页面信息
|
||||
const list = ref<CmsArticle[]>([]);
|
||||
const i18n = useI18n();
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
const total = ref(0);
|
||||
|
||||
// 获取状态
|
||||
const page = usePage();
|
||||
const layout = useLayout();
|
||||
|
||||
|
||||
// 搜索表单
|
||||
const where = reactive<CmsArticleParam>({
|
||||
keywords: '',
|
||||
page: 1,
|
||||
limit: 20,
|
||||
status: 0,
|
||||
parentId: undefined,
|
||||
categoryId: undefined,
|
||||
lang: i18n.locale.value
|
||||
});
|
||||
|
||||
|
||||
// 加载页面数据
|
||||
const reload = async () => {
|
||||
getCmsNavigation(paramsId()).then(data => {
|
||||
// 获取栏目信息
|
||||
page.value = data
|
||||
layout.value.banner = data.banner;
|
||||
|
||||
// 设置页面标题
|
||||
useSeoMeta({
|
||||
description: data.comments || data.title,
|
||||
keywords: data.title,
|
||||
titleTemplate: `${data?.title}` + ' - %s',
|
||||
})
|
||||
|
||||
// 二级栏目分类
|
||||
listCmsNavigation({
|
||||
parentId: data.parentId == 0 ? data.navigationId : data.parentId
|
||||
}).then(categoryData => {
|
||||
category.value = categoryData;
|
||||
// 加载文章列表
|
||||
if(data.parentId == 0 && category.value.length > 0){
|
||||
where.parentId = data.navigationId;
|
||||
}else {
|
||||
where.categoryId = data.navigationId;
|
||||
}
|
||||
pageCmsArticle(where).then(response => {
|
||||
if(response){
|
||||
total.value = response?.count;
|
||||
list.value = response?.list;
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}).catch(err => {
|
||||
console.log(err,'加载失败...')
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
* @param data
|
||||
*/
|
||||
const search = (data: CmsArticleParam) => {
|
||||
where.page = data.page;
|
||||
reload();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
|
||||
</script>
|
||||
129
pages/m/case/[id].vue
Normal file
129
pages/m/case/[id].vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
|
||||
<Banner :layout="layout" />
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="p-5">
|
||||
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>
|
||||
{{ page.title }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="content py-3">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="24" v-for="(item,index) in list" key="index">
|
||||
<div class="cast-item">
|
||||
<a :href="mDetail(item)" :title="item.title" class="img"><el-image :fit="`scale-down`" :src="item.image" :alt="item.title" /></a>
|
||||
<div class="flex flex-col leading-7">
|
||||
<a :href="mDetail(item)" class="text-[16px] font-bold" :title="item.title">{{ item.title }}</a>
|
||||
<a :href="mDetail(item)" class="more"><span class="text-gray-400">{{ $t('case.detail') }}>></span></a>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<Pagination :total="total" @done="search" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Banner from "@/components/Banner.vue";
|
||||
import {useLayout, usePage} from "~/composables/configState";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import type {CmsArticle, CmsArticleParam} from "~/api/cms/cmsArticle/model";
|
||||
import type { ComponentSize } from 'element-plus'
|
||||
import {paramsId} from "~/utils/common";
|
||||
import {getCmsNavigation, listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
import {pageCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import CmsArticleList from "~/components/CmsArticleList.vue";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
// 页面信息
|
||||
const list = ref<CmsArticle[]>([]);
|
||||
const i18n = useI18n();
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
const total = ref(0);
|
||||
|
||||
// 获取状态
|
||||
const page = usePage();
|
||||
const layout = useLayout();
|
||||
|
||||
// 搜索表单
|
||||
const where = reactive<CmsArticleParam>({
|
||||
keywords: '',
|
||||
page: 1,
|
||||
limit: 20,
|
||||
status: 0,
|
||||
parentId: undefined,
|
||||
categoryId: undefined,
|
||||
lang: i18n.locale.value
|
||||
});
|
||||
|
||||
|
||||
// 加载页面数据
|
||||
const reload = async () => {
|
||||
await getCmsNavigation(paramsId()).then(data => {
|
||||
page.value = data;
|
||||
// layout.value = data.design;
|
||||
layout.value.banner = data.banner;
|
||||
|
||||
// seo
|
||||
useSeoMeta({
|
||||
description: data.comments || data.title,
|
||||
keywords: data.title,
|
||||
titleTemplate: `${data?.title}` + ' - %s',
|
||||
})
|
||||
|
||||
// 二级栏目分类
|
||||
listCmsNavigation({
|
||||
parentId: data.parentId == 0 ? data.navigationId : data.parentId
|
||||
}).then(navigation => {
|
||||
category.value = navigation;
|
||||
// 加载文章列表
|
||||
if(data.parentId == 0 && category.value.length > 0){
|
||||
where.parentId = page.value.navigationId;
|
||||
}else {
|
||||
where.categoryId = page.value.navigationId;
|
||||
}
|
||||
pageCmsArticle(where).then(response => {
|
||||
if(response){
|
||||
total.value = response.count;
|
||||
list.value = response.list;
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
* @param data
|
||||
*/
|
||||
const search = (data: CmsArticleParam) => {
|
||||
where.page = data.page;
|
||||
reload();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.case_listn li{
|
||||
max-width: 200px;
|
||||
}
|
||||
.cast-item{
|
||||
border: 1px solid #eeeeee;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
67
pages/m/components/Carousel.vue
Normal file
67
pages/m/components/Carousel.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<!-- 移动端 -->
|
||||
<div class="sm:hidden w-full bg-white mb-3 " v-if="ad">
|
||||
<el-carousel indicator-position="none">
|
||||
<el-carousel-item v-for="(item,index) in ad?.imageList" :key="index">
|
||||
<el-image :src="item.url" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {CompanyParam} from "~/api/system/company/model";
|
||||
import type {CmsAd} from "~/api/cms/cmsAd/model";
|
||||
import {pageCmsAd} from "~/api/cms/cmsAd";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
config?: any;
|
||||
list?: any[];
|
||||
disabled?: boolean;
|
||||
title?: string;
|
||||
comments?: string;
|
||||
}>(),
|
||||
{
|
||||
title: '卡片标题',
|
||||
comments: '卡片描述'
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done'): void;
|
||||
}>();
|
||||
|
||||
const ad = ref<CmsAd>();
|
||||
|
||||
// 搜索表单
|
||||
const where = reactive<CompanyParam>({
|
||||
keywords: ''
|
||||
});
|
||||
|
||||
// 请求数据
|
||||
const reload = async () => {
|
||||
pageCmsAd({
|
||||
type: 1,
|
||||
lang: getLang()
|
||||
}).then(res => {
|
||||
if(res){
|
||||
ad.value = res.list[0];
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.config,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.el-carousel__container{
|
||||
height: 240px !important;
|
||||
}
|
||||
</style>
|
||||
202
pages/m/detail/[id].vue
Normal file
202
pages/m/detail/[id].vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<!-- 文章详情 -->
|
||||
<template>
|
||||
|
||||
<Banner :layout="layout"/>
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="p-5">
|
||||
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>
|
||||
{{ form.categoryName }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="content">
|
||||
|
||||
<!-- 新闻详细 -->
|
||||
<div class="news_detail">
|
||||
<h1 class="title">{{ form.title }}</h1>
|
||||
<div class="info_title clearfix">
|
||||
<h3 class="text-center text-gray-400">
|
||||
{{ $t('createTime') }}:<span>{{ dayjs(form.createTime).format('YYYY-MM-DD') }}</span>
|
||||
{{ $t('author') }}:<span>{{ form.nickname }}</span>
|
||||
{{ $t('click') }}:<span>{{ form.actualViews }}</span>
|
||||
</h3>
|
||||
<div class="share">
|
||||
<!-- Baidu Button BEGIN -->
|
||||
<div class="bdsharebuttonbox">
|
||||
<a href="#" class="bds_more" data-cmd="more"></a>
|
||||
<a href="#" class="bds_qzone" data-cmd="qzone"></a>
|
||||
<a href="#" class="bds_tsina" data-cmd="tsina"></a>
|
||||
<a href="#" class="bds_tqq" data-cmd="tqq"></a>
|
||||
<a href="#" class="bds_renren" data-cmd="renren"></a>
|
||||
<a href="#" class="bds_weixin" data-cmd="weixin"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content text-lg" v-html="form.content"></div>
|
||||
<h3 class="tag">{{ $t('articleUrl') }}:{{ locationUrl() }} </h3>
|
||||
<Tags :data="form.tags" />
|
||||
<NextArticle />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type {BreadcrumbItem} from "~/types/global";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import {locationUrl, paramsId} from "~/utils/common";
|
||||
import type {CmsArticle} from "~/api/cms/cmsArticle/model";
|
||||
import useFormData from "~/utils/use-form-data";
|
||||
import dayjs from "dayjs";
|
||||
import Banner from "@/components/Banner.vue";
|
||||
import type {Layout} from "~/api/layout/model";
|
||||
import {getCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import {listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
import Tags from "~/components/Tags.vue";
|
||||
|
||||
// 引入状态管理
|
||||
const route = useRoute();
|
||||
const layout = ref<Layout>({});
|
||||
const breadcrumb = ref<BreadcrumbItem>();
|
||||
const showPassword = ref<boolean>();
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
|
||||
// 配置信息
|
||||
const {form, assignFields} = useFormData<CmsArticle>({
|
||||
// 文章id
|
||||
articleId: undefined,
|
||||
// 文章模型
|
||||
model: undefined,
|
||||
// 文章标题
|
||||
title: undefined,
|
||||
// 分类类型
|
||||
type: undefined,
|
||||
// 展现方式
|
||||
showType: undefined,
|
||||
// 文章类型
|
||||
categoryId: undefined,
|
||||
// 文章分类
|
||||
categoryName: undefined,
|
||||
parentId: undefined,
|
||||
// 封面图
|
||||
image: undefined,
|
||||
// 附件
|
||||
files: undefined,
|
||||
// 附件
|
||||
fileList: [],
|
||||
// 缩列图
|
||||
thumbnail: undefined,
|
||||
// 视频地址
|
||||
video: undefined,
|
||||
// 上传的文件类型
|
||||
accept: undefined,
|
||||
// 来源
|
||||
source: undefined,
|
||||
// 文章内容
|
||||
content: undefined,
|
||||
// 虚拟阅读量
|
||||
virtualViews: undefined,
|
||||
// 实际阅读量
|
||||
actualViews: undefined,
|
||||
// 访问权限
|
||||
permission: undefined,
|
||||
// 访问密码
|
||||
password: undefined,
|
||||
password2: undefined,
|
||||
// 用户ID
|
||||
userId: undefined,
|
||||
// 用户昵称
|
||||
nickname: undefined,
|
||||
// 账号
|
||||
username: undefined,
|
||||
// 用户头像
|
||||
// userAvatar: undefined,
|
||||
author: undefined,
|
||||
// 所属门店ID
|
||||
shopId: undefined,
|
||||
//
|
||||
likes: undefined,
|
||||
// 排序
|
||||
sortNumber: undefined,
|
||||
// 备注
|
||||
comments: undefined,
|
||||
// 状态
|
||||
status: undefined,
|
||||
// 创建时间
|
||||
createTime: undefined,
|
||||
// 更新时间
|
||||
updateTime: undefined,
|
||||
// 租户ID
|
||||
tenantId: undefined,
|
||||
// 租户名称
|
||||
tenantName: undefined,
|
||||
// 租户logo
|
||||
logo: undefined,
|
||||
// 详情页路径
|
||||
detail: undefined
|
||||
});
|
||||
|
||||
// 请求数据
|
||||
const reload = async () => {
|
||||
await getCmsArticle(paramsId()).then(data => {
|
||||
assignFields(data)
|
||||
layout.value.banner = data?.banner;
|
||||
// 二级栏目分类
|
||||
if (data.parentId) {
|
||||
listCmsNavigation({parentId: data.parentId}).then(list => {
|
||||
category.value = list;
|
||||
})
|
||||
}
|
||||
|
||||
if(form.permission === 1){
|
||||
console.log('登录可见')
|
||||
return;
|
||||
}
|
||||
if(form.permission === 2){
|
||||
console.log('需要密码')
|
||||
showPassword.value = true;
|
||||
return;
|
||||
}
|
||||
})
|
||||
|
||||
// seo
|
||||
useSeoMeta({
|
||||
description: form?.comments,
|
||||
keywords: form.title,
|
||||
titleTemplate: `${form?.title}` + ' - %s',
|
||||
})
|
||||
|
||||
// 面包屑
|
||||
breadcrumb.value = form
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
(path) => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
padding-top: 15px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.content p{
|
||||
}
|
||||
.content img{
|
||||
padding: 10px 0;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.content video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
183
pages/m/index.vue
Normal file
183
pages/m/index.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
|
||||
<!-- 首页banner -->
|
||||
<Carousel ref="CarouselRef"/>
|
||||
|
||||
<div class="search">
|
||||
<el-input v-model="keyword" :placeholder="$t('index.keyword')" :suffix-icon="Search" @change="onSearch"/>
|
||||
</div>
|
||||
<!-- 产品分类 -->
|
||||
<div class="cp p-3" v-if="cpCategory">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="6" v-for="(item,index) in cpCategory" :key="index">
|
||||
<div class="item flex flex-col justify-center mb-2" v-if="index < 8">
|
||||
<a :href="navTo(item)" class="img" style="border-radius: 100%;">
|
||||
<el-avatar fit="fill" :size="65" :src="`${item.icon}`" style="border: 1px solid #FFFFFF; box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);"/>
|
||||
</a>
|
||||
<div class="text-center py-1"><a :href="navTo(item)">{{ item.title }}</a></div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<div class="clearboth"></div>
|
||||
|
||||
<div class="advs"><p><img :src="config?.MobileIndexInfoTopImage"
|
||||
title="1729219778290291.jpg" alt="1.jpg"/></p>
|
||||
<p><br/></p>
|
||||
<p><br/></p></div>
|
||||
|
||||
|
||||
<div class="clearboth"></div>
|
||||
|
||||
<div class="products">
|
||||
<div class="products_title">
|
||||
{{ $t('index.companyProfile') }}
|
||||
</div>
|
||||
<div class="contentss clearfix">
|
||||
<div class="tps"><p><a :href="i18n.locale.value == 'en' ? `/en/m/page/1100.html` : `/m/page/1025.html`" target="_self"><img
|
||||
:src="config.MobileIndexInfoImage" title="1729219913337024.jpg"
|
||||
alt="2.jpg"/></a></p>
|
||||
<p><br/></p></div>
|
||||
<div class="nrs">
|
||||
{{ config.MobileIndexInfo }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="products" v-if="caseCategory">
|
||||
<div class="products_title">
|
||||
{{ $t('index.parentNameCase') }}
|
||||
</div>
|
||||
<ul>
|
||||
<li v-for="(item,index) in caseCategory" :key="index">
|
||||
<a :href="navTo(item)" title="轨道交通建设项目" class="img">
|
||||
<img :src="item.icon" alt="轨道交通建设项目"/>
|
||||
<h3>{{ item.title }}</h3>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tu"><p><img :src="config.MobileIndexInfoHZGYImage" title="活动房安装"
|
||||
alt="活动房安装" border="0" vspace="0" style="white-space: normal;"/></p>
|
||||
<p><br/></p></div>
|
||||
|
||||
<div class="hezuo">
|
||||
<div class="products_title">
|
||||
<a><span class="text-[#0c6fcd]" >{{ $t('index.partner') }}</span></a>
|
||||
</div>
|
||||
<div class="con"><p><a><img
|
||||
:src="config.MobileIndexInfoLogoList" title="1587462469987062.jpg"
|
||||
alt="手机合作.jpg"/></a></p></div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 服务中国 走向海外 -->
|
||||
<div v-html="config.MobileIndexCode" class="mservice"></div>
|
||||
|
||||
|
||||
<div class="advs"><a :href="`${i18n.locale.value == 'en' ? '/en/m/video/1075.html' : '/m/video/1000.html'}`"><img :src="config.MobileIndexBottomBanner"
|
||||
title="1553249693490374.jpg" alt="555.jpg" border="0" vspace="0"/></a></div>
|
||||
|
||||
|
||||
<div class="news">
|
||||
<div class="products_title">
|
||||
{{ $t('index.news') }}
|
||||
</div>
|
||||
<ul>
|
||||
<li v-for="(item,index) in hotNews" :key="index">
|
||||
<a :href="mDetail(item)" :title="item.title">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
<div class="line-clamp-1 max-w-[320px]" v-html="item.comments"></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="clearboth"></div>
|
||||
|
||||
|
||||
<div class="products">
|
||||
<div class="products_title">
|
||||
{{ $t('index.contact') }}
|
||||
</div>
|
||||
<div class="flex flex-col p-3 leading-8">
|
||||
<span class="text-left">{{ $t('page.tel') }}:{{ config.tel }}</span>
|
||||
<span class="text-left">{{ $t('page.phone') }}:{{ config.fax }}</span>
|
||||
<span class="text-left">{{ $t('page.fax') }}:{{ config.phone }}</span>
|
||||
<span class="text-left">{{ $t('page.email') }}:{{ config.email }}</span>
|
||||
<span class="text-left">{{ $t('page.address') }}:{{ config.address }}</span>
|
||||
<span class="text-left">{{ $t('page.factory') }}:{{ config.address2 }}</span>
|
||||
<span class="text-left">{{ $t('page.domain') }}:{{ config.pageLeftInfoUrl }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="distraction">
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Carousel from "~/pages/m/components/Carousel.vue";
|
||||
import {useConfigInfo, useWebsite} from "~/composables/configState";
|
||||
import {Search} from '@element-plus/icons-vue'
|
||||
import type {CmsArticle} from "~/api/cms/cmsArticle/model";
|
||||
import {pageCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import {navTo} from "~/utils/common";
|
||||
import {getSiteInfo} from "~/api/layout";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
name?: any;
|
||||
}>(),
|
||||
{}
|
||||
);
|
||||
|
||||
const config = useConfigInfo();
|
||||
const website = useWebsite();
|
||||
const keyword = ref();
|
||||
const i18n = useI18n();
|
||||
const hotNews = ref<CmsArticle[]>([]);
|
||||
const topNavs = ref<any>([]);
|
||||
const cpCategory = ref<CmsNavigation[]>([]);
|
||||
const caseCategory = ref<any>([]);
|
||||
|
||||
|
||||
const onSearch = () => {
|
||||
window.location.href = `/m/search/${keyword.value}`;
|
||||
}
|
||||
|
||||
// TODO 读取服务器缓存数据
|
||||
await getSiteInfo({
|
||||
lang: i18n.locale.value
|
||||
}).then(data => {
|
||||
website.value = data
|
||||
topNavs.value = data.topNavs?.filter(d => d.title === '产品系列' || d.title === 'Product')
|
||||
if(topNavs.value[0].children){
|
||||
cpCategory.value = topNavs.value[0].children;
|
||||
}
|
||||
caseCategory.value = data.topNavs?.filter(d => d.title === '项目展示' || d.title === 'Case')[0].children
|
||||
})
|
||||
|
||||
const reload = async () => {
|
||||
// 新闻头条
|
||||
pageCmsArticle({
|
||||
limit: 4,
|
||||
status: 0,
|
||||
recommend: 1,
|
||||
parentId: i18n.locale.value == 'en' ? 1077 : 1002,
|
||||
lang: i18n.locale.value
|
||||
}).then(res => {
|
||||
if(res){
|
||||
hotNews.value = res?.list;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
reload();
|
||||
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
</style>
|
||||
220
pages/m/item/[id].vue
Normal file
220
pages/m/item/[id].vue
Normal file
@@ -0,0 +1,220 @@
|
||||
<script setup lang="ts">
|
||||
import type {BreadcrumbItem} from "~/types/global";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import {locationUrl, navTo, paramsId} from "~/utils/common";
|
||||
import type {CmsArticle} from "~/api/cms/cmsArticle/model";
|
||||
import useFormData from "~/utils/use-form-data";
|
||||
import Banner from "@/components/Banner.vue";
|
||||
import type {Layout} from "~/api/layout/model";
|
||||
import {getCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import {listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
import Tags from "~/components/Tags.vue";
|
||||
|
||||
|
||||
// 引入状态管理
|
||||
const route = useRoute();
|
||||
const layout = ref<Layout>({});
|
||||
const breadcrumb = ref<BreadcrumbItem>();
|
||||
const showPassword = ref<boolean>();
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
const fileList = ref<any>();
|
||||
|
||||
// 配置信息
|
||||
const {form, assignFields} = useFormData<CmsArticle>({
|
||||
// 文章id
|
||||
articleId: undefined,
|
||||
// 文章模型
|
||||
model: undefined,
|
||||
// 文章标题
|
||||
title: undefined,
|
||||
// 分类类型
|
||||
type: undefined,
|
||||
// 展现方式
|
||||
showType: undefined,
|
||||
// 文章类型
|
||||
categoryId: undefined,
|
||||
// 文章分类
|
||||
categoryName: undefined,
|
||||
parentId: undefined,
|
||||
// 封面图
|
||||
image: undefined,
|
||||
// 附件
|
||||
files: undefined,
|
||||
// 缩列图
|
||||
thumbnail: undefined,
|
||||
// 视频地址
|
||||
video: undefined,
|
||||
// 上传的文件类型
|
||||
accept: undefined,
|
||||
// 来源
|
||||
source: undefined,
|
||||
// 文章内容
|
||||
content: undefined,
|
||||
// 虚拟阅读量
|
||||
virtualViews: undefined,
|
||||
// 实际阅读量
|
||||
actualViews: undefined,
|
||||
// 访问权限
|
||||
permission: undefined,
|
||||
// 访问密码
|
||||
password: undefined,
|
||||
password2: undefined,
|
||||
// 用户ID
|
||||
userId: undefined,
|
||||
// 用户昵称
|
||||
nickname: undefined,
|
||||
// 账号
|
||||
username: undefined,
|
||||
// 用户头像
|
||||
// userAvatar: undefined,
|
||||
author: undefined,
|
||||
// 所属门店ID
|
||||
shopId: undefined,
|
||||
//
|
||||
likes: undefined,
|
||||
// 排序
|
||||
sortNumber: undefined,
|
||||
// 备注
|
||||
comments: undefined,
|
||||
// 状态
|
||||
status: undefined,
|
||||
// 创建时间
|
||||
createTime: undefined,
|
||||
// 更新时间
|
||||
updateTime: undefined,
|
||||
tenantId: undefined,
|
||||
// 租户名称
|
||||
tenantName: undefined,
|
||||
// 租户logo
|
||||
logo: undefined,
|
||||
// 详情页路径
|
||||
detail: undefined
|
||||
});
|
||||
|
||||
// 请求数据
|
||||
const reload = async () => {
|
||||
await getCmsArticle(paramsId()).then(data => {
|
||||
assignFields(data)
|
||||
layout.value.banner = data?.banner;
|
||||
// 二级栏目分类
|
||||
if (data.parentId) {
|
||||
listCmsNavigation({parentId: data.parentId}).then(list => {
|
||||
category.value = list;
|
||||
})
|
||||
}
|
||||
|
||||
if(form.permission === 1){
|
||||
console.log('登录可见')
|
||||
return;
|
||||
}
|
||||
if(form.permission === 2){
|
||||
console.log('需要密码')
|
||||
showPassword.value = true;
|
||||
return;
|
||||
}
|
||||
})
|
||||
|
||||
// seo
|
||||
useSeoMeta({
|
||||
description: form.comments || form.title,
|
||||
keywords: form.title,
|
||||
titleTemplate: `${form?.title}` + ' - %s',
|
||||
})
|
||||
|
||||
// 面包屑
|
||||
breadcrumb.value = form
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<Banner :layout="layout"/>
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="clearfix p-5">
|
||||
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>
|
||||
{{ form.categoryName || '分类名称' }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="detail-container">
|
||||
|
||||
<!-- 产品详细 -->
|
||||
<div class="product_detail" id="pd1">
|
||||
<div class="allcontent clearfix">
|
||||
<div style="float: left;">
|
||||
<div class="img clearfix" id="play">
|
||||
<el-carousel v-if="form.files" :interval="4000">
|
||||
<el-carousel-item v-for="item in JSON.parse(form.files)" :key="item" style="display: flex; align-items: center; justify-content: center">
|
||||
<el-image fit="cover" :src="item" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list mb-10">
|
||||
<ul class="list_p">
|
||||
<h1 class="title">{{ form.title }}</h1>
|
||||
<li><h2>{{ $t('categoryName') }}:<a :href="navTo(form,`/product/${form.categoryId}`)"><strong>{{ form.categoryName }}</strong></a></h2></li>
|
||||
<li class="text-left">{{ $t('createTime') }}:<span>{{ form.createTime }}</span></li>
|
||||
|
||||
<li class="text-left">{{ $t('overview') }}:</li>
|
||||
<div class="bg-gray-100 p-2 w-[360px]">{{ form.comments }}</div>
|
||||
|
||||
<li class="inquiry"><a :href="navTo(form,`/m/order/${form.articleId}.html}`)">{{ $t('onlineInquiry') }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearboth"></div>
|
||||
<div class="p_detail">
|
||||
<ul id="product-tab" class="product-tab clearfix">
|
||||
<li class="cur">{{ $t('show.detail') }}</li>
|
||||
|
||||
</ul>
|
||||
<div class="content tab-content text-sm" v-html="form.content"></div>
|
||||
</div>
|
||||
|
||||
<h3 class="tag">{{ $t('articleUrl') }}:{{ locationUrl() }} </h3>
|
||||
<Tags :data="form.tags" />
|
||||
<NextArticle />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
padding-top: 15px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.content p{
|
||||
text-indent: 0;
|
||||
}
|
||||
.content img{
|
||||
padding: 5px 0;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.content video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.product_detail{
|
||||
padding: 5px 0 !important;
|
||||
}
|
||||
.product_detail .list{
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.product_detail .img{
|
||||
width: 90vw !important;
|
||||
}
|
||||
</style>
|
||||
232
pages/m/order/[id].vue
Normal file
232
pages/m/order/[id].vue
Normal file
@@ -0,0 +1,232 @@
|
||||
<template>
|
||||
|
||||
<!-- Banner -->
|
||||
<Banner :layout="layout" />
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="clearfix p-5">
|
||||
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>{{ $t('order.title') }}</h2>
|
||||
<Breadcrumb :data="page" :categoryName="page.categoryName" />
|
||||
</div>
|
||||
<div class="form-box p-5">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="120"
|
||||
label-position="left"
|
||||
status-icon
|
||||
>
|
||||
<el-form-item :label="$t('order.title')" prop="title" class="hover:bg-gray-50 p-2">
|
||||
<el-input v-model="form.title" :placeholder="$t('order.title')"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('order.content')" prop="content" class="hover:bg-gray-50 p-2">
|
||||
<el-input type="textarea" :rows="5" cols="80" v-model="form.content" :placeholder="$t('order.content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('order.realName')" prop="realName" class="hover:bg-gray-50 p-2">
|
||||
<el-input v-model="form.realName" :placeholder="$t('order.realName')"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('order.phone')" prop="phone" class="hover:bg-gray-50 p-2">
|
||||
<el-input v-model="form.phone" :maxlength="11" :placeholder="$t('order.phone')"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('order.email')" prop="email" class="hover:bg-gray-50 p-2">
|
||||
<el-input v-model="form.email" :placeholder="$t('order.email')"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('order.address')" prop="address" class="hover:bg-gray-50 p-2">
|
||||
<el-input v-model="form.address" :placeholder="$t('order.address')"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('order.code')" prop="code" class="hover:bg-gray-50 p-2">
|
||||
<el-space class="flex">
|
||||
<el-input size="large" :placeholder="$t('order.imgCode')" maxlength="5" v-model="form.code" />
|
||||
<el-image :alt="$t('order.imgCode')" v-if="captcha" :src="captcha" @click="changeCaptcha" />
|
||||
</el-space>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div class="submitForm ml-2">
|
||||
<el-button type="primary" size="large" @click="submitForm(formRef)">
|
||||
{{ $t('order.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<div class="flex justify-center">
|
||||
<el-image w-full :src="dialogImageUrl" alt="查看证件" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {useLayout, usePage} from "~/composables/configState";
|
||||
import {paramsId} from "~/utils/common";
|
||||
import {ArrowRight} from '@element-plus/icons-vue'
|
||||
import type {FormInstance, FormRules} from 'element-plus'
|
||||
import type {CmsOrder} from "~/api/cms/cmsOrder/model";
|
||||
import useFormData from "~/utils/use-form-data";
|
||||
import {addCmsOrder} from "~/api/cms/cmsOrder";
|
||||
import {getCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import {getCaptcha} from "~/api/passport/login";
|
||||
|
||||
// 引入状态管理
|
||||
const route = useRoute();
|
||||
const layout = useLayout();
|
||||
const page = usePage();
|
||||
const dialogVisible = ref(false)
|
||||
const formRef = ref<FormInstance>()
|
||||
const dialogImageUrl = ref('')
|
||||
// 验证码 base64 数据
|
||||
const captcha = ref('');
|
||||
const text = ref<string>('');
|
||||
|
||||
|
||||
const {form, resetFields} = useFormData<CmsOrder>({
|
||||
// 订单号
|
||||
orderId: undefined,
|
||||
// 模型名称
|
||||
model: 'order',
|
||||
// 订单标题
|
||||
title: undefined,
|
||||
// 订单编号
|
||||
orderNo: undefined,
|
||||
// 订单类型,0商城 1询价 2留言
|
||||
type: undefined,
|
||||
// 关联项目ID,配合订单类型使用
|
||||
articleId: undefined,
|
||||
// 真实姓名
|
||||
realName: undefined,
|
||||
// 手机号码
|
||||
phone: undefined,
|
||||
// 电子邮箱
|
||||
email: undefined,
|
||||
// 收货地址
|
||||
address: undefined,
|
||||
// 订单内容
|
||||
content: undefined,
|
||||
// 订单总额
|
||||
totalPrice: '0.00',
|
||||
// 实际付款
|
||||
payPrice: '0.00',
|
||||
// 报价询价
|
||||
price: '0.00',
|
||||
// 购买数量
|
||||
totalNum: undefined,
|
||||
// 二维码地址,保存订单号,支付成功后才生成
|
||||
qrcode: undefined,
|
||||
// 下单渠道,0网站 1小程序 2其他
|
||||
channel: undefined,
|
||||
// 过期时间
|
||||
expirationTime: undefined,
|
||||
// 订单是否已结算(0未结算 1已结算)
|
||||
isSettled: undefined,
|
||||
// 用户id
|
||||
userId: undefined,
|
||||
// 备注
|
||||
comments: undefined,
|
||||
// 排序号
|
||||
sortNumber: undefined,
|
||||
// 是否删除, 0否, 1是
|
||||
deleted: undefined,
|
||||
// 租户id
|
||||
tenantId: undefined,
|
||||
// 创建时间
|
||||
createTime: undefined,
|
||||
// 图像验证码
|
||||
code: '',
|
||||
})
|
||||
|
||||
const rules = reactive<FormRules<CmsOrder>>({
|
||||
title: [
|
||||
{required: true, message: '请输入产品名称', trigger: 'blur'},
|
||||
],
|
||||
phone: [
|
||||
{required: true, message: '请输入手机号码', trigger: 'blur'},
|
||||
{pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur'},
|
||||
],
|
||||
realName: [
|
||||
{required: true, message: '请输入联系人姓名', trigger: 'blur'},
|
||||
],
|
||||
content: [
|
||||
{required: true, message: '请输入留言内容', trigger: 'blur'},
|
||||
]
|
||||
})
|
||||
|
||||
/* 获取图形验证码 */
|
||||
const changeCaptcha = async () => {
|
||||
getCaptcha().then(captchaData => {
|
||||
captcha.value = captchaData.base64;
|
||||
text.value = captchaData.text;
|
||||
})
|
||||
};
|
||||
|
||||
// 请求数据
|
||||
const reload = async () => {
|
||||
getCmsArticle(paramsId()).then(data => {
|
||||
form.articleId = data.articleId;
|
||||
layout.value.banner = data.banner;
|
||||
form.content = ''
|
||||
// seo
|
||||
useSeoMeta({
|
||||
description: form.comments || form.title,
|
||||
keywords: form.title,
|
||||
titleTemplate: `${form?.title}` + ' - %s',
|
||||
})
|
||||
changeCaptcha();
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitForm = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
if(form.code !== text.value){
|
||||
await reload();
|
||||
ElMessage.error('验证码不正确!');
|
||||
return false;
|
||||
}
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
addCmsOrder(form).then(res => {
|
||||
if (res.code == 0) {
|
||||
ElMessage.success(res.message)
|
||||
resetFields();
|
||||
reload();
|
||||
} else {
|
||||
return ElMessage.error(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 在这里放置你想要在组件渲染完成后执行的代码
|
||||
console.log('组件已挂载');
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
padding-top: 15px;
|
||||
overflow: hidden;
|
||||
text-indent: 2em;
|
||||
}
|
||||
.content p{
|
||||
line-height: 2em;
|
||||
}
|
||||
.content img{
|
||||
padding: 10px;
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
78
pages/m/page/[id].vue
Normal file
78
pages/m/page/[id].vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
|
||||
<!-- Banner -->
|
||||
<Banner :layout="layout" />
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="clearfix p-5">
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>{{ page.title }}</h2>
|
||||
</div>
|
||||
<div class="content text-lg" v-html="page.design?.content"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import { useLayout, usePage} from "~/composables/configState";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import {paramsId} from "~/utils/common";
|
||||
import {getCmsNavigation, listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
|
||||
// 引入状态管理
|
||||
const route = useRoute();
|
||||
const layout = useLayout();
|
||||
const page = usePage();
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
|
||||
|
||||
// 加载页面布局
|
||||
const reload = async () => {
|
||||
getCmsNavigation(paramsId()).then(data => {
|
||||
page.value = data
|
||||
layout.value.banner = data.banner;
|
||||
// 二级栏目分类
|
||||
if(data.parentId && data.parentId > 0){
|
||||
listCmsNavigation({
|
||||
parentId: data.parentId == 0 ? data.navigationId : data.parentId
|
||||
}).then(list => {
|
||||
category.value = list
|
||||
})
|
||||
}
|
||||
// seo
|
||||
useSeoMeta({
|
||||
description: data.comments || data.title,
|
||||
keywords: data.title,
|
||||
titleTemplate: `${data?.title}` + ' - %s',
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
padding-top: 15px;
|
||||
padding-bottom: 30px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.content p{
|
||||
}
|
||||
.content img{
|
||||
padding: 5px 0;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.content video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
122
pages/m/product/[id].vue
Normal file
122
pages/m/product/[id].vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
|
||||
<Banner :layout="layout" />
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="clearfix p-5">
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>
|
||||
{{ page.title }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="content">
|
||||
|
||||
<!-- 产品列表 -->
|
||||
<el-row :gutter="20">
|
||||
<template v-for="(item,index) in list" key="index">
|
||||
<el-col :span="24" class="my-3">
|
||||
<div class="item p-2 border-1 border-gray-200 border-solid hover:border-blue-500">
|
||||
<a :href="mDetail(item)" :title="item.title" class="img"><el-image :fit="`scale-down`" :src="item.image" :alt="item.title" /></a>
|
||||
<h3>
|
||||
<a :href="mDetail(item)" :title="item.title" class="text-lg font-bold">{{ item.title }}</a>
|
||||
<span class="line-clamp-1 text-gray-400 text-sm font-normal">{{ item.comments }}</span>
|
||||
</h3>
|
||||
</div>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row>
|
||||
|
||||
<Pagination :total="total" @done="search" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Banner from "@/components/Banner.vue";
|
||||
import {useLayout, usePage} from "~/composables/configState";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import type {CmsArticle, CmsArticleParam} from "~/api/cms/cmsArticle/model";
|
||||
import {mDetail, paramsId} from "~/utils/common";
|
||||
import {getCmsNavigation, listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
import {pageCmsArticle} from "~/api/cms/cmsArticle";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
// 页面信息
|
||||
const list = ref<CmsArticle[]>([]);
|
||||
const i18n = useI18n();
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
const total = ref(0);
|
||||
|
||||
// 获取状态
|
||||
const page = usePage();
|
||||
const layout = useLayout();
|
||||
|
||||
// 搜索表单
|
||||
const where = reactive<CmsArticleParam>({
|
||||
keywords: '',
|
||||
page: 1,
|
||||
limit: 20,
|
||||
status: 0,
|
||||
parentId: undefined,
|
||||
categoryId: undefined,
|
||||
lang: i18n.locale.value
|
||||
});
|
||||
|
||||
const reload = async () => {
|
||||
console.log(paramsId())
|
||||
getCmsNavigation(paramsId()).then(data => {
|
||||
// 获取栏目信息
|
||||
page.value = data
|
||||
layout.value.banner = data.banner;
|
||||
|
||||
// 设置页面标题
|
||||
useSeoMeta({
|
||||
description: data.comments || data.title,
|
||||
keywords: data.title,
|
||||
titleTemplate: `${data?.title}` + ' - %s',
|
||||
})
|
||||
|
||||
// 二级栏目分类
|
||||
listCmsNavigation({
|
||||
parentId: data.parentId == 0 ? data.navigationId : data.parentId
|
||||
}).then(categoryData => {
|
||||
category.value = categoryData;
|
||||
// 加载文章列表
|
||||
if(data.parentId == 0 && category.value.length > 0){
|
||||
where.parentId = data.navigationId;
|
||||
}else {
|
||||
where.categoryId = data.navigationId;
|
||||
}
|
||||
pageCmsArticle(where).then(response => {
|
||||
if(response){
|
||||
total.value = response?.count;
|
||||
list.value = response?.list;
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}).catch(err => {
|
||||
console.log(err,'加载失败...')
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
* @param data
|
||||
*/
|
||||
const search = (data: CmsArticleParam) => {
|
||||
where.page = data.page;
|
||||
reload();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
147
pages/m/search/[id].vue
Normal file
147
pages/m/search/[id].vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
|
||||
<Banner :layout="layout" />
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="p-5">
|
||||
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>
|
||||
{{ $t('searchKeywords') }}:{{ where.keywords }}
|
||||
</h2>
|
||||
</div>
|
||||
<el-alert v-if="where.keywords" :title="`${$t('search.results')}:${$t('search.find')} ${total} ${$t('search.nums')}`" type="warning" :closable="false" />
|
||||
<div class="content">
|
||||
|
||||
<ul class="news_listn clearfix">
|
||||
<template v-for="(item,index) in list" key="index">
|
||||
<li class="clearfix">
|
||||
<div class="">
|
||||
<h3 class="text-lg"><a :href="mDetail(item)" :title="item.title" v-html="replaceKeywords(item.title)"></a></h3>
|
||||
<div v-html="replaceKeywords(item.comments)" class="line-clamp-2 text-gray-400"></div>
|
||||
<div class="date text-gray-400">{{ $t('createTime') }}:{{ dayjs(item.createTime).format('YYYY-MM-DD') }}</div>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
<div class="clearboth"></div>
|
||||
</ul>
|
||||
|
||||
<Pagination :total="total" @done="search" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Banner from "@/components/Banner.vue";
|
||||
import {useConfigInfo, useLayout, usePage} from "~/composables/configState";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import type {CmsArticle, CmsArticleParam} from "~/api/cms/cmsArticle/model";
|
||||
import dayjs from "dayjs";
|
||||
import {getPath} from "~/utils/common";
|
||||
import {listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
import {pageCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import {listCmsModel} from "~/api/cms/cmsModel";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
// 页面信息
|
||||
const runtimeConfig = useRuntimeConfig();
|
||||
const list = ref<CmsArticle[]>([]);
|
||||
const i18n = useI18n();
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
const total = ref(0);
|
||||
|
||||
// 获取状态
|
||||
const page = usePage();
|
||||
const layout = useLayout();
|
||||
const config = useConfigInfo();
|
||||
|
||||
// 搜索表单
|
||||
const where = reactive<CmsArticleParam>({
|
||||
keywords: '',
|
||||
page: 1,
|
||||
limit: 10,
|
||||
status: 0,
|
||||
parentId: undefined,
|
||||
categoryId: undefined,
|
||||
lang: i18n.locale.value
|
||||
});
|
||||
|
||||
const replaceKeywords = (text: any) => {
|
||||
return text.replace(`${where.keywords}`,'<font color=#ff0000>' + where.keywords + '</font>');
|
||||
}
|
||||
|
||||
// 加载页面数据
|
||||
const reload = async () => {
|
||||
listCmsModel({
|
||||
model: getPath(2)
|
||||
}).then(response => {
|
||||
const data = response[0];
|
||||
if(data){
|
||||
// 获取栏目信息
|
||||
page.value = data
|
||||
layout.value.banner = data.banner;
|
||||
|
||||
// 设置页面标题
|
||||
useSeoMeta({
|
||||
description: data?.comments || `${route.params.id}`,
|
||||
keywords: `${route.params.id}`,
|
||||
titleTemplate: `【搜索结果】${route.params.id}` + ' - %s',
|
||||
})
|
||||
|
||||
// 二级栏目分类
|
||||
listCmsNavigation({
|
||||
parentId: i18n.locale.value == 'en' ? 1073 : 998,
|
||||
}).then(categoryData => {
|
||||
category.value = categoryData;
|
||||
// 加载文章列表
|
||||
if(!getPath(1)){
|
||||
return ElMessage.error('请输入搜索关键词!');
|
||||
}
|
||||
where.keywords = `${route.params.id}`;
|
||||
pageCmsArticle(where).then(response => {
|
||||
if(response){
|
||||
total.value = response?.count;
|
||||
list.value = response?.list;
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}).catch(err => {
|
||||
console.log(err,'加载失败...')
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
useHead({
|
||||
title: `搜索结果 - ${config.value.siteName || runtimeConfig.public.siteName}`,
|
||||
bodyAttrs: {
|
||||
class: "page-container",
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
* @param data
|
||||
*/
|
||||
const search = (data: CmsArticleParam) => {
|
||||
where.page = data.page;
|
||||
reload();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.sitemp h2{
|
||||
width: 500px !important;
|
||||
}
|
||||
</style>
|
||||
185
pages/m/show/[id].vue
Normal file
185
pages/m/show/[id].vue
Normal file
@@ -0,0 +1,185 @@
|
||||
<!-- 文章详情 -->
|
||||
<template>
|
||||
<Banner :layout="layout"/>
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="p-5">
|
||||
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>
|
||||
{{ form.categoryName || '分类名称' }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="detail-container">
|
||||
|
||||
<!-- 产品详细 -->
|
||||
<div class="product_detail" id="pd1">
|
||||
<div class="allcontent clearfix">
|
||||
<div class="text-center text-xl text-gray-800 py-2">{{ form.title }}</div>
|
||||
<el-carousel v-if="form.files" :interval="4000">
|
||||
<el-carousel-item v-for="item in form.files" :key="item" class="" style="display: flex; align-items: center; justify-content: center">
|
||||
<el-image :src="item" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
|
||||
<div class="clearboth"></div>
|
||||
<div class="p_detail">
|
||||
<ul id="product-tab" class="product-tab clearfix">
|
||||
<li class="cur">{{ $t('show.detail') }}</li>
|
||||
|
||||
</ul>
|
||||
<div class="content tab-content text-sm" v-html="form.content"></div>
|
||||
</div>
|
||||
<h3 class="tag">{{ $t('articleUrl') }}:{{ locationUrl() }} </h3>
|
||||
<Tags :data="form.tags" />
|
||||
<NextArticle />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import {locationUrl, paramsId} from "~/utils/common";
|
||||
import type {CmsArticle} from "~/api/cms/cmsArticle/model";
|
||||
import useFormData from "~/utils/use-form-data";
|
||||
import Banner from "@/components/Banner.vue";
|
||||
import type {Layout} from "~/api/layout/model";
|
||||
import {getCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import {listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
import Tags from "~/components/Tags.vue";
|
||||
|
||||
// 引入状态管理
|
||||
const route = useRoute();
|
||||
const layout = ref<Layout>({});
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
|
||||
// 配置信息
|
||||
const {form, assignFields} = useFormData<CmsArticle>({
|
||||
// 文章id
|
||||
articleId: undefined,
|
||||
// 文章模型
|
||||
model: undefined,
|
||||
// 文章标题
|
||||
title: undefined,
|
||||
// 分类类型
|
||||
type: undefined,
|
||||
// 展现方式
|
||||
showType: undefined,
|
||||
// 文章类型
|
||||
categoryId: undefined,
|
||||
// 文章分类
|
||||
categoryName: undefined,
|
||||
parentId: undefined,
|
||||
// 封面图
|
||||
image: undefined,
|
||||
// 附件
|
||||
files: undefined,
|
||||
// 缩列图
|
||||
thumbnail: undefined,
|
||||
// 视频地址
|
||||
video: undefined,
|
||||
// 上传的文件类型
|
||||
accept: undefined,
|
||||
// 来源
|
||||
source: undefined,
|
||||
// 文章内容
|
||||
content: undefined,
|
||||
// 虚拟阅读量
|
||||
virtualViews: undefined,
|
||||
// 实际阅读量
|
||||
actualViews: undefined,
|
||||
// 访问权限
|
||||
permission: undefined,
|
||||
// 访问密码
|
||||
password: undefined,
|
||||
password2: undefined,
|
||||
// 用户ID
|
||||
userId: undefined,
|
||||
// 用户昵称
|
||||
nickname: undefined,
|
||||
// 账号
|
||||
username: undefined,
|
||||
// 用户头像
|
||||
// userAvatar: undefined,
|
||||
author: undefined,
|
||||
// 所属门店ID
|
||||
shopId: undefined,
|
||||
//
|
||||
likes: undefined,
|
||||
// 排序
|
||||
sortNumber: undefined,
|
||||
// 备注
|
||||
comments: undefined,
|
||||
// 状态
|
||||
status: undefined,
|
||||
// 创建时间
|
||||
createTime: undefined,
|
||||
// 更新时间
|
||||
updateTime: undefined,
|
||||
tenantId: undefined,
|
||||
// 租户名称
|
||||
tenantName: undefined,
|
||||
// 租户logo
|
||||
logo: undefined,
|
||||
// 详情页路径
|
||||
detail: undefined
|
||||
});
|
||||
|
||||
// 请求数据
|
||||
const reload = async () => {
|
||||
await getCmsArticle(paramsId()).then(data => {
|
||||
|
||||
assignFields(data);
|
||||
layout.value.banner = data?.banner;
|
||||
if (data.files) {
|
||||
form.files = JSON.parse(data.files);
|
||||
}
|
||||
|
||||
// 二级栏目分类
|
||||
listCmsNavigation({
|
||||
parentId: data.parentId
|
||||
}).then(list => {
|
||||
category.value = list
|
||||
})
|
||||
|
||||
// seo
|
||||
useSeoMeta({
|
||||
description: form.comments || form.title,
|
||||
keywords: form.title,
|
||||
titleTemplate: `${form?.title}` + ' - %s',
|
||||
})
|
||||
|
||||
}).catch(err => {
|
||||
console.log(err,'err')
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
padding-top: 15px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.content p{
|
||||
}
|
||||
.content img{
|
||||
padding: 10px;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.content video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
135
pages/m/tags/[id].vue
Normal file
135
pages/m/tags/[id].vue
Normal file
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
|
||||
<Banner :layout="layout" />
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="p-5">
|
||||
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>
|
||||
{{ $t('label') }}:{{ where.tags }}
|
||||
</h2>
|
||||
</div>
|
||||
<el-alert v-if="where.keywords" :title="`${$t('search.results')}:${$t('search.find')} ${total} ${$t('search.nums')}`" type="warning" :closable="false" />
|
||||
<div class="content">
|
||||
|
||||
|
||||
<ul class="news_listn clearfix">
|
||||
<template v-for="(item,index) in list" key="index">
|
||||
<li class="clearfix">
|
||||
<div class="">
|
||||
<h3 class="text-lg"><a :href="mDetail(item)" :title="item.title" v-html="replaceKeywords(item.title)"></a></h3>
|
||||
<div v-html="replaceKeywords(item.comments)" class="line-clamp-2 text-gray-400"></div>
|
||||
<div class="date text-gray-400">{{ $t('createTime') }}:{{ dayjs(item.createTime).format('YYYY-MM-DD') }}</div>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
<div class="clearboth"></div>
|
||||
</ul>
|
||||
<Pagination :total="total" @done="search" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Banner from "@/components/Banner.vue";
|
||||
import {useLayout, usePage} from "~/composables/configState";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import type {CmsArticle, CmsArticleParam} from "~/api/cms/cmsArticle/model";
|
||||
import dayjs from "dayjs";
|
||||
import {getPath} from "~/utils/common";
|
||||
import {listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
import {pageCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import {listCmsModel} from "~/api/cms/cmsModel";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
// 页面信息
|
||||
const list = ref<CmsArticle[]>([]);
|
||||
const i18n = useI18n();
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
const total = ref(0);
|
||||
|
||||
// 获取状态
|
||||
const page = usePage();
|
||||
const layout = useLayout();
|
||||
|
||||
// 搜索表单
|
||||
const where = reactive<CmsArticleParam>({
|
||||
tags: '',
|
||||
page: 1,
|
||||
limit: 10,
|
||||
status: 0,
|
||||
parentId: undefined,
|
||||
categoryId: undefined,
|
||||
lang: i18n.locale.value
|
||||
});
|
||||
|
||||
const replaceKeywords = (text: any) => {
|
||||
return text.replace(`${where.keywords}`,'<font color=#ff0000>' + where.keywords + '</font>');
|
||||
}
|
||||
|
||||
// 加载页面数据
|
||||
const reload = async () => {
|
||||
listCmsModel({
|
||||
model: getPath(2)
|
||||
}).then(response => {
|
||||
const data = response[0];
|
||||
if(data){
|
||||
// 获取栏目信息
|
||||
page.value = data
|
||||
layout.value.banner = data.banner
|
||||
// 设置页面标题
|
||||
useSeoMeta({
|
||||
description: data?.comments || `${route.params.id}`,
|
||||
keywords: `${route.params.id}`,
|
||||
titleTemplate: `【搜索结果】${route.params.id}` + ' - %s',
|
||||
})
|
||||
// 二级栏目分类
|
||||
listCmsNavigation({
|
||||
parentId: i18n.locale.value == 'en' ? 1073 : 998,
|
||||
}).then(categoryData => {
|
||||
category.value = categoryData;
|
||||
// 加载文章列表
|
||||
if(!getPath(1)){
|
||||
return ElMessage.error('请输入搜索关键词!');
|
||||
}
|
||||
where.tags = `${route.params.id}`;
|
||||
pageCmsArticle(where).then(response => {
|
||||
if(response){
|
||||
total.value = response?.count;
|
||||
list.value = response?.list;
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}).catch(err => {
|
||||
console.log(err,'加载失败...')
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
* @param data
|
||||
*/
|
||||
const search = (data: CmsArticleParam) => {
|
||||
where.page = data.page;
|
||||
reload();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.sitemp h2{
|
||||
width: 500px !important;
|
||||
}
|
||||
</style>
|
||||
110
pages/m/video/[id].vue
Normal file
110
pages/m/video/[id].vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
|
||||
<Banner :layout="layout" />
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="p-5">
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>
|
||||
{{ page.title }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="content">
|
||||
|
||||
<!-- 产品列表 -->
|
||||
<MCmsProductList :data="list" />
|
||||
|
||||
<Pagination :total="total" @done="search" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Banner from "@/components/Banner.vue";
|
||||
import {useLayout, usePage} from "~/composables/configState";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import type {CmsArticle, CmsArticleParam} from "~/api/cms/cmsArticle/model";
|
||||
import {paramsId} from "~/utils/common";
|
||||
import {getCmsNavigation, listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
import {pageCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import MCmsProductList from "~/components/MCmsProductList.vue";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
// 页面信息
|
||||
const list = ref<CmsArticle[]>([]);
|
||||
const i18n = useI18n();
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
const total = ref(0);
|
||||
|
||||
// 获取状态
|
||||
const page = usePage();
|
||||
const layout = useLayout();
|
||||
|
||||
// 搜索表单
|
||||
const where = reactive<CmsArticleParam>({
|
||||
keywords: '',
|
||||
page: 1,
|
||||
limit: 20,
|
||||
status: 0,
|
||||
parentId: undefined,
|
||||
categoryId: undefined,
|
||||
lang: i18n.locale.value
|
||||
});
|
||||
|
||||
const reload = async () => {
|
||||
getCmsNavigation(paramsId()).then(data => {
|
||||
// 获取栏目信息
|
||||
page.value = data
|
||||
layout.value.banner = data.banner;
|
||||
|
||||
// 设置页面标题
|
||||
useSeoMeta({
|
||||
description: data.comments || data.title,
|
||||
keywords: data.title,
|
||||
titleTemplate: `${data?.title}` + ' - %s',
|
||||
})
|
||||
|
||||
// 二级栏目分类
|
||||
listCmsNavigation({
|
||||
parentId: data.parentId == 0 ? data.navigationId : data.parentId
|
||||
}).then(categoryData => {
|
||||
category.value = categoryData;
|
||||
// 加载文章列表
|
||||
if(data.parentId == 0 && category.value.length > 0){
|
||||
where.parentId = data.navigationId;
|
||||
}else {
|
||||
where.categoryId = data.navigationId;
|
||||
}
|
||||
pageCmsArticle(where).then(response => {
|
||||
if(response){
|
||||
total.value = response?.count;
|
||||
list.value = response?.list;
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}).catch(err => {
|
||||
console.log(err,'加载失败...')
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
* @param data
|
||||
*/
|
||||
const search = (data: CmsArticleParam) => {
|
||||
where.page = data.page;
|
||||
reload();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
183
pages/m/video/detail/[id].vue
Normal file
183
pages/m/video/detail/[id].vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<!-- 文章详情 -->
|
||||
<template>
|
||||
<Banner :layout="layout"/>
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="p-5">
|
||||
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>
|
||||
{{ form.categoryName || '分类名称' }}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="detail-container">
|
||||
|
||||
<!-- 产品详细 -->
|
||||
<div class="product_detail" id="pd1">
|
||||
<div class="allcontent clearfix">
|
||||
<div class="text-center text-xl text-gray-800 py-5">{{ form.title }}</div>
|
||||
<el-carousel v-if="form.files" :interval="4000" height="400px">
|
||||
<el-carousel-item v-for="item in form.files" :key="item" style="display: flex; align-items: center; justify-content: center">
|
||||
<el-image :src="item" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
|
||||
<div class="clearboth"></div>
|
||||
<div class="p_detail">
|
||||
<ul id="product-tab" class="product-tab clearfix">
|
||||
<li class="cur">{{ $t('show.detail') }}</li>
|
||||
|
||||
</ul>
|
||||
<!-- 内容组件 -->
|
||||
<MContent class="text-sm" :data="form.content" />
|
||||
</div>
|
||||
<h3 class="tag">{{ $t('articleUrl') }}:{{ locationUrl() }} </h3>
|
||||
<Tags :data="form.tags" />
|
||||
<NextArticle />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import {locationUrl, paramsId} from "~/utils/common";
|
||||
import type {CmsArticle} from "~/api/cms/cmsArticle/model";
|
||||
import useFormData from "~/utils/use-form-data";
|
||||
import Banner from "@/components/Banner.vue";
|
||||
import type {Layout} from "~/api/layout/model";
|
||||
import {getCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import {listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
import Tags from "~/components/Tags.vue";
|
||||
import MContent from "~/components/MContent.vue";
|
||||
|
||||
// 引入状态管理
|
||||
const route = useRoute();
|
||||
const i18n = useI18n();
|
||||
const layout = ref<Layout>({});
|
||||
const category = ref<CmsNavigation[]>([]);
|
||||
const parentName = ref('项目展示');
|
||||
|
||||
// 配置信息
|
||||
const {form, assignFields} = useFormData<CmsArticle>({
|
||||
// 文章id
|
||||
articleId: undefined,
|
||||
// 文章模型
|
||||
model: undefined,
|
||||
// 文章标题
|
||||
title: undefined,
|
||||
// 分类类型
|
||||
type: undefined,
|
||||
tags: undefined,
|
||||
// 展现方式
|
||||
showType: undefined,
|
||||
// 文章类型
|
||||
categoryId: undefined,
|
||||
// 文章分类
|
||||
categoryName: undefined,
|
||||
parentId: undefined,
|
||||
// 封面图
|
||||
image: undefined,
|
||||
// 附件
|
||||
files: undefined,
|
||||
// 缩列图
|
||||
thumbnail: undefined,
|
||||
// 视频地址
|
||||
video: undefined,
|
||||
// 上传的文件类型
|
||||
accept: undefined,
|
||||
// 来源
|
||||
source: undefined,
|
||||
// 文章内容
|
||||
content: undefined,
|
||||
// 虚拟阅读量
|
||||
virtualViews: undefined,
|
||||
// 实际阅读量
|
||||
actualViews: undefined,
|
||||
// 访问权限
|
||||
permission: undefined,
|
||||
// 访问密码
|
||||
password: undefined,
|
||||
password2: undefined,
|
||||
// 用户ID
|
||||
userId: undefined,
|
||||
// 用户昵称
|
||||
nickname: undefined,
|
||||
// 账号
|
||||
username: undefined,
|
||||
// 用户头像
|
||||
// userAvatar: undefined,
|
||||
author: undefined,
|
||||
// 所属门店ID
|
||||
shopId: undefined,
|
||||
//
|
||||
likes: undefined,
|
||||
// 排序
|
||||
sortNumber: undefined,
|
||||
// 备注
|
||||
comments: undefined,
|
||||
// 状态
|
||||
status: undefined,
|
||||
// 创建时间
|
||||
createTime: undefined,
|
||||
// 更新时间
|
||||
updateTime: undefined,
|
||||
tenantId: undefined,
|
||||
// 租户名称
|
||||
tenantName: undefined,
|
||||
// 租户logo
|
||||
logo: undefined,
|
||||
// 详情页路径
|
||||
detail: undefined
|
||||
});
|
||||
|
||||
// 请求数据
|
||||
const reload = async () => {
|
||||
await getCmsArticle(paramsId()).then(data => {
|
||||
|
||||
assignFields(data);
|
||||
|
||||
layout.value.banner = data?.banner;
|
||||
if (data.files) {
|
||||
form.files = JSON.parse(data.files);
|
||||
}
|
||||
|
||||
// 二级栏目分类
|
||||
listCmsNavigation({
|
||||
parentId: data.parentId,
|
||||
lang: i18n.locale.value
|
||||
}).then(list => {
|
||||
category.value = list
|
||||
// 宣传视频
|
||||
if(data.categoryName == '宣传视频'){
|
||||
parentName.value = '宣传视频'
|
||||
category.value = [];
|
||||
}
|
||||
})
|
||||
|
||||
// seo
|
||||
useSeoMeta({
|
||||
description: form.comments || form.title,
|
||||
keywords: form.title,
|
||||
titleTemplate: `${form?.title}` + ' - %s',
|
||||
})
|
||||
|
||||
}).catch(err => {
|
||||
console.log(err,'err')
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
||||
Reference in New Issue
Block a user