style: css修改; fix: 详情页面显示 空字段修改,eslint修改
This commit is contained in:
parent
61d98f78b0
commit
bb958ce2fe
7
components.d.ts
vendored
7
components.d.ts
vendored
@ -1,8 +1,11 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
// biome-ignore lint: disable
|
||||
// oxlint-disable
|
||||
// ------
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
// biome-ignore lint: disable
|
||||
|
||||
export {}
|
||||
|
||||
/* prettier-ignore */
|
||||
@ -20,6 +23,7 @@ declare module 'vue' {
|
||||
VanNoticeBar: typeof import('vant/es')['NoticeBar']
|
||||
VanPopover: typeof import('vant/es')['Popover']
|
||||
VanPopup: typeof import('vant/es')['Popup']
|
||||
VanRate: typeof import('vant/es')['Rate']
|
||||
VanSearch: typeof import('vant/es')['Search']
|
||||
VanStepper: typeof import('vant/es')['Stepper']
|
||||
VanSwipe: typeof import('vant/es')['Swipe']
|
||||
@ -27,5 +31,6 @@ declare module 'vue' {
|
||||
VanSwitch: typeof import('vant/es')['Switch']
|
||||
VanTab: typeof import('vant/es')['Tab']
|
||||
VanTabs: typeof import('vant/es')['Tabs']
|
||||
VanUploader: typeof import('vant/es')['Uploader']
|
||||
}
|
||||
}
|
||||
|
||||
15
env.d.ts
vendored
15
env.d.ts
vendored
@ -1 +1,16 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import type { Component } from 'vue'
|
||||
const component: Component
|
||||
export default component
|
||||
}
|
||||
|
||||
declare module '*.css'
|
||||
declare module '*.scss'
|
||||
declare module '*.sass'
|
||||
declare module '*.less'
|
||||
declare module '*.png'
|
||||
declare module '*.jpg'
|
||||
declare module '*.jpeg'
|
||||
declare module '*.svg'
|
||||
|
||||
@ -2,31 +2,34 @@ import { globalIgnores } from 'eslint/config'
|
||||
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
|
||||
import pluginVue from 'eslint-plugin-vue'
|
||||
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'
|
||||
const path = require('path')
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
// To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
|
||||
// import { configureVueProject } from '@vue/eslint-config-typescript'
|
||||
// configureVueProject({ scriptLangs: ['ts', 'tsx'] })
|
||||
// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup
|
||||
const tsconfigRootDir = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
export default defineConfigWithVueTs(
|
||||
{
|
||||
name: 'app/files-to-lint',
|
||||
files: ['**/*.{ts,mts,tsx,vue}'],
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
sconfigRootDir: path.resolve(__dirname),
|
||||
project: './tsconfig.json',
|
||||
requireConfigFile: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ name: 'app/files-to-lint', files: ['**/*.{ts,mts,tsx,vue}'] },
|
||||
|
||||
|
||||
|
||||
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
|
||||
|
||||
pluginVue.configs['flat/essential'],
|
||||
vueTsConfigs.recommended,
|
||||
skipFormatting,
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
tsconfigRootDir,
|
||||
project: ['./tsconfig.json'],
|
||||
extraFileExtensions: ['.vue']
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-empty-object-type': 'off',
|
||||
'@typescript-eslint/no-unused-expressions': 'off',
|
||||
'vue/multi-word-component-names': 'off'
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vite App</title>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
4396
pnpm-lock.yaml
generated
Normal file
4396
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
46
src/api/types/shop.ts
Normal file
46
src/api/types/shop.ts
Normal file
@ -0,0 +1,46 @@
|
||||
export type PrDetailType = {
|
||||
adminCategoryId1: 146
|
||||
adminCategoryId2: 147
|
||||
appCategoryId1: 48
|
||||
appCategoryId2: 56
|
||||
createTime: 1762760434000
|
||||
defaultSort: 0
|
||||
frontPage: 1
|
||||
id: 73
|
||||
isDelete: 0
|
||||
isFlash: 0
|
||||
isNew: 1
|
||||
isTest: 0
|
||||
mainImageUrl: 'https://heyuimage.ihzhy.com/prd/202511/9a77567562f87caf.jpg?key=xxxxxxx'
|
||||
modifyTime: 1762760434000
|
||||
realSaleCount: 0
|
||||
showPromotionPrice: 0
|
||||
showSaleCount: 0
|
||||
showSalePrice: 0
|
||||
status: 'online'
|
||||
title: 'Akoya双珠海水戒指'
|
||||
vvSkuList: SkuType[]
|
||||
vvProductDetailList: []
|
||||
vvProductPropertyList: []
|
||||
}
|
||||
|
||||
export type SkuType = {
|
||||
createTime: number
|
||||
id: 364
|
||||
isDelete: 0
|
||||
modifyTime: 1762760434000
|
||||
productId: 73
|
||||
promotionPrice: 0
|
||||
showSaleCount: 0
|
||||
stock: 0
|
||||
}
|
||||
|
||||
export type ProductDetailImagesType = {
|
||||
createTime: 1762760434000
|
||||
detail: 'https://heyuimage.ihzhy.com/prd/202511/304182481ebfc9ab.jpg?key=xxxxxxx'
|
||||
id: 187
|
||||
isDelete: 0
|
||||
modifyTime: 1762760434000
|
||||
productId: 73
|
||||
type: 1
|
||||
}
|
||||
128
src/auto-import.d.ts
vendored
128
src/auto-import.d.ts
vendored
@ -6,70 +6,70 @@
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
const customRef: typeof import('vue')['customRef']
|
||||
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||
const defineComponent: typeof import('vue')['defineComponent']
|
||||
const effectScope: typeof import('vue')['effectScope']
|
||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||
const getCurrentWatcher: typeof import('vue')['getCurrentWatcher']
|
||||
const h: typeof import('vue')['h']
|
||||
const inject: typeof import('vue')['inject']
|
||||
const isProxy: typeof import('vue')['isProxy']
|
||||
const isReactive: typeof import('vue')['isReactive']
|
||||
const isReadonly: typeof import('vue')['isReadonly']
|
||||
const isRef: typeof import('vue')['isRef']
|
||||
const isShallow: typeof import('vue')['isShallow']
|
||||
const markRaw: typeof import('vue')['markRaw']
|
||||
const nextTick: typeof import('vue')['nextTick']
|
||||
const onActivated: typeof import('vue')['onActivated']
|
||||
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
|
||||
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
|
||||
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||
const onMounted: typeof import('vue')['onMounted']
|
||||
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||
const onUpdated: typeof import('vue')['onUpdated']
|
||||
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
|
||||
const provide: typeof import('vue')['provide']
|
||||
const reactive: typeof import('vue')['reactive']
|
||||
const readonly: typeof import('vue')['readonly']
|
||||
const ref: typeof import('vue')['ref']
|
||||
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
const showToast: typeof import('vant/es')['showToast']
|
||||
const toRaw: typeof import('vue')['toRaw']
|
||||
const toRef: typeof import('vue')['toRef']
|
||||
const toRefs: typeof import('vue')['toRefs']
|
||||
const toValue: typeof import('vue')['toValue']
|
||||
const triggerRef: typeof import('vue')['triggerRef']
|
||||
const unref: typeof import('vue')['unref']
|
||||
const useAttrs: typeof import('vue')['useAttrs']
|
||||
const useCssModule: typeof import('vue')['useCssModule']
|
||||
const useCssVars: typeof import('vue')['useCssVars']
|
||||
const useId: typeof import('vue')['useId']
|
||||
const useLink: typeof import('vue-router')['useLink']
|
||||
const useModel: typeof import('vue')['useModel']
|
||||
const useRoute: typeof import('vue-router')['useRoute']
|
||||
const useRouter: typeof import('vue-router')['useRouter']
|
||||
const useSlots: typeof import('vue')['useSlots']
|
||||
const useTemplateRef: typeof import('vue')['useTemplateRef']
|
||||
const watch: typeof import('vue')['watch']
|
||||
const watchEffect: typeof import('vue')['watchEffect']
|
||||
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
|
||||
const EffectScope: typeof import('vue').EffectScope
|
||||
const computed: typeof import('vue').computed
|
||||
const createApp: typeof import('vue').createApp
|
||||
const customRef: typeof import('vue').customRef
|
||||
const defineAsyncComponent: typeof import('vue').defineAsyncComponent
|
||||
const defineComponent: typeof import('vue').defineComponent
|
||||
const effectScope: typeof import('vue').effectScope
|
||||
const getCurrentInstance: typeof import('vue').getCurrentInstance
|
||||
const getCurrentScope: typeof import('vue').getCurrentScope
|
||||
const getCurrentWatcher: typeof import('vue').getCurrentWatcher
|
||||
const h: typeof import('vue').h
|
||||
const inject: typeof import('vue').inject
|
||||
const isProxy: typeof import('vue').isProxy
|
||||
const isReactive: typeof import('vue').isReactive
|
||||
const isReadonly: typeof import('vue').isReadonly
|
||||
const isRef: typeof import('vue').isRef
|
||||
const isShallow: typeof import('vue').isShallow
|
||||
const markRaw: typeof import('vue').markRaw
|
||||
const nextTick: typeof import('vue').nextTick
|
||||
const onActivated: typeof import('vue').onActivated
|
||||
const onBeforeMount: typeof import('vue').onBeforeMount
|
||||
const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
|
||||
const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
|
||||
const onBeforeUnmount: typeof import('vue').onBeforeUnmount
|
||||
const onBeforeUpdate: typeof import('vue').onBeforeUpdate
|
||||
const onDeactivated: typeof import('vue').onDeactivated
|
||||
const onErrorCaptured: typeof import('vue').onErrorCaptured
|
||||
const onMounted: typeof import('vue').onMounted
|
||||
const onRenderTracked: typeof import('vue').onRenderTracked
|
||||
const onRenderTriggered: typeof import('vue').onRenderTriggered
|
||||
const onScopeDispose: typeof import('vue').onScopeDispose
|
||||
const onServerPrefetch: typeof import('vue').onServerPrefetch
|
||||
const onUnmounted: typeof import('vue').onUnmounted
|
||||
const onUpdated: typeof import('vue').onUpdated
|
||||
const onWatcherCleanup: typeof import('vue').onWatcherCleanup
|
||||
const provide: typeof import('vue').provide
|
||||
const reactive: typeof import('vue').reactive
|
||||
const readonly: typeof import('vue').readonly
|
||||
const ref: typeof import('vue').ref
|
||||
const resolveComponent: typeof import('vue').resolveComponent
|
||||
const shallowReactive: typeof import('vue').shallowReactive
|
||||
const shallowReadonly: typeof import('vue').shallowReadonly
|
||||
const shallowRef: typeof import('vue').shallowRef
|
||||
const showToast: typeof import('vant/es').showToast
|
||||
const toRaw: typeof import('vue').toRaw
|
||||
const toRef: typeof import('vue').toRef
|
||||
const toRefs: typeof import('vue').toRefs
|
||||
const toValue: typeof import('vue').toValue
|
||||
const triggerRef: typeof import('vue').triggerRef
|
||||
const unref: typeof import('vue').unref
|
||||
const useAttrs: typeof import('vue').useAttrs
|
||||
const useCssModule: typeof import('vue').useCssModule
|
||||
const useCssVars: typeof import('vue').useCssVars
|
||||
const useId: typeof import('vue').useId
|
||||
const useLink: typeof import('vue-router').useLink
|
||||
const useModel: typeof import('vue').useModel
|
||||
const useRoute: typeof import('vue-router').useRoute
|
||||
const useRouter: typeof import('vue-router').useRouter
|
||||
const useSlots: typeof import('vue').useSlots
|
||||
const useTemplateRef: typeof import('vue').useTemplateRef
|
||||
const watch: typeof import('vue').watch
|
||||
const watchEffect: typeof import('vue').watchEffect
|
||||
const watchPostEffect: typeof import('vue').watchPostEffect
|
||||
const watchSyncEffect: typeof import('vue').watchSyncEffect
|
||||
}
|
||||
// for type re-export
|
||||
declare global {
|
||||
|
||||
17
src/hooks/web/useDesign.ts
Normal file
17
src/hooks/web/useDesign.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import variables from "@/styles/variables.module.scss";
|
||||
|
||||
export const useDesign = () => {
|
||||
const lessVariables = variables;
|
||||
|
||||
/**
|
||||
* @param scope 类名
|
||||
* @returns 返回空间名-类名
|
||||
*/
|
||||
const getPrefixCls = (scope: string) => {
|
||||
return `${lessVariables.namespace}-${scope}`;
|
||||
};
|
||||
return {
|
||||
variables: lessVariables,
|
||||
getPrefixCls,
|
||||
};
|
||||
};
|
||||
@ -12,6 +12,7 @@ import App from './App.vue'
|
||||
import router from './router'
|
||||
import GetUserInfo from './utils/getUserInfo'
|
||||
|
||||
import '@/styles/index.scss'
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(createPinia().use(piniaPluginPersistedstate))
|
||||
@ -19,6 +20,8 @@ app.use(router)
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
!location.host.startsWith('app') && new VConsole()
|
||||
if (!location.host.startsWith('app')) {
|
||||
new VConsole()
|
||||
}
|
||||
|
||||
GetUserInfo.getInstance()
|
||||
|
||||
@ -6,58 +6,85 @@ const router = createRouter({
|
||||
{
|
||||
path: '/demo',
|
||||
name: 'demo',
|
||||
meta: {
|
||||
title: "测试入口"
|
||||
},
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/demo/index.vue'),
|
||||
component: () => import('@/views/demo/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/commodity-detail',
|
||||
name: 'commodity-detail',
|
||||
meta: {
|
||||
title: "商品详情",
|
||||
section: "/commodity"
|
||||
},
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/commodity-detail/index.vue'),
|
||||
component: () => import('@/views/commodity-detail/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/order',
|
||||
name: 'order',
|
||||
meta: {
|
||||
title: "我的订单",
|
||||
section: "/order"
|
||||
},
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/order/index.vue'),
|
||||
component: () => import('@/views/order/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/order/detail',
|
||||
name: 'order/detail',
|
||||
meta: {
|
||||
title: "订单详情",
|
||||
section: "/order"
|
||||
},
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/order/detail.vue'),
|
||||
component: () => import('@/views/order/detail.vue'),
|
||||
},
|
||||
{
|
||||
path: '/search-container',
|
||||
name: 'search-container',
|
||||
meta: {
|
||||
title: "搜索",
|
||||
section: "/search"
|
||||
},
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/search-container/index.vue'),
|
||||
component: () => import('@/views/search-container/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/review/center',
|
||||
name: 'review/center',
|
||||
meta: {
|
||||
title: "评价中心",
|
||||
section: "/review"
|
||||
},
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/review/center.vue'),
|
||||
component: () => import('@/views/review/center.vue'),
|
||||
},
|
||||
{
|
||||
path: '/review/write',
|
||||
name: 'review/write',
|
||||
meta: {
|
||||
title: "填写评价",
|
||||
section: "/review"
|
||||
},
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/review/write.vue'),
|
||||
component: () => import('@/views/review/write.vue'),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
0
src/styles/app.scss
Normal file
0
src/styles/app.scss
Normal file
0
src/styles/color.scss
Normal file
0
src/styles/color.scss
Normal file
0
src/styles/common.scss
Normal file
0
src/styles/common.scss
Normal file
1
src/styles/index.scss
Normal file
1
src/styles/index.scss
Normal file
@ -0,0 +1 @@
|
||||
@import './var.scss'
|
||||
4
src/styles/var.scss
Normal file
4
src/styles/var.scss
Normal file
@ -0,0 +1,4 @@
|
||||
:root{
|
||||
--app-footer-bg-height: 40px;
|
||||
--app-footer-bg-color: #fff;
|
||||
}
|
||||
12
src/styles/variables.module.scss
Normal file
12
src/styles/variables.module.scss
Normal file
@ -0,0 +1,12 @@
|
||||
// 命名空间
|
||||
$namespace: v;
|
||||
// el命名空间
|
||||
$elNamespace: vant;
|
||||
|
||||
// 主色调
|
||||
$colorPrimary: #3e7bfb;
|
||||
|
||||
:export {
|
||||
namespace: #{$namespace};
|
||||
elNamespace: #{$elNamespace};
|
||||
}
|
||||
@ -5,8 +5,8 @@
|
||||
<div class="mb-8">
|
||||
<div class="cart-wrap">
|
||||
<p class="flex justify-between" @click="showAddressList = true">
|
||||
<van-icon name="location-o" class="mr-1" /><span class="max-w-12 mr-1">{{ curAddressData.buyerName }}</span>
|
||||
<b class="font- flex-1">{{ curAddressData.province + curAddressData.city + curAddressData.district + curAddressData.detail }}</b
|
||||
<van-icon name="location-o" class="mr-1" /><span class="max-w-12 mr-1">{{ curAddressData?.buyerName }}</span>
|
||||
<b class="font- flex-1">{{ (curAddressData?.province ?? '') + (curAddressData?.city ?? '') + (curAddressData?.district ?? '') + (curAddressData?.detail?? '') }}</b
|
||||
><van-icon name="arrow" />
|
||||
</p>
|
||||
</div>
|
||||
@ -15,7 +15,7 @@
|
||||
<img class="w-16 h-16 mr-4" style="border-radius: 0.04rem" :src="curPageData.imageUrl" alt="" />
|
||||
<div>
|
||||
<p>
|
||||
¥<span>{{ curPageData.price }}</span>
|
||||
¥<span>{{ curPageData?.price }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<van-stepper v-model="formData.num" input-width=".4rem" button-size=".2rem" min="1" :max="curPageData.num" />
|
||||
@ -27,12 +27,12 @@
|
||||
<h4>{{ key }}</h4>
|
||||
<div class="cagetory">
|
||||
<p
|
||||
v-for="item in arr"
|
||||
:key="item.propertyId"
|
||||
:class="{ 'theme-border-color theme-color': item.propertyId === curPropertyIds.find((it) => it.productPropertyName === key).id }"
|
||||
@click="onChooseProperty(item, key)"
|
||||
v-for="v in arr"
|
||||
:key="v.propertyId"
|
||||
:class="{ 'theme-border-color theme-color': v.propertyId === curPropertyIds.find((it) => it.productPropertyName === key).id }"
|
||||
@click="onChooseProperty(v, key)"
|
||||
>
|
||||
{{ item.label }}
|
||||
{{ v?.label }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
@ -52,12 +52,12 @@ import { requestPayment } from '@/utils/wx-minprogram'
|
||||
|
||||
const model = defineModel<boolean>()
|
||||
const showAddressList = defineModel<boolean>('showAddressList')
|
||||
const props = defineProps<{ list: any[]; curAddressData: Recordable<any>; scene: 'order' | 'cart' }>()
|
||||
const skuData = ref({}) // sku分类,key为属性的类目,value为属性的分类{ 颜色: [{ '黄色'}]}
|
||||
const commodityData = ref({}) // 商品对象, value为每种商品的skuId,图片,销售价,成交价,库存(key为属性id的集合)
|
||||
const curPropertyIds = ref([]) // 当前选中的属性id的集合[{ id: 1, name: '颜色'},{id: 2, name: '重量'}] name是用来赋值的
|
||||
const curPageData = ref({ price: '', imageUrl: '', num: 0 }) // 当前商品页面数据
|
||||
const formData = ref({ skuId: NaN, num: 1 })
|
||||
const props = defineProps<{ list: Array<any>; curAddressData: Recordable<any>; scene: 'order' | 'cart' }>()
|
||||
const skuData = ref<any>({}) // sku分类,key为属性的类目,value为属性的分类{ 颜色: [{ '黄色'}]}
|
||||
const commodityData = ref<any>({}) // 商品对象, value为每种商品的skuId,图片,销售价,成交价,库存(key为属性id的集合)
|
||||
const curPropertyIds = ref<any>([]) // 当前选中的属性id的集合[{ id: 1, name: '颜色'},{id: 2, name: '重量'}] name是用来赋值的
|
||||
const curPageData = ref<any>({ price: '', imageUrl: '', num: 0 }) // 当前商品页面数据
|
||||
const formData = ref<any>({ skuId: NaN, num: 1 })
|
||||
|
||||
watch(model, (val) => {
|
||||
if (val) {
|
||||
@ -93,15 +93,15 @@ const handleGetSkuList = (list: any[]) => {
|
||||
return { result, commodityMap, firstShopIds }
|
||||
}
|
||||
|
||||
const onChooseProperty = (item, categoryName) => {
|
||||
curPropertyIds.value.find((it) => it.productPropertyName === categoryName).id = item.propertyId
|
||||
const onChooseProperty = (v, categoryName) => {
|
||||
curPropertyIds.value.find((it) => it.productPropertyName === categoryName).id = v.propertyId
|
||||
const { pageData, skuId } = handleGetPageData(commodityData.value, curPropertyIds.value)
|
||||
curPageData.value = pageData
|
||||
formData.value = { skuId, num: 1 }
|
||||
}
|
||||
const handleGetPageData = (commodityData, curPropertyIds) => {
|
||||
const data = commodityData[curPropertyIds.map((item) => item.id).join('_')]
|
||||
return { pageData: { price: data.price, imageUrl: data.imageUrl, num: data.num }, skuId: data.id }
|
||||
return { pageData: { price: data?.price, imageUrl: data?.imageUrl, num: data?.num }, skuId: data?.id }
|
||||
}
|
||||
|
||||
const onSubmit = async () => {
|
||||
0
src/views/commodity-detail/components/types.ts
Normal file
0
src/views/commodity-detail/components/types.ts
Normal file
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div id="commodity-detail">
|
||||
<div id="commodity-detail" :class="[prefixCls]">
|
||||
<header class="h-70 bg-[#aaa]">
|
||||
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
|
||||
<van-swipe-item><img class="h-full w-full" :src="detail.mainImg" alt="" /></van-swipe-item>
|
||||
@ -25,7 +25,7 @@
|
||||
<b>用户评价({{ reviews.length }}+)</b><span @click="onShowAllReview">全部评价 ></span>
|
||||
</h3>
|
||||
<div class="mt-5">
|
||||
<review-single :data="reviews[0]" />
|
||||
<review-single v-if="reviews.length > 0" :data="reviews[0]" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap">
|
||||
@ -44,7 +44,7 @@
|
||||
<instruction-info class="mt3" />
|
||||
</div>
|
||||
</main>
|
||||
<footer class="flex fixed bottom-0 left-0 w-full h-10 justify-between items-center pr-2 box-border bg-white">
|
||||
<footer class="flex fixed bottom-0 left-0 w-full h-[--app-footer-bg-height] justify-between items-center pr-2 box-border bg-[var(--app-footer-bg-color)]">
|
||||
<div class="flex items-center w-[1.4rem] justify-around">
|
||||
<p class="icon-wrap">
|
||||
<van-icon name="phone-o" size=".14rem" />
|
||||
@ -83,11 +83,17 @@
|
||||
import api from '@/api'
|
||||
import allReview from './components/all-review.vue'
|
||||
import reviewSingle from './components/review-single.vue'
|
||||
import infoTable from './components/info-table.vue'
|
||||
// import infoTable from './components/info-table.vue'
|
||||
import instructionInfo from './components/instruction-info.vue'
|
||||
import shoppingCart from './components/shopping-cart.vue'
|
||||
import shoppingCart from './components/shopping-cart.vue'
|
||||
import addressList from './components/address-list.vue'
|
||||
import addressForm from './components/address-form.vue'
|
||||
import { useDesign } from '@/hooks/web/useDesign.ts'
|
||||
|
||||
|
||||
const { getPrefixCls } = useDesign()
|
||||
|
||||
const prefixCls = getPrefixCls("commodity-detail")
|
||||
|
||||
const detail = reactive({
|
||||
mainImg: '',
|
||||
@ -97,15 +103,15 @@ const detail = reactive({
|
||||
title: '',
|
||||
})
|
||||
|
||||
const showShopCart = ref(false) // 展示购物车
|
||||
const showShopCart = ref<boolean>(false) // 展示购物车
|
||||
const cartType = ref<'order' | 'cart'>('order')
|
||||
const showAllReview = ref(false) // 展示全部评价
|
||||
const showAddressList = ref(false) // 展示收货地址列表
|
||||
const showAddAddressFormDialog = ref(false) // 展示收货地址form
|
||||
const showAllReview = ref<boolean>(false) // 展示全部评价
|
||||
const showAddressList = ref<boolean>(false) // 展示收货地址列表
|
||||
const showAddAddressFormDialog = ref<boolean>(false) // 展示收货地址form
|
||||
const addressFormType = ref<'add' | 'edit'>('add')
|
||||
const isUpDateAddressList = ref(false) // 是否需要更新收货地址列表
|
||||
const editAddressData = ref({}) // 编辑的收货地址
|
||||
const curAddressData = ref({}) // 当前选中的收货地址
|
||||
const isUpDateAddressList = ref<boolean>(false) // 是否需要更新收货地址列表
|
||||
const editAddressData = ref<any>({}) // 编辑的收货地址
|
||||
const curAddressData = ref<any>({}) // 当前选中的收货地址
|
||||
|
||||
const route = useRoute()
|
||||
const init = () => {
|
||||
@ -137,6 +143,8 @@ const skuList = ref([])
|
||||
// 获取商品详情
|
||||
const handleGetCommodityDetail = (productId: number) => {
|
||||
api.shop.getCommodityDetail.post<any>({ productId }).then((res) => {
|
||||
|
||||
|
||||
detail.mainImg = res.data.mainImageUrl
|
||||
detail.video = res.data.videoUrl
|
||||
detail.subImgs = res.data.vvProductDetailList.filter((item) => item.type === 1)?.map((item) => item.detail)
|
||||
@ -155,6 +163,12 @@ init()
|
||||
</script>
|
||||
|
||||
<style scope lang="scss">
|
||||
|
||||
$prefix-cls: #{$namespace}-commodity-detail;
|
||||
.#{$prefix-cls} {
|
||||
padding-bottom: calc(var(--app-footer-bg-height) + 10px);
|
||||
}
|
||||
|
||||
#commodity-detail {
|
||||
background: #f2f2f2;
|
||||
.my-swipe {
|
||||
|
||||
@ -57,6 +57,7 @@ const orderDetail = ref({
|
||||
#order-detail {
|
||||
.product-name {
|
||||
display: -webkit-box;
|
||||
line-clamp: 1;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
"exclude": ["src/**/__tests__/*"],
|
||||
"compilerOptions": {
|
||||
"strict": false,
|
||||
|
||||
@ -1,11 +1,23 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"include": [
|
||||
"env.d.ts",
|
||||
"types/**/*.d.ts",
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"vite.config.ts",
|
||||
"vitest.config.ts",
|
||||
"eslint.config.ts"
|
||||
],
|
||||
"exclude": ["src/**/__tests__/*"],
|
||||
"compilerOptions": {
|
||||
"strict": false,
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"typeRoots": ["./node_modules/@types", "./types"],
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"#/*": ["./types/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
"strict": false,
|
||||
"moduleResolution": "Bundler",
|
||||
"types": ["node"],
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
"#/*": ["types/*"]
|
||||
|
||||
@ -6,7 +6,7 @@ import vue from '@vitejs/plugin-vue'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { VantResolver } from '@vant/auto-import-resolver'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
// import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
@ -45,7 +45,18 @@ export default defineConfig({
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: `@use "@/assets/variables.scss" as *;`,
|
||||
additionalData: (source, fp) => {
|
||||
const id = String(fp).replace(/\\/g, '/'); // 兼容 Windows 路径
|
||||
// 避免给自身注入,尤其是 tokens/variables 文件本体
|
||||
if (
|
||||
id.endsWith('/assets/variables.scss') ||
|
||||
id.endsWith('/styles/variables.module.scss')
|
||||
) {
|
||||
return source;
|
||||
}
|
||||
// 只注入纯 Sass 变量文件(不要注入 .module.scss)
|
||||
return `@use "@/assets/variables.scss" as *; @use "@/styles/variables.module.scss" as *; ${source}`;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user