Compare commits
2 Commits
4d45f5fbc3
...
9d9fdc48f4
Author | SHA1 | Date |
---|---|---|
|
9d9fdc48f4 | 6 months ago |
|
bca962f79d | 6 months ago |
18 changed files with 1528 additions and 222 deletions
@ -0,0 +1,92 @@ |
|||
import type {PageParam} from '@/api'; |
|||
import type {CmsDesign} from "~/api/cms/cmsDesign/model"; |
|||
|
|||
/** |
|||
* 网站导航记录表 |
|||
*/ |
|||
export interface CmsNavigation { |
|||
// ID
|
|||
navigationId?: number; |
|||
// 上级id, 0是顶级
|
|||
parentId?: number; |
|||
// 菜单名称
|
|||
title?: string; |
|||
// 模型
|
|||
model?: string; |
|||
// 标识
|
|||
code?: string; |
|||
// 菜单路由地址
|
|||
path?: string; |
|||
// 菜单组件地址, 目录可为空
|
|||
component?: string; |
|||
componentPath?: string; |
|||
// 打开位置
|
|||
target?: string; |
|||
// 菜单图标
|
|||
icon?: string; |
|||
// 图标颜色
|
|||
color?: string; |
|||
// 是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)
|
|||
hide?: number; |
|||
// 可见类型 0所有人 1登录可见 2密码可见
|
|||
permission?: number; |
|||
// 访问密码
|
|||
password?: string; |
|||
// 位置 0不限 1顶部 2底部
|
|||
position?: number; |
|||
// 仅在顶部显示
|
|||
top?: number; |
|||
// 仅在底部显示
|
|||
bottom?: number; |
|||
// 菜单侧栏选中的path
|
|||
active?: string; |
|||
// 其它路由元信息
|
|||
meta?: string; |
|||
// css样式
|
|||
style?: string; |
|||
// 父级栏目路由
|
|||
parentPath?: string; |
|||
// 父级栏目名称
|
|||
parentName?: string; |
|||
// 模型名称
|
|||
modelName?: string; |
|||
// 类型(已废弃)
|
|||
type?: number; |
|||
// 绑定的页面(已废弃)
|
|||
pageId?: number; |
|||
// 项目ID
|
|||
itemId?: number; |
|||
// 是否微信小程序菜单
|
|||
isMpWeixin?: string; |
|||
// 用户ID
|
|||
userId?: number; |
|||
// 设为首页
|
|||
home?: number; |
|||
// 排序(数字越小越靠前)
|
|||
sortNumber?: number; |
|||
// 备注
|
|||
comments?: string; |
|||
// 是否删除, 0否, 1是
|
|||
deleted?: number; |
|||
// 状态, 0正常, 1冻结
|
|||
status?: number; |
|||
// 租户id
|
|||
tenantId?: number; |
|||
// 创建时间
|
|||
createTime?: string; |
|||
children?: CmsNavigation[]; |
|||
disabled?: boolean; |
|||
label?: string; |
|||
value?: number; |
|||
design?: CmsDesign; |
|||
childHeight?: number, |
|||
showChild?: boolean |
|||
} |
|||
|
|||
/** |
|||
* 网站导航记录表搜索条件 |
|||
*/ |
|||
export interface CmsNavigationParam extends PageParam { |
|||
navigationId?: number; |
|||
keywords?: string; |
|||
} |
@ -0,0 +1,103 @@ |
|||
import type { PageParam } from '@/api'; |
|||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model"; |
|||
|
|||
/** |
|||
* 网站信息记录表 |
|||
*/ |
|||
export interface CmsWebsite { |
|||
// 站点ID
|
|||
websiteId?: number; |
|||
// 网站名称
|
|||
websiteName?: string; |
|||
// 网站标识
|
|||
websiteCode?: string; |
|||
// 网站LOGO
|
|||
websiteIcon?: string; |
|||
// 网站LOGO
|
|||
websiteLogo?: string; |
|||
// 网站LOGO(深色模式)
|
|||
websiteDarkLogo?: string; |
|||
// 网站类型
|
|||
websiteType?: string; |
|||
// 网站关键词
|
|||
keywords?: string; |
|||
// 域名前缀
|
|||
prefix?: string; |
|||
// 绑定域名
|
|||
domain?: string; |
|||
// 全局样式
|
|||
style?: string; |
|||
// 后台管理地址
|
|||
adminUrl?: string; |
|||
// 应用版本 10免费版 20专业版 30永久授权
|
|||
version?: number; |
|||
// 服务到期时间
|
|||
expirationTime?: string; |
|||
// 模版ID
|
|||
templateId?: number; |
|||
// 行业类型(父级)
|
|||
industryParent?: string; |
|||
// 行业类型(子级)
|
|||
industryChild?: string; |
|||
// 企业ID
|
|||
companyId?: number; |
|||
// 所在国家
|
|||
country?: string; |
|||
// 所在省份
|
|||
province?: string; |
|||
// 所在城市
|
|||
city?: string; |
|||
// 所在辖区
|
|||
region?: string; |
|||
// 经度
|
|||
longitude?: string; |
|||
// 纬度
|
|||
latitude?: string; |
|||
// 街道地址
|
|||
address?: string; |
|||
// 联系电话
|
|||
phone?: string; |
|||
// 电子邮箱
|
|||
email?: string; |
|||
// ICP备案号
|
|||
icpNo?: string; |
|||
// 公安备案
|
|||
policeNo?: string; |
|||
// 备注
|
|||
comments?: string; |
|||
// 是否推荐
|
|||
recommend?: number; |
|||
// 状态 0未开通 1运行中 2维护中 3已关闭 4已欠费停机 5违规关停
|
|||
status?: number; |
|||
// 维护说明
|
|||
statusText?: string; |
|||
// 关闭说明
|
|||
statusClose?: string; |
|||
// 全局样式
|
|||
styles?: string; |
|||
// 排序号
|
|||
sortNumber?: number; |
|||
// 用户ID
|
|||
userId?: number; |
|||
// 是否删除, 0否, 1是
|
|||
deleted?: number; |
|||
// 租户id
|
|||
tenantId?: number; |
|||
// 创建时间
|
|||
createTime?: string; |
|||
// 修改时间
|
|||
updateTime?: string; |
|||
// 网站配置
|
|||
config?: any; |
|||
topNavs?: CmsNavigation[]; |
|||
bottomNavs?: CmsNavigation[]; |
|||
} |
|||
|
|||
/** |
|||
* 网站信息记录表搜索条件 |
|||
*/ |
|||
export interface CmsWebsiteParam extends PageParam { |
|||
websiteId?: number; |
|||
status?: number; |
|||
keywords?: string; |
|||
} |
@ -0,0 +1,139 @@ |
|||
<template> |
|||
<div class="w-full bg-white pb-20 mb-3 relative" |
|||
:style="`background: url('${config?.IndexAboutBg}') no-repeat center`"> |
|||
<template v-if="showAboutUs"> |
|||
<div class="text-center flex flex-col items-center py-15 relative "> |
|||
<div class="sub-title"> |
|||
<p class="text-gray-200 text-6xl font-bold dark:text-gray-700 py-0 line-height-5"> |
|||
{{ comments }} |
|||
</p> |
|||
</div> |
|||
<h2 class="text-3xl font-bold tracking-tight text-green-600 dark:text-white sm:text-4xl lg:text-5xl"> |
|||
{{ title }} |
|||
</h2> |
|||
</div> |
|||
<div class="hidden-sm-and-down"> |
|||
<div class="xl:w-screen-xl m-auto text-xl flex justify-between " v-if="config?.IndexAboutInfo"> |
|||
<p class="indent-xl max-w-3/5 px-4 left-2-right" :class="config?.IndexAboutStyle" |
|||
style="font-family: Source Han Serif, SimSun,serif">{{ config?.IndexAboutInfo }}</p> |
|||
<div class="carousel px-3 text-center right-to-left"> |
|||
<img :src="config?.IndexAboutImg" class="scale-img"/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="hidden-sm-and-up"> |
|||
<div class="xl:w-screen-xl m-auto text-lg flex flex-col " v-if="config?.IndexAboutInfo"> |
|||
<div class="carousel px-3 text-center right-to-left"> |
|||
<img :src="config?.IndexAboutImg" class="scale-img"/> |
|||
</div> |
|||
<p class="p-3 left-2-right" :class="config?.IndexAboutStyle" |
|||
style="font-family: Source Han Serif, SimSun,serif">{{ config?.IndexAboutInfo }}</p> |
|||
</div> |
|||
</div> |
|||
|
|||
</template> |
|||
</div> |
|||
|
|||
|
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import {useServerRequest} from "~/composables/useServerRequest"; |
|||
import type {ApiResult} from "~/api"; |
|||
import type {Config} from "~/types/global"; |
|||
|
|||
const props = withDefaults( |
|||
defineProps<{ |
|||
config?: any; |
|||
title?: string; |
|||
comments?: string; |
|||
scrollTop: number; |
|||
}>(), |
|||
{} |
|||
); |
|||
|
|||
const emit = defineEmits<{ |
|||
(e: 'done'): void; |
|||
}>(); |
|||
|
|||
const showAboutUs = ref(false) |
|||
watch( |
|||
() => props.scrollTop, |
|||
() => { |
|||
if (props.scrollTop > 700) showAboutUs.value = true |
|||
}, |
|||
{immediate: true} |
|||
); |
|||
// 请求数据 |
|||
// const reload = async () => { |
|||
// const { data: fields } = await useServerRequest<ApiResult<Config>>('/cms/cms-website-field/config', {baseURL: 'https://server.gxwebsoft.com/api',}); |
|||
// if (fields.value?.data) { |
|||
// config.value = fields.value?.data; |
|||
// } |
|||
// } |
|||
|
|||
// reload(); |
|||
</script> |
|||
|
|||
<style lang="less"> |
|||
/* 在全局样式表如 app.css 或 styles.css 中添加 */ |
|||
.el-tabs__item { |
|||
font-size: 3em; /* 调整为你想要的字体大小 */ |
|||
} |
|||
|
|||
.custom-tabs .el-tabs__item { |
|||
font-size: 20px; /* 调整为你想要的字体大小 */ |
|||
} |
|||
</style> |
|||
|
|||
<style lang="less" scoped> |
|||
.scale-img { |
|||
width: 500px; |
|||
max-width: 100% !important; |
|||
} |
|||
|
|||
.scale-img:hover { |
|||
animation: scale; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
|
|||
@keyframes scale { |
|||
from { |
|||
transform: scale(1); |
|||
} |
|||
to { |
|||
transform: scale(1.1); |
|||
} |
|||
} |
|||
|
|||
.left-2-right { |
|||
animation: left-2-right-ani; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
|
|||
@keyframes left-2-right-ani { |
|||
from { |
|||
transform: translateX(100%); |
|||
} |
|||
to { |
|||
transform: translateX(0); |
|||
} |
|||
} |
|||
|
|||
.right-to-left { |
|||
animation: right-to-left-ani; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
|
|||
@keyframes right-to-left-ani { |
|||
from { |
|||
transform: translateX(-100%); |
|||
} |
|||
to { |
|||
transform: translateX(0); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,75 @@ |
|||
<template> |
|||
<div> |
|||
<div class="w-full bg-white mt-[60px] mb-3 hidden-sm-and-down" v-if="ad"> |
|||
<el-carousel indicator-position="none" :height="ad?.height"> |
|||
<el-carousel-item v-for="(item,index) in ad?.imgArr" :key="index"> |
|||
<div class="item relative"> |
|||
<el-image :src="item.url" /> |
|||
</div> |
|||
</el-carousel-item> |
|||
</el-carousel> |
|||
</div> |
|||
<!-- 移动端 --> |
|||
<div class="sm:hidden w-full bg-white mt-[48px] mb-3 hidden-sm-and-up" v-if="ad"> |
|||
<el-carousel indicator-position="none" height="160"> |
|||
<el-carousel-item v-for="(item,index) in ad?.imgArr" :key="index"> |
|||
<el-image :src="item.url" /> |
|||
</el-carousel-item> |
|||
</el-carousel> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import {useServerRequest} from "~/composables/useServerRequest"; |
|||
import type {ApiResult, PageResult} from "~/api"; |
|||
import type {CompanyParam} from "~/api/system/company/model"; |
|||
import type {CmsAd} from "~/api/cms/cmsAd/model"; |
|||
|
|||
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 () => { |
|||
const {data: response} = await useServerRequest<ApiResult<PageResult<CmsAd>>>('/cms/cms-ad/page',{params: {adType: '幻灯片',pageName: '首页'}}) |
|||
if (response.value?.data?.list) { |
|||
ad.value = response.value.data?.list[0]; |
|||
} |
|||
} |
|||
|
|||
watch( |
|||
() => props.config, |
|||
() => { |
|||
reload(); |
|||
}, |
|||
{immediate: true} |
|||
); |
|||
</script> |
|||
|
|||
<style> |
|||
.hidden-sm-and-up .el-carousel{ |
|||
height: 160px; |
|||
} |
|||
</style> |
@ -0,0 +1,121 @@ |
|||
<template> |
|||
<div class="w-full bg-gray-100 pb-20 bg-white"> |
|||
<div class="text-center flex flex-col items-center py-15 relative "> |
|||
<div class="sub-title"> |
|||
<p class="text-gray-200 text-5xl font-bold dark:text-gray-700 py-0 line-height-5"> |
|||
{{ comments }} |
|||
</p> |
|||
</div> |
|||
<h2 class="text-3xl font-bold tracking-tight text-[#FF6E0CFF] dark:text-white sm:text-4xl lg:text-5xl"> |
|||
{{ title }} |
|||
</h2> |
|||
</div> |
|||
<div class="xl:w-screen-xl m-auto text-xl right-to-left hidden-sm-and-down" v-if="show"> |
|||
<el-carousel :interval="4000" type="card" height="350px" arrow="never" indicator-position="none"> |
|||
<el-carousel-item class="relative" v-for="(item,index) in list" :key="index"> |
|||
<el-image :src="item.image" class="cursor-pointer scale-img w-full" /> |
|||
<div class="absolute bg-[#e65a01]/75 w-full py-2 z-100 text-center text-sm text-white bottom-0" v-if="item.comments" @click="openSpmUrl(`/detail`,item,item.articleId,true)">{{ item.comments }}</div> |
|||
</el-carousel-item> |
|||
</el-carousel> |
|||
</div> |
|||
<div class="xl:w-screen-xl m-auto text-xl right-to-left hidden-sm-and-up"> |
|||
<el-carousel :interval="4000" type="card" height="350px" arrow="never" indicator-position="none"> |
|||
<el-carousel-item class="relative" v-for="(item,index) in list" :key="index"> |
|||
<el-image :src="item.image" class="cursor-pointer scale-img w-full" @click="openSpmUrl(`/detail`,item,item.articleId,true)" /> |
|||
<div class="absolute bg-[#e65a01]/75 w-full py-2 z-100 text-center text-sm text-white bottom-0" v-if="item.comments" >{{ item.comments }}</div> |
|||
</el-carousel-item> |
|||
</el-carousel> |
|||
</div> |
|||
</div> |
|||
|
|||
|
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import {useServerRequest} from "~/composables/useServerRequest"; |
|||
import type {ApiResult, PageResult} from "~/api"; |
|||
import type {FileRecord} from "~/api/system/file/model"; |
|||
import type {CmsArticle} from "~/api/cms/cmsArticle/model"; |
|||
|
|||
const props = withDefaults( |
|||
defineProps<{ |
|||
config?: any; |
|||
groupId?: number; |
|||
title?: string; |
|||
comments?: string; |
|||
scrollTop: number; |
|||
}>(), |
|||
{ |
|||
title: '卡片标题', |
|||
comments: '卡片描述' |
|||
} |
|||
); |
|||
|
|||
const emit = defineEmits<{ |
|||
(e: 'done'): void; |
|||
}>(); |
|||
|
|||
const list = ref<CmsArticle[]>([]) |
|||
|
|||
const reload = async () => { |
|||
const {data: response} = await useServerRequest<ApiResult<PageResult<CmsArticle>>>('/cms/cms-article/page', { |
|||
params: { |
|||
categoryId: 989, |
|||
limit: 8 |
|||
} |
|||
}) |
|||
if(response.value?.data){ |
|||
if(response.value?.data.list){ |
|||
list.value = response.value?.data.list |
|||
} |
|||
} |
|||
// const {data: response} = await useServerRequest<ApiResult<PageResult<FileRecord>>>('/file/page',{ |
|||
// baseURL: 'https://server.gxwebsoft.com/api', |
|||
// query: { |
|||
// groupId: props.groupId |
|||
// } |
|||
// }) |
|||
} |
|||
|
|||
const show = ref(false) |
|||
watch( |
|||
() => [props.groupId, props.scrollTop], |
|||
() => { |
|||
reload(); |
|||
if (props.scrollTop >= 1580) show.value = true |
|||
}, |
|||
|
|||
{immediate: true} |
|||
); |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.scale-img:hover { |
|||
animation: scale; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
|
|||
@keyframes scale { |
|||
from { |
|||
transform: scale(1); |
|||
} |
|||
to { |
|||
transform: scale(1.1); |
|||
} |
|||
} |
|||
|
|||
.right-to-left { |
|||
animation: right-to-left-ani; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
@keyframes right-to-left-ani { |
|||
from { |
|||
transform: translateX(100%); |
|||
} |
|||
to { |
|||
transform: translateX(0); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,121 @@ |
|||
<template> |
|||
<div class="w-full bg-gray-100 pb-20"> |
|||
<div class="text-center flex flex-col items-center py-15 relative "> |
|||
<div class="sub-title"> |
|||
<p class="text-gray-200 text-5xl font-bold dark:text-gray-700 py-0 line-height-5"> |
|||
{{ comments }} |
|||
</p> |
|||
</div> |
|||
<h2 class="text-3xl font-bold tracking-tight text-[#ff0000] dark:text-white sm:text-4xl lg:text-5xl"> |
|||
{{ title }} |
|||
</h2> |
|||
</div> |
|||
<div class="xl:w-screen-xl m-auto text-xl right-to-left hidden-sm-and-down" v-if="show"> |
|||
<el-carousel :interval="4000" type="card" height="450px" arrow="never" indicator-position="none"> |
|||
<el-carousel-item class="relative" v-for="(item,index) in list" :key="index"> |
|||
<el-image :src="item.image" class="cursor-pointer scale-img w-full" /> |
|||
<div class="absolute bg-[#e65a01]/75 w-full py-2 z-100 text-center text-sm text-white bottom-0" v-if="item.comments" @click="openSpmUrl(`/detail`,item,item.articleId,true)">{{ item.comments }}</div> |
|||
</el-carousel-item> |
|||
</el-carousel> |
|||
</div> |
|||
<div class="xl:w-screen-xl m-auto text-xl right-to-left hidden-sm-and-up"> |
|||
<el-carousel :interval="4000" type="card" height="350px" arrow="never" indicator-position="none"> |
|||
<el-carousel-item class="relative" v-for="(item,index) in list" :key="index"> |
|||
<el-image :src="item.image" class="cursor-pointer scale-img w-full" @click="openSpmUrl(`/detail`,item,item.articleId,true)" /> |
|||
<div class="absolute bg-[#e65a01]/75 w-full py-2 z-100 text-center text-sm text-white bottom-0" v-if="item.comments" >{{ item.comments }}</div> |
|||
</el-carousel-item> |
|||
</el-carousel> |
|||
</div> |
|||
</div> |
|||
|
|||
|
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import {useServerRequest} from "~/composables/useServerRequest"; |
|||
import type {ApiResult, PageResult} from "~/api"; |
|||
import type {FileRecord} from "~/api/system/file/model"; |
|||
import type {CmsArticle} from "~/api/cms/cmsArticle/model"; |
|||
|
|||
const props = withDefaults( |
|||
defineProps<{ |
|||
config?: any; |
|||
groupId?: number; |
|||
title?: string; |
|||
comments?: string; |
|||
scrollTop: number; |
|||
}>(), |
|||
{ |
|||
title: '卡片标题', |
|||
comments: '卡片描述' |
|||
} |
|||
); |
|||
|
|||
const emit = defineEmits<{ |
|||
(e: 'done'): void; |
|||
}>(); |
|||
|
|||
const list = ref<CmsArticle[]>([]) |
|||
|
|||
const reload = async () => { |
|||
const {data: response} = await useServerRequest<ApiResult<PageResult<CmsArticle>>>('/cms/cms-article/page', { |
|||
params: { |
|||
categoryId: 990, |
|||
limit: 8 |
|||
} |
|||
}) |
|||
if(response.value?.data){ |
|||
if(response.value?.data.list){ |
|||
list.value = response.value?.data.list |
|||
} |
|||
} |
|||
// const {data: response} = await useServerRequest<ApiResult<PageResult<FileRecord>>>('/file/page',{ |
|||
// baseURL: 'https://server.gxwebsoft.com/api', |
|||
// query: { |
|||
// groupId: props.groupId |
|||
// } |
|||
// }) |
|||
} |
|||
|
|||
const show = ref(false) |
|||
watch( |
|||
() => [props.groupId, props.scrollTop], |
|||
() => { |
|||
reload(); |
|||
if (props.scrollTop >= 2240) show.value = true |
|||
}, |
|||
|
|||
{immediate: true} |
|||
); |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.scale-img:hover { |
|||
animation: scale; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
|
|||
@keyframes scale { |
|||
from { |
|||
transform: scale(1); |
|||
} |
|||
to { |
|||
transform: scale(1.1); |
|||
} |
|||
} |
|||
|
|||
.right-to-left { |
|||
animation: right-to-left-ani; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
@keyframes right-to-left-ani { |
|||
from { |
|||
transform: translateX(100%); |
|||
} |
|||
to { |
|||
transform: translateX(0); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,167 @@ |
|||
<template> |
|||
<div class="xl:w-screen-2xl m-auto text-xl"> |
|||
<el-row :gutter="20"> |
|||
<el-col :span="12"> |
|||
<el-card shadow="hover" class="bg-gray-50 w-full h-[150px]"> |
|||
<template #header> |
|||
<div class="card-header"> |
|||
<span class="font-bold text-[#ff0000]">重大信息公开</span> |
|||
</div> |
|||
</template> |
|||
<template v-for="(item,index) in list" :key="index"> |
|||
<li class="flex justify-between py-2"> |
|||
<a class="line-clamp-1 max-w-2xl" :class="`item-${index}`" |
|||
:href="getSpmUrl(`/detail`,item,item.articleId)" target="_blank">{{ item.title }}</a> |
|||
<span class="text-gray-400 font-200">{{ dayjs(item.createTime).format('YYYY-MM-DD') }}</span> |
|||
</li> |
|||
</template> |
|||
</el-card> |
|||
</el-col> |
|||
<el-col :span="12"> |
|||
<el-card shadow="hover" class="bg-gray-50 w-full h-[150px]"> |
|||
<template #header> |
|||
<div class="card-header"> |
|||
<span class="font-bold text-[#ff0000]">党建专题</span> |
|||
</div> |
|||
</template> |
|||
<div class="flex justify-between"> |
|||
<div class="flex flex-col"> |
|||
<span class="text-[#ff0000]">【2023】关于2023年“三重一大”的启动通知</span> |
|||
<span class="text-sm text-gray-500">2023-03-07</span> |
|||
</div> |
|||
<div class="flex flex-col items-end"> |
|||
<span class="text-[#ff0000]">【2023】关于2023年“三重一大”的启动通知</span> |
|||
</div> |
|||
</div> |
|||
</el-card> |
|||
</el-col> |
|||
</el-row> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import {getSpmUrl, openSpmUrl} from "~/utils/common"; |
|||
import dayjs from "dayjs"; |
|||
import {useServerRequest} from "~/composables/useServerRequest"; |
|||
import type {ApiResult, PageResult} from "~/api"; |
|||
import type {CmsArticle} from "~/api/cms/cmsArticle/model"; |
|||
import type {CompanyParam} from "~/api/system/company/model"; |
|||
import {TENANT_ID} from "~/config"; |
|||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model"; |
|||
|
|||
const props = withDefaults( |
|||
defineProps<{ |
|||
config?: any; |
|||
scrollTop: number; |
|||
parentId?: any; |
|||
disabled?: boolean; |
|||
title?: string; |
|||
comments?: string; |
|||
}>(), |
|||
{ |
|||
title: '卡片标题', |
|||
comments: '卡片描述' |
|||
} |
|||
); |
|||
|
|||
const emit = defineEmits<{ |
|||
(e: 'done'): void; |
|||
}>(); |
|||
|
|||
const category = ref<ApiResult<CmsNavigation[]>>(); |
|||
const list = ref<CmsArticle[]>([]); |
|||
const hotList = ref<CmsArticle[]>([]); |
|||
const categoryId = ref(); |
|||
|
|||
// 搜索表单 |
|||
const where = reactive<CompanyParam>({ |
|||
keywords: '' |
|||
}); |
|||
|
|||
const handleClick = () => { |
|||
reload(); |
|||
} |
|||
|
|||
// 轮播图 |
|||
const {data: hotResponse} = await useServerRequest<ApiResult<PageResult<CmsArticle>>>('/cms/cms-article/page', { |
|||
params: { |
|||
recommend: 1, |
|||
limit: 5 |
|||
} |
|||
}) |
|||
if (hotResponse.value?.data) { |
|||
hotList.value = hotResponse.value?.data.list |
|||
} |
|||
|
|||
// 请求文章栏目 |
|||
const getCategory = async () => { |
|||
const {data: categoryInfo} = await useServerRequest<ApiResult<CmsNavigation[]>>('/cms/cms-navigation', { |
|||
params: { |
|||
parentId: props.parentId |
|||
} |
|||
}) |
|||
if (categoryInfo.value) { |
|||
category.value = categoryInfo.value |
|||
categoryId.value = categoryInfo.value?.data && categoryInfo.value?.data[0].navigationId |
|||
} |
|||
await reload(); |
|||
} |
|||
|
|||
// 请求数据 |
|||
const reload = async () => { |
|||
const {data: response} = await useServerRequest<ApiResult<PageResult<CmsArticle>>>('/cms/cms-article/page', { |
|||
params: { |
|||
categoryId: Number(categoryId.value), |
|||
limit: 8 |
|||
} |
|||
}) |
|||
if (response.value?.data) { |
|||
list.value = response.value?.data.list |
|||
} |
|||
} |
|||
|
|||
const showNews = ref(false) |
|||
|
|||
watch( |
|||
() => [props.parentId, props.scrollTop], |
|||
([parentId, scrollTop]) => { |
|||
getCategory(); |
|||
if (props.scrollTop > 70) showNews.value = true |
|||
}, |
|||
{immediate: true} |
|||
); |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
|
|||
.left-2-right { |
|||
animation: left-2-right-ani; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
|
|||
@keyframes left-2-right-ani { |
|||
from { |
|||
transform: translateX(100%); |
|||
} |
|||
to { |
|||
transform: translateX(0); |
|||
} |
|||
} |
|||
|
|||
.right-to-left { |
|||
animation: right-to-left-ani; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
|
|||
@keyframes right-to-left-ani { |
|||
from { |
|||
transform: translateX(-100%); |
|||
} |
|||
to { |
|||
transform: translateX(0); |
|||
} |
|||
} |
|||
//.hidden-sm-and-down .carousel{display: none;} |
|||
</style> |
@ -0,0 +1,204 @@ |
|||
<template> |
|||
<div class="w-full bg-white pb-20 mb-3 hidden-sm-and-down"> |
|||
<div class="text-center flex flex-col items-center py-15 relative bg-white"> |
|||
<div class="sub-title"> |
|||
<p class="text-gray-200 text-6xl font-bold dark:text-gray-700 py-0 line-height-5"> |
|||
{{ comments }} |
|||
</p> |
|||
</div> |
|||
<h2 class="text-3xl font-bold tracking-tight text-[#409eff] lg:text-5xl"> |
|||
{{ title }} |
|||
</h2> |
|||
</div> |
|||
<div class="xl:w-screen-2xl m-auto text-xl"> |
|||
<el-row :gutter="20" v-if="showNews"> |
|||
<el-col :span="10"> |
|||
<div class="carousel py-2 right-to-left"> |
|||
<el-carousel indicator-position="none" height="400px"> |
|||
<el-carousel-item class="relative" v-for="(item,index) in hotList" :key="index"> |
|||
<el-image :src="item.image" @click="openSpmUrl(`/detail`,item,item.articleId,true)" |
|||
class="cursor-pointer"/> |
|||
<div class="absolute bg-[#e65a01]/75 w-full py-2 z-100 text-center text-sm text-white bottom-0"> |
|||
{{ item.title }} |
|||
</div> |
|||
</el-carousel-item> |
|||
</el-carousel> |
|||
</div> |
|||
</el-col> |
|||
<el-col :span="13"> |
|||
<div class="tabs px-10 w-full left-2-right"> |
|||
<el-tabs class="custom-tabs" v-model="categoryId" @tab-change="handleClick"> |
|||
<el-tab-pane v-for="(cate,index) in category?.data" :key="index" :label="cate.title" |
|||
:name="cate.navigationId" class="text-xl"/> |
|||
</el-tabs> |
|||
<template v-for="(item,index) in list" :key="index"> |
|||
<li class="flex justify-between py-2"> |
|||
<a class="line-clamp-1 max-w-2xl" :class="`item-${index}`" |
|||
:href="getSpmUrl(`/detail`,item,item.articleId)" target="_blank">{{ item.title }}</a> |
|||
<span class="text-gray-400 font-200">{{ dayjs(item.createTime).format('YYYY-MM-DD') }}</span> |
|||
</li> |
|||
</template> |
|||
</div> |
|||
</el-col> |
|||
</el-row> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="w-full bg-white pb-20 mb-3 hidden-sm-and-up"> |
|||
<div class="text-center flex flex-col items-center py-15 relative bg-white"> |
|||
<div class="sub-title"> |
|||
<p class="text-gray-200 text-5xl font-bold dark:text-gray-700 py-0 line-height-5"> |
|||
{{ comments }} |
|||
</p> |
|||
</div> |
|||
<h2 class="text-4xl font-bold tracking-tight text-[#409eff] lg:text-5xl"> |
|||
{{ title }} |
|||
</h2> |
|||
</div> |
|||
<div class="xl:w-screen-2xl m-auto text-lg"> |
|||
<div class="tabs px-3 w-full left-2-right"> |
|||
<el-tabs class="custom-tabs" v-model="categoryId" @tab-change="handleClick"> |
|||
<el-tab-pane v-for="(cate,index) in category?.data" :key="index" :label="cate.title" |
|||
:name="cate.navigationId" class="text-lg"/> |
|||
</el-tabs> |
|||
<template v-for="(item,index) in list" :key="index"> |
|||
<li class="flex justify-between py-2"> |
|||
<a class="" :class="`item-${index}`" |
|||
:href="getSpmUrl(`/detail`,item,item.articleId)" target="_blank">{{ item.title }}<span class="text-gray-400 font-200 px-1">{{ dayjs(item.createTime).format('MM-DD') }}</span></a> |
|||
|
|||
</li> |
|||
</template> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
|
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import {getSpmUrl, openSpmUrl} from "~/utils/common"; |
|||
import dayjs from "dayjs"; |
|||
import {useServerRequest} from "~/composables/useServerRequest"; |
|||
import type {ApiResult, PageResult} from "~/api"; |
|||
import type {CmsArticle} from "~/api/cms/cmsArticle/model"; |
|||
import type {CompanyParam} from "~/api/system/company/model"; |
|||
import {TENANT_ID} from "~/config"; |
|||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model"; |
|||
|
|||
const props = withDefaults( |
|||
defineProps<{ |
|||
config?: any; |
|||
parentId?: number | string; |
|||
list?: any[]; |
|||
disabled?: boolean; |
|||
title?: string; |
|||
comments?: string; |
|||
scrollTop: number; |
|||
}>(), |
|||
{ |
|||
title: '卡片标题', |
|||
comments: '卡片描述' |
|||
} |
|||
); |
|||
|
|||
const emit = defineEmits<{ |
|||
(e: 'done'): void; |
|||
}>(); |
|||
|
|||
const category = ref<ApiResult<CmsNavigation[]>>(); |
|||
const list = ref<CmsArticle[]>([]); |
|||
const hotList = ref<CmsArticle[]>([]); |
|||
const categoryId = ref(); |
|||
|
|||
// 搜索表单 |
|||
const where = reactive<CompanyParam>({ |
|||
keywords: '' |
|||
}); |
|||
|
|||
const handleClick = () => { |
|||
reload(); |
|||
} |
|||
|
|||
// 轮播图 |
|||
const {data: hotResponse} = await useServerRequest<ApiResult<PageResult<CmsArticle>>>('/cms/cms-article/page', { |
|||
params: { |
|||
recommend: 1, |
|||
limit: 5 |
|||
} |
|||
}) |
|||
if (hotResponse.value?.data) { |
|||
hotList.value = hotResponse.value?.data.list |
|||
} |
|||
|
|||
// 请求文章栏目 |
|||
const getCategory = async () => { |
|||
const {data: categoryInfo} = await useServerRequest<ApiResult<CmsNavigation[]>>('/cms/cms-navigation', { |
|||
params: { |
|||
parentId: props.parentId |
|||
} |
|||
}) |
|||
if (categoryInfo.value) { |
|||
category.value = categoryInfo.value |
|||
categoryId.value = categoryInfo.value?.data && categoryInfo.value?.data[0].navigationId |
|||
} |
|||
await reload(); |
|||
} |
|||
|
|||
// 请求数据 |
|||
const reload = async () => { |
|||
const {data: response} = await useServerRequest<ApiResult<PageResult<CmsArticle>>>('/cms/cms-article/page', { |
|||
params: { |
|||
categoryId: Number(categoryId.value), |
|||
limit: 8 |
|||
} |
|||
}) |
|||
if (response.value?.data) { |
|||
list.value = response.value?.data.list |
|||
} |
|||
} |
|||
|
|||
const showNews = ref(false) |
|||
|
|||
watch( |
|||
() => [props.parentId, props.scrollTop], |
|||
([parentId, scrollTop]) => { |
|||
getCategory(); |
|||
if (props.scrollTop > 70) showNews.value = true |
|||
}, |
|||
{immediate: true} |
|||
); |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
|
|||
.left-2-right { |
|||
animation: left-2-right-ani; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
|
|||
@keyframes left-2-right-ani { |
|||
from { |
|||
transform: translateX(100%); |
|||
} |
|||
to { |
|||
transform: translateX(0); |
|||
} |
|||
} |
|||
|
|||
.right-to-left { |
|||
animation: right-to-left-ani; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
|
|||
@keyframes right-to-left-ani { |
|||
from { |
|||
transform: translateX(-100%); |
|||
} |
|||
to { |
|||
transform: translateX(0); |
|||
} |
|||
} |
|||
//.hidden-sm-and-down .carousel{display: none;} |
|||
</style> |
@ -0,0 +1,121 @@ |
|||
<template> |
|||
<div class="w-full bg-white pb-20 mb-3 hidden-sm-and-down"> |
|||
<div class="text-center flex flex-col items-center py-15 relative "> |
|||
<div class="sub-title"> |
|||
<p class="text-gray-200 text-5xl font-bold dark:text-gray-700 py-0 line-height-5"> |
|||
{{ comments }} |
|||
</p> |
|||
</div> |
|||
<h2 class="text-3xl font-bold tracking-tight text-[#FF6E0CFF] lg:text-5xl"> |
|||
{{ title }} |
|||
</h2> |
|||
</div> |
|||
<div class="xl:w-screen-xl m-auto text-xl scale" v-if="config && show"> |
|||
<div class="carousel py-3 text-center" v-if="config?.IndexVideoCenter"> |
|||
<video id="my-video" class="video-js vjs-default-skin" controls preload="auto" width="900" height="510" |
|||
:poster="config?.IndexVideoImg" data-setup="{}"> |
|||
<source :src="config?.IndexVideoCenter" type="video/mp4"> |
|||
<p class="vjs-no-js"> |
|||
To view this video please enable JavaScript, and consider upgrading to a web browser that |
|||
<a :href="config?.IndexVideoCenter" target="_blank">supports HTML5 video</a> |
|||
</p> |
|||
</video> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="w-full bg-white pb-20 mb-3 hidden-sm-and-up"> |
|||
<div class="text-center flex flex-col items-center py-15 relative "> |
|||
<div class="sub-title"> |
|||
<p class="text-gray-200 text-6xl font-bold dark:text-gray-700 py-0 line-height-5"> |
|||
{{ comments }} |
|||
</p> |
|||
</div> |
|||
<h2 class="text-3xl font-bold tracking-tight text-[#FF6E0CFF] lg:text-5xl"> |
|||
{{ title }} |
|||
</h2> |
|||
</div> |
|||
<div class="xl:w-screen-xl m-auto text-xl scale" v-if="config && show"> |
|||
<div class="hidden-sm-and-down carousel py-3 text-center" v-if="config?.IndexVideoCenter"> |
|||
<video id="my-video" class="video-js vjs-default-skin" controls preload="auto" width="900" height="510" |
|||
:poster="config?.IndexVideoImg" data-setup="{}"> |
|||
<source :src="config?.IndexVideoCenter" type="video/mp4"> |
|||
<p class="vjs-no-js"> |
|||
To view this video please enable JavaScript, and consider upgrading to a web browser that |
|||
<a :href="config?.IndexVideoCenter" target="_blank">supports HTML5 video</a> |
|||
</p> |
|||
</video> |
|||
</div> |
|||
<div class="hidden-sm-and-up carousel text-center" v-if="config?.IndexVideoCenter"> |
|||
<video id="my-video" class="video-js vjs-default-skin" controls preload="auto" width="350" height="210" |
|||
:poster="config?.IndexVideoImg" data-setup="{}"> |
|||
<source :src="config?.IndexVideoCenter" type="video/mp4"> |
|||
<p class="vjs-no-js"> |
|||
To view this video please enable JavaScript, and consider upgrading to a web browser that |
|||
<a :href="config?.IndexVideoCenter" target="_blank">supports HTML5 video</a> |
|||
</p> |
|||
</video> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
|
|||
const props = withDefaults( |
|||
defineProps<{ |
|||
config?: any; |
|||
list?: any[]; |
|||
disabled?: boolean; |
|||
title?: string; |
|||
comments?: string; |
|||
scrollTop: number; |
|||
}>(), |
|||
{ |
|||
title: '卡片标题', |
|||
comments: '卡片描述' |
|||
} |
|||
); |
|||
|
|||
const emit = defineEmits<{ |
|||
(e: 'done'): void; |
|||
}>(); |
|||
|
|||
const indexVideo = ref(); |
|||
const indexVideoImg = ref(); |
|||
|
|||
// 请求数据 |
|||
const reload = async () => { |
|||
|
|||
} |
|||
|
|||
const show = ref(false) |
|||
watch( |
|||
() => props.scrollTop, |
|||
() => { |
|||
if (props.scrollTop >= 1500) show.value = true |
|||
}, |
|||
|
|||
{immediate: true} |
|||
); |
|||
|
|||
reload(); |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.scale{ |
|||
animation: scale-ani; |
|||
animation-duration: 0.5s; |
|||
animation-fill-mode: forwards; |
|||
} |
|||
|
|||
@keyframes scale-ani { |
|||
from{ |
|||
transform: scale(1.5); |
|||
opacity: 0; |
|||
} |
|||
to{ |
|||
transform: scale(1); |
|||
opacity: 1; |
|||
} |
|||
} |
|||
</style> |
Loading…
Reference in new issue