完成适配移动端
This commit is contained in:
@@ -9,25 +9,27 @@ export interface CmsWebsiteSetting {
|
||||
// 关联网站ID
|
||||
websiteId?: number;
|
||||
// 是否官方插件
|
||||
official?: string;
|
||||
official?: boolean;
|
||||
// 是否展示在插件市场
|
||||
market?: string;
|
||||
market?: boolean;
|
||||
// 是否允许被搜索
|
||||
search?: string;
|
||||
search?: boolean;
|
||||
// 是否共享
|
||||
share?: string;
|
||||
share?: boolean;
|
||||
// 是否插件 0应用1 插件
|
||||
plugin?: string;
|
||||
plugin?: boolean;
|
||||
// 编辑器类型 1 md-editor-v3, 2 tinymce-editor
|
||||
editor?: number;
|
||||
// 显示站内搜索
|
||||
searchBtn?: string;
|
||||
searchBtn?: boolean;
|
||||
// 显示登录注册功能
|
||||
loginBtn?: string;
|
||||
loginBtn?: boolean;
|
||||
// 显示语言切换
|
||||
langBtn?: boolean;
|
||||
// 显示悬浮客服工具
|
||||
floatTool?: boolean;
|
||||
// 显示版权链接
|
||||
copyrightLink?: string;
|
||||
copyrightLink?: boolean;
|
||||
// 导航栏最多显示数量
|
||||
maxMenuNum?: string;
|
||||
// 排序号
|
||||
|
||||
@@ -5,12 +5,13 @@ const config = useConfigInfo();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full bg-black">
|
||||
<!-- PC端 -->
|
||||
<div class="w-full sm:bg-black hidden-sm-and-down">
|
||||
<div class="xl:w-screen-xl flex flex-col justify-between m-auto">
|
||||
<!-- 友情链接 -->
|
||||
<Link />
|
||||
<!-- 版权信息 -->
|
||||
<div class="w-full xl:w-screen-xl xl:px-0 px-4 w-full m-auto flex sm:flex-row flex-col-reverse sm:justify-between justify-center items-center sm:py-3 text-center text-sm">
|
||||
<div class="w-full xl:w-screen-xl xl:px-0 px-4 w-full m-auto flex flex-row sm:justify-between justify-center items-center sm:py-3 text-center text-sm">
|
||||
<div class="text-gray-400 sm:gap-xs leading-7 flex flex-col sm:flex-row">
|
||||
<span>Copyright © {{ new Date().getFullYear() }} {{ config?.copyright }}</span>
|
||||
<nuxt-link to="https://beian.miit.gov.cn/" class="visited:text-gray-400 hover:text-gray-200" target="_blank"> <span>备案号:{{ config?.icpNo }}</span></nuxt-link>
|
||||
@@ -21,6 +22,23 @@ const config = useConfigInfo();
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 移动端 -->
|
||||
<div class="w-full sm:bg-black hidden-sm-and-up">
|
||||
<div class="xl:w-screen-xl flex flex-col justify-between m-auto">
|
||||
<!-- 友情链接 -->
|
||||
<Link />
|
||||
<!-- 版权信息 -->
|
||||
<div class="w-full xl:w-screen-xl xl:px-0 px-4 w-full m-auto flex flex-col sm:justify-between justify-center items-center py-3 text-center text-sm">
|
||||
<div class="text-gray-400 sm:gap-xs leading-7 flex flex-col sm:flex-row">
|
||||
<span>Copyright © {{ new Date().getFullYear() }} {{ config?.copyright }}</span>
|
||||
<nuxt-link to="https://beian.miit.gov.cn/" class="visited:text-gray-400 hover:text-gray-200" target="_blank"> <span>备案号:{{ config?.icpNo }}</span></nuxt-link>
|
||||
</div>
|
||||
<div class="tools flex items-center opacity-80 hover:opacity-90 text-gray-300 text-xs mt-5">
|
||||
Powered by <a rel="nofollow" href="https://site.websoft.top" target="_blank" class="visited:text-gray-300 hover:text-gray-200 ml-1">云·企业官网</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
<template>
|
||||
<el-space class="text-gray-400 text-sm hidden-sm-and-down">
|
||||
<span>友情链接:</span>
|
||||
<template v-for="(item,index) in list" :key="index">
|
||||
<nuxt-link :to="item.url" target="_blank" class="link:text-gray-400 visited:text-gray-400 hover:text-gray-200">{{ item.name }}</nuxt-link>
|
||||
<el-divider v-if="list.length-1 != index" direction="vertical" style="border-color: #9ca3af;" />
|
||||
</template>
|
||||
</el-space>
|
||||
<div class="border-b-solid bg-gray-700 border-1 mt-4 opacity-40 hidden-sm-and-down"></div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {listCmsLink} from "~/api/cms/cmsLink";
|
||||
import type {CmsLink} from "~/api/cms/cmsLink/model";
|
||||
@@ -7,18 +17,6 @@ listCmsLink({}).then(res => {
|
||||
list.value = res;
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-space class="text-gray-400 text-sm">
|
||||
<span>友情链接:</span>
|
||||
<template v-for="(item,index) in list" :key="index">
|
||||
<nuxt-link :to="item.url" target="_blank" class="link:text-gray-400 visited:text-gray-400 hover:text-gray-200">{{ item.name }}</nuxt-link>
|
||||
<el-divider v-if="list.length-1 != index" direction="vertical" style="border-color: #9ca3af;" />
|
||||
</template>
|
||||
</el-space>
|
||||
<div class="border-b-solid bg-gray-700 border-1 mt-4 opacity-40"></div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import {useConfigInfo, useSubMenu} from "~/composables/configState";
|
||||
const subMenu = useSubMenu();
|
||||
const config = useConfigInfo();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full bg-black h-[300px] py-5">
|
||||
<!-- PC端 -->
|
||||
<div class="w-full bg-black h-[300px] py-5 hidden-sm-and-down">
|
||||
<div class="xl:w-screen-xl flex justify-between m-auto">
|
||||
<template v-for="(item,index) in subMenu">
|
||||
<div class="item">
|
||||
@@ -23,8 +18,38 @@ const config = useConfigInfo();
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 移动端 -->
|
||||
<el-collapse v-model="activeNames" accordion class="hidden-sm-and-up my-collapse">
|
||||
<template v-for="(item,index) in subMenu">
|
||||
<el-collapse-item :title="item.title" :name="index">
|
||||
<template v-if="item.children">
|
||||
<template v-for="sub in item.children">
|
||||
<nuxt-link :to="sub.path" class="block cursor-pointer text-gray-600 hover:text-gray-900 py-0.5">
|
||||
<span class="px-4">{{ sub.title }}</span>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
</template>
|
||||
</el-collapse-item>
|
||||
</template>
|
||||
</el-collapse>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {useConfigInfo, useSubMenu} from "~/composables/configState";
|
||||
const subMenu = useSubMenu();
|
||||
const config = useConfigInfo();
|
||||
const activeNames = ref(['1'])
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
<style lang="scss">
|
||||
.my-collapse{
|
||||
.el-collapse-item__header{
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.el-collapse-item__wrap{
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.el-collapse-item{
|
||||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,7 +5,7 @@ const setting = useSetting()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="toolbar" v-if="setting.floatTool">
|
||||
<div id="toolbar" v-if="setting.floatTool" class="hidden-sm-and-down">
|
||||
<ul>
|
||||
<li><a :href="`http://wpa.qq.com/msgrd?v=3&uin=${config.qqCode}&site=qq&menu=yes`" target="_blank">
|
||||
<span class="icon-font icon-qq"></span>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<!-- 头部组件 -->
|
||||
<div class="shadow-sm fixed z-100 top-0 w-full bg-white bg-opacity-90">
|
||||
<div class="sm:p-0 px-4 shadow-sm fixed z-100 top-0 w-full bg-white bg-opacity-90">
|
||||
<!-- 顶部通栏 -->
|
||||
<TopBar />
|
||||
<!-- 导航栏 -->
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<div class="fr clearfix flex items-center">
|
||||
<div v-if="setting.searchBtn" class="fl mr-5">
|
||||
<!-- PC端 -->
|
||||
<div v-if="setting.searchBtn" class="fl mr-5 hidden-sm-and-down">
|
||||
<el-input v-model="keywords" :placeholder="`${$t('searchKeywords')}`" :suffix-icon="Search" @change="onSearch"/>
|
||||
</div>
|
||||
<template v-if="setting.loginBtn">
|
||||
<!-- 未登录 -->
|
||||
<div v-if="!token" class="lang flex justify-center text-center items-center">
|
||||
<el-space>
|
||||
<el-space class="hidden-sm-and-down">
|
||||
<nuxt-link to="/passport/login?type=register" type="text" class="text-sm text-gray-500">注册</nuxt-link>
|
||||
<el-divider direction="vertical"/>
|
||||
<nuxt-link to="/passport/login" type="text" class="text-sm text-gray-500">登录</nuxt-link>
|
||||
@@ -43,16 +44,62 @@
|
||||
</el-space>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 移动端 -->
|
||||
<div class="hidden-sm-and-up mx-7 sm:mx-0">
|
||||
<div class="el-dropdown-link flex items-center" @click="drawer = true">
|
||||
<el-avatar v-if="token" class="cursor-pointer" :src="user?.avatar" :size="30"/>
|
||||
<el-icon v-else color="black" :size="24"><Fold /></el-icon>
|
||||
</div>
|
||||
<el-drawer
|
||||
v-model="drawer"
|
||||
:size="290"
|
||||
>
|
||||
<div id="menu">
|
||||
<el-menu
|
||||
currentIndex="/product"
|
||||
:unique-opened="true"
|
||||
>
|
||||
<template v-for="(item,index) in navigations" :key="index">
|
||||
<el-sub-menu v-if="item?.children && item.children.length > 0" :index="`${index}`">
|
||||
<template #title><span>{{ item.title }}</span></template>
|
||||
<el-menu-item v-for="(sub,subIndex) in item.children" :index="`${subIndex}`">
|
||||
<el-space>
|
||||
<el-avatar v-if="sub.icon" :src="sub.icon" shape="square" size="small"></el-avatar>
|
||||
<a :href="navTo(sub)">{{ sub.title }}</a>
|
||||
</el-space>
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-menu-item v-else :index="`${index}`"><a :href="navTo(item)">{{ item.title }}</a></el-menu-item>
|
||||
</template>
|
||||
</el-menu>
|
||||
<!-- <div v-if="setting.searchBtn" class="search-tools flex justify-center p-4 mt-5">-->
|
||||
<!-- <el-input v-model="keywords" placeholder="请输入关键词..." :suffix-icon="Search" @change="onSearch"/>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div v-if="setting.langBtn" class="lang flex justify-center text-center">-->
|
||||
<!-- <el-space>-->
|
||||
<!-- <a @click="onLang(`zh`)" class="text-sm text-gray-500">中文版</a>-->
|
||||
<!-- <el-divider direction="vertical" />-->
|
||||
<!-- <a @click="onLang(`en`)" class="text-sm text-gray-400">English</a>-->
|
||||
<!-- </el-space>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import {useConfigInfo, useSetting} from "~/composables/configState";
|
||||
import { Search, Fold } from '@element-plus/icons-vue'
|
||||
import {useConfigInfo, useMenu, useSetting} from "~/composables/configState";
|
||||
import type {CmsLangLog} from "~/api/cms/cmsLangLog/model";
|
||||
import {listCmsLangLog} from "~/api/cms/cmsLangLog";
|
||||
const token = useToken();
|
||||
const user = useUser();
|
||||
const navigations = useMenu();
|
||||
const setting = useSetting();
|
||||
const keywords = ref<string>();
|
||||
const drawer = ref<boolean>(false);
|
||||
const langList = ref<CmsLangLog[]>([]);
|
||||
|
||||
const onSearch = () => {
|
||||
navigateTo(`/search/${keywords.value || '关键词不能为空!'}`)
|
||||
@@ -69,6 +116,16 @@ function handleCommand(command: string) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 读取国际化配置
|
||||
listCmsLangLog({}).then(list => {
|
||||
langList.value = list;
|
||||
})
|
||||
|
||||
const onLang = (lang: string) => {
|
||||
navigateTo(`?lang=${lang}`)
|
||||
drawer.value = false;
|
||||
}
|
||||
|
||||
function logOut() {
|
||||
token.value = '';
|
||||
localStorage.clear();
|
||||
@@ -76,5 +133,7 @@ function logOut() {
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
.el-menu{
|
||||
border-right: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<nuxt-link to="/" class="flex items-center cursor-pointer gap-sm mr-7" v-if="website">
|
||||
<el-image v-if="website.websiteLogo || logo?.value" :style="`${logo?.style}`" :src="logo?.value || website?.websiteLogo" class=" rounded-sm rounded-sm w-[107px] h-[24px]"/>
|
||||
<el-image v-if="website.websiteLogo || logo?.value" :style="`${logo?.style}`" :src="logo?.value || website?.websiteLogo" class="rounded-sm rounded-sm w-[107px] h-[24px] py-3 sm:py-0"/>
|
||||
<h4 v-else class="text-gray-700 text-xl font-bold" :style="`${logo?.style}`">{{ website?.websiteName }}</h4>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
|
||||
@@ -1,26 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {navigateTo} from "#imports";
|
||||
|
||||
const navigations = useMenu();
|
||||
import {useMenu} from "~/composables/configState";
|
||||
const handleSelect = (index: any,keyPath: string[]) => {
|
||||
const split = index.split('-');
|
||||
if(split.length == 1){
|
||||
const item = navigations.value[index];
|
||||
navigateTo(item)
|
||||
}
|
||||
if(split.length == 2){
|
||||
const item = navigations.value[split[0]];
|
||||
if(item.children){
|
||||
const child = item.children[split[1]];
|
||||
navigateTo(child.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- PC版菜单 -->
|
||||
<el-menu
|
||||
class="hidden-sm-and-down"
|
||||
mode="horizontal"
|
||||
style="background-color: transparent;"
|
||||
active-text-color="#1b850c"
|
||||
@@ -54,7 +35,27 @@ const handleSelect = (index: any,keyPath: string[]) => {
|
||||
</template>
|
||||
</el-menu>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {navigateTo} from "#imports";
|
||||
import {useMenu} from "~/composables/configState";
|
||||
|
||||
const navigations = useMenu();
|
||||
|
||||
const handleSelect = (index: any,keyPath: string[]) => {
|
||||
const split = index.split('-');
|
||||
if(split.length == 1){
|
||||
const item = navigations.value[index];
|
||||
navigateTo(item)
|
||||
}
|
||||
if(split.length == 2){
|
||||
const item = navigations.value[split[0]];
|
||||
if(item.children){
|
||||
const child = item.children[split[1]];
|
||||
navigateTo(child.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.el-menu--horizontal > .el-menu-item:nth-child(1) {
|
||||
margin-right: auto;
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import {detail} from "~/utils/common";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
data?: any;
|
||||
}>(),
|
||||
{}
|
||||
);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<template v-for="(item,index) in data" 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="detail(item)" :title="item.title" class="img"><el-image :fit="`scale-down`" :src="item.image" :alt="item.title" /></a>
|
||||
<h3>
|
||||
<a :href="detail(item)" :title="item.title" class="text-lg font-bold">{{ item.title }}</a>
|
||||
<span class="line-clamp-2 text-gray-400 text-sm font-normal py-3 text-left">{{ item.comments }}</span>
|
||||
</h3>
|
||||
</div>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -1,35 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
data?: any;
|
||||
isMobile?: boolean;
|
||||
}>(),
|
||||
{}
|
||||
);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="content text-[16px]" v-html="data"></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
padding-top: 15px;
|
||||
overflow: hidden;
|
||||
color: #333131;
|
||||
}
|
||||
.content p{
|
||||
padding: 0;
|
||||
line-height: 2.2rem;
|
||||
}
|
||||
.content img{
|
||||
padding: 8px 0;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.content video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -1,34 +0,0 @@
|
||||
<template>
|
||||
<div class="h-[40px]"></div>
|
||||
<div class="footer">
|
||||
<div class="ffs">
|
||||
<a :href="`tel:${config.callPhone}`"><span class="span1">{{ $t('tel') }}</span></a>
|
||||
<a :href="`/${i18n.locale.value}/m/page/1008.html`"><span class="span2">{{ $t('map') }}</span></a>
|
||||
<a :href="`/${i18n.locale.value}/m/order/1003.do`"><span class="span3">{{ $t('message') }}</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 请求数据
|
||||
import {useConfigInfo} from "#imports";
|
||||
import {configWebsiteField} from "~/api/cms/cmsWebsiteField";
|
||||
|
||||
const config = useConfigInfo();
|
||||
const i18n = useI18n();
|
||||
|
||||
// TODO 读取网站配置信息
|
||||
configWebsiteField({
|
||||
lang: i18n.locale.value
|
||||
}).then(res => {
|
||||
config.value = res;
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.el-divider__text{
|
||||
display: block;
|
||||
margin-top: -1px;
|
||||
--el-bg-color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
@@ -1,153 +0,0 @@
|
||||
<template>
|
||||
|
||||
<header class="clearfix flex justify-between items-center w-full">
|
||||
<div class="logo" :class="logo?.style">
|
||||
<nuxt-link :to="`/m`" target="_top"><el-image :src="logo?.value" class=" rounded-sm rounded-sm w-[107px] h-[40px]"/></nuxt-link>
|
||||
</div>
|
||||
<div class="sub-menu">
|
||||
<el-icon color="black" :size="20" @click="drawer = true"><Fold /></el-icon>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<el-drawer
|
||||
v-model="drawer"
|
||||
:size="290"
|
||||
>
|
||||
<div id="menu">
|
||||
<el-menu
|
||||
currentIndex="/product"
|
||||
:unique-opened="true"
|
||||
>
|
||||
<template v-for="(item,index) in navigations" :key="index">
|
||||
<el-sub-menu v-if="item?.children && item.children.length > 0" :index="`${index}`">
|
||||
<template #title><span>{{ item.title }}</span></template>
|
||||
<el-menu-item v-for="(sub,subIndex) in item.children" :index="`${subIndex}`">
|
||||
<el-space>
|
||||
<el-avatar v-if="sub.icon" :src="sub.icon" shape="square" size="small"></el-avatar>
|
||||
<a :href="navTo(sub)">{{ sub.title }}</a>
|
||||
</el-space>
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-menu-item v-else :index="`${index}`"><a :href="navTo(item)">{{ item.title }}</a></el-menu-item>
|
||||
</template>
|
||||
</el-menu>
|
||||
<div class="search-tools flex justify-center p-4 mt-5">
|
||||
<el-input v-model="keyword" placeholder="请输入关键词..." :suffix-icon="Search" @change="onSearch"/>
|
||||
</div>
|
||||
<div class="lang flex justify-center text-center" v-if="langList.length > 0">
|
||||
<el-space>
|
||||
<a :href="`/m?spm=zh_CN`" class="text-sm text-gray-500">中文版</a>
|
||||
<el-divider direction="vertical" />
|
||||
<a :href="`/en/m?spm=en_US`" class="text-sm text-gray-400">English</a>
|
||||
</el-space>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 引入所需的图标
|
||||
import {
|
||||
useConfigInfo, useLogo,
|
||||
useMenu,
|
||||
useToken,
|
||||
useUser, useWebsite
|
||||
} from "~/composables/configState";
|
||||
import {getPath, isMobileDevice, navTo} from "#imports";
|
||||
import { Search, Expand, Fold } from '@element-plus/icons-vue'
|
||||
import {configWebsiteField, listCmsWebsiteField} from "~/api/cms/cmsWebsiteField";
|
||||
import {getSiteInfo, getUserInfo} from "~/api/layout";
|
||||
import {listCmsLangLog} from "~/api/cms/cmsLangLog";
|
||||
import type {CmsLangLog} from "~/api/cms/cmsLangLog/model";
|
||||
import type {CmsWebsiteField} from "~/api/cms/cmsWebsiteField/model";
|
||||
import {getWebsiteField} from "~/api/cms/cmsWebsiteField";
|
||||
|
||||
const token = useToken();
|
||||
const user = useUser();
|
||||
const navigations = useMenu();
|
||||
const config = useConfigInfo();
|
||||
const i18n = useI18n();
|
||||
const isMobile = ref<boolean>(false);
|
||||
const langList = ref<CmsLangLog[]>([]);
|
||||
const drawer = ref<boolean>(false);
|
||||
const logo = useLogo()
|
||||
const keyword = ref();
|
||||
|
||||
const setNav = () => {
|
||||
navigations.value = navigations.value.map(item => {
|
||||
item.showChild = false
|
||||
item.childHeight = 0;
|
||||
return item
|
||||
})
|
||||
}
|
||||
setNav()
|
||||
|
||||
const onSearch = () => {
|
||||
window.location.href = `/m/search/${keyword.value}`;
|
||||
}
|
||||
|
||||
|
||||
const reload = async () => {
|
||||
|
||||
// TODO 读取网站配置信息
|
||||
configWebsiteField({
|
||||
lang: i18n.locale.value
|
||||
}).then(res => {
|
||||
config.value = res;
|
||||
})
|
||||
|
||||
// TODO 读取国际化配置
|
||||
listCmsLangLog({}).then(list => {
|
||||
langList.value = list;
|
||||
})
|
||||
|
||||
listCmsWebsiteField({
|
||||
name: 'siteLogo'
|
||||
}).then(data => {
|
||||
if(data[0]){
|
||||
logo.value = data[0]
|
||||
}
|
||||
})
|
||||
|
||||
// TODO 是否跳转H5版
|
||||
if(isMobileDevice()){
|
||||
isMobile.value = true;
|
||||
const path = getPath(1);
|
||||
if(!path || !path.startsWith('/m')){
|
||||
let newUrl = '';
|
||||
let origin = window.location.origin;
|
||||
let href = window.location.href;
|
||||
let pathname = window.location.pathname;
|
||||
if(pathname.startsWith('/m') || pathname.startsWith(`/${i18n.locale.value}/m`)){
|
||||
return false;
|
||||
}
|
||||
newUrl = href.replace(origin,origin + '/m');
|
||||
window.location.href = newUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
// token.value = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJ1c2VybmFtZVwiOlwiMTM4MDAwMTAzMTdcIixcInRlbmFudElkXCI6MTAzMTd9IiwiZXhwIjoxNzM1Nzk2NjA1LCJpYXQiOjE3MzMyMDQ2MDV9.hx6OV4ZHe6XTnNye1gvsuXjoxHW0YihcEwSuppUcoCc'
|
||||
// 获取用户信息
|
||||
if (token.value) {
|
||||
getUserInfo().then(data => {
|
||||
user.value = data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 在这里放置你想要在组件渲染完成后执行的代码
|
||||
reload();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.el-menu{
|
||||
border-right: none !important;
|
||||
}
|
||||
.el-menu-item, .el-sub-menu{
|
||||
border-bottom: 1px solid #f3f3f3;
|
||||
}
|
||||
</style>
|
||||
@@ -29,24 +29,16 @@ nextArticle.value = await getNext({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex justify-between my-3 gap-4">
|
||||
<nuxt-link :to="previousArticle ? detail(previousArticle) : ''" class="w-[50%] flex flex-col justify-center p-4 border-1 border-solid border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50">
|
||||
<div class="flex justify-between flex-col sm:flex-row my-3 gap-4">
|
||||
<nuxt-link :to="previousArticle ? detail(previousArticle) : ''" class="w-auto sm:w-[50%] flex flex-col justify-center p-4 border-1 border-solid border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50">
|
||||
<span class="text-lg text-gray-800">{{ previousArticle?.title || '没有了' }}</span>
|
||||
<span class="text-gray-400">{{ $t('previous') }}</span>
|
||||
</nuxt-link>
|
||||
<nuxt-link :to="nextArticle ? detail(nextArticle) : ''" class="w-[50%] flex flex-col justify-center p-4 border-1 border-solid border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50">
|
||||
<nuxt-link :to="nextArticle ? detail(nextArticle) : ''" class="w-auto sm:w-[50%] flex flex-col justify-center p-4 border-1 border-solid border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50">
|
||||
<span class="text-lg text-gray-800">{{ nextArticle?.title || '没有了' }}</span>
|
||||
<span class="text-gray-400">{{ $t('next') }}</span>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<!-- <div class="page flex flex-col">-->
|
||||
<!-- <span class="text-left">-->
|
||||
<!-- {{ $t('previous') }}:<a :href="detail(previousArticle)">{{ previousArticle?.title }}</a>-->
|
||||
<!-- </span>-->
|
||||
<!-- <span class="text-left">-->
|
||||
<!-- {{ $t('next') }}:<a :href="detail(nextArticle)">{{ nextArticle?.title }}</a>-->
|
||||
<!-- </span>-->
|
||||
<!-- </div>-->
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -13,10 +13,12 @@ const i18n = useI18n();
|
||||
|
||||
<template>
|
||||
<div class="tag pt-1" v-if="data">
|
||||
<el-space>
|
||||
<span>{{ $t('keyword') }}:</span>
|
||||
<el-tag v-for="(item,index) in JSON.parse(data)" :key="index"><a :href="`${i18n.locale.value == 'en' ? '/en' : ''}/tags/${item}`" target="_blank">{{ item }}</a></el-tag>
|
||||
</el-space>
|
||||
<div class="flex justify-between">
|
||||
<div class="text-nowrap">{{ $t('keyword') }}:</div>
|
||||
<el-space class="flex-wrap">
|
||||
<el-tag v-for="(item,index) in JSON.parse(data)" :key="index"><a :href="`${i18n.locale.value == 'en' ? '/en' : ''}/tags/${item}`" target="_blank">{{ item }}</a></el-tag>
|
||||
</el-space>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
<template>
|
||||
<div class="overflow-x-hidden">
|
||||
<!-- 手机版 -->
|
||||
<MHeader/>
|
||||
<slot />
|
||||
<MFooter/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useMenu, useSubMenu, useWebsite} from "~/composables/configState";
|
||||
import MHeader from "~/components/MHeader.vue";
|
||||
import MFooter from "~/components/MFooter.vue";
|
||||
import {useI18n} from "#imports";
|
||||
import {getSiteInfo} from "~/api/layout";
|
||||
import {getTenantIdByDomain} from "~/api/cms/cmsDomain";
|
||||
|
||||
// 加载状态
|
||||
const website = useWebsite()
|
||||
const menu = useMenu()
|
||||
const subMenu = useSubMenu()
|
||||
const i18n = useI18n()
|
||||
|
||||
|
||||
// 挂载钩子
|
||||
onMounted(() => {
|
||||
//必须在onMounted的时候才能用local和window
|
||||
// getLoacl();
|
||||
window.onbeforeunload = () => {
|
||||
//离开页面时保存数据,由于可能突发情况,所以重要数据请手动调用setLocal函数
|
||||
// setLocal(); //如果需要调试本地存储数据,记得把这个注释一下
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
// 加载数据
|
||||
const reload = async () => {
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: 'Loading'
|
||||
})
|
||||
|
||||
// TODO 1 查询当前域名是否合法
|
||||
const domain = window.location.hostname;
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
getTenantIdByDomain({
|
||||
domain
|
||||
}).then(data => {
|
||||
if(data?.count && data.count > 0){
|
||||
console.log('域名已授权 => ',data.list[0].domain)
|
||||
localStorage.setItem('TenantId',`${data?.list[0].tenantId}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TODO 2 读取服务器缓存数据
|
||||
await getSiteInfo({
|
||||
lang: i18n.locale.value
|
||||
}).then(data => {
|
||||
website.value = data
|
||||
localStorage.setItem('SiteName',`${data.websiteName}`);
|
||||
if (data.topNavs) {
|
||||
menu.value = data.topNavs;
|
||||
}
|
||||
if (data.bottomNavs) {
|
||||
subMenu.value = data.bottomNavs;
|
||||
}
|
||||
if(data.config){
|
||||
localStorage.setItem('Domain',data.config.Domain);
|
||||
localStorage.setItem('SysDomain',data.config.SysDomain);
|
||||
}
|
||||
// 站点状态
|
||||
if(data.running != 1){
|
||||
showError({
|
||||
statusCode: data.running,
|
||||
message: data.statusText
|
||||
})
|
||||
}
|
||||
})
|
||||
loading.close();
|
||||
}
|
||||
|
||||
reload()
|
||||
</script>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-12 px-4 sm:px-0 sm:mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ page.title }} </span>
|
||||
<span class="text-large font-600"> {{ page.title }} </span>
|
||||
</template>
|
||||
<el-row :gutter="24" id="container" class="clearfix">
|
||||
<el-col v-for="(item,index) in list" :key="index" :span="6" class="left mb-6">
|
||||
<el-col v-for="(item,index) in list" :key="index" :xs="24" :sm="8" class="left mb-6">
|
||||
<el-card shadow="hover" :body-style="{ padding: '0px' }" class=" hover:bg-gray-50 cursor-pointer" @click="navigateTo(`/detail/${item.articleId}.html`)">
|
||||
<el-image
|
||||
:src="item.image"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ page.title }} </span>
|
||||
<span class="text-large font-600"> {{ page.title }} </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-space class="flex items-center">
|
||||
|
||||
@@ -1,26 +1,48 @@
|
||||
<template>
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-12 px-4 sm:px-0 sm:mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 客户案例 </span>
|
||||
<span class="text-large font-600 line-clamp-1"> 客户案例 </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-space class="flex items-center">
|
||||
<el-input v-model="where.keywords" style="width: 400px" :placeholder="`搜索关键词`" :suffix-icon="Search"
|
||||
@change="reload"/>
|
||||
<el-input
|
||||
v-model="where.keywords"
|
||||
:placeholder="`搜索关键词`"
|
||||
class="hidden-sm-and-down"
|
||||
:suffix-icon="Search"
|
||||
:style="{ width: inputWidth }"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
@change="reload"
|
||||
/>
|
||||
<el-button class="hidden-sm-and-up" :icon="Search" @click="showSearch = true"></el-button>
|
||||
</el-space>
|
||||
<el-dialog
|
||||
v-model="showSearch"
|
||||
fullscreen
|
||||
>
|
||||
<el-input
|
||||
v-model="where.keywords"
|
||||
:placeholder="`搜索关键词`"
|
||||
size="large"
|
||||
class="w-full my-5"
|
||||
:suffix-icon="Search"
|
||||
@change="reload"
|
||||
/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<el-row :gutter="24" id="container" class="clearfix">
|
||||
<el-col v-for="(item,index) in list" :key="index" :span="8" class="left mb-8">
|
||||
<el-col v-for="(item,index) in list" :key="index" :xs="24" :sm="8" class="left mb-8">
|
||||
<el-card shadow="hover" :body-style="{ padding: '0px' }" class="cursor-pointer" @mouseover="showDomain(item)"
|
||||
@mouseleave="hideDomain">
|
||||
<nuxt-link :to="`/market/${item.websiteId}`">
|
||||
<div class="flex-1 px-4 py-5 sm:p-4 !p-4">
|
||||
<div class="text-gray-700 dark:text-white text-base font-semibold flex gap-1.5">
|
||||
<el-avatar
|
||||
:src="item.websiteLogo" shape="square" :size="55" style="background-color: white;"/>
|
||||
:src="item.websiteLogo" shape="square" :size="55" style="background-color: white;"/>
|
||||
<div class="flex-1 text-lg cursor-pointer flex flex-col">
|
||||
{{ item.websiteName }}
|
||||
<div class="flex justify-between items-center">
|
||||
@@ -58,6 +80,8 @@ const router = useRouter();
|
||||
const list = ref<CmsWebsite[]>([]);
|
||||
const total = ref(0);
|
||||
const id = ref<number>();
|
||||
const inputWidth = ref<string>('180px');
|
||||
const showSearch = ref<boolean>(false);
|
||||
|
||||
// 搜索表单
|
||||
const where = reactive<CmsWebsiteParam>({
|
||||
@@ -75,6 +99,13 @@ const where = reactive<CmsWebsiteParam>({
|
||||
const goBack = () => {
|
||||
router.back();
|
||||
}
|
||||
const handleFocus = () => {
|
||||
inputWidth.value = '400px'; // 聚焦时宽度
|
||||
}
|
||||
const handleBlur = () => {
|
||||
inputWidth.value = '180px'; // 聚焦时宽度
|
||||
}
|
||||
|
||||
const showDomain = (item: CmsWebsite) => {
|
||||
id.value = Number(item.websiteId);
|
||||
};
|
||||
@@ -91,7 +122,7 @@ const reload = async () => {
|
||||
total.value = response.count;
|
||||
}
|
||||
}).catch(() => {
|
||||
})
|
||||
}).finally(() => showSearch.value = false)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,14 +135,17 @@ const search = (data: CmsArticleParam) => {
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.params.id,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
() => route.params.id,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.el-input {
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<!-- 文章详情 -->
|
||||
<template>
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-12 px-4 sm:px-0 sm:mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="font-600 mr-3"> 文章详情 </span>
|
||||
</template>
|
||||
|
||||
<el-card shadow="hover" class=" my-10 px-2">
|
||||
<el-card shadow="hover" class="my-5 sm:my-10 sm:px-2">
|
||||
|
||||
<!-- 新闻详细 -->
|
||||
<div class=" bg-white">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 my-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 插件编辑 </span>
|
||||
<span class="text-large font-600"> 插件编辑 </span>
|
||||
</template>
|
||||
|
||||
<div class="login-layout mt-10 sm:w-screen-xl w-full">
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
<template>
|
||||
|
||||
<div class="flex mb-20 mt-30 justify-start">
|
||||
<div class="w-auto">
|
||||
<div class="w-screen-sm my-1 bg-green-700 h-[50px]"></div>
|
||||
<div class="w-screen-md my-1 bg-green-700 h-[50px]"></div>
|
||||
<div class="w-screen-lg my-1 bg-green-700 h-[50px]"></div>
|
||||
<div class="w-screen-xl my-1 bg-green-700 h-[50px]"></div>
|
||||
<div class="w-screen-2xl my-1 bg-green-700 h-[50px]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 开发者中心</span>
|
||||
<span class="text-large font-600"> 开发者中心</span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-space class="flex items-center">
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<Banner :layout="layout" />
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-12 px-4 sm:px-0 sm:mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ page.title }} </span>
|
||||
<span class="text-large font-600"> {{ page.title }} </span>
|
||||
</template>
|
||||
<el-row :gutter="24" id="container" class="clearfix">
|
||||
<el-col v-for="(item,index) in list" :key="index" :span="6" class="left mb-6">
|
||||
<el-col v-for="(item,index) in list" :key="index" :xs="24" :span="6" class="left mb-6">
|
||||
<el-card shadow="hover" :body-style="{ padding: '0px' }" class=" hover:bg-gray-50 cursor-pointer" @click="navigateTo(`/detail/${item.articleId}.html`)">
|
||||
<el-image
|
||||
:src="item.image"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<Banner :layout="layout" />
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-12 px-4 sm:px-0 sm:mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 文档中心 </span>
|
||||
<span class="text-large font-600"> 文档中心 </span>
|
||||
</template>
|
||||
<el-row :gutter="24" id="container" class="clearfix">
|
||||
<el-col v-for="(item,index) in list" :key="index" :span="6" class="left mb-6">
|
||||
<el-col v-for="(item,index) in list" :key="index" :xs="12" sm:="8" class="left mb-6">
|
||||
<el-card shadow="hover" :body-style="{ padding: '0px' }" class=" hover:bg-white cursor-pointer" @click="navigateTo(`/docs/${item.navigationId}.html`)">
|
||||
<div class="flex-1 px-4 py-5 sm:p-4 !p-4">
|
||||
<div class="text-gray-700 dark:text-white text-base font-semibold flex flex-col items-center gap-1.5">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 产品详情 </span>
|
||||
<span class="text-large font-600"> 产品详情 </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<div class="h-[32px]"></div>
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
<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>
|
||||
@@ -1,129 +0,0 @@
|
||||
<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>
|
||||
@@ -1,67 +0,0 @@
|
||||
<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>
|
||||
@@ -1,202 +0,0 @@
|
||||
<!-- 文章详情 -->
|
||||
<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>
|
||||
@@ -1,183 +0,0 @@
|
||||
<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>
|
||||
@@ -1,220 +0,0 @@
|
||||
<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>
|
||||
@@ -1,232 +0,0 @@
|
||||
<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>
|
||||
@@ -1,267 +0,0 @@
|
||||
<template>
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="clearfix p-5" style="border-top: #f9f9f9 16px solid;">
|
||||
|
||||
<div class="m-page">
|
||||
<div class="sitemp h-[32px] flex justify-between">
|
||||
<h2>矛盾纠纷收集与处理</h2>
|
||||
</div>
|
||||
<div class="form-box p-5">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="120"
|
||||
label-position="top"
|
||||
status-icon
|
||||
>
|
||||
<el-form-item :label="`您的姓名`" prop="realName" class=" p-2 text-left">
|
||||
<el-input v-model="form.realName" class="text-left" :placeholder="`您的姓名`"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="`手机号码`" prop="phone" class=" p-2">
|
||||
<el-input v-model="form.phone" :maxlength="11" :placeholder="`手机号码`"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="`您的住址`" prop="address" class="p-2 text-left">
|
||||
<el-cascader v-model="value" class="w-full" :options="options" placeholder="所在城区" @change="handleChange" />
|
||||
<el-input class="mt-2" v-model="form.address" :placeholder="`您的住址`"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="`纠纷描述`" prop="content" class=" p-2">
|
||||
<el-input type="textarea" :rows="5" cols="80" v-model="form.content"
|
||||
:placeholder="`您要反映的矛盾纠纷内容`"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="`附件上传`" prop="files" class=" p-2">
|
||||
<el-upload
|
||||
v-model:file-list="files"
|
||||
action="https://server.gxwebsoft.com/api/oss/upload"
|
||||
:headers="{
|
||||
Authorization: token,
|
||||
TenantId: 5,
|
||||
}"
|
||||
:limit="8"
|
||||
list-type="picture-card"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="filesRemove"
|
||||
:on-success="filesSuccess"
|
||||
>
|
||||
<el-icon>
|
||||
<Plus/>
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item :label="`验证码`" prop="code" class=" 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="ml-2 w-full">
|
||||
<el-button type="primary" size="large" class="block w-full" @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 {ArrowRight, Plus} from '@element-plus/icons-vue'
|
||||
import type {UploadProps, UploadUserFile} from 'element-plus'
|
||||
import type {FormInstance, FormRules} from 'element-plus'
|
||||
import RegionsData from '~/api/json/regions-data.json'
|
||||
import type {CmsOrder} from "~/api/cms/cmsOrder/model";
|
||||
import useFormData from "~/utils/use-form-data";
|
||||
import {addCmsOrder} from "~/api/cms/cmsOrder";
|
||||
import {getCaptcha} from "~/api/passport/login";
|
||||
|
||||
// 引入状态管理
|
||||
const route = useRoute();
|
||||
const token = useToken();
|
||||
const files = ref<UploadUserFile[]>([])
|
||||
|
||||
const srcList = ref<string[]>([])
|
||||
const address = ref<string>()
|
||||
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: 1,
|
||||
// 关联项目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,
|
||||
// 图像验证码内容
|
||||
files: 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'},
|
||||
],
|
||||
address: [
|
||||
{required: true, message: '请填写您的住址', trigger: 'blur'},
|
||||
],
|
||||
realName: [
|
||||
{required: true, message: '请输入联系人姓名', trigger: 'blur'},
|
||||
],
|
||||
content: [
|
||||
{required: true, message: '请输入纠纷内容', trigger: 'blur'},
|
||||
]
|
||||
})
|
||||
|
||||
const value = ref([])
|
||||
const options = ref<any>([])
|
||||
const props = {
|
||||
expandTrigger: 'hover' as const,
|
||||
}
|
||||
|
||||
const handleChange = (value:any) => {
|
||||
address.value = ''
|
||||
console.log(value)
|
||||
const province = RegionsData.find(item => item.value == value[0]);
|
||||
if(province){
|
||||
address.value = `${province?.label}`
|
||||
const city = province.children?.find(item => item.value == value[1]);
|
||||
if(city){
|
||||
address.value = `${province?.label}${city.label}`
|
||||
const region = city.children?.find(item => item.value == value[2]);
|
||||
if(region){
|
||||
address.value = `${province?.label}${city.label}${region.label}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 获取图形验证码 */
|
||||
const changeCaptcha = async () => {
|
||||
getCaptcha().then(captchaData => {
|
||||
captcha.value = captchaData.base64;
|
||||
text.value = captchaData.text;
|
||||
})
|
||||
};
|
||||
|
||||
// 请求数据
|
||||
const reload = async () => {
|
||||
form.content = ''
|
||||
// seo
|
||||
useSeoMeta({
|
||||
description: form.comments || form.title,
|
||||
keywords: form.title,
|
||||
titleTemplate: `${form?.title || '矛盾纠纷收集平台'}` + ' - %s',
|
||||
})
|
||||
const gx = RegionsData.find(item => item.value == '450000')
|
||||
options.value = gx?.children
|
||||
changeCaptcha();
|
||||
}
|
||||
|
||||
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
||||
dialogImageUrl.value = uploadFile.url!
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const filesRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
|
||||
form.files = JSON.stringify('');
|
||||
}
|
||||
|
||||
const filesSuccess = (e: any) => {
|
||||
srcList.value.push(e.data.downloadUrl)
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitForm = (formEl: FormInstance | undefined) => {
|
||||
if (process.client) {
|
||||
addCmsOrder({
|
||||
...form,
|
||||
files: JSON.stringify(srcList.value) || undefined,
|
||||
address: `${address.value} ${form.address}`
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
resetFields();
|
||||
files.value = []
|
||||
ElMessage.success(res.message)
|
||||
} else {
|
||||
return ElMessage.error(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 在这里放置你想要在组件渲染完成后执行的代码
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
||||
@@ -1,78 +0,0 @@
|
||||
<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>
|
||||
@@ -1,122 +0,0 @@
|
||||
<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>
|
||||
@@ -1,147 +0,0 @@
|
||||
<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>
|
||||
@@ -1,185 +0,0 @@
|
||||
<!-- 文章详情 -->
|
||||
<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>
|
||||
@@ -1,135 +0,0 @@
|
||||
<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>
|
||||
@@ -1,110 +0,0 @@
|
||||
<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>
|
||||
@@ -1,183 +0,0 @@
|
||||
<!-- 文章详情 -->
|
||||
<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>
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-12 px-4 sm:px-0 sm:mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 产品详情 </span>
|
||||
<span class="text-large font-600"> 产品详情 </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<div class="h-[32px]"></div>
|
||||
|
||||
@@ -1,71 +1,91 @@
|
||||
<template>
|
||||
<div v-if="form" class="app-info bg-white py-5 flex justify-around items-center">
|
||||
<div class="item text-center">
|
||||
<div class="rate text-gray-400">评分</div>
|
||||
<div class="text-2xl font-bold">3.1</div>
|
||||
<el-rate v-model="form.rate" disabled size="small"/>
|
||||
</div>
|
||||
<el-divider class="opacity-40" style="height: 40px" direction="vertical" />
|
||||
<div class="item text-center flex flex-col items-center">
|
||||
<div class="text-gray-400">类别</div>
|
||||
<el-icon size="24" class="py-1"><Monitor /></el-icon>
|
||||
<span class="text-gray-500">{{ form.industryParent || '网站' }}</span>
|
||||
</div>
|
||||
<el-divider class="opacity-40" style="height: 40px" direction="vertical" />
|
||||
<nuxt-link :to="`https://${form.domain}`" class="item text-center flex flex-col items-center">
|
||||
<div class="text-gray-400">域名</div>
|
||||
<div>
|
||||
<svg t="1739721752315" class="icon pt-2" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11933" width="22" height="22"><path d="M319.9 428.9h37.7l-66.1 216.7H259c-28.9-98-43.9-149.1-44.9-154.3-2.1-4.6-3.1-12.4-3.1-23.2h-1c0 4.6-1 12.4-3.1 23.2-2.1 4.6-18.1 56.2-48 154.3h-32.5l-63-216.7h37.7c23.7 91.3 36.6 141.4 38.7 149.6 0 0.5 0.5 1.5 1 3.1 1.5 9.8 2.1 17 2.1 21.2h1c0-7.7 1.5-15.5 4.1-24.3 2.1-5.7 17-55.7 44.9-149.6h35.6c25.8 94.4 39.7 144.5 41.8 149.6 2.6 8.3 4.1 16.5 4.1 24.3h1c0-4.1 0.5-11.4 2.1-21.2 0.5-1.5 1-2.6 1-3.1 2.7-8.2 16.1-58.2 41.4-149.6z m300.8 0h37.7l-66.1 216.7h-32.5c-28.9-98-43.9-149.1-44.9-154.3-2.1-4.6-3.1-12.4-3.1-23.2h-1c0 4.6-1 12.4-3.1 23.2-2.1 4.6-18.1 56.2-48 154.3h-32.5l-63-216.7h37.7c23.7 91.3 36.6 141.4 38.7 149.6 0 0.5 0.5 1.5 1 3.1 1.5 9.8 2.1 17 2.1 21.2h0.5c0-7.7 1.5-15.5 4.1-24.3 2.1-5.7 17-55.7 44.9-149.6h35.6c25.8 94.4 39.7 144.5 41.8 149.6 2.6 8.3 4.1 16.5 4.1 24.3h1c0-4.1 0.5-11.4 2.1-21.2 0.5-1.5 1-2.6 1-3.1 3.2-8.2 16.6-58.2 41.9-149.6z m300.9 0h37.7l-66.1 216.7h-32.5c-28.9-98-43.9-149.1-44.9-154.3-2.1-4.6-3.1-12.4-3.1-23.2h-1c0 4.6-1 12.4-3.1 23.2-2.1 4.6-18.1 56.2-48 154.3h-32.5l-63-216.7h37.7c23.7 91.3 36.6 141.4 38.7 149.6 0 0.5 0.5 1.5 1 3.1 1.5 9.8 2.1 17 2.1 21.2h1c0-7.7 1.5-15.5 4.1-24.3 2.1-5.7 17-55.7 44.9-149.6h35.6C856 523.4 870 573.4 872 578.6c2.6 8.3 4.1 16.5 4.1 24.3h1c0-4.1 0.5-11.4 2.1-21.2 0.5-1.5 1-2.6 1-3.1 2.7-8.3 16.1-58.3 41.4-149.7z m-755.5-39.2C222.9 254 357 158.5 513.4 158.5S803.9 254 860.7 389.7h45.9c-58.8-160-212.6-274-393.2-274s-333.9 114-393.2 274h45.9z m691 299.3c-58.8 131.1-190.4 222.9-343.7 222.9-153.3 0-284.8-91.3-343.7-222.9h-46.4c61.4 155.3 212.6 265.2 390.1 265.2 177 0 328.7-109.9 390.1-265.2h-46.4z" fill="" p-id="11934"></path><path d="M513.4 217.8c-123.2 0-230.1 69.7-283.4 171.9h-14.9c54.4-109.8 167.6-185.2 298.4-185.2" fill="" p-id="11935"></path></svg>
|
||||
<el-scrollbar style="height: 100%;" class="bg-white">
|
||||
<div v-if="form" class="app-info bg-white px-5 py-5 flex justify-around items-center">
|
||||
<div class="item text-center">
|
||||
<div class="rate text-gray-400">评分</div>
|
||||
<div class="text-2xl font-bold">3.1</div>
|
||||
<el-rate v-model="form.rate" disabled size="small"/>
|
||||
</div>
|
||||
<!-- <el-icon size="24" class="py-1"><Compass /></el-icon>-->
|
||||
<span class="text-gray-500">{{ form.domain }}</span>
|
||||
</nuxt-link>
|
||||
<el-divider class="opacity-40" style="height: 40px" direction="vertical" />
|
||||
<nuxt-link :to="`/market/user/${form.userId}`" class="item text-center flex flex-col items-center">
|
||||
<div class="text-gray-400">开发者</div>
|
||||
<el-icon size="24" class="py-1"><Avatar /></el-icon>
|
||||
<span class="text-gray-500">{{ form || 'WebSoft Inc.' }}</span>
|
||||
</nuxt-link>
|
||||
<el-divider class="opacity-40" style="height: 40px" direction="vertical" />
|
||||
<nuxt-link :to="`http://git.gxwebsoft.com`" class="item text-center">
|
||||
<div class="text-gray-400">仓库</div>
|
||||
<div class="text-2xl font-bold">
|
||||
<!-- <svg t="1739721615244" class="icon pt-2" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10773" width="22" height="22"><path d="M512 64c81.636 0 156.8 19.911 225.493 59.733s122.951 94.08 162.773 162.773S960 430.364 960 512s-19.911 156.8-59.733 225.493-94.08 122.951-162.773 162.773S593.636 960 512 960s-156.8-19.911-225.493-59.733-122.951-94.08-162.773-162.773S64 593.636 64 512s19.911-156.8 59.733-225.493 94.08-122.951 162.773-162.773S430.364 64 512 64z m119.467 812.373c57.742-17.92 108.516-48.782 152.32-92.587 43.804-43.805 75.164-94.578 94.08-152.32 18.916-57.742 23.396-117.476 13.44-179.2-9.956-61.724-32.853-117.476-68.693-167.253-35.84-49.778-81.138-88.604-135.893-116.48C631.964 140.658 573.724 126.72 512 126.72s-119.964 13.938-174.72 41.813-100.053 66.702-135.893 116.48-58.738 105.529-68.693 167.253c-9.956 61.724-5.476 121.458 13.44 179.2s50.276 108.516 94.08 152.32c43.804 43.804 94.578 74.667 152.32 92.587h2.987c5.973 0 10.951-1.493 14.933-4.48 3.982-2.987 5.973-7.467 5.973-13.44v-65.707l-20.907 2.987H377.6c-19.911 1.991-38.329-1.991-55.253-11.947S293.974 759.893 288 741.973l-17.92-32.853-11.947-11.947-23.893-17.92c-3.982-3.982-5.973-6.969-5.973-8.96s0.996-3.982 2.987-5.973l14.933-2.987c5.973 0 11.947 1.493 17.92 4.48 5.973 2.987 11.947 5.476 17.92 7.467l11.947 14.933 11.947 11.947c7.964 13.938 17.422 24.889 28.373 32.853 10.951 7.964 23.893 11.449 38.827 10.453 14.933-0.996 29.369-4.48 43.307-10.453 1.991-9.956 4.978-19.413 8.96-28.373 3.982-8.96 8.96-16.427 14.933-22.4-25.884-1.991-49.778-7.467-71.68-16.427-21.902-8.96-40.818-21.404-56.747-37.333-15.929-15.929-26.88-34.844-32.853-56.747-7.964-25.884-11.947-52.764-11.947-80.64 0-17.92 3.484-35.84 10.453-53.76 6.969-17.92 16.427-33.849 28.373-47.787-1.991-7.964-3.484-15.431-4.48-22.4s-1.493-14.933-1.493-23.893 0.996-17.92 2.987-26.88c1.991-8.96 3.982-18.418 5.973-28.373h8.96c7.964 0 16.427 0.996 25.387 2.987s17.422 4.978 25.387 8.96l26.88 14.933 20.907 11.947c63.716-17.92 127.431-17.92 191.147 0l20.907-11.947 26.88-14.933c7.964-3.982 15.929-6.969 23.893-8.96 7.964-1.991 16.924-2.987 26.88-2.987h5.973c3.982 9.956 6.969 19.413 8.96 28.373 1.991 8.96 2.987 17.92 2.987 26.88 0 8.96-0.498 16.924-1.493 23.893s-2.489 14.436-4.48 22.4c11.947 13.938 21.404 29.867 28.373 47.787 6.969 17.92 10.453 35.84 10.453 53.76 0 27.876-3.982 54.756-11.947 80.64-5.973 21.902-16.924 40.818-32.853 56.747-15.929 15.929-35.342 28.373-58.24 37.333-22.898 8.96-47.289 14.436-73.173 16.427 9.956 7.964 16.924 18.418 20.907 31.36 3.982 12.942 5.973 26.382 5.973 40.32v104.533c0 5.973 1.991 10.453 5.973 13.44 3.982 2.987 7.964 4.48 11.947 4.48h5.972z" p-id="10774"></path></svg>-->
|
||||
<svg t="1739720696276" class="icon pt-2" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4176" width="22" height="22"><path d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9 23.5 23.2 38.1 55.4 38.1 91v112.5c0.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z" p-id="4177"></path></svg>
|
||||
<el-divider class="opacity-40" style="height: 40px" direction="vertical"/>
|
||||
<div class="item text-center flex flex-col items-center">
|
||||
<div class="text-gray-400">类别</div>
|
||||
<el-icon size="24" class="py-1">
|
||||
<Monitor/>
|
||||
</el-icon>
|
||||
<span class="text-gray-500">{{ form.industryParent || '网站' }}</span>
|
||||
</div>
|
||||
<span class="text-gray-500">3.12 MB</span>
|
||||
</nuxt-link>
|
||||
<el-divider class="opacity-40" style="height: 40px" direction="vertical" />
|
||||
<div class="item text-center flex flex-col items-center">
|
||||
<div class="text-gray-400">插件ID</div>
|
||||
<el-icon size="24" class="py-1"><Cpu /></el-icon>
|
||||
<span class="text-gray-500">{{ form.websiteId }}</span>
|
||||
<el-divider class="opacity-40" style="height: 40px" direction="vertical"/>
|
||||
<nuxt-link :to="`https://${form.domain}`" class="item text-center flex flex-col items-center">
|
||||
<div class="text-gray-400">域名</div>
|
||||
<div>
|
||||
<svg t="1739721752315" class="icon pt-2" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" p-id="11933" width="22" height="22">
|
||||
<path
|
||||
d="M319.9 428.9h37.7l-66.1 216.7H259c-28.9-98-43.9-149.1-44.9-154.3-2.1-4.6-3.1-12.4-3.1-23.2h-1c0 4.6-1 12.4-3.1 23.2-2.1 4.6-18.1 56.2-48 154.3h-32.5l-63-216.7h37.7c23.7 91.3 36.6 141.4 38.7 149.6 0 0.5 0.5 1.5 1 3.1 1.5 9.8 2.1 17 2.1 21.2h1c0-7.7 1.5-15.5 4.1-24.3 2.1-5.7 17-55.7 44.9-149.6h35.6c25.8 94.4 39.7 144.5 41.8 149.6 2.6 8.3 4.1 16.5 4.1 24.3h1c0-4.1 0.5-11.4 2.1-21.2 0.5-1.5 1-2.6 1-3.1 2.7-8.2 16.1-58.2 41.4-149.6z m300.8 0h37.7l-66.1 216.7h-32.5c-28.9-98-43.9-149.1-44.9-154.3-2.1-4.6-3.1-12.4-3.1-23.2h-1c0 4.6-1 12.4-3.1 23.2-2.1 4.6-18.1 56.2-48 154.3h-32.5l-63-216.7h37.7c23.7 91.3 36.6 141.4 38.7 149.6 0 0.5 0.5 1.5 1 3.1 1.5 9.8 2.1 17 2.1 21.2h0.5c0-7.7 1.5-15.5 4.1-24.3 2.1-5.7 17-55.7 44.9-149.6h35.6c25.8 94.4 39.7 144.5 41.8 149.6 2.6 8.3 4.1 16.5 4.1 24.3h1c0-4.1 0.5-11.4 2.1-21.2 0.5-1.5 1-2.6 1-3.1 3.2-8.2 16.6-58.2 41.9-149.6z m300.9 0h37.7l-66.1 216.7h-32.5c-28.9-98-43.9-149.1-44.9-154.3-2.1-4.6-3.1-12.4-3.1-23.2h-1c0 4.6-1 12.4-3.1 23.2-2.1 4.6-18.1 56.2-48 154.3h-32.5l-63-216.7h37.7c23.7 91.3 36.6 141.4 38.7 149.6 0 0.5 0.5 1.5 1 3.1 1.5 9.8 2.1 17 2.1 21.2h1c0-7.7 1.5-15.5 4.1-24.3 2.1-5.7 17-55.7 44.9-149.6h35.6C856 523.4 870 573.4 872 578.6c2.6 8.3 4.1 16.5 4.1 24.3h1c0-4.1 0.5-11.4 2.1-21.2 0.5-1.5 1-2.6 1-3.1 2.7-8.3 16.1-58.3 41.4-149.7z m-755.5-39.2C222.9 254 357 158.5 513.4 158.5S803.9 254 860.7 389.7h45.9c-58.8-160-212.6-274-393.2-274s-333.9 114-393.2 274h45.9z m691 299.3c-58.8 131.1-190.4 222.9-343.7 222.9-153.3 0-284.8-91.3-343.7-222.9h-46.4c61.4 155.3 212.6 265.2 390.1 265.2 177 0 328.7-109.9 390.1-265.2h-46.4z"
|
||||
fill="" p-id="11934"></path>
|
||||
<path d="M513.4 217.8c-123.2 0-230.1 69.7-283.4 171.9h-14.9c54.4-109.8 167.6-185.2 298.4-185.2" fill=""
|
||||
p-id="11935"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- <el-icon size="24" class="py-1"><Compass /></el-icon>-->
|
||||
<span class="text-gray-500">{{ form.domain }}</span>
|
||||
</nuxt-link>
|
||||
<el-divider class="opacity-40" style="height: 40px" direction="vertical"/>
|
||||
<nuxt-link :to="`/market/user/${form.userId}`" class="item text-center flex flex-col items-center">
|
||||
<div class="text-gray-400">开发者</div>
|
||||
<el-icon size="24" class="py-1">
|
||||
<Avatar/>
|
||||
</el-icon>
|
||||
<span class="text-gray-500">{{ 'WebSoft Inc.' }}</span>
|
||||
</nuxt-link>
|
||||
<el-divider class="opacity-40" style="height: 40px" direction="vertical"/>
|
||||
<nuxt-link :to="`http://git.gxwebsoft.com`" class="item text-center">
|
||||
<div class="text-gray-400">仓库</div>
|
||||
<div class="text-2xl font-bold">
|
||||
<!-- <svg t="1739721615244" class="icon pt-2" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10773" width="22" height="22"><path d="M512 64c81.636 0 156.8 19.911 225.493 59.733s122.951 94.08 162.773 162.773S960 430.364 960 512s-19.911 156.8-59.733 225.493-94.08 122.951-162.773 162.773S593.636 960 512 960s-156.8-19.911-225.493-59.733-122.951-94.08-162.773-162.773S64 593.636 64 512s19.911-156.8 59.733-225.493 94.08-122.951 162.773-162.773S430.364 64 512 64z m119.467 812.373c57.742-17.92 108.516-48.782 152.32-92.587 43.804-43.805 75.164-94.578 94.08-152.32 18.916-57.742 23.396-117.476 13.44-179.2-9.956-61.724-32.853-117.476-68.693-167.253-35.84-49.778-81.138-88.604-135.893-116.48C631.964 140.658 573.724 126.72 512 126.72s-119.964 13.938-174.72 41.813-100.053 66.702-135.893 116.48-58.738 105.529-68.693 167.253c-9.956 61.724-5.476 121.458 13.44 179.2s50.276 108.516 94.08 152.32c43.804 43.804 94.578 74.667 152.32 92.587h2.987c5.973 0 10.951-1.493 14.933-4.48 3.982-2.987 5.973-7.467 5.973-13.44v-65.707l-20.907 2.987H377.6c-19.911 1.991-38.329-1.991-55.253-11.947S293.974 759.893 288 741.973l-17.92-32.853-11.947-11.947-23.893-17.92c-3.982-3.982-5.973-6.969-5.973-8.96s0.996-3.982 2.987-5.973l14.933-2.987c5.973 0 11.947 1.493 17.92 4.48 5.973 2.987 11.947 5.476 17.92 7.467l11.947 14.933 11.947 11.947c7.964 13.938 17.422 24.889 28.373 32.853 10.951 7.964 23.893 11.449 38.827 10.453 14.933-0.996 29.369-4.48 43.307-10.453 1.991-9.956 4.978-19.413 8.96-28.373 3.982-8.96 8.96-16.427 14.933-22.4-25.884-1.991-49.778-7.467-71.68-16.427-21.902-8.96-40.818-21.404-56.747-37.333-15.929-15.929-26.88-34.844-32.853-56.747-7.964-25.884-11.947-52.764-11.947-80.64 0-17.92 3.484-35.84 10.453-53.76 6.969-17.92 16.427-33.849 28.373-47.787-1.991-7.964-3.484-15.431-4.48-22.4s-1.493-14.933-1.493-23.893 0.996-17.92 2.987-26.88c1.991-8.96 3.982-18.418 5.973-28.373h8.96c7.964 0 16.427 0.996 25.387 2.987s17.422 4.978 25.387 8.96l26.88 14.933 20.907 11.947c63.716-17.92 127.431-17.92 191.147 0l20.907-11.947 26.88-14.933c7.964-3.982 15.929-6.969 23.893-8.96 7.964-1.991 16.924-2.987 26.88-2.987h5.973c3.982 9.956 6.969 19.413 8.96 28.373 1.991 8.96 2.987 17.92 2.987 26.88 0 8.96-0.498 16.924-1.493 23.893s-2.489 14.436-4.48 22.4c11.947 13.938 21.404 29.867 28.373 47.787 6.969 17.92 10.453 35.84 10.453 53.76 0 27.876-3.982 54.756-11.947 80.64-5.973 21.902-16.924 40.818-32.853 56.747-15.929 15.929-35.342 28.373-58.24 37.333-22.898 8.96-47.289 14.436-73.173 16.427 9.956 7.964 16.924 18.418 20.907 31.36 3.982 12.942 5.973 26.382 5.973 40.32v104.533c0 5.973 1.991 10.453 5.973 13.44 3.982 2.987 7.964 4.48 11.947 4.48h5.972z" p-id="10774"></path></svg>-->
|
||||
<svg t="1739720696276" class="icon pt-2" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" p-id="4176" width="22" height="22">
|
||||
<path
|
||||
d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9 23.5 23.2 38.1 55.4 38.1 91v112.5c0.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z"
|
||||
p-id="4177"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="text-gray-500">3.12 MB</span>
|
||||
</nuxt-link>
|
||||
<el-divider class="opacity-40" style="height: 40px" direction="vertical"/>
|
||||
<div class="item text-center flex flex-col items-center">
|
||||
<div class="text-gray-400">插件ID</div>
|
||||
<el-icon size="24" class="py-1">
|
||||
<Cpu/>
|
||||
</el-icon>
|
||||
<span class="text-gray-500">{{ form.websiteId }}</span>
|
||||
</div>
|
||||
<!-- <el-divider class="opacity-40" style="height: 40px" direction="vertical" />-->
|
||||
<!-- <div class="item text-center flex flex-col items-center">-->
|
||||
<!-- <div class="text-gray-400">下载次数</div>-->
|
||||
<!-- <el-icon size="24" class="py-1"><Download /></el-icon>-->
|
||||
<!-- <span class="text-gray-500">{{ form.downloads }}</span>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<!-- <el-divider class="opacity-40" style="height: 40px" direction="vertical" />-->
|
||||
<!-- <div class="item text-center flex flex-col items-center">-->
|
||||
<!-- <div class="text-gray-400">下载次数</div>-->
|
||||
<!-- <el-icon size="24" class="py-1"><Download /></el-icon>-->
|
||||
<!-- <span class="text-gray-500">{{ form.downloads }}</span>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ArrowLeft,View, Menu, Search,Compass, Cpu,Monitor, Download, Platform, Avatar } from '@element-plus/icons-vue'
|
||||
import {ArrowLeft, View, Menu, Search, Compass, Cpu, Monitor, Download, Platform, Avatar} from '@element-plus/icons-vue'
|
||||
import type {CmsWebsite} from "~/api/cms/cmsWebsite/model";
|
||||
import {getUser, listUsers} from "~/api/system/user";
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
title?: string;
|
||||
desc?: string;
|
||||
buyUrl?: string;
|
||||
form?: CmsWebsite;
|
||||
value?: number;
|
||||
}>(),
|
||||
{}
|
||||
defineProps<{
|
||||
title?: string;
|
||||
desc?: string;
|
||||
buyUrl?: string;
|
||||
form?: CmsWebsite;
|
||||
value?: number;
|
||||
}>(),
|
||||
{}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -84,3 +104,13 @@ const where = reactive<any>({
|
||||
});
|
||||
|
||||
</script>
|
||||
<style lang="less">
|
||||
.app-info{
|
||||
.item {
|
||||
min-width: 100px;
|
||||
white-space: nowrap; /* 防止内容换行 */
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -4,39 +4,45 @@
|
||||
<el-space class="my-2">
|
||||
<h4 class="text-sm w-[40px] text-gray-400 font-normal text-center">行业</h4>
|
||||
<div class="flex-wrap">
|
||||
<el-radio-group v-model="selectIndustry" @change="onIndustry">
|
||||
<el-radio-button v-for="(item,index) in IndustryData" :key="index" :label="item.label" :value="item.value" />
|
||||
</el-radio-group>
|
||||
<el-radio-group v-model="selectIndustry" @change="onIndustry">
|
||||
<el-radio-button v-for="(item,index) in IndustryData" :key="index" :label="item.label"
|
||||
:value="item.value"/>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</el-space>
|
||||
<el-space class="my-2">
|
||||
<h4 class="text-sm w-[40px] text-gray-400 font-normal text-center">类型</h4>
|
||||
<el-radio-group v-model="selectType" @change="onType">
|
||||
<el-radio-button v-for="(item,index) in websiteType" :key="index" :label="item.label" :value="item.value" />
|
||||
<el-radio-button v-for="(item,index) in websiteType" :key="index" :label="item.label" :value="item.value"/>
|
||||
</el-radio-group>
|
||||
</el-space>
|
||||
<el-space class="my-2" :size="12">
|
||||
<h4 class="text-sm w-[40px] text-gray-400 font-normal text-center">色系</h4>
|
||||
<template v-for="(item,index) in colors" :key="index">
|
||||
<nuxt-link :to="`?color=${item.label}`" @click="handleColor(item.label)">
|
||||
<el-avatar v-if="selectColor == item.label" :size="28" :style="item.comments" class="border-solid border-1 border-gray-800 rounded-full"></el-avatar>
|
||||
<el-avatar v-if="selectColor == item.label" :size="28" :style="item.comments"
|
||||
class="border-solid border-1 border-gray-800 rounded-full"></el-avatar>
|
||||
<el-avatar v-else :size="24" :style="item.comments"></el-avatar>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
</el-space>
|
||||
</div>
|
||||
</div>
|
||||
<el-space class="gap-4 mt-5">
|
||||
<el-button type="primary" @click="handleDefault">默认</el-button>
|
||||
<el-button @click="handleLast">最新</el-button>
|
||||
<el-button @click="handleHot">最热</el-button>
|
||||
<el-button @click="handleFree">免费</el-button>
|
||||
<el-button @click="handlePay">付费</el-button>
|
||||
<el-button @click="handleOfficial">官方</el-button>
|
||||
<el-input v-model="keywords" style="width: 400px" :placeholder="`云官网`"
|
||||
:suffix-icon="Search" @change="handleKeywords"/>
|
||||
<el-button @click="clearWhere">重置</el-button>
|
||||
</el-space>
|
||||
<el-scrollbar style="height: 100%;">
|
||||
<el-space class="gap-4 mt-5">
|
||||
<el-button type="primary" @click="handleDefault">默认</el-button>
|
||||
<el-button @click="handleLast">最新</el-button>
|
||||
<el-button @click="handleHot">最热</el-button>
|
||||
<el-button @click="handleFree">免费</el-button>
|
||||
<el-button @click="handlePay">付费</el-button>
|
||||
<el-button @click="handleOfficial">官方</el-button>
|
||||
<el-input v-model="keywords" :placeholder="`云官网`"
|
||||
style="min-width: 220px"
|
||||
class="hidden-sm-and-down"
|
||||
:suffix-icon="Search" @change="handleKeywords"/>
|
||||
<el-button class="hidden-sm-and-down" @click="clearWhere">重置</el-button>
|
||||
</el-space>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -161,7 +167,7 @@ const reload = () => {
|
||||
|
||||
const onType = (text: string) => {
|
||||
where.websiteType = text
|
||||
if(text == '全部'){
|
||||
if (text == '全部') {
|
||||
where.websiteType = undefined
|
||||
}
|
||||
reload();
|
||||
@@ -169,7 +175,7 @@ const onType = (text: string) => {
|
||||
|
||||
const onIndustry = (text: string) => {
|
||||
where.industry = text
|
||||
if(text == '全部'){
|
||||
if (text == '全部') {
|
||||
where.industry = undefined
|
||||
}
|
||||
reload();
|
||||
|
||||
@@ -1,20 +1,46 @@
|
||||
<template>
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-12 px-4 sm:px-0 sm:mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 插件市场 </span>
|
||||
<div class="text-large font-600"> 插件市场 </div>
|
||||
</template>
|
||||
<template #extra>
|
||||
<span class="text-gray-400">基于WebSoft开发的应用和插件!</span>
|
||||
<div class="text-gray-300 hidden-sm-and-down">基于WebSoft开发的应用和插件!</div>
|
||||
<el-space class="hidden-sm-and-up">
|
||||
<el-input
|
||||
v-model="where.keywords"
|
||||
:placeholder="`搜索关键词`"
|
||||
class="hidden-sm-and-down"
|
||||
:suffix-icon="Search"
|
||||
:style="{ width: inputWidth }"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
@change="reload"
|
||||
/>
|
||||
<el-button class="hidden-sm-and-up" :icon="Search" @click="showSearch = true"></el-button>
|
||||
<el-dialog
|
||||
v-model="showSearch"
|
||||
fullscreen
|
||||
>
|
||||
<el-input
|
||||
v-model="where.keywords"
|
||||
:placeholder="`搜索关键词`"
|
||||
size="large"
|
||||
class="w-full my-5"
|
||||
:suffix-icon="Search"
|
||||
@change="reload"
|
||||
/>
|
||||
</el-dialog>
|
||||
</el-space>
|
||||
</template>
|
||||
<!-- 搜索工具栏 -->
|
||||
<SearchBar :where="where" id="search" />
|
||||
|
||||
<!-- 应用列表 -->
|
||||
<el-row :gutter="24" id="container" class="clearfix">
|
||||
<el-col v-for="(item,index) in list" :key="index" :span="8" class="left mb-8">
|
||||
<el-col v-for="(item,index) in list" :key="index" :xs="24" :sm="8" class="left mb-8">
|
||||
<el-card shadow="hover" :body-style="{ padding: '0px' }" class="cursor-pointer" @mouseover="showDomain(item)"
|
||||
@mouseleave="hideDomain">
|
||||
<nuxt-link :to="`/market/${item.websiteId}`">
|
||||
@@ -59,6 +85,10 @@ const router = useRouter();
|
||||
const list = ref<CmsWebsite[]>([]);
|
||||
const total = ref(0);
|
||||
const id = ref<number>();
|
||||
|
||||
const inputWidth = ref<string>('180px');
|
||||
const showSearch = ref<boolean>(false);
|
||||
|
||||
const loading = ref<boolean>(false)
|
||||
const where = ref<CmsWebsiteParam>({
|
||||
|
||||
@@ -75,6 +105,13 @@ const hideDomain = () => {
|
||||
id.value = 0;
|
||||
};
|
||||
|
||||
const handleFocus = () => {
|
||||
inputWidth.value = '400px'; // 聚焦时宽度
|
||||
}
|
||||
const handleBlur = () => {
|
||||
inputWidth.value = '180px'; // 聚焦时宽度
|
||||
}
|
||||
|
||||
// 加载页面数据
|
||||
const reload = async (where: any) => {
|
||||
if (loading.value) return;
|
||||
@@ -97,7 +134,7 @@ const reload = async (where: any) => {
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
}).finally(() => {
|
||||
console.log('index>>>>')
|
||||
showSearch.value = false
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 插件市场 </span>
|
||||
<span class="text-large font-600"> 插件市场 </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-space class="flex items-center">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 相关插件 </span>
|
||||
<span class="text-large font-600"> 相关插件 </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-space class="flex items-center">
|
||||
|
||||
@@ -3,39 +3,39 @@
|
||||
<!-- Banner -->
|
||||
<Banner :layout="layout"/>
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-12 px-4 sm:px-0 sm:mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ page.title }} </span>
|
||||
<span class="text-large font-600"> {{ page.title }} </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
</template>
|
||||
<el-card shadow="hover" class="my-10 px-2">
|
||||
<el-row :gutter="30" justify="space-between">
|
||||
<el-col :span="13">
|
||||
<el-card shadow="hover" class="my-5 sm:my-10 sm:px-2">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-8">
|
||||
<div class="col-span-2">
|
||||
<div class="my-2">
|
||||
<el-alert title="填写您的需求,为您量身定制." type="warning"/>
|
||||
</div>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="120"
|
||||
label-position="left"
|
||||
status-icon
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="80"
|
||||
label-position="left"
|
||||
status-icon
|
||||
>
|
||||
<el-form-item :label="$t('order.title')" prop="title" class="hover:bg-gray-50 p-2">
|
||||
<el-select
|
||||
v-model="form.title"
|
||||
filterable
|
||||
placeholder="选择产品"
|
||||
@change="onWebsite"
|
||||
v-model="form.title"
|
||||
filterable
|
||||
placeholder="选择产品"
|
||||
@change="onWebsite"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in siteList"
|
||||
:key="item.websiteId"
|
||||
:label="item.websiteName"
|
||||
:value="item.websiteId"
|
||||
v-for="item in siteList"
|
||||
:key="item.websiteId"
|
||||
:label="item.websiteName"
|
||||
:value="item.websiteId"
|
||||
>
|
||||
<div class="flex justify-between">
|
||||
<span>{{ item.websiteName }}</span>
|
||||
@@ -44,12 +44,6 @@
|
||||
</span>
|
||||
</div>
|
||||
</el-option>
|
||||
<!-- <el-option-->
|
||||
<!-- v-for="item in siteList"-->
|
||||
<!-- :key="item.websiteId"-->
|
||||
<!-- :label="item.websiteName"-->
|
||||
<!-- :value="`${item.websiteId}`"-->
|
||||
<!-- />-->
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('order.content')" prop="content" class="hover:bg-gray-50 p-2">
|
||||
@@ -65,9 +59,6 @@
|
||||
<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"/>
|
||||
@@ -82,11 +73,11 @@
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
</div>
|
||||
<div class="hidden-sm-and-down">
|
||||
<el-image class="py-2" v-if="page.icon" :src="page.icon"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-page-header>
|
||||
</div>
|
||||
@@ -268,12 +259,12 @@ const goBack = () => {
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.params.id,
|
||||
(id) => {
|
||||
navId.value = getNavIdByParamsId(id);
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
() => route.params.id,
|
||||
(id) => {
|
||||
navId.value = getNavIdByParamsId(id);
|
||||
reload();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
<!-- Banner -->
|
||||
<Banner :layout="layout" />
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-12 px-4 sm:px-0 sm:mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ page.title || '页面标题' }} </span>
|
||||
<span class="text-large font-600"> {{ page.title || '页面标题' }} </span>
|
||||
</template>
|
||||
<el-card shadow="hover" class=" my-5">
|
||||
<el-image :src="page?.design?.photo" class="right max-w-lg" />
|
||||
<el-card shadow="hover" class="my-5 sm:my-10 sm:px-2">
|
||||
<el-image v-if="page?.design?.photo" :src="page?.design?.photo" class="right max-w-lg" />
|
||||
<!-- 新闻详细 -->
|
||||
<div class=" bg-white">
|
||||
<!-- 内容组件 -->
|
||||
<Content class="content text-lg py-3" :data="page.design?.content" />
|
||||
|
||||
<h3 class="tag">{{ $t('articleUrl') }}:{{ locationUrl() }} </h3>
|
||||
<h3 class="tag" @click="copyText(locationUrl())">{{ $t('articleUrl') }}:{{ locationUrl() }} </h3>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-page-header>
|
||||
@@ -24,7 +24,7 @@
|
||||
<script setup lang="ts">
|
||||
import {useLayout, usePage} from "~/composables/configState";
|
||||
import type {CmsNavigation} from "~/api/cms/cmsNavigation/model";
|
||||
import {getNavIdByParamsId, getViews, locationUrl, paramsId} from "~/utils/common";
|
||||
import {copyText, getNavIdByParamsId, getViews, locationUrl, paramsId} from "~/utils/common";
|
||||
import Left from "~/components/Left.vue";
|
||||
import { ArrowLeft,View } from '@element-plus/icons-vue'
|
||||
import {getCmsNavigation, listCmsNavigation} from "~/api/cms/cmsNavigation";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 注册 </span>
|
||||
<span class="text-large font-600"> 注册 </span>
|
||||
</template>
|
||||
</el-page-header>
|
||||
<el-card shadow="hover" class=" my-5 px-2">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ page.title }} </span>
|
||||
<span class="text-large font-600"> {{ page.title }} </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<div class="flex items-center">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ '站内搜索' }} </span>
|
||||
<span class="text-large font-600"> {{ '站内搜索' }} </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-radio-group v-model="where.model" @change="reload">
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<!-- <Breadcrumb :data="form" :categoryName="form?.categoryName" />-->
|
||||
<!-- </template>-->
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> {{ page.title }} </span>
|
||||
<span class="text-large font-600"> {{ page.title }} </span>
|
||||
</template>
|
||||
<el-row :gutter="24" class="mt-5">
|
||||
<el-col :span="18" :xs="24">
|
||||
|
||||
33
pages/tailwind-css/mobile/index.vue
Normal file
33
pages/tailwind-css/mobile/index.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600"> TailwindCSS 测试</span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-space class="flex items-center">
|
||||
</el-space>
|
||||
</template>
|
||||
<div class="flex mb-20 mt-10 justify-center">
|
||||
<div class="hidden-sm-and-up w-full">
|
||||
<h1 class="text-xl text-left my-4">手机版</h1>
|
||||
<div class="my-1 bg-white text-center h-[100px] items-center flex justify-center text-xl">小屏幕≥640px</div>
|
||||
</div>
|
||||
<div class="hidden-sm-and-down text-center w-full">
|
||||
<h1 class="text-xl text-left my-4">PC版</h1>
|
||||
<div class="my-1 bg-white text-center h-[100px] items-center flex justify-center text-xl">640px≥屏幕</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-page-header>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const goBack = () => {
|
||||
router.back();
|
||||
}
|
||||
</script>
|
||||
44
pages/tailwind-css/screen/index.vue
Normal file
44
pages/tailwind-css/screen/index.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<!-- 主体部分 -->
|
||||
<div class="xl:w-screen-xl m-auto py-4 mt-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600"> TailwindCSS 测试</span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-space class="flex items-center">
|
||||
</el-space>
|
||||
</template>
|
||||
</el-page-header>
|
||||
</div>
|
||||
<div class="flex mb-20 mt-10 justify-start">
|
||||
<div class="hidden-sm-and-up text-2xl flex justify-center">
|
||||
<span class="my-1 bg-gray-400 h-[50px] text-center items-center flex justify-center text-white text-xl">hidden-sm-and-up</span>
|
||||
</div>
|
||||
<div class="hidden-sm-and-down text-center">
|
||||
<span class="my-1 bg-gray-400 h-[50px] text-center items-center flex justify-center text-white text-xl">hidden-sm-and-down</span>
|
||||
</div>
|
||||
<div class="w-auto hidden-sm-and-down">
|
||||
<h2 class="text-lg">w-screen-sm:宽度小于640px</h2>
|
||||
<div class="w-screen-sm sm:flex my-1 bg-gray-400 h-[50px] text-center items-center flex justify-center text-white text-xl">w-screen-sm</div>
|
||||
<h2 class="text-lg">w-screen-md:宽度小于768px</h2>
|
||||
<div class="w-screen-md md:flex my-1 bg-gray-400 h-[50px] text-center items-center flex justify-center text-white text-xl">w-screen-md</div>
|
||||
<h2 class="text-lg">w-screen-lg:宽度小于1024px</h2>
|
||||
<div class="w-screen-lg lg:flex my-1 bg-gray-400 h-[50px] text-center items-center flex justify-center text-white text-xl">w-screen-lg</div>
|
||||
<h2 class="text-lg">w-screen-xl:宽度小于1280px</h2>
|
||||
<div class="w-screen-xl xl:flex my-1 bg-gray-400 h-[50px] text-center items-center flex justify-center text-white text-xl">w-screen-xl</div>
|
||||
<h2 class="text-lg">w-screen-2xl:宽度小于1536px</h2>
|
||||
<div class="w-screen-2xl 2xl:flex my-1 bg-gray-400 h-[50px] text-center items-center flex justify-center text-white text-xl">w-screen-2xl</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const goBack = () => {
|
||||
router.back();
|
||||
}
|
||||
</script>
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 my-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 实名认证 </span>
|
||||
<span class="text-large font-600"> 实名认证 </span>
|
||||
</template>
|
||||
<el-card shadow="hover" class="my-10 px-2">
|
||||
<el-row :gutter="30" justify="space-between">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 my-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 用户中心{{ user?.certification }} </span>
|
||||
<span class="text-large font-600"> 用户中心</span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<nuxt-link to="/user/modify" class="text-gray-400 text-sm">修改资料</nuxt-link>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 my-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 退出登录 </span>
|
||||
<span class="text-large font-600"> 退出登录 </span>
|
||||
</template>
|
||||
<div class="login-layout mt-10 sm:w-screen-xl w-full">
|
||||
<div class="m-auto flex sm:flex-row flex-col sm:px-0 px-3">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 my-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 修改资料 </span>
|
||||
<span class="text-large font-600"> 修改资料 </span>
|
||||
</template>
|
||||
<div class="login-layout mt-10 sm:w-screen-xl w-full">
|
||||
<div class="m-auto flex sm:flex-row flex-col sm:px-0 px-3">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 my-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 已购插件 </span>
|
||||
<span class="text-large font-600"> 已购插件 </span>
|
||||
</template>
|
||||
<div class="login-layout m-auto mt-10 sm:w-screen-xl w-full">
|
||||
<div class="m-auto flex sm:flex-row flex-col sm:px-0 px-3">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="xl:w-screen-xl m-auto py-4 my-20">
|
||||
<el-page-header :icon="ArrowLeft" @back="goBack">
|
||||
<template #content>
|
||||
<span class="text-large font-600 mr-3"> 用户中心 </span>
|
||||
<span class="text-large font-600"> 用户中心 </span>
|
||||
</template>
|
||||
<div class="login-layout m-auto mt-10 sm:w-screen-xl w-full">
|
||||
<div class="m-auto flex sm:flex-row flex-col sm:px-0 px-3">
|
||||
|
||||
9
tailwind.config.js
Normal file
9
tailwind.config.js
Normal file
@@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
theme: {
|
||||
extend: {
|
||||
screens: {
|
||||
'custom-breakpoint': '1400px',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -111,9 +111,9 @@ export function navTo(d?: any, path?: string,spm?: boolean){
|
||||
path = d?.path;
|
||||
}
|
||||
// 是否移动设备
|
||||
if(isMobileDevice()){
|
||||
path = '/m' + path;
|
||||
}
|
||||
// if(isMobileDevice()){
|
||||
// path = '/m' + path;
|
||||
// }
|
||||
// 国际化配置
|
||||
const i18n = useI18n();
|
||||
if(i18n.locale.value){
|
||||
@@ -169,3 +169,21 @@ export function loginAdminByToken(): void {
|
||||
export function getTimeStamp(): number {
|
||||
return new Date().getTime();
|
||||
}
|
||||
|
||||
// 复制文本
|
||||
export const copyText = (text: string) => {
|
||||
// 模拟 输入框
|
||||
const cInput = document.createElement('input');
|
||||
cInput.value = text;
|
||||
document.body.appendChild(cInput);
|
||||
cInput.select(); // 选取文本框内容
|
||||
|
||||
// 执行浏览器复制命令
|
||||
// 复制命令会将当前选中的内容复制到剪切板中(这里就是创建的input标签)
|
||||
// Input要在正常的编辑状态下原生复制方法才会生效
|
||||
ElMessage.success(`复制成功`);
|
||||
document.execCommand('copy');
|
||||
|
||||
// 复制成功后再将构造的标签 移除
|
||||
document.body.removeChild(cInput);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user