@@ -178,10 +177,12 @@ import StripePaymentForm from '@/components/StripePaymentForm.vue' import { Country, State } from 'country-state-city' import { useI18n } from 'vue-i18n' import { PayServer } from '@deotaland/utils' +import { requestUtils,clientApi } from '@deotaland/utils' const payserver = new PayServer(); const props = defineProps({ modelData: { type: Object, default: () => ({}) }, - show: { type: Boolean, default: false } + show: { type: Boolean, default: false }, + series: { type: String, default: '' } }) const emit = defineEmits(['close']) const onClose = () => emit('close') @@ -198,7 +199,7 @@ const showPayingOverlay = ref(false) // 省州映射数据已移至国际化文件 const amountCents = computed(() => { - let base = 299 // 默认价格,移除了尺寸相关定价 + let base = price.value // 默认价格,移除了尺寸相关定价 if (addons.value.gloss) base += 300 if (addons.value.base) base += 400 if (addons.value.matte) base += 200 @@ -219,6 +220,22 @@ const isPayButtonDisabled = computed(() => { ipName.value.trim() ) }) +const unt = ref(''); +const price = ref(0); +const seriesId = ref(''); +//获取对应价格 +const getPrice = async () => { + const res = await requestUtils.common(clientApi.default.getProductList) + if(res.code === 0){ + const data = res.data.list || [] + const item = data.find(item => item.name === props.series) + if(item){ + price.value = item.price?.amount || 0 + unt.value = item.price?.currency || '' + seriesId.value = item.id || '' + } + } +} const incQty = () => { qty.value = Math.min(qty.value+1, 99) } const decQty = () => { qty.value = Math.max(qty.value-1, 1) } const goShopify = () => {//用户点击购买 @@ -265,6 +282,8 @@ const goShopify = () => {//用户点击购买 // Save shipping and contact information if checkbox is checked saveLocal() // 在控制台打印整理后的信息 + console.log('Order Parameters:', params) + params.product_id = seriesId.value payserver.createPayorOrder(params); } @@ -298,6 +317,7 @@ onMounted(() => { if (c) Object.assign(contact.value, JSON.parse(c)) updateCountryOptions() updateStates() + getPrice(); } catch (e) {} }) watch(() => shipping.value.country, () => { updateStates() }) diff --git a/apps/frontend/src/components/SeriesSelector.vue b/apps/frontend/src/components/SeriesSelector.vue index 162e451..b74b0b2 100644 --- a/apps/frontend/src/components/SeriesSelector.vue +++ b/apps/frontend/src/components/SeriesSelector.vue @@ -12,26 +12,26 @@
-
- Done +
-
Done
-
- - -
-
- Oone +
+
{{ series.name }}
+
{{ series.description }}
+
+ {{ formatPrice(series.price?.amount, series.price?.currency) }} +
-
Oone
@@ -41,9 +41,9 @@ \ No newline at end of file diff --git a/apps/frontend/src/components/layout/AppHeader.vue b/apps/frontend/src/components/layout/AppHeader.vue index f72d74a..13c8feb 100644 --- a/apps/frontend/src/components/layout/AppHeader.vue +++ b/apps/frontend/src/components/layout/AppHeader.vue @@ -415,6 +415,12 @@ export default { transition: all 0.2s ease; } +.mobile-menu-button svg { + width: 24px; + height: 24px; + flex-shrink: 0; +} + .mobile-menu-button:hover { background: var(--hover-bg, #f3f4f6); } diff --git a/apps/frontend/src/components/layout/AppSidebar.vue b/apps/frontend/src/components/layout/AppSidebar.vue index 14ad43c..ca731ef 100644 --- a/apps/frontend/src/components/layout/AppSidebar.vue +++ b/apps/frontend/src/components/layout/AppSidebar.vue @@ -79,7 +79,8 @@ import { DataAnalysis as AnalyticsIcon, Folder as ProjectIcon, Bell as NotificationIcon, - Key as ApiIcon + Key as ApiIcon, + ShoppingCartFull } from '@element-plus/icons-vue' // 定义组件名称(用于调试和递归组件) @@ -112,10 +113,11 @@ const remainingPoints = ref(1280) const currentUser = computed(() => authStore.user) const userRole = computed(() => ({ '1': 'free', - '2': 'creator', -}[authStore.user?.user_role || '1'])) // 可切换为 'free' 测试不同样式 + '2':'creator' +}[authStore.user?.user_role || authStore.user?.userRole||'1'])) // 可切换为 'free' 测试不同样式 const sidebarClasses = computed(() => ({ - 'sidebar-mobile': isMobile.value + 'sidebar-mobile': isMobile.value, + 'show': isMobile.value && !props.collapsed })) // 核心菜单项 (6个主要功能) @@ -208,7 +210,7 @@ onUnmounted(() => { height: 100%; background: var(--sidebar-bg, #ffffff); border-right: 1px solid var(--border-color, #e5e7eb); - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + /* transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); */ position: relative; overflow: hidden; z-index: 100; @@ -640,12 +642,14 @@ onUnmounted(() => { position: fixed; left: 0; top: 0; + height: 100vh; z-index: 1000; transform: translateX(-100%); box-shadow: 4px 0 24px rgba(107, 70, 193, 0.2); - transition: transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); + /* transition: transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); */ backdrop-filter: blur(12px); border-right: 1px solid rgba(107, 70, 193, 0.1); + padding-top: 64px; } .sidebar-mobile.show { @@ -683,28 +687,53 @@ onUnmounted(() => { @media (max-width: 767px) { .app-sidebar { width: 100%; - max-width: 320px; + height: 100vh; + } + + .sidebar-nav { + padding: 16px 8px; + height: calc(100vh - 64px); + overflow-y: auto; } .nav-item { - padding: 16px 20px; - min-height: 72px; - margin: 8px 16px; + /* padding: 12px 8px; */ + min-height: 50px; + /* margin: 6px 4px; */ + flex-direction: column; + justify-content: center; + align-items: center; + gap: 0; + max-height: 50px; } .nav-icon { - width: 32px; - height: 32px; - margin-bottom: 8px; + width: 24px; + height: 24px; + margin-bottom: 0; + flex-shrink: 0; } .nav-icon svg { - width: 22px; - height: 22px; + width: 20px; + height: 20px; } .nav-text { - font-size: 15px; + display: none; + } + + .sidebar-footer { + padding: 12px 8px; + } + + .user-avatar-container { + width: 32px; + height: 32px; + } + + .role-badge { + display: none; } } diff --git a/apps/frontend/src/components/layout/MainLayout.vue b/apps/frontend/src/components/layout/MainLayout.vue index 4f1c609..cbbcd8f 100644 --- a/apps/frontend/src/components/layout/MainLayout.vue +++ b/apps/frontend/src/components/layout/MainLayout.vue @@ -14,6 +14,7 @@