Browse Source

修复异常状态的展示效果

master
科技小王子 9 months ago
parent
commit
a585703ea2
  1. 4
      api/cms/navigation/model/index.ts
  2. 14
      api/cms/website/model/index.ts
  3. 1
      assets/svg/github-mark-white.svg
  4. 1
      assets/svg/github-mark.svg
  5. 15
      assets/svg/websoft-mark-white.svg
  6. 19
      components/AppFooter.vue
  7. 32
      components/AppHeader.vue
  8. 5
      components/Breadcrumb.vue
  9. 26
      components/UnderMaintenance.vue
  10. 71
      layouts/default.vue
  11. 2
      pages/[custom]/index.vue
  12. 34
      pages/a.vue
  13. 38
      pages/article/[id].vue
  14. 2
      pages/product/[name].vue
  15. 2
      pages/search/index.vue

4
api/cms/navigation/model/index.ts

@ -33,9 +33,13 @@ export interface Navigation {
isMpWeixin?: boolean;
target?: string;
design?: Design;
// 用于面包肖屑
parentName?: string;
parentPath?: string;
parentStatus?: number;
categoryName?: string;
categoryPath?: string;
currentTitle?: string;
}
/**

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

@ -13,12 +13,13 @@ export interface Website {
websiteIcon?: string;
websiteLogo?: string;
websiteDarkLogo?: string;
websiteType?: string;
styles?: string;
keywords?: string;
address?: string;
phone?: string;
email?: string;
version?: number;
websiteType?: string;
expirationTime?: string;
templateId?: string;
industryParent?: string;
@ -39,9 +40,20 @@ export interface Website {
region?: string;
appId?: number;
fields?: WebsiteField[];
// 状态码
status?: number;
// 状态名称
statusName?: string;
// 状态图标
statusIcon?: string;
// 状态说明
statusText?: string;
// 关闭原因
statusClose?: string;
// 跳转按钮文本
statusBtnText?: string;
// 跳转地址
statusUrl?: string;
tenantId?: number;
tenantName?: string;
navigations?: Navigation[];

1
assets/svg/github-mark-white.svg

@ -0,0 +1 @@
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 960 B

1
assets/svg/github-mark.svg

@ -0,0 +1 @@
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>

After

Width:  |  Height:  |  Size: 963 B

15
assets/svg/websoft-mark-white.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

19
components/AppFooter.vue

@ -13,7 +13,7 @@
<!-- 底部菜单 -->
<div class="left flex flex-col sm:flex-row sm:flex-wrap justify-between gap-3xl sm:w-8/12 flex-wrap w-full">
<template v-for="item in subMenu">
<div class="sub-menu-item text-left pr-10">
<div class="sub-menu-item text-left">
<div class="pb-4">
<text class="text-gray-400 hover:text-gray-300 font-bold text-[16px]">{{ item.title }}</text>
</div>
@ -29,8 +29,11 @@
</div>
<!-- 关注我们 -->
<div class="right w-3/12">
<div class="right w-3/12 pr-3 text-right flex justify-end">
<div class="qrcode flex flex-col items-center">
<el-image src="https://oss.wsdns.cn/20240327/f1175cc5aae741d3af05484747270bd5.jpeg" class="w-[100px]" />
<text class="text-gray-400 py-2">扫一扫关注</text>
</div>
</div>
</div>
@ -53,11 +56,17 @@
<!-- </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="text-gray-400 gap-xl flex flex-col sm:flex-row m-auto">
<div class="w-full md:w-3/4 w-full m-auto flex sm:flex-row flex-col-reverse sm:justify-between justify-center items-center sm:py-10 pt-6 pb-6 text-center p-2">
<div class="text-gray-400 sm:gap-xl leading-7 flex flex-col sm:flex-row">
<span>Copyright © {{ new Date().getFullYear() }} {{ config?.copyright }}</span>
<a class="text-gray-400 hover:text-gray-400" href="https://beian.miit.gov.cn/" target="_blank"> 备案号{{ config?.icpNo }}</a>
</div>
<div class="tools flex gap-xl items-center">
<!-- <a href="https://github.com" class="sm:flex hidden items-center" target="_blank"><img src="@/assets/svg/github-mark-white.svg" alt="github" width="20" class="text-gray-400" /></a>-->
<!-- <a href="https://github.com" class="sm:hidden flex items-center" target="_blank"><img src="@/assets/svg/github-mark.svg" alt="github" width="20" class="text-gray-400" /></a>-->
<a :href="`https://${website.tenantId}.websoft.top`" target="_blank"><img src="@/assets/svg/websoft-mark-white.svg" alt="github" width="28" class="text-gray-400" /></a>
</div>
</div>
</div>
</footer>
@ -67,8 +76,10 @@
<script setup lang="ts">
//
import {useConfigInfo} from "#imports";
import { UserOutlined } from '@ant-design/icons-vue';
import {useSubMenu, useWebsite} from "~/composables/configState";
import Breadcrumb from "~/components/Breadcrumb.vue";
import UnderMaintenance from "~/components/UnderMaintenance.vue";
const config = useConfigInfo();
const website = useWebsite();

32
components/AppHeader.vue

@ -1,5 +1,5 @@
<template>
<header class="header bg-black fixed z-10 top-0 w-full">
<header class="header bg-black fixed z-100 top-0 w-full">
<div class="flex between md:w-3/4 m-auto px-2">
<div class="header__left flex">
<div class="logo mt-1 sm:w-[170px] py-2 flex items-center">
@ -83,21 +83,15 @@
</div>
</div>
</header>
<div class="header__height__placeholder"></div>
</template>
<script setup lang="ts">
//
import type { Config } from '~/types/global';
import type {ApiResult, PageResult} from '~/api';
import type { Navigation } from '~/api/cms/navigation/model';
import { useServerRequest } from '~/composables/useServerRequest';
import {useConfigInfo, useMenu} from "~/composables/configState";
import {listDomain} from "~/api/cms/domain";
import type {Domain} from "~/api/cms/domain/model";
//
import {useConfigInfo, useMenu, useWebsite} from "~/composables/configState";
import UnderMaintenance from "~/components/UnderMaintenance.vue";
const route = useRoute();
const website = useWebsite()
const searchValue = ref<string>();
const token = ref<string | undefined>(undefined);
const navigations = useMenu();
@ -106,7 +100,6 @@ import type {Domain} from "~/api/cms/domain/model";
const visibleNumber = ref<number>(10);
// index
const currentIndex = ref<string>('2');
const showSubMenu = ref<boolean>(false);
function handleCommand(command: string) {
switch (command) {
@ -133,21 +126,6 @@ import type {Domain} from "~/api/cms/domain/model";
navigateTo(`${key}`);
}
//
// const reload = async () => {
// await nextTick();
// const { data: fields } = await useServerRequest<ApiResult<Config>>('/cms/website-field/config', {});
// if (fields.value?.data) {
// config.value = fields.value.data;
// }
// const { data: navigation } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', {
// query: {
// position: 1
// }
// });
// };
// reload();
</script>
<style lang="scss">

5
components/Breadcrumb.vue

@ -2,9 +2,9 @@
<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?.parentName" :to="{ path: 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-item v-if="title">{{ title }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
@ -17,7 +17,6 @@ const route = useRoute();
withDefaults(
defineProps<{
//
data?: Navigation;
title?: string;
}>(),

26
components/UnderMaintenance.vue

@ -1,28 +1,16 @@
<template>
<el-card class="m-5">
<!-- 维护中 -->
<el-card class="m-5 w-screen-sm mt-[60px] m-auto">
<!-- 异常状态 -->
<el-result
v-if="website.status == 1"
:icon="'warning'"
:title="status"
:icon="website.statusIcon || 'info'"
:title="`${website.statusName}`"
: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>
<el-button type="primary" v-if="website.statusUrl" @click="navigateTo(`${website.statusUrl}`)">{{ website.statusBtnText }}</el-button>
</template>
</el-result>
</el-card>
<div></div>
</template>
@ -31,8 +19,6 @@ import {useWebsite} from "~/composables/configState";
const website = useWebsite()
const status = ['运行中','维护中','已关闭'][Number(website.value.status)];
const navigateTo = (url: string) => {
window.location.href = url;
}

71
layouts/default.vue

@ -1,17 +1,17 @@
<template>
<!-- 运行中 -->
<template v-if="website.status == 0">
<!-- 加载应用 -->
<template v-if="!loading">
<app-header />
<slot />
<app-footer />
</template>
<template v-else>
<UnderMaintenance />
</template>
<!-- 异常状态 -->
<UnderMaintenance v-if="loading" />
</template>
<script setup lang="ts">
import {getLoacl, setLocal} from "~/utils/common";
import {listWebsite} from "~/api/cms/website";
import {useServerRequest} from "~/composables/useServerRequest";
import type {ApiResult} from "~/api";
import type {Domain} from "~/api/cms/domain/model";
@ -19,33 +19,50 @@
import type {Website} from "~/api/cms/website/model";
import type {Navigation} from "~/api/cms/navigation/model";
import type {Config} from "~/types/global";
import {getLoacl, setLocal} from "~/utils/common";
import UnderMaintenance from "~/components/UnderMaintenance.vue";
//
const loading = ref<boolean>(false)
const website = useWebsite()
const config = useConfigInfo();
const menu = useMenu()
const subMenu = useSubMenu()
//
onMounted(() => {
//onMountedlocalwindow
// getLoacl();
window.onbeforeunload = () => {
//setLocal
// setLocal(); //
};
});
//
const reload = async () => {
// const loading = ElLoading.service({
// lock: true,
// text: 'Loading'
// })
// TODO 1 ,ID
localStorage.removeItem('TID_DOMAIN');
if (!localStorage.getItem('TID_DOMAIN')) {
const domain = window.location.hostname;
const {data: domainInfo } = await useServerRequest<ApiResult<Domain>>('/cms/domain/getByDomain/' + domain);
const data = domainInfo.value?.data;
console.log(data,'当前域名是否有绑定')
if (data) {
localStorage.setItem('TID_DOMAIN',`${data?.tenantId}`)
}
}
// TODO 2
onMounted(() => {
//onMountedlocalwindow
// getLoacl();
window.onbeforeunload = () => {
//setLocal
// setLocal(); //
};
});
// TODO 3
const website = useWebsite()
// TODO 2
const {data: websiteInfo } = await useServerRequest<ApiResult<Website>>('/cms/website/getSiteInfo');
if(!websiteInfo.value){
ElMessage.error('require is not defined.')
return false;
}
if(websiteInfo.value?.data){
website.value = websiteInfo.value?.data;
}
@ -53,19 +70,22 @@
// TODO 4
const {data: websiteRealTime } = await useServerRequest<ApiResult<Website>>('/cms/website/' + website.value.websiteId);
website.value = Object.assign({},website.value,websiteRealTime.value?.data)
if (website.value?.status != 1) {
useHead({title: ''})
loading.value = true;
return false;
}
// TODO 5
const config = useConfigInfo();
const { data: fields } = await useServerRequest<ApiResult<Config>>('/cms/website-field/config', {});
if (fields.value?.data) {
config.value = fields.value?.data;
}
// TODO 6
const menu = useMenu()
const { data: menuInfo } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', {
query: {
position: 1
top: 0
}
});
if(menuInfo.value?.data){
@ -73,14 +93,15 @@
}
// TODO 7
const subMenu = useSubMenu()
const { data: subMenuInfo } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', {
query: {
position: 2
bottom: 0
}
});
if(subMenuInfo.value?.data){
subMenu.value = subMenuInfo.value?.data
}
}
reload()
</script>

2
pages/[custom]/index.vue

@ -44,7 +44,7 @@ const { data: nav } = await useServerRequest<ApiResult<Navigation>>('/cms/naviga
}
})
if (nav.value) {
if (nav.value?.data) {
// seo
form.value = nav.value.data
useHead({

34
pages/a.vue

@ -0,0 +1,34 @@
<template>
<el-button
v-loading.fullscreen.lock="fullscreenLoading"
type="primary"
@click="openFullScreen1"
>
As a directive
</el-button>
<el-button type="primary" @click="openFullScreen2"> As a service </el-button>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ElLoading } from 'element-plus'
const fullscreenLoading = ref(false)
const openFullScreen1 = () => {
fullscreenLoading.value = true
setTimeout(() => {
fullscreenLoading.value = false
}, 2000)
}
const openFullScreen2 = () => {
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
setTimeout(() => {
loading.close()
}, 2000)
}
</script>

38
pages/article/[id].vue

@ -4,7 +4,7 @@
<div class="container flex flex-col w-full md:w-3/4 m-auto my-3">
<Breadcrumb :data="form" :title="form?.categoryName" />
<Breadcrumb :data="form" :title="form?.categoryName || '文章列表'" />
<!-- 左右结构 -->
<div class="news-box sm:mt-0 mt-2 flex sm:flex-row flex-col justify-between sm:space-x-4">
@ -83,6 +83,7 @@ import type {Design} from "~/api/cms/design/model";
import {useClientRequest} from "~/composables/useClientRequest";
import {pageArticle} from "~/api/cms/article";
import Breadcrumb from "~/components/Breadcrumb.vue";
import type {Navigation} from "~/api/cms/navigation/model";
const route = useRoute();
const { query, params } = route;
@ -98,7 +99,7 @@ const disabled = ref<boolean>(false);
const newList = ref<Article[]>();
//
const form = ref<Design | any>();
const form = ref<Navigation | any>();
const load = () => {
if(!disabled.value){
@ -109,6 +110,24 @@ const load = () => {
//
const reload = async () => {
//
const { data: navInfo } = await useServerRequest<ApiResult<Article>>('/cms/navigation/' + id);
console.log(navInfo.value);
// categoryName.value = d.categoryName;
form.value = navInfo.value;
useHead({
title: `${form.value.currentTitle} - 网宿软件`,
meta: [{ name: "keywords", content: form.value.title }],
bodyAttrs: {
class: "page-container",
},
script: [
{
children: "console.log('Hello World')",
},
],
});
await useServerRequest<ApiResult<PageResult<Article>>>('/cms/article/page',{
params: {
page: page.value,
@ -130,20 +149,7 @@ const reload = async () => {
// list.value = articleList.value.data?.list;
list.value.map((d,i)=>{
if(i === 0){
categoryName.value = d.categoryName;
form.value = d;
useHead({
title: `${d.categoryName} - 网宿软件`,
meta: [{ name: "keywords", content: d.title }],
bodyAttrs: {
class: "page-container",
},
script: [
{
children: "console.log('Hello World')",
},
],
});
}
});
})

2
pages/product/[name].vue

@ -3,7 +3,7 @@
<Breadcrumb :data="form" />
<ProductShopInfo :data="goods?.merchant" />
<!-- <ProductShopInfo :data="goods?.merchant" />-->
<div class="bg-white p-4 mt-4 flex gap-xl rounded-xl" v-if="goods">
<div class="goods-image flex gap-xl">

2
pages/search/index.vue

@ -5,7 +5,7 @@
<!-- 容器 -->
<div class="container md:w-3/4 m-auto">
<div class="flex flex-col">
<Breadcrumb :title="`站内搜索`" />
<Breadcrumb />
</div>
</div>

Loading…
Cancel
Save