Browse Source

给url设计spm参数生成函数

master
科技小王子 8 months ago
parent
commit
1bd1f56375
  1. 6
      components/AppHeader.vue
  2. 8
      components/Breadcrumb.vue
  3. 5
      composables/configState.ts
  4. 34
      pages/a.vue
  5. 0
      pages/a/index.vue
  6. 5
      pages/article/detail/[id].vue
  7. 167
      pages/product/[detail].vue
  8. 117
      pages/product/[name].vue
  9. 75
      pages/product/index.vue
  10. 6
      pages/spm/[spm].vue

6
components/AppHeader.vue

@ -1,5 +1,5 @@
<template>
<header class="header bg-black fixed z-100 top-0 w-full">
<header class="header bg-black z-100 top-0 w-full" :class="affix ? 'absolute' : 'fixed'">
<div class="flex between md:w-3/4 m-auto px-2">
<div class="header__left flex">
<div class="logo mt-1 sm:w-[170px] py-2 flex items-center">
@ -88,7 +88,7 @@
<script setup lang="ts">
//
import {useConfigInfo, useMenu, useWebsite} from "~/composables/configState";
import {useConfigInfo, useMenu, useProductAffix, useWebsite} from "~/composables/configState";
import UnderMaintenance from "~/components/UnderMaintenance.vue";
const route = useRoute();
const website = useWebsite()
@ -96,6 +96,8 @@
const token = ref<string | undefined>(undefined);
const navigations = useMenu();
const config = useConfigInfo();
const affix = useProductAffix();
//
const visibleNumber = ref<number>(10);
// index

8
components/Breadcrumb.vue

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

5
composables/configState.ts

@ -23,4 +23,9 @@ export const useSubMenu = () =>
return [];
});
export const useProductAffix = () =>
useState<boolean>('affixTop', () => {
return false;
});
export const useToken = () => useState('token', () => 'token xxx');

34
pages/a.vue

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

0
pages/a/[id].vue → pages/a/index.vue

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

@ -30,9 +30,10 @@ import Breadcrumb from "~/components/Breadcrumb.vue";
import {getIdByParam} from "~/utils/common";
const route = useRoute();
const { params } = route;
const { params, query } = route;
const { id } = params;
const { spm } = query;
console.log('spm=', spm)
//
const form = ref<Article | any>();

167
pages/product/[detail].vue

@ -0,0 +1,167 @@
<template>
<el-affix :offset="0" @change="onAffix">
<div class="affix justify-between p-2 opacity-90 border-b-solid border-gray-200 border-b-1" :class="affix ? 'bg-white w-full' : 'hidden'">
<div class="w-3/4 m-auto flex justify-between">
<a class="goods-name text-xl font-bold cursor-pointer hover:text-gray-900">{{ goods?.goodsName }}</a>
<div class="affix-bar">
<el-anchor :offset="100" direction="horizontal" :marker="false">
<el-anchor-link :href="`#basic`">
参数信息
</el-anchor-link>
<el-anchor-link :href="`#photo`">
图文详情
</el-anchor-link>
<el-anchor-link :href="`#comment`">
用户评价
</el-anchor-link>
<el-anchor-link :href="`#buynow`">
<el-button type="danger" size="small">立即购买</el-button>
</el-anchor-link>
</el-anchor>
</div>
</div>
</div>
</el-affix>
<div id="buynow" class="flex flex-col w-full md:w-3/4 m-auto md:pt-[60px]" v-if="goods">
<Breadcrumb :data="goods" />
<div class="content bg-white rounded-xl">
<!-- <ProductShopInfo :data="goods?.merchant" />-->
<div id="buynow" 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" v-if="goods?.files">
<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>
<div class="goods-info flex flex-col gap-xs">
<div class="goods-name text-2xl">{{ goods.goodsName }}</div>
<div class="goods-price text-2xl red">{{ Number(goods?.salePrice) * Number(goods?.num) }}</div>
<div class="text-green-7">购买得积分</div>
<div class="text-gray-4">配送无需配送</div>
<div class="text-gray-4">保障假一赔四 退货包运费 极速退款</div>
<div class="text-gray-4">销量 {{ goods.sales }}</div>
<!-- <template v-for="spec in goods?.goodsSpecValue">-->
<!-- <div class="flex items-center">-->
<!-- <div class="text-gray-4">{{ spec.value }}</div>-->
<!-- <el-radio-group v-model="goods.radio">-->
<!-- <el-radio v-for="(specValue,specIndex) in spec.detail" :label="specIndex" border>{{ specValue }}</el-radio>-->
<!-- </el-radio-group>-->
<!-- </div>-->
<!-- </template>-->
<div class="text-gray-4">
已选中{{ goods.radio }}
</div>
<div class="text-gray-4">
数量
<el-input-number v-model="goods.num" :min="1" :max="10" label="描述文字"></el-input-number>
</div>
<div class="py-5">
<el-button-group size="large">
<el-button type="danger">立即购买</el-button>
<el-button type="warning">加入购物车</el-button>
</el-button-group>
<el-button size="large" class="ml-3">收藏</el-button>
</div>
</div>
</div>
</div>
<div id="basic" class="bg-white p-4 mt-4 flex gap-xl rounded-xl">
<el-descriptions class="margin-top" title="参数信息" :column="1" border>
<el-descriptions-item label="品牌">websoft</el-descriptions-item>
<el-descriptions-item label="版本">2.0</el-descriptions-item>
<el-descriptions-item label="开发语言">JavaVue3Nuxt</el-descriptions-item>
<el-descriptions-item label="版本">
<el-tag size="small">授权版</el-tag>
</el-descriptions-item>
<el-descriptions-item label="备注">江苏省苏州市吴中区吴中大道 1188 </el-descriptions-item>
</el-descriptions>
</div>
<div id="photo" class="bg-white p-4 mt-4 flex gap-xl rounded-xl flex-col">
<div class="font-bold">图文详情</div>
<div class="files flex flex-col w-3/4" v-if="goods?.files">
<el-image v-for="item in JSON.parse(goods.files)" :src="item.url" />
</div>
</div>
<div id="comment" class="bg-white p-4 mt-4 flex gap-xl rounded-xl">
<div class="font-bold">用户评价</div>
</div>
<div v-if="!goods">
<el-empty description="404 该商品找不到了222"></el-empty>
</div>
</div>
</template>
<script setup lang="ts">
import type {ApiResult} from "~/api";
import {useServerRequest} from "~/composables/useServerRequest";
import type {Goods} from "~/api/shop/goods/model";
import Breadcrumb from "~/components/Breadcrumb.vue";
import type {Navigation} from "~/api/cms/navigation/model";
import {useProductAffix} from "~/composables/configState";
const route = useRoute();
const affix = useProductAffix();
// ID
const goodsId = ref();
//
const form = ref<Navigation>();
//
const goods = ref<Goods>();
const onAffix = (index: boolean) => {
affix.value = index;
}
//
const reload = async () => {
// TODO
// const { data: nav } = await useServerRequest<ApiResult<Navigation>>('/cms/navigation/getNavigationByPath',{
// query: {
// path: goodsId.value
// }
// })
// if(nav.value?.data){
// form.value = nav.value.data;
// }
// TODO
console.log(goodsId.value,'sss')
const { data: info } = await useServerRequest<ApiResult<Goods>>('/shop/goods/' + goodsId.value)
goods.value = info.value?.data;
console.log(goods.value)
}
watch(
() => route.query.spm,
(spm) => {
console.log(spm)
// TODO spmID
const spmValue = String(spm).split('.')
if(spmValue[5]){
goodsId.value = spmValue[5];
}
console.log(goodsId.value)
// TODO ()paramsID
const { detail } = route.params
const split = String(detail).split('.');
if(Number(split[0]) > 0){
goodsId.value = split[0];
}
reload();
},
{ immediate: true }
);
</script>

117
pages/product/[name].vue

@ -1,117 +0,0 @@
<template>
<div class="flex flex-col w-full md:w-3/4 m-auto md:pt-[70px] pt-[60px]">
<Breadcrumb :data="form" />
<!-- <ProductShopInfo :data="goods?.merchant" />-->
<div class="bg-white p-4 mt-4 flex gap-xl rounded-xl" v-if="goods">
<div class="goods-image flex gap-xl">
<div class="gap-xs flex flex-col">
<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>
<div class="goods-info flex flex-col gap-xs">
<div class="goods-name text-2xl">{{ goods.goodsName }}</div>
<div class="goods-price text-2xl red">{{ goods?.salePrice * goods?.num }}</div>
<div class="text-green-7">购买得积分</div>
<div class="text-gray-4">配送无需配送</div>
<div class="text-gray-4">保障假一赔四 退货包运费 极速退款</div>
<div class="text-gray-4">销量 {{ goods.sales }}</div>
<template v-for="spec in goods.goodsSpecValue">
<div class="flex items-center">
<div class="text-gray-4">{{ spec.value }}</div>
<el-radio-group v-model="goods.radio">
<el-radio v-for="(specValue,specIndex) in spec.detail" :label="specIndex" border>{{ specValue }}</el-radio>
</el-radio-group>
</div>
</template>
<div class="text-gray-4">
已选中{{ goods.radio }}
</div>
<div class="text-gray-4">
数量
<el-input-number v-model="goods.num" @change="handleChange" :min="1" :max="10" label="描述文字"></el-input-number>
</div>
<div class="py-5">
<el-button-group size="large">
<el-button type="danger">立即购买</el-button>
<el-button type="warning">加入购物车</el-button>
</el-button-group>
<el-button size="large" class="ml-3">收藏</el-button>
</div>
</div>
</div>
<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>
<el-descriptions-item label="品牌">websoft</el-descriptions-item>
<el-descriptions-item label="版本">2.0</el-descriptions-item>
<el-descriptions-item label="开发语言">JavaVue3Nuxt</el-descriptions-item>
<el-descriptions-item label="版本">
<el-tag size="small">授权版</el-tag>
</el-descriptions-item>
<el-descriptions-item label="备注">江苏省苏州市吴中区吴中大道 1188 </el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="图文详情" name="content">
<div class="files flex flex-col w-3/4" v-if="goods?.files">
<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>
</el-tabs>
</div>
</div>
<div v-if="!form">
<el-empty description="404 页面不存在"></el-empty>
</div>
</template>
<script setup lang="ts">
import type {ApiResult} from "~/api";
import {useServerRequest} from "~/composables/useServerRequest";
import type {Goods} from "~/api/shop/goods/model";
import Breadcrumb from "~/components/Breadcrumb.vue";
import type {Navigation} from "~/api/cms/navigation/model";
const route = useRoute();
const { query, params } = route;
const { name: productName } = params;
const activeName = ref('parameter');
const rate = ref(4);
//
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;
goods.value.num = 1;
const handleClick = (tab, event) => {
console.log(tab, event);
}
</script>
<style scoped lang="scss">
</style>

75
pages/product/index.vue

@ -1,75 +0,0 @@
<template>
<!-- Banner -->
<Banner :data="form" />
<div class="container">
<div v-if="form" class="flex flex-col w-[1280px] m-auto">
<Breadcrumb :data="goods" />
<div class="w-7xl m-auto bg-white">
<div class="title text-3xl text-center py-10">{{ form.name }}</div>
<div class="p-4 leading-7" v-html="form.content">
</div>
</div>
</div>
</div>
<div v-if="!form">
<el-empty description="404 页面不存在"></el-empty>
</div>
</template>
<script setup lang="ts">
import type {Design} from "~/api/cms/design/model";
import type {ApiResult} from "~/api";
import {useServerRequest} from "~/composables/useServerRequest";
import {useConfigInfo, useToken} from "~/composables/configState";
import type {GoodsCategory} from "~/api/shop/goodsCategory/model";
import Breadcrumb from "~/components/Breadcrumb.vue";
const route = useRoute();
const { query, params } = route;
const pageName = window.location.pathname;
console.log(window.location.pathname,'pageName')
//
const config = useConfigInfo();
const token = useToken();
//
const form = ref<Design | any>();
//
const { data: design } = await useServerRequest<ApiResult<Design[]>>('/cms/design', {params: {
path: `${pageName}`
}})
if (design.value) {
design.value?.data?.map((d,i) => {
if(i == 0){
form.value = d;
console.log(d.name)
useHead({
title: `${d.name} 网宿软件`,
meta: [{ name: "keywords", content: "Nuxt Vue SSR Typescript" }],
bodyAttrs: {
class: "page-container",
},
script: [
{
children: "console.log('Hello World')",
},
],
});
}
})
}
const { data: category } = useServerRequest<ApiResult<GoodsCategory>>('/shop/goods-category')
console.log(category.value)
</script>
<style scoped lang="scss">
</style>

6
pages/test.vue → pages/spm/[spm].vue

@ -47,6 +47,12 @@ const movieList = ref<any>();
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
const route = useRoute();
const { params, query } = route;
const { spm } = query;
console.log(spm,'spm=')
//
const reload = async () => {
await nextTick()
Loading…
Cancel
Save