Browse Source

优化状态管理等

master
科技小王子 9 months ago
parent
commit
70996cb8b5
  1. 1
      api/cms/design/model/index.ts
  2. 45
      components/AppFooter.vue
  3. 33
      components/AppHeader.vue
  4. 5
      components/Banner.vue
  5. 40
      components/ProductShopInfo.vue
  6. 11
      composables/configState.ts
  7. 30
      layouts/default.vue
  8. 2
      pages/[custom]/index.vue
  9. 58
      pages/product/[name].vue

1
api/cms/design/model/index.ts

@ -37,6 +37,7 @@ export interface Design {
// 页面布局
layout?: string;
backgroundColor?: string;
buyUrl?: string;
}
/**

45
components/AppFooter.vue

@ -6,10 +6,39 @@
本站仅供测试和学习交流请大家支持正版
</div>
<footer>
<div class="w-full bg-gray-900 flex flex-col justify-between">
<div class="sub-menu w-full md:w-3/4 m-auto flex justify-between py-10 text-center p-2">
<!-- 底部菜单 -->
<div class="left flex justify-between gap-3xl w-8/12">
<template v-for="item in subMenu">
<div class="sub-menu-item text-left pr-10">
<div class="pb-4">
<text class="text-gray-500 hover:text-gray-400 font-bold text-[16px]">{{ item.title }}</text>
</div>
<template v-if="item.children">
<div class="sub-menu-children flex flex-col gap-xs">
<template v-for="sub in item.children">
<a :href="sub.path" class="text-gray-500 hover:text-gray-400">{{ sub.title }}</a>
</template>
</div>
</template>
</div>
</template>
</div>
<!-- 关注我们 -->
<div class="right w-3/12">
<el-image src="https://oss.wsdns.cn/20240327/f1175cc5aae741d3af05484747270bd5.jpeg" class="w-[100px]" />
</div>
</div>
<!-- 版权信息 -->
<div class="w-full md:w-3/4 m-auto flex justify-between py-10 text-center p-2">
<div class="text-gray-5 gap-xl flex">
<div class="text-gray-500 gap-xl flex">
<span>Copyright © {{ new Date().getFullYear() }} {{ config?.copyright }}</span>
<a class="text-gray-5" href="https://beian.miit.gov.cn/" target="_blank"> 备案号{{ config?.icpNo }}</a>
<a class="text-gray-500 hover:text-gray-400" href="https://beian.miit.gov.cn/" target="_blank"> 备案号{{ config?.icpNo }}</a>
</div>
</div>
</div>
</footer>
@ -19,20 +48,14 @@
<script setup lang="ts">
//
import {useConfigInfo} from "#imports";
import {useWebsite} from "~/composables/configState";
import {useSubMenu, useWebsite} from "~/composables/configState";
const config = useConfigInfo();
const website = useWebsite();
const subMenu = useSubMenu();
console.log('---------config---------',config.value)
console.log('---------website---------',website.value)
//
// const reload = async () => {
// const { data: fields } = await useServerRequest<ApiResult<Config>>('/cms/website-field/config', {})
// config.value = fields.value?.data;
// ElMessage.success('')
// }
//
// reload();
console.log('---------subMenu---------',subMenu.value)
</script>
<style lang="scss">

33
components/AppHeader.vue

@ -94,14 +94,14 @@
import type {ApiResult, PageResult} from '~/api';
import type { Navigation } from '~/api/cms/navigation/model';
import { useServerRequest } from '~/composables/useServerRequest';
import {useConfigInfo} from "~/composables/configState";
import {useConfigInfo, useMenu} from "~/composables/configState";
import {listDomain} from "~/api/cms/domain";
import type {Domain} from "~/api/cms/domain/model";
const route = useRoute();
const searchValue = ref<string>();
const token = ref<string | undefined>(undefined);
const navigations = ref<Navigation[] | any>([]);
const navigations = useMenu();
const config = useConfigInfo();
//
const visibleNumber = ref<number>(10);
@ -130,28 +130,25 @@ import type {Domain} from "~/api/cms/domain/model";
};
function handleSelect(key: string, keyPath: any) {
console.log(key,'key')
console.log(keyPath,'keyPath')
currentIndex.value = key;
navigateTo(`${key}`);
}
//
const reload = async () => {
await nextTick();
const { data: fields } = await useServerRequest<ApiResult<Config>>('/cms/website-field/config', {});
if (fields.value?.data) {
config.value = fields.value.data;
}
const { data: navigation } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', {
query: {
position: 1
}
});
navigations.value = navigation.value?.data;
};
// const reload = async () => {
// await nextTick();
// const { data: fields } = await useServerRequest<ApiResult<Config>>('/cms/website-field/config', {});
// if (fields.value?.data) {
// config.value = fields.value.data;
// }
// const { data: navigation } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', {
// query: {
// position: 1
// }
// });
// };
reload();
// reload();
</script>
<style lang="scss">

5
components/Banner.vue

@ -6,7 +6,10 @@
<div class="banner-text py-12 md:w-3/4 m-auto opacity-90 flex flex-col justify-center">
<div class="keywords my-4 text-5xl">{{ data.design?.name }}</div>
<div class="description my-4 text-2xl max-w-3xl text-gray-600">{{ data.design?.description }}</div>
<div class="description text-sm max-w-xl text-gray-600">{{ data.design?.keywords }}</div>
<!-- <div class="description text-sm max-w-xl text-gray-600">{{ data.design?.keywords }}</div>-->
<div class="buy-btn" v-if="data?.design?.buyUrl">
<el-button @click="navigateTo(data.design.buyUrl)" type="primary">立即购买</el-button>
</div>
</div>
</div>
</template>

40
components/ProductShopInfo.vue

@ -0,0 +1,40 @@
<template>
<div class="bg-white p-3 mt-3 flex items-center justify-between rounded-xl">
<div class="left flex gap-xs items-center">
<el-avatar shape="square" :src="data?.image" :size="55" />
<div class="shop-name flex flex-col">
<div class="shop-name cursor-pointer">
<div class="flex items-center">
<text class="text-xl">{{ data?.merchantName }}</text>
<el-tag type="success" size="small" class="ml-2">官网</el-tag>
</div>
</div>
<el-rate
v-model="rate"
show-score
text-color="#ff9900"
score-template="{value}">
</el-rate>
</div>
</div>
<el-button>进入店铺</el-button>
</div>
</template>
<script setup lang="ts">
import type {Navigation} from "~/api/cms/navigation/model";
import type {Merchant} from "~/api/shop/merchant/model";
withDefaults(
defineProps<{
data?: Merchant;
}>(),
{}
);
const rate = ref(5);
</script>
<style scoped lang="scss">
</style>

11
composables/configState.ts

@ -1,6 +1,7 @@
import { useState } from '#imports';
import type { Config } from '~/types/global';
import type {Website} from "~/api/cms/website/model";
import type {Navigation} from "~/api/cms/navigation/model";
export const useWebsite = () =>
useState<Website>('website', () => {
@ -12,4 +13,14 @@ export const useConfigInfo = () =>
return {};
});
export const useMenu = () =>
useState<Navigation[]>('menu', () => {
return [];
});
export const useSubMenu = () =>
useState<Navigation[]>('subMenu', () => {
return [];
});
export const useToken = () => useState('token', () => 'token xxx');

30
layouts/default.vue

@ -9,8 +9,10 @@
import {useServerRequest} from "~/composables/useServerRequest";
import type {ApiResult} from "~/api";
import type {Domain} from "~/api/cms/domain/model";
import {useWebsite} from "~/composables/configState";
import {useConfigInfo, useMenu, useSubMenu, useWebsite} from "~/composables/configState";
import type {Website} from "~/api/cms/website/model";
import type {Navigation} from "~/api/cms/navigation/model";
import type {Config} from "~/types/global";
// TODO 1 ,ID
localStorage.removeItem('TID_DOMAIN');
@ -42,6 +44,32 @@
}
// TODO 4
const config = useConfigInfo();
const { data: fields } = await useServerRequest<ApiResult<Config>>('/cms/website-field/config', {});
if (fields.value?.data) {
config.value = fields.value?.data;
}
// TODO 5
const menu = useMenu()
const { data: menuInfo } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', {
query: {
position: 1
}
});
if(menuInfo.value?.data){
menu.value = menuInfo.value?.data
}
// TODO 6
const subMenu = useSubMenu()
const { data: subMenuInfo } = await useServerRequest<ApiResult<Navigation[]>>('/cms/navigation/tree', {
query: {
position: 2
}
});
if(subMenuInfo.value?.data){
subMenu.value = subMenuInfo.value?.data
}
</script>

2
pages/[custom]/index.vue

@ -40,7 +40,7 @@ const breadcrumb = ref<BreadcrumbItem>();
//
const { data: nav } = await useServerRequest<ApiResult<Navigation>>('/cms/navigation/getNavigationByPath',{
query: {
path
path: '/' + path
}
})

58
pages/product/[name].vue

@ -1,34 +1,14 @@
<template>
<!-- Banner -->
<Banner :data="form" />
<div class="flex flex-col w-full md:w-3/4 m-auto pt-[70px]">
<div v-if="goods" class="flex flex-col w-full md:w-3/4 m-auto my-3">
<Breadcrumb :data="goods" />
<div class="bg-white p-3 mt-3 flex items-center justify-between">
<div class="left flex gap-xs items-center">
<el-avatar shape="square" :size="55" />
<div class="shop-name flex flex-col">
<div class="shop-name cursor-pointer">
<div class="flex items-center">
<text class="text-xl">南宁市网宿信息科技有限公司</text>
<el-tag type="success" size="small" class="ml-2">官网</el-tag>
</div>
</div>
<el-rate
v-model="rate"
show-score
text-color="#ff9900"
score-template="{value}">
</el-rate>
</div>
</div>
<el-button>进入店铺</el-button>
</div>
<Breadcrumb :data="form" />
<div class="bg-white p-4 mt-4 flex gap-xl">
<ProductShopInfo :data="goods?.merchant" />
<div class="bg-white p-4 mt-4 flex gap-xl rounded-xl">
<div class="goods-image flex gap-xl">
<div class="gap-xs flex flex-col">
<el-avatar v-for="item in goods.files" :src="item.url" size="large" shape="square" />
<el-avatar v-for="item in JSON.parse(goods.files)" :src="item.url" size="large" shape="square" />
</div>
<el-image :src="goods.image" fit="contain" class="w-2xl h-2xl bg-gray-100 border-radius:30px"></el-image>
</div>
@ -63,7 +43,7 @@
</div>
</div>
</div>
<div class="content p-4 bg-white">
<div class="content p-4 bg-white mt-4 rounded-xl">
<el-tabs v-model="activeName" :lazy="true" @tab-click="handleClick">
<el-tab-pane label="参数信息" name="parameter">
<el-descriptions class="margin-top" title="参数信息" :column="1" border>
@ -78,7 +58,7 @@
</el-tab-pane>
<el-tab-pane label="图文详情" name="content">
<div class="files flex flex-col w-3/4">
<el-image v-for="item in goods.files" :src="item.url" />
<el-image v-for="item in JSON.parse(goods.files)" :src="item.url" />
</div>
</el-tab-pane>
<el-tab-pane label="用户评价" name="reviews">用户评价</el-tab-pane>
@ -94,6 +74,7 @@ import type {ApiResult} from "~/api";
import {useServerRequest} from "~/composables/useServerRequest";
import type {Goods} from "~/api/shop/goods/model";
import Breadcrumb from "~/components/Breadcrumb.vue";
import type {Navigation} from "~/api/cms/navigation/model";
const route = useRoute();
const { query, params } = route;
@ -103,17 +84,26 @@ const rate = ref(4);
//
const form = ref<Goods | any>();
const form = ref<Navigation>();
//
const goods = ref<Goods>();
//
// TODO
const pathName = window.location.pathname;
console.log(pathName)
const split = pathName.split('/');
const { data: nav } = await useServerRequest<ApiResult<Navigation>>('/cms/navigation/getNavigationByPath',{
query: {
path: pathName
}
})
if(nav.value?.data){
form.value = nav.value.data;
}
// TODO
const { data: info } = await useServerRequest<ApiResult<Goods>>('/shop/goods/' + productName)
goods.value = info.value?.data;
// form.value.files = JSON.parse(form.value.files);
// form.value.num = 1;
// form.value.radio = '0'
const handleClick = (tab, event) => {

Loading…
Cancel
Save