Browse Source

调H5端兼容

master
科技小王子 9 months ago
parent
commit
26903c5737
  1. 2
      api/cms/website/model/index.ts
  2. 1
      assets/css/main.css
  3. 20
      components/AppFooter.vue
  4. 31
      components/AppHeader.vue
  5. 5
      components/Banner.vue
  6. 19
      components/Breadcrumb.vue
  7. 39
      components/UnderMaintenance.vue
  8. 25
      layouts/default.vue
  9. 53
      pages/a/[id].vue
  10. 74
      pages/article/[id].vue
  11. 24
      pages/article/detail/[id].vue
  12. 58
      pages/article/detail/name.vue
  13. 150
      pages/index.vue
  14. 67
      pages/search/index.vue
  15. 95
      pages/test.vue
  16. 11
      utils/common.ts

2
api/cms/website/model/index.ts

@ -40,6 +40,8 @@ export interface Website {
appId?: number; appId?: number;
fields?: WebsiteField[]; fields?: WebsiteField[];
status?: number; status?: number;
statusText?: string;
statusClose?: string;
tenantId?: number; tenantId?: number;
tenantName?: string; tenantName?: string;
navigations?: Navigation[]; navigations?: Navigation[];

1
assets/css/main.css

@ -39,7 +39,6 @@ h1, h2, h3, h4, h5, h6 {
.container { .container {
width: auto; width: auto;
margin: 0 auto; margin: 0 auto;
padding: 0 10px;
overflow: hidden; overflow: hidden;
} }
} }

20
components/AppFooter.vue

@ -1,11 +1,11 @@
<template> <template>
<div class="sm:h-[100px] h-[50px]"></div>
<div class="text-center bg-white text-red-7 py-10" style="display: none">
本网站为小象CMS演示站提供的电视剧和电影资源均系收集于各大视频网站<br />
若本站收录的节目无意侵犯了贵司版权,请给我们留言,我们会及时逐步删除和规避程序自动搜索采集到的不提供分享的版权影视<br />
本站仅供测试和学习交流请大家支持正版
</div>
<footer>
<footer class="overflow-hidden">
<div class="sm:h-[100px] h-[50px]"></div>
<div class="text-center bg-white text-red-7 py-10" style="display: none">
本网站为小象CMS演示站提供的电视剧和电影资源均系收集于各大视频网站<br />
若本站收录的节目无意侵犯了贵司版权,请给我们留言,我们会及时逐步删除和规避程序自动搜索采集到的不提供分享的版权影视<br />
本站仅供测试和学习交流请大家支持正版
</div>
<div class="w-full flex flex-col sm:bg-black justify-between"> <div class="w-full flex flex-col sm:bg-black justify-between">
<!-- PC版 --> <!-- PC版 -->
<div class="sub-menu w-full md:w-3/4 m-auto flex justify-between py-10 text-center p-2 hidden-sm-and-down"> <div class="sub-menu w-full md:w-3/4 m-auto flex justify-between py-10 text-center p-2 hidden-sm-and-down">
@ -48,9 +48,9 @@
</el-collapse> </el-collapse>
</div> </div>
<div class="sm:hidden p-4 mt-3">
<el-button type="primary" class="w-full" size="large">联系我们</el-button>
</div>
<!-- <div class="sm:hidden p-4 mt-3">-->
<!-- <el-button type="primary" class="w-full" size="large">联系我们</el-button>-->
<!-- </div>-->
<!-- 版权信息 --> <!-- 版权信息 -->
<div class="w-full md:w-3/4 w-full m-auto flex justify-between sm:py-10 pt-6 pb-6 text-center p-2"> <div class="w-full md:w-3/4 w-full m-auto flex justify-between sm:py-10 pt-6 pb-6 text-center p-2">

31
components/AppHeader.vue

@ -1,14 +1,14 @@
<template> <template>
<header class="header bg-black fixed z-10 w-full">
<header class="header bg-black fixed z-10 top-0 w-full">
<div class="flex between md:w-3/4 m-auto px-2"> <div class="flex between md:w-3/4 m-auto px-2">
<div class="header__left flex"> <div class="header__left flex">
<div class="logo mt-1 w-[170px] max-h-[60px] py-2 flex items-center" @click="reload">
<div class="logo mt-1 sm:w-[170px] py-2 flex items-center">
<nuxt-link v-if="config?.siteLogo" to="/"> <nuxt-link v-if="config?.siteLogo" to="/">
<el-image <el-image
:src="config.siteLogo" :src="config.siteLogo"
shape="square" shape="square"
fit="fill" fit="fill"
class="h-[20px] sm:h-[30px]"
class="h-[23px] w-auto sm:h-[30px]"
:alt="config.siteName" :alt="config.siteName"
:title="config.siteName" :title="config.siteName"
/> />
@ -31,17 +31,13 @@
> >
<template v-for="(item, index) in navigations"> <template v-for="(item, index) in navigations">
<el-menu-item :index="item.path" v-if="index < visibleNumber"> <el-menu-item :index="item.path" v-if="index < visibleNumber">
<template v-if="item.children.length > 0">
<el-sub-menu :index="item.path">
<el-sub-menu v-if="item?.children && item.children.length > 0" :index="`${item.path}`">
<template #title> <template #title>
<text class="text-[17px]">{{ item.title }}</text> <text class="text-[17px]">{{ item.title }}</text>
</template> </template>
<el-menu-item v-for="(sub,subIndex) in item.children" :index="`${sub.path}`" :key="subIndex">{{ sub.title }}</el-menu-item> <el-menu-item v-for="(sub,subIndex) in item.children" :index="`${sub.path}`" :key="subIndex">{{ sub.title }}</el-menu-item>
</el-sub-menu> </el-sub-menu>
</template>
<template v-else>
<text class="text-[17px]">{{ item.title }}</text>
</template>
<text v-else class="text-[17px]">{{ item.title }}</text>
</el-menu-item> </el-menu-item>
</template> </template>
@ -58,13 +54,15 @@
</nav> </nav>
</div> </div>
<div class="header__right items-center"> <div class="header__right items-center">
<el-input
class="w-20 mr-4"
placeholder="站内搜索"
:suffix-icon="ElIconSearch"
v-model="searchValue"
@keyup.enter.native="handleSearch"
/>
<div class="sm:flex hidden">
<el-input
class="w-20 mr-4"
placeholder="站内搜索"
:suffix-icon="ElIconSearch"
v-model="searchValue"
@keyup.enter.native="handleSearch"
/>
</div>
<ClientOnly> <ClientOnly>
<template v-if="token"> <template v-if="token">
<el-dropdown @command="handleCommand"> <el-dropdown @command="handleCommand">
@ -78,6 +76,7 @@
</el-dropdown> </el-dropdown>
</template> </template>
<template v-else> <template v-else>
<el-button circle :icon="ElIconSearch" @click="navigateTo('/search')"></el-button>
<el-button circle :icon="ElIconUserFilled" @click="goLogin"></el-button> <el-button circle :icon="ElIconUserFilled" @click="goLogin"></el-button>
</template> </template>
</ClientOnly> </ClientOnly>

5
components/Banner.vue

@ -1,12 +1,11 @@
<template> <template>
<div class="banner m-auto sm:pt-[60px] pt-[47px] relative">
<div class="banner m-auto sm:pt-[60px] pt-[47px] relative sm:flex">
<template v-if="data"> <template v-if="data">
<el-image :src="data.design?.photo || config.subpageBanner" class="sm:h-auto"></el-image> <el-image :src="data.design?.photo || config.subpageBanner" class="sm:h-auto"></el-image>
<div class="banner-bar absolute top-0 w-full mt-[60px]">
<div class="banner-bar absolute top-0 w-full mt-[60px] sm:flex hidden">
<div class="banner-text py-12 md:w-3/4 m-auto opacity-90 flex flex-col justify-center"> <div class="banner-text py-12 md:w-3/4 m-auto opacity-90 flex flex-col justify-center">
<div class="keywords my-4 text-5xl">{{ data.design?.name }}</div> <div class="keywords my-4 text-5xl">{{ data.design?.name }}</div>
<div class="description my-4 text-2xl max-w-3xl text-gray-600">{{ data.design?.description }}</div> <div class="description my-4 text-2xl max-w-3xl text-gray-600">{{ data.design?.description }}</div>
<!-- <div class="description text-sm max-w-xl text-gray-600">{{ data.design?.keywords }}</div>-->
<div class="buy-btn" v-if="data?.design?.buyUrl"> <div class="buy-btn" v-if="data?.design?.buyUrl">
<el-button @click="navigateTo(data.design.buyUrl)" type="primary">立即购买</el-button> <el-button @click="navigateTo(data.design.buyUrl)" type="primary">立即购买</el-button>
</div> </div>

19
components/Breadcrumb.vue

@ -1,20 +1,27 @@
<template> <template>
<el-breadcrumb v-if="data" class="sm:py-4 sm:px-0 px-3 py-2" :separator-icon="ArrowRight">
<el-breadcrumb-item :to="{ path: '/' }"><el-icon><ElIconHouse /></el-icon></el-breadcrumb-item>
<el-breadcrumb-item v-if="data.parentName" :to="{ path: data.parentStatus == 0 ? data.parentPath : ''}">{{ data.parentName }}</el-breadcrumb-item>
<el-breadcrumb-item v-if="data.categoryName" :to="{ path: data.categoryPath }">{{ data.categoryName }}</el-breadcrumb-item>
<el-breadcrumb-item>{{ data.title }}</el-breadcrumb-item>
</el-breadcrumb>
<div class="sm:py-4 sm:px-0 mx-3 py-2">
<el-breadcrumb :separator-icon="ArrowRight">
<el-breadcrumb-item :to="{ path: '/' }"><el-icon><ElIconHouse /></el-icon></el-breadcrumb-item>
<el-breadcrumb-item v-if="data?.parentName" :to="{ path: data.parentStatus == 0 ? data.parentPath : ''}">{{ data.parentName }}</el-breadcrumb-item>
<el-breadcrumb-item v-if="data?.categoryName" :to="{ path: data.categoryPath }">{{ data.categoryName }}</el-breadcrumb-item>
<el-breadcrumb-item>{{ title || data?.title }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ArrowRight } from '@element-plus/icons-vue' import { ArrowRight } from '@element-plus/icons-vue'
import type {Navigation} from "~/api/cms/navigation/model"; import type {Navigation} from "~/api/cms/navigation/model";
const route = useRoute();
withDefaults( withDefaults(
defineProps<{ defineProps<{
// //
data?: Navigation; data?: Navigation;
title?: string;
}>(), }>(),
{} {}
); );
</script> </script>

39
components/UnderMaintenance.vue

@ -0,0 +1,39 @@
<template>
<el-card class="m-5">
<!-- 维护中 -->
<el-result
v-if="website.status == 1"
:icon="'warning'"
:title="status"
:sub-title="website.statusText"
>
<template #extra>
<el-button @click="navigateTo(`https://${website.tenantId}.wsdns.cn`)">网站首页</el-button>
<el-button @click="navigateTo(`https://${website.tenantId}.websoft.top`)">管理后台</el-button>
</template>
</el-result>
<!-- 已关闭 -->
<el-result
v-if="website.status == 2"
:icon="'error'"
:title="status"
:sub-title="website.statusClose || '网站功能未开通或管理员操作关闭'"
>
<template #extra>
<el-button type="primary" v-if="!website.statusClose" @click="navigateTo(`https://www.websoft.top/product/124`)">{{ website.statusClose }}去开通</el-button>
</template>
</el-result>
</el-card>
<div></div>
</template>
<script setup lang="ts">
import {useWebsite} from "~/composables/configState";
const website = useWebsite()
const status = ['运行中','维护中','已关闭'][Number(website.value.status)];
const navigateTo = (url: string) => {
window.location.href = url;
}
</script>

25
layouts/default.vue

@ -1,7 +1,13 @@
<template> <template>
<app-header />
<slot />
<app-footer />
<!-- 运行中 -->
<template v-if="website.status == 0">
<app-header />
<slot />
<app-footer />
</template>
<template v-else>
<UnderMaintenance />
</template>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {getLoacl, setLocal} from "~/utils/common"; import {getLoacl, setLocal} from "~/utils/common";
@ -13,6 +19,7 @@
import type {Website} from "~/api/cms/website/model"; import type {Website} from "~/api/cms/website/model";
import type {Navigation} from "~/api/cms/navigation/model"; import type {Navigation} from "~/api/cms/navigation/model";
import type {Config} from "~/types/global"; import type {Config} from "~/types/global";
import UnderMaintenance from "~/components/UnderMaintenance.vue";
// TODO 1 ,ID // TODO 1 ,ID
localStorage.removeItem('TID_DOMAIN'); localStorage.removeItem('TID_DOMAIN');
@ -36,21 +43,25 @@
}; };
}); });
// TODO 3
// TODO 3
const website = useWebsite() const website = useWebsite()
const {data: websiteInfo } = await useServerRequest<ApiResult<Website>>('/cms/website/getSiteInfo'); const {data: websiteInfo } = await useServerRequest<ApiResult<Website>>('/cms/website/getSiteInfo');
if(websiteInfo.value?.data){ if(websiteInfo.value?.data){
website.value = websiteInfo.value?.data; website.value = websiteInfo.value?.data;
} }
// TODO 4
// TODO 4
const {data: websiteRealTime } = await useServerRequest<ApiResult<Website>>('/cms/website/' + website.value.websiteId);
website.value = Object.assign({},website.value,websiteRealTime.value?.data)
// TODO 5
const config = useConfigInfo(); const config = useConfigInfo();
const { data: fields } = await useServerRequest<ApiResult<Config>>('/cms/website-field/config', {}); const { data: fields } = await useServerRequest<ApiResult<Config>>('/cms/website-field/config', {});
if (fields.value?.data) { if (fields.value?.data) {
config.value = fields.value?.data; config.value = fields.value?.data;
} }
// TODO 5
// TODO 6
const menu = useMenu() const menu = useMenu()
const { data: menuInfo } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', { const { data: menuInfo } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', {
query: { query: {
@ -61,7 +72,7 @@
menu.value = menuInfo.value?.data menu.value = menuInfo.value?.data
} }
// TODO 6
// TODO 7
const subMenu = useSubMenu() const subMenu = useSubMenu()
const { data: subMenuInfo } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', { const { data: subMenuInfo } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', {
query: { query: {

53
pages/a/[id].vue

@ -0,0 +1,53 @@
<template>
<!-- Banner -->
<Banner :data="form" />
<div v-if="form" class="flex flex-col w-full md:w-3/4 m-auto my-3">
<Breadcrumb :data="form" title="文章详情" />
<div class="m-3 bg-white p-3 mt-4 flex flex-col gap-xl rounded-lg">
<div class="article-title-box p-4">
<div class="sm:text-3xl text-xl sm:text-left text-center">{{ form.title }}</div>
<div class="text-sm pt-2 text-gray-4 flex gap-xl sm:text-left sm:justify-start justify-center">
<span>{{ form.createTime }}</span>
<span>浏览{{ form.actualViews }}</span>
</div>
</div>
<el-divider style="height: 1px " />
<div class="content leading-8 sm:text-xl px-3 text-gray-700" v-html="form.content"></div>
</div>
</div>
<div v-if="!form">
<el-empty description="404 页面不存在"></el-empty>
</div>
</template>
<script setup lang="ts">
import type {ApiResult} from "~/api";
import {useServerRequest} from "~/composables/useServerRequest";
import type {Goods} from "~/api/shop/goods/model";
import type {Article} from "~/api/cms/article/model";
import Breadcrumb from "~/components/Breadcrumb.vue";
import {getIdByParam} from "~/utils/common";
const route = useRoute();
const { params } = route;
const { id } = params;
//
const form = ref<Article | any>();
//
const { data: info } = await useServerRequest<ApiResult<Article>>('/cms/article/' + getIdByParam(id))
form.value = info.value?.data;
form.value.num = 1;
form.value.radio = '0'
</script>
<style scoped lang="scss">
.content *{
max-width: 100%;
overflow: hidden;
}
</style>

74
pages/article/[id].vue

@ -2,27 +2,31 @@
<!-- Banner --> <!-- Banner -->
<Banner :data="form" /> <Banner :data="form" />
<div class="flex flex-col w-full md:w-3/4 m-auto my-3">
<div class="container flex flex-col w-full md:w-3/4 m-auto my-3">
<Breadcrumb :data="form" />
<Breadcrumb :data="form" :title="form?.categoryName" />
<el-row :gutter="20" class="mt-3">
<el-col :span="18">
<div class="news-list p-4 bg-white">
<ul class="infinite-list" v-infinite-scroll="load" :infinite-scroll-disabled="disabled" style="overflow:auto">
<!-- 左右结构 -->
<div class="news-box sm:mt-0 mt-2 flex sm:flex-row flex-col justify-between sm:space-x-4">
<div class="left sm:w-18/24">
<!-- 文章列表 -->
<div class="news-list">
<ul class="infinite-list px-3" v-infinite-scroll="load" :infinite-scroll-disabled="disabled">
<li v-for="item in list"> <li v-for="item in list">
<div class="item flex gap-xl mb-5 h-[120px] w-full hover:bg-gray-50">
<div class="item-image">
<el-image :src="item.image" class="w-[180px] h-[120px] bg-gray-50 cursor-pointer" fit="contain" />
</div>
<div class="item flex py-3 px-4 gap-xl mb-5 rounded-lg mb-3 bg-white hover:shadow">
<div class="item-info py-2 flex flex-col justify-between"> <div class="item-info py-2 flex flex-col justify-between">
<a :href="`/article/detail/${item.articleId}`" target="_blank" class="text-xl">{{ item.title }}</a>
<div class="desc text-gray-5" v-html="item.comments"></div>
<div class="title line-clamp-2 overflow-hidden text-ellipsis group-hover:group-hover:text-ellipsis">
<a :href="`/article/detail/${item.articleId}`" target="_blank" class="text-xl">{{ item.title }}</a>
</div>
<div class="desc max-w-22/24 text-gray-5 sm:block hidden" v-html="item.comments"></div>
<div class="actions text-gray-4 text-sm flex gap-2xl"> <div class="actions text-gray-4 text-sm flex gap-2xl">
<span href="#">{{ item.updateTime }}</span> <span href="#">{{ item.updateTime }}</span>
<span href="#">浏览{{ item.actualViews }}</span> <span href="#">浏览{{ item.actualViews }}</span>
</div> </div>
</div> </div>
<div class="item-image flex items-center" @click="navigateTo(`/article/detail/${item.articleId}`)">
<el-image :src="item.image" lazy class="sm:w-[140px] sm:h-[140px] w-[110px] h-[110px] bg-gray-50 cursor-pointer transition rounded-lg sm:rounded-lg ease-in-out delay-150 hover:-translate-y-1 hover:scale-110 duration-300" fit="contain" />
</div>
</div> </div>
</li> </li>
</ul> </ul>
@ -31,26 +35,40 @@
<text @click="load" v-else>加载更多</text> <text @click="load" v-else>加载更多</text>
</div> </div>
</div> </div>
</el-col>
<el-col :span="6">
<div class="hot-new bg-white p-1">
<div class="title bg-gray-50 p-2 flex items-center gap-xs"><el-icon><ElIconLink/></el-icon></div>
<div class="news-list p-3">
<a class="item py-1 block cursor-pointer" v-for="(item,index) in list">
{{item.title}}
</a>
</div>
<div class="right sm:mt-0 mt-4 sm:w-6/24">
<!-- 推荐文章 -->
<div class="category-item bg-white rounded-lg p-3 hover:shadow">
<div class="category-name text-lg text-gray-600 border-b border-gray-200 border-b-solid pb-2 mx-2">
<el-icon>
<ElIconLink/>
</el-icon>
<text class="ml-2">推荐文章</text>
</div>
<div class="flex flex-wrap px-2 py-4">
<div v-for="(item,index) in links" class="flex items-center">
<a :href="item.url" target="_blank">{{ item.name }}</a>
<el-divider v-if="index + 1 != links.length" direction="vertical" />
</div>
</div> </div>
</div> </div>
<div class="view-rank bg-white p-1 mt-5">
<div class="title bg-gray-50 p-2 flex items-center gap-xs"><el-icon><ElIconLink/></el-icon></div>
<div class="news-list p-3">
<a class="item py-1 block cursor-pointer" v-for="(item,index) in list">
{{item.title}}
</a>
<div class="category-item mt-4 bg-white rounded-lg p-3 hover:shadow">
<div class="category-name text-lg text-gray-600 border-b border-gray-200 border-b-solid pb-2 mx-2">
<el-icon>
<ElIconLink/>
</el-icon>
<text class="ml-2">点击排行</text>
</div>
<div class="flex flex-wrap px-2 py-4">
<div v-for="(item,index) in links" class="flex items-center">
<a :href="item.url" target="_blank">{{ item.name }}</a>
<el-divider v-if="index + 1 != links.length" direction="vertical" />
</div>
</div> </div>
</div> </div>
</el-col>
</el-row>
</div>
</div>
</div> </div>
<el-divider /> <el-divider />
<div v-if="!list"> <div v-if="!list">

24
pages/article/detail/[id].vue

@ -4,18 +4,17 @@
<div v-if="form" class="flex flex-col w-full md:w-3/4 m-auto my-3"> <div v-if="form" class="flex flex-col w-full md:w-3/4 m-auto my-3">
<Breadcrumb :data="form" />
<Breadcrumb :data="form" title="文章详情" />
<div class="bg-white p-4 mt-4 flex flex-col gap-xl">
<div class="m-3 bg-white p-3 mt-4 flex flex-col gap-xl rounded-lg">
<div class="article-title-box p-4"> <div class="article-title-box p-4">
<div class="text-3xl">{{ form.title }}</div>
<div class="text-sm pt-3 text-gray-4 flex gap-xl">
<div class="sm:text-3xl text-xl sm:text-left text-center">{{ form.title }}</div>
<div class="text-sm pt-2 text-gray-4 flex gap-xl sm:text-left sm:justify-start justify-center">
<span>{{ form.createTime }}</span> <span>{{ form.createTime }}</span>
<span>浏览{{ form.actualViews }}</span> <span>浏览{{ form.actualViews }}</span>
</div> </div>
<el-divider style="height: 1px " />
</div> </div>
<div class="content leading-8 text-xl p-3 text-gray-8" v-html="form.content"></div>
<div class="content leading-8 sm:text-xl px-3 pb-5 text-gray-700" v-html="form.content"></div>
</div> </div>
</div> </div>
<div v-if="!form"> <div v-if="!form">
@ -28,31 +27,26 @@ import {useServerRequest} from "~/composables/useServerRequest";
import type {Goods} from "~/api/shop/goods/model"; import type {Goods} from "~/api/shop/goods/model";
import type {Article} from "~/api/cms/article/model"; import type {Article} from "~/api/cms/article/model";
import Breadcrumb from "~/components/Breadcrumb.vue"; import Breadcrumb from "~/components/Breadcrumb.vue";
import {getIdByParam} from "~/utils/common";
const route = useRoute(); const route = useRoute();
const { query, params } = route;
const { params } = route;
const { id } = params; const { id } = params;
const activeName = ref('parameter');
const rate = ref(4);
// //
const form = ref<Article | any>(); const form = ref<Article | any>();
// //
const { data: info } = await useServerRequest<ApiResult<Article>>('/cms/article/' + id)
const { data: info } = await useServerRequest<ApiResult<Article>>('/cms/article/' + getIdByParam(id))
form.value = info.value?.data; form.value = info.value?.data;
// form.value.files = JSON.parse(form.value.files);
form.value.num = 1; form.value.num = 1;
form.value.radio = '0' form.value.radio = '0'
const handleClick = (tab, event) => {
console.log(tab, event);
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.content *{ .content *{
max-width: 100%; max-width: 100%;
overflow: hidden;
} }
</style> </style>

58
pages/article/detail/name.vue

@ -0,0 +1,58 @@
<template>
<!-- Banner -->
<Banner :data="form" />
<div v-if="form" class="flex flex-col w-full md:w-3/4 m-auto my-3">
<Breadcrumb :data="form" />
<div class="p-4 mt-4 flex flex-col gap-xl">
<div class="article-title-box p-4">
<div class="text-3xl">{{ form.title }}</div>
<div class="text-sm pt-3 text-gray-4 flex gap-xl">
<span>{{ form.createTime }}</span>
<span>浏览{{ form.actualViews }}</span>
</div>
<el-divider style="height: 1px " />
</div>
<div class="content leading-8 text-xl p-3 text-gray-8" v-html="form.content"></div>
</div>
</div>
<div v-if="!form">
<el-empty description="404 页面不存在"></el-empty>
</div>
</template>
<script setup lang="ts">
import type {ApiResult} from "~/api";
import {useServerRequest} from "~/composables/useServerRequest";
import type {Goods} from "~/api/shop/goods/model";
import type {Article} from "~/api/cms/article/model";
import Breadcrumb from "~/components/Breadcrumb.vue";
const route = useRoute();
const { query, params } = route;
const { id } = params;
const activeName = ref('parameter');
const rate = ref(4);
//
const form = ref<Article | any>();
//
const { data: info } = await useServerRequest<ApiResult<Article>>('/cms/article/' + id)
form.value = info.value?.data;
// form.value.files = JSON.parse(form.value.files);
form.value.num = 1;
form.value.radio = '0'
const handleClick = (tab, event) => {
console.log(tab, event);
}
</script>
<style scoped lang="scss">
.content *{
max-width: 100%;
}
</style>

150
pages/index.vue

@ -1,9 +1,7 @@
<template> <template>
<!-- 首页幻灯片 -->
<div class="banner sm:pt-[60px] pt-[46px]" v-if="banner"> <div class="banner sm:pt-[60px] pt-[46px]" v-if="banner">
<el-carousel :interval="5000" arrow="always" :height="screenWidth <= 768 ? `170px` : `${screenHeight - 200}px`">
<!-- <el-carousel-item class="hidden-sm-and-down">-->
<!-- <video :autoplay="true" loop="" muted="" id="video" class="video"><source src="https://www.algig.cn/upload/media/2022/07/07/5ebe65d7280e4e0c947f4207646d75c4.mp4" type="video/mp4"></video>-->
<!-- </el-carousel-item>-->
<el-carousel :interval="5000" arrow="always" :height="screenWidth <= 768 ? `170px` : `750px`">
<el-carousel-item v-for="item in banner.data" :key="item.uid"> <el-carousel-item v-for="item in banner.data" :key="item.uid">
<nuxt-link v-if="item.path" :to="item.path"> <nuxt-link v-if="item.path" :to="item.path">
<el-image :src="item.url" style="width: 100%" fit="cover"/> <el-image :src="item.url" style="width: 100%" fit="cover"/>
@ -14,125 +12,37 @@
</el-carousel-item> </el-carousel-item>
</el-carousel> </el-carousel>
</div> </div>
<div class="container w-full md:w-3/4 index">
<el-row :gutter="20" class="mt-20" v-for="categoryItem in movieList">
<el-col :sm="18">
<div class="panel_hd between items-center">
<div class="panel_hd__left">
<h3 class="title items-center">
<nuxt-link to="/">最新电影</nuxt-link>
</h3>
</div>
<div class="panel_hd__right items-center">
<ul class="items-center">
<li class="hidden-sm-and-down">
<nuxt-link :to="`/c`">动作片</nuxt-link>
</li>
<li class="hidden-sm-and-down">
<nuxt-link :to="`/c`">科幻片</nuxt-link>
</li>
<li>
<nuxt-link :to="`/c-`" class="items-center">
更多
<el-icon>
<ElIconArrowRight/>
</el-icon>
</nuxt-link>
</li>
</ul>
</div>
</div>
<div class="video-list">
<el-row :gutter="20">
<el-col :sm="4" :xs="8" v-for="item in categoryItem.rows">
<div class="video-list__block">
<nuxt-link :to="`/c-`" class="img-box">
<el-image lazy class="video-list__block__img" :src="'/default.jpg'" fit="cover"/>
<span>暂无评分</span>
</nuxt-link>
<div class="video-list__detail">
<h4 class="title text-overflow">封神</h4>
<p class="text-overflow">
<template>张三</template>
</p>
</div>
</div>
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="6" class="hidden-sm-and-down">
<div class="panel_hd items-center">
<h3 class="title items-center">
电影榜单
</h3>
</div>
<ul class="col-pd">
<li v-for="(item, index) in categoryItem.ranks">
<nuxt-link :to="`/c-`" class="between">
<div>
<span class="badge">{{ index + 1 }}</span>
封神
</div>
<span class="text-muted">更新至1集</span>
</nuxt-link>
</li>
</ul>
</el-col>
</el-row>
<div class="flex flex-col gap-2xl">
<el-card shadow="hover">
<template #header>
<div class="flex items-center gap-xs">
<el-icon>
<ElIconLink/>
</el-icon>
<span>热门推荐</span>
</div>
</template>
<div class="flex flex-wrap p-2">
<div v-for="(item,index) in links" class="flex items-center">
<a :href="item.url" target="_blank">{{ item.name }}</a>
<el-divider v-if="index + 1 != links.length" direction="vertical" />
</div>
</div>
</el-card>
<el-card shadow="hover">
<template #header>
<div class="flex items-center gap-xs">
<el-icon>
<ElIconLink/>
</el-icon>
<span>推荐文章</span>
</div>
</template>
<div class="flex flex-wrap p-2">
<div v-for="(item,index) in links" class="flex items-center">
<a :href="item.url" target="_blank">{{ item.name }}</a>
<el-divider v-if="index + 1 != links.length" direction="vertical" />
</div>
<!-- 首页新闻栏目 -->
<div class="category md:w-3/4 m-auto my-3 p-3 flex flex-col gap-xl">
<div class="category-item bg-white rounded-lg p-3 hover:shadow">
<div class="category-name text-lg text-gray-600 border-b border-gray-200 border-b-solid pb-2 mx-2">
<el-icon>
<ElIconLink/>
</el-icon>
<text class="ml-2">栏目名称</text>
</div>
<div class="flex flex-wrap px-2 py-4">
<div v-for="(item,index) in links" class="flex items-center">
<a :href="item.url" target="_blank">{{ item.name }}</a>
<el-divider v-if="index + 1 != links.length" direction="vertical" />
</div> </div>
</el-card>
<el-card shadow="hover">
<template #header>
<div class="flex items-center gap-xs">
<el-icon>
<ElIconLink/>
</el-icon>
<span>友情链接</span>
</div>
</template>
<div class="flex flex-wrap p-2">
<div v-for="(item,index) in links" class="flex items-center">
<a :href="item.url" target="_blank">{{ item.name }}</a>
<el-divider v-if="index + 1 != links.length" direction="vertical" />
</div>
</div>
</div>
<div class="category-item bg-white rounded-lg p-3 hover:shadow">
<div class="category-name text-lg text-gray-600 border-b border-gray-200 border-b-solid pb-2 mx-2 flex items-center">
<el-icon>
<ElIconLink/>
</el-icon>
<text class="ml-2">友情链接</text>
</div>
<div class="flex flex-wrap px-2 py-4">
<div v-for="(item,index) in links" class="flex items-center">
<a :href="item.url" target="_blank">{{ item.name }}</a>
<el-divider v-if="index + 1 != links.length" direction="vertical" />
</div> </div>
</el-card>
</div>
</div> </div>
</div> </div>
</template> </template>

67
pages/search/index.vue

@ -0,0 +1,67 @@
<template>
<!-- Banner -->
<Banner :data="form" />
<!-- 容器 -->
<div class="container md:w-3/4 m-auto">
<div class="flex flex-col">
<Breadcrumb :title="`站内搜索`" />
</div>
</div>
<div v-if="!form">
<el-empty description="404 页面不存在"></el-empty>
</div>
</template>
<script setup lang="ts">
import type {Design} from "~/api/cms/design/model";
import type {ApiResult} from "~/api";
import {useServerRequest} from "~/composables/useServerRequest";
import {useConfigInfo, useToken} from "~/composables/configState";
import Breadcrumb from "~/components/Breadcrumb.vue";
import type {BreadcrumbItem} from "~/types/global";
import type {Navigation} from "~/api/cms/navigation/model";
const route = useRoute();
const { params } = route;
const { custom: path } = params;
//
const config = useConfigInfo();
const token = useToken();
//
const form = ref<Navigation | any>();
const breadcrumb = ref<BreadcrumbItem>();
//
const { data: nav } = await useServerRequest<ApiResult<Navigation>>('/cms/navigation/getNavigationByPath',{
query: {
path: '/' + path
}
})
if (nav.value) {
// seo
form.value = nav.value.data
if(form.value){
useHead({
title: `${form.value.title} - 网宿软件`,
meta: [{ name: form.value.design.keywords, content: form.value.design.description }],
bodyAttrs: {
class: "page-container",
},
script: [
{
children: "console.log('Hello World')",
},
],
});
//
breadcrumb.value = form.value.breadcrumb
}
}
</script>
<style scoped lang="scss">
</style>

95
pages/test.vue

@ -1,44 +1,61 @@
<script setup lang="ts">
import {useServerRequest} from "~/composables/useServerRequest";
import type {ApiResult, PageResult} from "~/api";
import type {Domain} from "~/api/cms/domain/model";
const {data: domainInfo } = await useServerRequest<ApiResult<PageResult<Domain>>>('/cms/domain/getByDomain/nbg.wsdns.cn');
console.log(domainInfo.value)
</script>
<template> <template>
<div class="p-20 pt-[200px]">
<el-card shadow="hover">
<template #header>
<div class="flex items-center gap-xs">
<el-icon>
<ElIconLink/>
</el-icon>
<span>推荐文章</span>
</div>
</template>
<div class="flex flex-wrap p-2">
<div v-for="(item,index) in links" class="flex items-center">
<a :href="item.url" target="_blank">{{ item.name }}</a>
<el-divider v-if="index + 1 != links.length" direction="vertical" />
</div>
</div>
</el-card>
<el-card shadow="hover">
<template #header>
<div class="flex items-center gap-xs">
<el-icon>
<ElIconLink/>
</el-icon>
<span>友情链接</span>
</div>
</template>
<div class="flex flex-wrap p-2">
<div v-for="(item,index) in links" class="flex items-center">
<a :href="item.url" target="_blank">{{ item.name }}</a>
<el-divider v-if="index + 1 != links.length" direction="vertical" />
</div>
</div>
</el-card>
<el-icon>
<ElIconLink/>
</el-icon>
<el-icon><ElIconArrowDown /></el-icon>
<!-- <el-dropdown>-->
<!-- <span class="el-dropdown-link">-->
<!-- Dropdown List-->
<!-- <el-icon class="el-icon&#45;&#45;right">-->
<!-- <arrow-down />-->
<!-- </el-icon>-->
<!-- </span>-->
<!-- <template #dropdown>-->
<!-- <el-dropdown-menu>-->
<!-- <el-dropdown-item>Action 1</el-dropdown-item>-->
<!-- <el-dropdown-item>Action 2</el-dropdown-item>-->
<!-- <el-dropdown-item>Action 3</el-dropdown-item>-->
<!-- <el-dropdown-item disabled>Action 4</el-dropdown-item>-->
<!-- <el-dropdown-item divided>Action 5</el-dropdown-item>-->
<!-- </el-dropdown-menu>-->
<!-- </template>-->
<!-- </el-dropdown>-->
<!-- <el-tag type="primary">Tag 1</el-tag>-->
</div>
</template> </template>
<style scoped lang="scss">
<script setup lang="ts">
import type {ApiResult} from "~/api";
import type {AdItem} from "~/api/cms/ad/model";
import type {Link} from "~/api/cms/link/model";
import {useServerRequest} from "~/composables/useServerRequest";
</style>
const banner = ref<any>();
const links = ref<any>();
const movieList = ref<any>();
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
//
const reload = async () => {
await nextTick()
const getSlide = useServerRequest<ApiResult<AdItem[]>>('/cms/ad/side');
const getLink = useServerRequest<ApiResult<Link[]>>('/oa/link?linkType=友情链接');
const [{data: slide}, {data: link}] = await Promise.all([getSlide, getLink]);
console.log(slide.value)
banner.value = slide.value?.data;
links.value = link.value?.data;
}
reload();
</script>

11
utils/common.ts

@ -58,3 +58,14 @@ export const getLoacl = () => {
export const isInteger = (num: any) => { export const isInteger = (num: any) => {
return /^-?\d+$/.test(num); return /^-?\d+$/.test(num);
} }
/**
* ID
* param 12334.html
* return 1234
* @param num
*/
export const getIdByParam = (text: any) => {
const split = String(text).split('.')
return split[0];
}

Loading…
Cancel
Save