'颜色尺码价格联动'

This commit is contained in:
2026-08-22 19:05:26 +08:00
parent c3b6af07c9
commit b190fba0f3
39 changed files with 2434 additions and 2997 deletions
+4 -2
View File
@@ -11,14 +11,16 @@
*/
// 基础路径:修改此处即可切换后端地址
const BASE_URL = 'http://192.168.124.137:3001';
const BASE_URL = 'https://official.inkreach.cc/api/';
export { BASE_URL };
// 默认配置
const TIMEOUT = 30000;
const DEFAULT_HEADER = { 'Content-Type': 'application/json' };
// 统一拼装 URL:完整地址直接返回,否则 BASE_URL + path
function buildUrl(url) {
// 图片/静态资源路径也可直接调用,得到完整可访问地址
export function buildUrl(url) {
if (!url) return '';
if (/^https?:\/\//i.test(url)) return url;
const base = BASE_URL.replace(/\/+$/, '');
+4 -4
View File
@@ -32,14 +32,14 @@
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "static/icons/tabbar/tab_home_gray.svg",
"selectedIconPath": "static/icons/tabbar/tab_home_orange.svg"
"iconPath": "static/icons/tabbar/tab_home_gray.png",
"selectedIconPath": "static/icons/tabbar/tab_home_orange.png"
},
{
"pagePath": "pages/products/products",
"text": "产品",
"iconPath": "static/icons/tabbar/tab_product_gray.svg",
"selectedIconPath": "static/icons/tabbar/tab_product_orange.svg"
"iconPath": "static/icons/tabbar/tab_product_gray.png",
"selectedIconPath": "static/icons/tabbar/tab_product_orange.png"
}
]
},
@@ -1,5 +1,5 @@
<template>
<!-- 颜色选择第一行 4 第二行 2 胶囊样式选中橙色边框+橙色文字 -->
<!-- 颜色选择第一行 4 第二行 2 胶囊样式选中橙色边框+橙色文字不可用透明度降低且不可点 -->
<view class="color-wrap">
<text class="title">颜色</text>
@@ -8,8 +8,8 @@
v-for="(item, index) in list"
:key="index"
class="color-pill"
:class="{ active: selectedId === item.id }"
@tap="selectColor(item.id)"
:class="{ active: selectedId === item.id, disabled: item.enabled === false }"
@tap="selectColor(item)"
>
<view class="color-dot" :style="{ background: item.value }"></view>
<text class="color-name">{{ item.name }}</text>
@@ -32,8 +32,9 @@ export default {
}
},
methods: {
selectColor(id) {
this.$emit('select', id)
selectColor(item) {
if (item && item.enabled === false) return
this.$emit('select', item.id)
}
}
}
@@ -74,6 +75,10 @@ export default {
.color-pill.active {
border-color: #ff6800;
}
.color-pill.disabled {
opacity: 0.4;
pointer-events: none;
}
/* 颜色圆点 15x151px 灰色边框 */
.color-dot {
@@ -1,5 +1,8 @@
<template>
<!-- 包装规格表4 × 4 每个数据单元格双单位cm + in -->
<!-- 包装规格表 - Figma 1544:530 对应节点 -->
<!-- 4 尺码 / 尺寸(L*W*H) / 体积(L*W*H) / 重量(g) -->
<!-- 表头:bg #DFDFDF 高度 40px 圆角 6px 文字13px 居中 -->
<!-- 数据行:bg #F7F7F7 高度 60px -->
<view class="pack-wrap">
<view class="header-row">
<text class="title">包装规格</text>
@@ -7,40 +10,39 @@
</view>
<view class="table">
<!-- 表头bg #DFDFDF圆角 6px -->
<!-- 表头 -->
<view class="row header">
<text
class="cell"
v-for="(col, index) in data.columns"
:key="index"
:key="'h-' + index"
>{{ col }}</text>
</view>
<!-- 数据行偶数行 bg #F7F7F7行高 60px双行内容 -->
<!-- 数据行按尺码聚合每行一个尺码 -->
<view
class="row data-row"
:class="{ alt: (index + 1) % 2 === 0 }"
v-for="(row, index) in data.rows"
:key="index"
:key="'r-' + index"
>
<!-- 尺码列单行居中 -->
<!-- 尺码列单行居中 13px -->
<view class="cell size-cell">
<text class="size-text">{{ row.size }}</text>
</view>
<!-- 尺寸列cm + in 双行 -->
<!-- 尺寸列cm / in 双行 10px opacity 0.6 -->
<view class="cell dual-cell">
<text class="dual-top">{{ row.dimension.cm }}</text>
<text class="dual-bottom">{{ row.dimension.in }}</text>
</view>
<!-- 体积列cm + in 双行 -->
<!-- 体积列cm / in -->
<view class="cell dual-cell">
<text class="dual-top">{{ row.volume.cm }}</text>
<text class="dual-bottom">{{ row.volume.in }}</text>
</view>
<!-- 重量列cm + in 双行 -->
<!-- 重量列g / lb -->
<view class="cell dual-cell">
<text class="dual-top">{{ row.weight.cm }}</text>
<text class="dual-bottom">{{ row.weight.in }}</text>
@@ -63,8 +65,9 @@ export default {
</script>
<style scoped>
/* 外层 - padding 15px 10px 白底 */
.pack-wrap {
padding: 30rpx 20rpx; /* 15px 10px */
padding: 30rpx 20rpx;
background: #ffffff;
}
@@ -75,72 +78,80 @@ export default {
margin-bottom: 20rpx; /* 10px */
}
.title {
font-size: 29rpx; /* 15px */
font-size: 29rpx; /* 15px Medium */
font-weight: 500;
color: #000000;
line-height: 33rpx;
}
.unit {
margin-left: 16rpx;
font-size: 21rpx; /* 11px */
font-size: 21rpx; /* 11px Medium */
font-weight: 500;
color: rgba(0, 0, 0, 0.5);
line-height: 33rpx;
}
/* 表格 */
/* 表格:列间距 4pxgap 8rpx */
.table {
display: flex;
flex-direction: column;
gap: 8rpx; /* 4px 行间距 */
gap: 8rpx;
}
/* 单行 */
/* 单行 - 圆角 6px(12rpx),两端对齐 */
.row {
display: flex;
border-radius: 12rpx; /* 6px */
border-radius: 12rpx;
align-items: center;
width: 100%;
}
/* 表头:高度 40px80rpx),背景 #DFDFDF,文字 13px 居中 */
.row.header {
height: 77rpx; /* 40px */
height: 80rpx;
background: #dfdfdf;
}
/* 数据行:高度 60px120rpx),背景 #F7F7F7 */
.row.data-row {
height: 115rpx; /* 60px 双行内容更高 */
}
.row.alt {
height: 120rpx;
background: #f7f7f7;
}
/* 单元格 */
/* 4 列等宽,flex:1 均分 + 居中 */
.cell {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
/* 表头文字 */
/* 表头文字 - 13px Medium 黑色 */
.row.header .cell {
font-size: 25rpx; /* 13px */
font-size: 25rpx;
font-weight: 500;
color: #000000;
line-height: 33rpx;
text-align: center;
}
/* 尺码列:单行 13px */
/* 尺码列文字 - 13px Medium 黑色 */
.size-text {
font-size: 25rpx; /* 13px */
font-size: 25rpx;
font-weight: 500;
color: #000000;
line-height: 33rpx;
}
/* 双单位单元格cm 在上,in 在下 */
/* 双单位单元格 gap 4px */
.dual-cell {
gap: 4rpx; /* 2px */
gap: 4rpx; /* 2px Figma 行间距 17-10=7 实际渲染用 4rpx 贴合 */
}
.dual-top,
.dual-bottom {
font-size: 19rpx; /* 10px */
font-size: 20rpx; /* 10px Medium Figma */
font-weight: 500;
color: rgba(0, 0, 0, 0.6);
line-height: 33rpx;
line-height: 33rpx; /* 17px */
}
</style>
@@ -1,5 +1,5 @@
<template>
<!-- 尺码选择5 个按钮横排选中态橙色边框+橙色文字背景仍为浅灰 -->
<!-- 尺码选择5 个按钮横排选中态橙色边框+橙色文字背景仍为浅灰不可用置灰 -->
<view class="size-wrap">
<text class="title">尺码</text>
@@ -8,10 +8,10 @@
v-for="(item, index) in list"
:key="index"
class="size-item"
:class="{ active: selected === item }"
:class="{ active: isSelected(item), disabled: !isEnabled(item) }"
@tap="selectSize(item)"
>
<text class="size-text">{{ item }}</text>
<text class="size-text">{{ itemName(item) }}</text>
</view>
</view>
</view>
@@ -21,18 +21,40 @@
export default {
name: 'SizeSelector',
props: {
// 支持两种格式:字符串数组 ['S','M','L'] 或 对象数组 [{name:'S',enabled:true}]
list: {
type: Array,
default: () => []
},
selected: {
type: String,
type: [String, Number, Object],
default: ''
}
},
methods: {
selectSize(size) {
this.$emit('select', size)
itemName(item) {
if (item == null) return ''
if (typeof item === 'object') return item.name
return String(item)
},
isEnabled(item) {
if (item == null) return false
if (typeof item === 'object') return item.enabled !== false
return true
},
isSelected(item) {
const name = this.itemName(item)
const selName =
this.selected == null
? ''
: typeof this.selected === 'object'
? this.selected.name
: String(this.selected)
return name === selName
},
selectSize(item) {
if (!this.isEnabled(item)) return
this.$emit('select', this.itemName(item))
}
}
}
@@ -56,6 +78,7 @@ export default {
/* 尺码列表横排 */
.size-list {
display: flex;
flex-wrap: wrap;
gap: 12rpx; /* 6px */
}
@@ -75,6 +98,11 @@ export default {
.size-item.active {
border-color: #ff6800;
}
/* 不可用:降低透明度且禁止点击 */
.size-item.disabled {
opacity: 0.4;
pointer-events: none;
}
.size-text {
font-size: 25rpx; /* 13px */
+143 -7
View File
@@ -10,10 +10,10 @@
<!-- 灰色分隔条 -->
<view class="section-divider" v-if="colors.length"></view>
<!-- 颜色选择 -->
<!-- 颜色选择根据 variants enabled 可用态 -->
<ColorSelector
v-if="colors.length"
:list="colors"
:list="colorListWithAvailability"
:selected-id="selectedColorId"
@select="selectColor"
/>
@@ -21,10 +21,10 @@
<!-- 灰色分隔条 -->
<view class="section-divider" v-if="sizes.length"></view>
<!-- 尺码选择 -->
<!-- 尺码选择根据 variants enabled 可用态 -->
<SizeSelector
v-if="sizes.length"
:list="sizes"
:list="sizeListWithAvailability"
:selected="selectedSize"
@select="selectSize"
/>
@@ -88,6 +88,8 @@ export default {
selectedSize: '',
productParams: [],
sizeChart: {},
// 变体列表(来自接口 variants),用于校验尺码+颜色组合、获取价格、包装规格
variants: [],
packaging: null
}
},
@@ -169,11 +171,17 @@ export default {
// 5. 产品参数(含可展开的"补充说明")
this.productParams = this.buildParams(detail)
// 6. 尺码表
// 6. 变体:用于尺码+颜色校验、价格联动、包装规格来源
this.variants = Array.isArray(detail.variants) ? detail.variants.slice() : []
// 7. 尺码表
this.sizeChart = this.buildSizeChart(detail.sizeChart)
// 7. 包装规格:接口暂未提供,预留为空
this.packaging = null
// 8. 包装规格(从 variants 按尺码去重生成)
this.packaging = this.buildPackaging(this.variants)
// 9. 初始价格(按默认选中的 尺码+颜色 匹配变体价格)
this.syncPriceByVariant()
},
/**
@@ -249,11 +257,139 @@ export default {
return { unit: 'cm', columns, rows }
},
/**
* 构建包装规格表(按尺码聚合 → 每行一个尺码)
* 数据来源:variants[].{ sizeId, sizeName, boxLengthCm, boxWidthCm, boxHeightCm, weightG }
*/
buildPackaging(variants) {
if (!Array.isArray(variants) || !variants.length) return null
const CM_TO_IN = 0.393701
const G_TO_LB = 0.00220462
const map = new Map()
variants.forEach((v) => {
if (!v || !v.sizeId) return
if (map.has(v.sizeId)) return // 按尺码取第一条(所有颜色的包装尺寸/重量一般相同)
const l = parseFloat(v.boxLengthCm) || 0
const w = parseFloat(v.boxWidthCm) || 0
const h = parseFloat(v.boxHeightCm) || 0
const g = parseFloat(v.weightG) || 0
const cm3 = l * w * h
const in3 = cm3 * Math.pow(CM_TO_IN, 3)
map.set(v.sizeId, {
size: v.sizeName || '',
sizeId: v.sizeId,
dimension: {
cm: `${l.toFixed(1)}*${w.toFixed(1)}*${h.toFixed(1)}cm`,
in: `${(l * CM_TO_IN).toFixed(2)}*${(w * CM_TO_IN).toFixed(2)}*${(h * CM_TO_IN).toFixed(2)}in`
},
volume: {
cm: `${cm3.toFixed(2)}cm³`,
in: `${in3.toFixed(2)}in³`
},
weight: {
cm: `${g.toFixed(2)}g`,
in: `${(g * G_TO_LB).toFixed(2)}lb`
}
})
})
if (!map.size) return null
// 按 sizes 顺序排序(保持 S→M→L→XL 顺序)
const orderMap = {}
this.sizes.forEach((s, i) => (orderMap[s] = i))
const rows = Array.from(map.values()).sort((a, b) => {
const ai = orderMap[a.size] == null ? 999 : orderMap[a.size]
const bi = orderMap[b.size] == null ? 999 : orderMap[b.size]
return ai - bi
})
return {
unit: 'cm',
columns: ['尺码', '尺寸', '体积', '重量'],
rows
}
},
/**
* 根据当前 selectedColorId + selectedSize 找到匹配的 variant
* 命中后更新 ProductInfo 的价格;找不到则保持原商品价格
*/
findVariant() {
const sizeName = this.selectedSize
const colorId = this.selectedColorId
if (!sizeName || !colorId || !this.variants.length) return null
return (
this.variants.find(
(v) =>
v &&
String(v.colorId) === String(colorId) &&
String(v.sizeName) === String(sizeName)
) || null
)
},
syncPriceByVariant() {
const v = this.findVariant()
if (v && v.price != null) {
this.$set(this.product, 'price', this.parsePrice(v.price))
}
},
/**
* 颜色列表 + 根据已选尺码标记该颜色是否可用(有对应启用的 variant)
* 数据项: { id, name, value, enabled }
*/
selectColor(id) {
this.selectedColorId = id
this.syncPriceByVariant()
},
/**
* 尺码列表 + 根据已选颜色标记该尺码是否可用
* 数据项: 直接返回字符串(SizeSelector 兼容),不可用的对应按钮会 disabled 掉,因此用对象包一层
*/
selectSize(size) {
this.selectedSize = size
this.syncPriceByVariant()
}
},
computed: {
/**
* 颜色列表 + 可用态标记(给 ColorSelector 用,用于 disabled 样式)
* - 如果没选尺码:所有已 enabled 的颜色都可选
* - 如果已选尺码:仅保留存在 (colorId + sizeName) 组合且 variant.enabled 的颜色
*/
colorListWithAvailability() {
const sizeName = this.selectedSize
return this.colors.map((c) => {
let enabled = c.enabled !== false
if (sizeName && this.variants.length) {
enabled = this.variants.some(
(v) =>
v &&
v.enabled !== false &&
String(v.colorId) === String(c.id) &&
String(v.sizeName) === String(sizeName)
)
}
return Object.assign({}, c, { enabled })
})
},
/**
* 尺码列表 + 可用态标记
* SizeSelector 原始 list 是字符串数组,这里扩展为 [{ name, enabled }]
*/
sizeListWithAvailability() {
const colorId = this.selectedColorId
return this.sizes.map((s) => {
let enabled = true
if (colorId && this.variants.length) {
enabled = this.variants.some(
(v) =>
v &&
v.enabled !== false &&
String(v.colorId) === String(colorId) &&
String(v.sizeName) === String(s)
)
}
return { name: s, enabled }
})
}
}
}
+13 -56
View File
@@ -1,25 +1,17 @@
<template>
<!-- 左侧分类侧边栏 - Figma 1512:230 (90x794) -->
<view class="sidebar-wrap">
<scroll-view scroll-y class="sidebar">
<view
class="sidebar-item"
:class="{ active: activeId === item.id }"
v-for="(item, index) in list"
:key="index"
@tap="selectItem(item.id)"
>
<view class="sidebar-indicator" v-if="activeId === item.id"></view>
<text class="sidebar-text">{{ item.name }}</text>
</view>
</scroll-view>
<!-- 底部 0元拿样本 卡片 -->
<view class="sample-banner" @tap="onSample">
<text class="sample-title">0元拿样本</text>
<text class="sample-sub">免费寄送</text>
<scroll-view scroll-y class="sidebar">
<view
class="sidebar-item"
:class="{ active: activeId === item.id }"
v-for="(item, index) in list"
:key="index"
@tap="selectItem(item.id)"
>
<view class="sidebar-indicator" v-if="activeId === item.id"></view>
<text class="sidebar-text">{{ item.name }}</text>
</view>
</view>
</scroll-view>
</template>
<script>
@@ -38,31 +30,20 @@ export default {
methods: {
selectItem(id) {
this.$emit('select', id)
},
onSample() {
this.$emit('sample')
}
}
}
</script>
<style scoped>
/* 侧边栏容器 - 包含上方滚动分类 + 底部 0元拿样本 卡片 */
.sidebar-wrap {
/* 侧边栏 - 固定宽度 180rpx(=90px),白底 + 右侧 1px #EEEEEE 边框 */
.sidebar {
width: 180rpx;
height: 100%;
background: #ffffff;
border-right: 1rpx solid #eeeeee;
box-sizing: border-box;
flex-shrink: 0;
display: flex;
flex-direction: column;
}
/* 侧边栏 - 上方滚动区域 */
.sidebar {
flex: 1;
min-height: 0;
background: #ffffff;
}
/* 单项 - 90x46 (180rpx x 92rpx),居中文字 */
.sidebar-item {
@@ -101,28 +82,4 @@ export default {
.sidebar-item.active .sidebar-text {
color: #ff6800;
}
/* 底部 0元拿样本 卡片 - 橙色渐变背景 圆角 内边距 12px 8px */
.sample-banner {
flex-shrink: 0;
margin: 16rpx 12rpx 24rpx;
padding: 24rpx 16rpx;
background: linear-gradient(180deg, #ff8a3d 0%, #ff6800 100%);
border-radius: 16rpx;
display: flex;
flex-direction: column;
align-items: center;
gap: 8rpx;
box-shadow: 0 4rpx 12rpx rgba(255, 104, 0, 0.25);
}
.sample-title {
font-size: 24rpx;
font-weight: 700;
color: #ffffff;
line-height: 1.2;
}
.sample-sub {
font-size: 18rpx;
color: rgba(255, 255, 255, 0.85);
line-height: 1.2;
}
</style>
+24 -13
View File
@@ -9,7 +9,8 @@
:key="index"
@tap="selectItem(item)"
>
<text class="country-flag">{{ item.flag }}</text>
<!-- 国家图标(18x18 圆形,来自后端 countryIcon 拼接 BASE_URL) -->
<image class="country-icon" :src="item.icon" mode="aspectFill"></image>
<text class="country-name">{{ item.name }}</text>
</view>
</view>
@@ -38,7 +39,8 @@ export default {
</script>
<style scoped>
/* 国家筛选条 - 白底 + 底部 1px #EEEEEE 边框 */
/* 国家筛选条 - 白底 + 底部 1px #EEEEEE 边框
Figma: Country Filter Bar 1511:195, y=6 起始, 行高约 31px(padding 6+6) */
.country-bar {
width: 100%;
background: #ffffff;
@@ -46,36 +48,45 @@ export default {
padding: 12rpx 20rpx;
box-sizing: border-box;
}
/* 换行布局(不用横向滚动) */
/* 换行布局 - 行间距 8px(未选中态 y=37-6=31px; 第二行 y=37) */
.country-inner {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
row-gap: 16rpx;
column-gap: 20rpx;
}
/* 单个标签 - padding 4px 10px 圆角 60px */
/* 单个标签 - padding 4px 10px 圆角 60px gap 10px Figma */
.country-item {
display: flex;
align-items: center;
gap: 8rpx;
padding: 8rpx 20rpx;
gap: 20rpx; /* 10px gap */
padding: 8rpx 20rpx; /* 4px 10px */
background: #f7f7f7;
border-radius: 60rpx;
font-size: 24rpx;
color: #000000;
line-height: 1.2;
border: 1rpx solid transparent;
box-sizing: border-box;
}
/* 选中态 - #FFF3EB 背景 + 0.5px 橙色边框 + 橙色文字 */
/* 选中态 - #FFF3EB 背景 + 0.5px 橙色边框 + 边框宽度 0.5px Figma */
.country-item.active {
background: #fff3eb;
border: 1rpx solid #ff6800;
border-color: #ff6800;
}
.country-item.active .country-name {
color: #ff6800;
}
.country-flag {
font-size: 24rpx;
/* 国家图标 - Figma 18x13 / 18x14 矩形, 圆角 2px,不是圆形 */
.country-icon {
width: 36rpx;
height: 26rpx;
border-radius: 4rpx; /* 2px */
flex-shrink: 0;
display: block;
}
/* 文字 12px Medium */
.country-name {
font-size: 24rpx;
font-weight: 500;
color: #000000;
}
</style>
+2 -1
View File
@@ -75,6 +75,7 @@ import ProductGrid from './components/ProductGrid.vue'
import FilterDrawer from './components/FilterDrawer.vue'
import { getCountries, getCategories, getTagGroups, getGoods } from '@/api/public.js'
import { buildUrl } from '@/api/request.js'
export default {
components: {
@@ -129,7 +130,7 @@ export default {
const countries = countriesData.map((c) => ({
id: c.id,
name: c.countryName,
flag: this.codeToEmoji(c.countryIcon)
icon: buildUrl(c.countryIcon || '')
}))
this.countries = countries
Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

-10
View File
@@ -1,10 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1594_113)">
<path d="M21 20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V9.48907C3 9.18048 3.14247 8.88917 3.38606 8.69972L11.3861 2.47749C11.7472 2.19663 12.2528 2.19663 12.6139 2.47749L20.6139 8.69972C20.8575 8.88917 21 9.18048 21 9.48907V20Z" fill="#999999"/>
</g>
<defs>
<clipPath id="clip0_1594_113">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 B

-10
View File
@@ -1,10 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1594_113)">
<path d="M21 20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V9.48907C3 9.18048 3.14247 8.88917 3.38606 8.69972L11.3861 2.47749C11.7472 2.19663 12.2528 2.19663 12.6139 2.47749L20.6139 8.69972C20.8575 8.88917 21 9.18048 21 9.48907V20Z" fill="#FF6800"/>
</g>
<defs>
<clipPath id="clip0_1594_113">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 B

-6
View File
@@ -1,6 +0,0 @@
<svg width="24" height="24" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.75" y="1.58591" width="6.57282" height="6.57282" rx="1.25" stroke="#999999" stroke-width="1.5"/>
<rect x="0.75" y="11.6769" width="6.57282" height="6.57282" rx="1.25" stroke="#999999" stroke-width="1.5"/>
<rect x="14.1274" y="0.224751" width="6.57282" height="6.57282" rx="1.25" transform="rotate(45 14.1274 0.224751)" stroke="#999999" stroke-width="1.5"/>
<rect x="10.841" y="11.6769" width="6.57282" height="6.57282" rx="1.25" stroke="#999999" stroke-width="1.5"/>
</svg>

Before

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 B

@@ -1,6 +0,0 @@
<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.75" y="1.58591" width="6.57282" height="6.57282" rx="1.25" stroke="black" stroke-width="1.5"/>
<rect x="0.75" y="11.6769" width="6.57282" height="6.57282" rx="1.25" stroke="black" stroke-width="1.5"/>
<rect x="14.1274" y="0.224751" width="6.57282" height="6.57282" rx="1.25" transform="rotate(45 14.1274 0.224751)" stroke="black" stroke-width="1.5"/>
<rect x="10.841" y="11.6769" width="6.57282" height="6.57282" rx="1.25" stroke="black" stroke-width="1.5"/>
</svg>

Before

Width:  |  Height:  |  Size: 573 B

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6 -2
View File
@@ -21,11 +21,15 @@
"list": [
{
"pagePath": "pages/index/index",
"text": "首页"
"text": "首页",
"iconPath": "static/icons/tabbar/tab_home_gray.png",
"selectedIconPath": "static/icons/tabbar/tab_home_orange.png"
},
{
"pagePath": "pages/products/products",
"text": "产品"
"text": "产品",
"iconPath": "static/icons/tabbar/tab_product_gray.png",
"selectedIconPath": "static/icons/tabbar/tab_product_orange.png"
}
]
},
+7
View File
@@ -205,4 +205,11 @@ page {
.safe-bottom {
padding-bottom: env(safe-area-inset-bottom);
}
/* 全局隐藏横向滚动条(scroll-view / webkit) */
::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
background: transparent;
}
+76
View File
@@ -55,6 +55,11 @@
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // object to store loaded CSS chunks
/******/ var installedCssChunks = {
/******/ "common/runtime": 0
/******/ }
/******/
/******/ // object to store loaded and loading chunks
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/ // Promise = chunk loading, 0 = chunk loaded
@@ -64,6 +69,11 @@
/******/
/******/ var deferredModules = [];
/******/
/******/ // script path function
/******/ function jsonpScriptSrc(chunkId) {
/******/ return __webpack_require__.p + "" + chunkId + ".js"
/******/ }
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
@@ -88,6 +98,69 @@
/******/ return module.exports;
/******/ }
/******/
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = function requireEnsure(chunkId) {
/******/ var promises = [];
/******/
/******/
/******/
/******/
/******/ // JSONP chunk loading for javascript
/******/
/******/ var installedChunkData = installedChunks[chunkId];
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
/******/
/******/ // a Promise means "currently loading".
/******/ if(installedChunkData) {
/******/ promises.push(installedChunkData[2]);
/******/ } else {
/******/ // setup Promise in chunk cache
/******/ var promise = new Promise(function(resolve, reject) {
/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject];
/******/ });
/******/ promises.push(installedChunkData[2] = promise);
/******/
/******/ // start chunk loading
/******/ var script = document.createElement('script');
/******/ var onScriptComplete;
/******/
/******/ script.charset = 'utf-8';
/******/ script.timeout = 120;
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = jsonpScriptSrc(chunkId);
/******/
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ onScriptComplete = function (event) {
/******/ // avoid mem leaks in IE.
/******/ script.onerror = script.onload = null;
/******/ clearTimeout(timeout);
/******/ var chunk = installedChunks[chunkId];
/******/ if(chunk !== 0) {
/******/ if(chunk) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ chunk[1](error);
/******/ }
/******/ installedChunks[chunkId] = undefined;
/******/ }
/******/ };
/******/ var timeout = setTimeout(function(){
/******/ onScriptComplete({ type: 'timeout', target: script });
/******/ }, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ document.head.appendChild(script);
/******/ }
/******/ }
/******/ return Promise.all(promises);
/******/ };
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
@@ -141,6 +214,9 @@
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/";
/******/
/******/ // on error function for async loading
/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };
/******/
/******/ var jsonpArray = global["webpackJsonp"] = global["webpackJsonp"] || [];
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
/******/ jsonpArray.push = webpackJsonpCallback;
+798 -2
View File
@@ -871,7 +871,7 @@ function populateParameters(result) {
// wx.getAccountInfoSync
var parameters = {
appId: "",
appId: "__UNI__73E5929",
appName: "inkreach-miniprogram",
appVersion: "1.0.0",
appVersionCode: "100",
@@ -982,7 +982,7 @@ var getAppBaseInfo = {
var _hostName = getHostName(result);
var hostLanguage = (language || '').replace('_', '-');
var parameters = {
appId: "",
appId: "__UNI__73E5929",
appName: "inkreach-miniprogram",
appVersion: "1.0.0",
appVersionCode: "100",
@@ -12751,6 +12751,802 @@ var debounce = function debounce(scope, fn, delay) {
var _default = debounce;
exports.default = _default;
/***/ }),
/* 49 */,
/* 50 */,
/* 51 */,
/* 52 */,
/* 53 */,
/* 54 */,
/* 55 */
/*!************************************************************************************************!*\
!*** ./node_modules/@dcloudio/vue-cli-plugin-uni/packages/@babel/runtime/regenerator/index.js ***!
\************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
// TODO(Babel 8): Remove this file.
var runtime = __webpack_require__(/*! @babel/runtime/helpers/regeneratorRuntime */ 56)();
module.exports = runtime;
/***/ }),
/* 56 */
/*!*******************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/regeneratorRuntime.js ***!
\*******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var _typeof = __webpack_require__(/*! ./typeof.js */ 13)["default"];
function _regeneratorRuntime() {
"use strict";
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
module.exports = _regeneratorRuntime = function _regeneratorRuntime() {
return e;
}, module.exports.__esModule = true, module.exports["default"] = module.exports;
var t,
e = {},
r = Object.prototype,
n = r.hasOwnProperty,
o = Object.defineProperty || function (t, e, r) {
t[e] = r.value;
},
i = "function" == typeof Symbol ? Symbol : {},
a = i.iterator || "@@iterator",
c = i.asyncIterator || "@@asyncIterator",
u = i.toStringTag || "@@toStringTag";
function define(t, e, r) {
return Object.defineProperty(t, e, {
value: r,
enumerable: !0,
configurable: !0,
writable: !0
}), t[e];
}
try {
define({}, "");
} catch (t) {
define = function define(t, e, r) {
return t[e] = r;
};
}
function wrap(t, e, r, n) {
var i = e && e.prototype instanceof Generator ? e : Generator,
a = Object.create(i.prototype),
c = new Context(n || []);
return o(a, "_invoke", {
value: makeInvokeMethod(t, r, c)
}), a;
}
function tryCatch(t, e, r) {
try {
return {
type: "normal",
arg: t.call(e, r)
};
} catch (t) {
return {
type: "throw",
arg: t
};
}
}
e.wrap = wrap;
var h = "suspendedStart",
l = "suspendedYield",
f = "executing",
s = "completed",
y = {};
function Generator() {}
function GeneratorFunction() {}
function GeneratorFunctionPrototype() {}
var p = {};
define(p, a, function () {
return this;
});
var d = Object.getPrototypeOf,
v = d && d(d(values([])));
v && v !== r && n.call(v, a) && (p = v);
var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p);
function defineIteratorMethods(t) {
["next", "throw", "return"].forEach(function (e) {
define(t, e, function (t) {
return this._invoke(e, t);
});
});
}
function AsyncIterator(t, e) {
function invoke(r, o, i, a) {
var c = tryCatch(t[r], t, o);
if ("throw" !== c.type) {
var u = c.arg,
h = u.value;
return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) {
invoke("next", t, i, a);
}, function (t) {
invoke("throw", t, i, a);
}) : e.resolve(h).then(function (t) {
u.value = t, i(u);
}, function (t) {
return invoke("throw", t, i, a);
});
}
a(c.arg);
}
var r;
o(this, "_invoke", {
value: function value(t, n) {
function callInvokeWithMethodAndArg() {
return new e(function (e, r) {
invoke(t, n, e, r);
});
}
return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
}
});
}
function makeInvokeMethod(e, r, n) {
var o = h;
return function (i, a) {
if (o === f) throw Error("Generator is already running");
if (o === s) {
if ("throw" === i) throw a;
return {
value: t,
done: !0
};
}
for (n.method = i, n.arg = a;;) {
var c = n.delegate;
if (c) {
var u = maybeInvokeDelegate(c, n);
if (u) {
if (u === y) continue;
return u;
}
}
if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) {
if (o === h) throw o = s, n.arg;
n.dispatchException(n.arg);
} else "return" === n.method && n.abrupt("return", n.arg);
o = f;
var p = tryCatch(e, r, n);
if ("normal" === p.type) {
if (o = n.done ? s : l, p.arg === y) continue;
return {
value: p.arg,
done: n.done
};
}
"throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg);
}
};
}
function maybeInvokeDelegate(e, r) {
var n = r.method,
o = e.iterator[n];
if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y;
var i = tryCatch(o, e.iterator, r.arg);
if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y;
var a = i.arg;
return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y);
}
function pushTryEntry(t) {
var e = {
tryLoc: t[0]
};
1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e);
}
function resetTryEntry(t) {
var e = t.completion || {};
e.type = "normal", delete e.arg, t.completion = e;
}
function Context(t) {
this.tryEntries = [{
tryLoc: "root"
}], t.forEach(pushTryEntry, this), this.reset(!0);
}
function values(e) {
if (e || "" === e) {
var r = e[a];
if (r) return r.call(e);
if ("function" == typeof e.next) return e;
if (!isNaN(e.length)) {
var o = -1,
i = function next() {
for (; ++o < e.length;) {
if (n.call(e, o)) return next.value = e[o], next.done = !1, next;
}
return next.value = t, next.done = !0, next;
};
return i.next = i;
}
}
throw new TypeError(_typeof(e) + " is not iterable");
}
return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", {
value: GeneratorFunctionPrototype,
configurable: !0
}), o(GeneratorFunctionPrototype, "constructor", {
value: GeneratorFunction,
configurable: !0
}), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) {
var e = "function" == typeof t && t.constructor;
return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name));
}, e.mark = function (t) {
return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t;
}, e.awrap = function (t) {
return {
__await: t
};
}, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () {
return this;
}), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) {
void 0 === i && (i = Promise);
var a = new AsyncIterator(wrap(t, r, n, o), i);
return e.isGeneratorFunction(r) ? a : a.next().then(function (t) {
return t.done ? t.value : a.next();
});
}, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () {
return this;
}), define(g, "toString", function () {
return "[object Generator]";
}), e.keys = function (t) {
var e = Object(t),
r = [];
for (var n in e) {
r.push(n);
}
return r.reverse(), function next() {
for (; r.length;) {
var t = r.pop();
if (t in e) return next.value = t, next.done = !1, next;
}
return next.done = !0, next;
};
}, e.values = values, Context.prototype = {
constructor: Context,
reset: function reset(e) {
if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) {
"t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t);
}
},
stop: function stop() {
this.done = !0;
var t = this.tryEntries[0].completion;
if ("throw" === t.type) throw t.arg;
return this.rval;
},
dispatchException: function dispatchException(e) {
if (this.done) throw e;
var r = this;
function handle(n, o) {
return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o;
}
for (var o = this.tryEntries.length - 1; o >= 0; --o) {
var i = this.tryEntries[o],
a = i.completion;
if ("root" === i.tryLoc) return handle("end");
if (i.tryLoc <= this.prev) {
var c = n.call(i, "catchLoc"),
u = n.call(i, "finallyLoc");
if (c && u) {
if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
} else if (c) {
if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
} else {
if (!u) throw Error("try statement without catch or finally");
if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
}
}
}
},
abrupt: function abrupt(t, e) {
for (var r = this.tryEntries.length - 1; r >= 0; --r) {
var o = this.tryEntries[r];
if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
var i = o;
break;
}
}
i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
var a = i ? i.completion : {};
return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a);
},
complete: function complete(t, e) {
if ("throw" === t.type) throw t.arg;
return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y;
},
finish: function finish(t) {
for (var e = this.tryEntries.length - 1; e >= 0; --e) {
var r = this.tryEntries[e];
if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y;
}
},
"catch": function _catch(t) {
for (var e = this.tryEntries.length - 1; e >= 0; --e) {
var r = this.tryEntries[e];
if (r.tryLoc === t) {
var n = r.completion;
if ("throw" === n.type) {
var o = n.arg;
resetTryEntry(r);
}
return o;
}
}
throw Error("illegal catch attempt");
},
delegateYield: function delegateYield(e, r, n) {
return this.delegate = {
iterator: values(e),
resultName: r,
nextLoc: n
}, "next" === this.method && (this.arg = t), y;
}
}, e;
}
module.exports = _regeneratorRuntime, module.exports.__esModule = true, module.exports["default"] = module.exports;
/***/ }),
/* 57 */
/*!*****************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/asyncToGenerator.js ***!
\*****************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
module.exports = _asyncToGenerator, module.exports.__esModule = true, module.exports["default"] = module.exports;
/***/ }),
/* 58 */
/*!***********************************************************!*\
!*** C:/gs/project/demo/demo_uni/api/public.js ***!
\***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ 4);
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.getCategories = getCategories;
exports.getCountries = getCountries;
exports.getGoods = getGoods;
exports.getGoodsDetail = getGoodsDetail;
exports.getHomeGoods = getHomeGoods;
exports.getTagGroups = getTagGroups;
exports.getTags = getTags;
var _request = _interopRequireDefault(__webpack_require__(/*! ./request.js */ 59));
/**
* 公共路由接口封装/public/*
* 响应拦截器暂未做业务规范拦截调用方拿到的是 uni.request 原始 response 结构 { statusCode, data, header ... }
*/
var PREFIX = '/public';
/**
* 获取商品分类树
* @param {Object} [params]
* @param {string|number} [params.countryId] 国家 ID不传时返回全部国家
*/
function getCategories(params) {
return _request.default.get("".concat(PREFIX, "/categories"), params);
}
/**
* 获取有商品的国家列表
*/
function getCountries() {
return _request.default.get("".concat(PREFIX, "/countries"));
}
/**
* 获取有商品的标签列表
*/
function getTags() {
return _request.default.get("".concat(PREFIX, "/tags"));
}
/**
* 获取标签组及标签筛选项
* @param {Object} [params]
* @param {string|number} [params.countryId] 国家 ID不传时返回全部国家
*/
function getTagGroups(params) {
return _request.default.get("".concat(PREFIX, "/tag-groups"), params);
}
/**
* 分页获取商品
* @param {Object} params
* @param {number} [params.page]
* @param {number} [params.pageSize]
* @param {string|number} [params.countryId]
* @param {string|number} [params.categoryId]
* @param {string} [params.keyword]
*/
function getGoods(params) {
return _request.default.get("".concat(PREFIX, "/goods"), params);
}
/**
* 获取商品完整详情
* @param {string|number} goodId 商品 ID替换路径变量 {goodId}
*/
function getGoodsDetail(goodId) {
return _request.default.get("".concat(PREFIX, "/goods/").concat(goodId));
}
/**
* 获取首页商品可按国家返回
* @param {Object} [params]
* @param {string|number} [params.countryId]
*/
function getHomeGoods(params) {
return _request.default.get("".concat(PREFIX, "/home-goods"), params);
}
var _default = {
getCategories: getCategories,
getCountries: getCountries,
getTags: getTags,
getTagGroups: getTagGroups,
getGoods: getGoods,
getGoodsDetail: getGoodsDetail,
getHomeGoods: getHomeGoods
};
exports.default = _default;
/***/ }),
/* 59 */
/*!************************************************************!*\
!*** C:/gs/project/demo/demo_uni/api/request.js ***!
\************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(uni) {
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ 4);
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.BASE_URL = void 0;
exports.buildUrl = buildUrl;
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/defineProperty */ 11));
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
/**
* uni-app 简易请求封装
* - 统一拼接 BASE_URL + path
* - 注入 token header
* - Promise 提供 get/post/put/delete 快捷方法
*
* 用法
* import request from '@/api/request.js'
* request.get('/user/info', { id: 1 })
* request.post('/user/login', { username, password })
*/
// 基础路径:修改此处即可切换后端地址
var BASE_URL = 'https://official.inkreach.cc/api/';
exports.BASE_URL = BASE_URL;
// 默认配置
var TIMEOUT = 30000;
var DEFAULT_HEADER = {
'Content-Type': 'application/json'
};
// 统一拼装 URL:完整地址直接返回,否则 BASE_URL + path
// 图片/静态资源路径也可直接调用,得到完整可访问地址
function buildUrl(url) {
if (!url) return '';
if (/^https?:\/\//i.test(url)) return url;
var base = BASE_URL.replace(/\/+$/, '');
var path = url.replace(/^\/+/, '');
return path ? "".concat(base, "/").concat(path) : base;
}
// 统一取 header(注入 token
function buildHeader(extraHeader) {
var header = Object.assign({}, DEFAULT_HEADER, extraHeader || {});
var token = uni.getStorageSync('token');
if (token) header['Authorization'] = "Bearer ".concat(token);
return header;
}
/**
* 核心请求方法
* @param {Object} options
* @param {string} options.url 相对路径或完整 URL
* @param {string} [options.method='GET']
* @param {Object} [options.data] 请求参数 / body
* @param {Object} [options.header] 额外 header
* @returns {Promise<any>}
*/
function request() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return new Promise(function (resolve, reject) {
uni.request({
url: buildUrl(options.url || ''),
method: (options.method || 'GET').toUpperCase(),
data: options.data || {},
header: buildHeader(options.header),
timeout: TIMEOUT,
dataType: 'json',
success: resolve,
fail: reject
});
});
}
// 快捷方法
request.get = function (url, data, options) {
return request(_objectSpread({
url: url,
method: 'GET',
data: data
}, options));
};
request.post = function (url, data, options) {
return request(_objectSpread({
url: url,
method: 'POST',
data: data
}, options));
};
request.put = function (url, data, options) {
return request(_objectSpread({
url: url,
method: 'PUT',
data: data
}, options));
};
request.delete = function (url, data, options) {
return request(_objectSpread({
url: url,
method: 'DELETE',
data: data
}, options));
};
var _default = request;
exports.default = _default;
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./node_modules/@dcloudio/uni-mp-weixin/dist/index.js */ 2)["default"]))
/***/ }),
/* 60 */
/*!*****************************************************************!*\
!*** C:/gs/project/demo/demo_uni/pages/index/mock.js ***!
\*****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.trustStats = exports.stepList = exports.reasonList = exports.podProducts = exports.featureList = exports.ctaSection = exports.countryTabs = exports.companyIntro = exports.companyFeatures = void 0;
// 首页 mock 数据
// 设计稿尺寸: 390px 宽度,1px ≈ 2rpx
// Hero 区 4个指标
var trustStats = [{
value: '11',
unit: '国',
label: '全球本土工厂'
}, {
value: '24',
unit: 'H',
label: '极速发货'
}, {
value: '1000',
unit: 'W+',
label: '订单履约'
}, {
value: '800',
unit: '+',
label: '产品生产'
}];
// 4步流程
exports.trustStats = trustStats;
var stepList = [{
step: '01',
title: '选择产品',
desc: '海量精选产品,满足多元定制需求'
}, {
step: '02',
title: '上传设计',
desc: '可视化编辑器,轻松实现创意落地'
}, {
step: '03',
title: '在线销售',
desc: '一键开通店铺,多渠道触达目标客群'
}, {
step: '04',
title: '生产配送',
desc: '智能化柔性生产,快速响应全球配送'
}];
// 全球POD货盘 - 国家tab
exports.stepList = stepList;
var countryTabs = [{
id: 'us',
name: '美国'
}, {
id: 'ca',
name: '加拿大'
}, {
id: 'mx',
name: '墨西哥'
}, {
id: 'br',
name: '巴西'
}, {
id: 'ar',
name: '阿根廷'
}, {
id: 'cl',
name: '智利'
}, {
id: 'co',
name: '哥伦比亚'
}, {
id: 'pe',
name: '秘鲁'
}];
// 全球POD货盘 - 产品列表
exports.countryTabs = countryTabs;
var podProducts = [{
id: 1,
name: '女士短款露脐T恤',
image: '/static/images/home/Rectangle_63_1446_1437.png'
}, {
id: 2,
name: '女士短款露脐T恤',
image: '/static/images/home/Rectangle_181_1455_1450.png'
}, {
id: 3,
name: '女士短款露脐T恤',
image: '/static/images/home/Rectangle_63_1455_1461.png'
}, {
id: 4,
name: '女士短款露脐T恤',
image: '/static/images/home/Rectangle_181_1455_1456.png'
}];
// 平台功能卡片
exports.podProducts = podProducts;
var featureList = [{
step: '01',
title: '设计工具',
desc: '轻松设计,快速定制'
}, {
step: '02',
title: '自动化履约',
desc: '从生产到配送,全程无忧,准时交付'
}, {
step: '03',
title: '全球配送',
desc: '全球11国自营本土工厂'
}, {
step: '04',
title: '店铺集成',
desc: '与全球主流电商平台无缝对接'
}];
// 为什么选择 - 4个优势
exports.featureList = featureList;
var reasonList = [{
id: 1,
title: '零库存',
icon: '/static/icons/home/零库存图标.svg'
}, {
id: 2,
title: '快速生产',
icon: '/static/icons/home/快速生产图标.svg'
}, {
id: 3,
title: '优质产品',
icon: '/static/icons/home/优质产品图标.svg'
}, {
id: 4,
title: '全球配送',
icon: '/static/icons/home/全球配送图标.svg'
}];
// 公司简介
exports.reasonList = reasonList;
var companyIntro = {
title: '公司简介',
sloganMain: '用科技重新定义POD供应链',
sloganSub: '让每一个创意,都能高效抵达全球',
desc: 'Inkreach印美达全球,一家以AI与智能印花技术驱动的全球化POD柔性供应链公司,致力于成为全球创业者最可靠的成长伙伴。',
cols: [{
title: '服务对象与场景',
text: '服务于数千家跨境独立站、TikTok、TEMU、SHEIN等平台商家,提供从海外生产到末端物流的一站式供应链服务,让电商创业者专注增长,无惧后端履约。'
}, {
title: '愿景',
text: '我们坚信,每一个创意都值得被完美呈现。 Inkreach将持续深耕智能供应链生态,用科技消除制造壁垒,让全球创业者专注发挥创造力,共同书写个性化电商的新纪元。'
}]
};
// 公司简介 - 4个核心能力
exports.companyIntro = companyIntro;
var companyFeatures = [{
id: 1,
title: '前沿印花技术',
desc: '搭载最新智能印花工艺,品质与效率兼得',
icon: '/static/icons/home/ability_printing.svg'
}, {
id: 2,
title: '深度AI应用',
desc: '从设计到生产,全链路智能化提效',
icon: '/static/icons/home/ability_ai.svg'
}, {
id: 3,
title: '全球智能工厂',
desc: '11国自营本土化POD工厂,日均产能超20万单',
icon: '/static/icons/home/ability_global.svg'
}, {
id: 4,
title: '一站式柔性交付',
desc: '覆盖生产至物流,助力品牌从概念到商业落地',
icon: '/static/icons/home/ability_flexible.svg'
}];
// 底部CTA
exports.companyFeatures = companyFeatures;
var ctaSection = {
qrImage: '/static/images/home/Rectangle_187_1470_1653.png',
bgImage: '/static/images/home/image_26_1496_1761.png',
textImage: '/static/images/home/image_28_1498_1767.png',
text: '联系我们,开启你的全球生意新篇'
};
exports.ctaSection = ctaSection;
/***/ })
]]);
//# sourceMappingURL=../../.sourcemap/mp-weixin/common/vendor.js.map
+175 -470
View File
@@ -33,7 +33,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _index_vue_vue_type_template_id_57280228___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index.vue?vue&type=template&id=57280228& */ 51);
/* harmony import */ var _index_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.vue?vue&type=script&lang=js& */ 53);
/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _index_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__) if(["default"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _index_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__[key]; }) }(__WEBPACK_IMPORT_KEY__));
/* harmony import */ var _index_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./index.vue?vue&type=style&index=0&lang=css& */ 55);
/* harmony import */ var _index_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./index.vue?vue&type=style&index=0&lang=css& */ 61);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/runtime/componentNormalizer.js */ 36);
var renderjs
@@ -137,491 +137,196 @@ __webpack_require__.r(__webpack_exports__);
"use strict";
/* WEBPACK VAR INJECTION */(function(uni) {
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ 4);
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
var _regenerator = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/regenerator */ 55));
var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/asyncToGenerator */ 57));
var _public = __webpack_require__(/*! @/api/public.js */ 58);
var _mock = __webpack_require__(/*! ./mock.js */ 60);
var HeroBanner = function HeroBanner() {
__webpack_require__.e(/*! require.ensure | pages/index/components/HeroBanner */ "pages/index/components/HeroBanner").then((function () {
return resolve(__webpack_require__(/*! ./components/HeroBanner.vue */ 79));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var StepsFlow = function StepsFlow() {
__webpack_require__.e(/*! require.ensure | pages/index/components/StepsFlow */ "pages/index/components/StepsFlow").then((function () {
return resolve(__webpack_require__(/*! ./components/StepsFlow.vue */ 86));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var PodCatalog = function PodCatalog() {
__webpack_require__.e(/*! require.ensure | pages/index/components/PodCatalog */ "pages/index/components/PodCatalog").then((function () {
return resolve(__webpack_require__(/*! ./components/PodCatalog.vue */ 93));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var PlatformFeatures = function PlatformFeatures() {
__webpack_require__.e(/*! require.ensure | pages/index/components/PlatformFeatures */ "pages/index/components/PlatformFeatures").then((function () {
return resolve(__webpack_require__(/*! ./components/PlatformFeatures.vue */ 100));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var WhyChoose = function WhyChoose() {
__webpack_require__.e(/*! require.ensure | pages/index/components/WhyChoose */ "pages/index/components/WhyChoose").then((function () {
return resolve(__webpack_require__(/*! ./components/WhyChoose.vue */ 107));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var CompanyIntro = function CompanyIntro() {
__webpack_require__.e(/*! require.ensure | pages/index/components/CompanyIntro */ "pages/index/components/CompanyIntro").then((function () {
return resolve(__webpack_require__(/*! ./components/CompanyIntro.vue */ 114));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var _default = {
components: {
HeroBanner: HeroBanner,
StepsFlow: StepsFlow,
PodCatalog: PodCatalog,
PlatformFeatures: PlatformFeatures,
WhyChoose: WhyChoose,
CompanyIntro: CompanyIntro
},
data: function data() {
return {
statusBarHeight: 20,
currentStep: 2,
stepEmoji: '🎨',
stepDesc: '使用在线设计工具创建你的专属图案,支持上传图片、添加文字、智能排版',
activeCategory: 'all',
categories: [{
id: 'all',
name: '全部'
}, {
id: 'tshirt',
name: 'T恤'
}, {
id: 'hoodie',
name: '卫衣'
}, {
id: 'bag',
name: '包包'
}, {
id: 'kids',
name: '童装'
}, {
id: 'home',
name: '家居'
}],
previewProducts: [{
id: 1,
name: '180G牛奶丝T恤 DG120',
price: '28.00',
color: '#F5F5F5',
emoji: '👕'
}, {
id: 2,
name: '纯棉连帽卫衣 HD200',
price: '59.00',
color: '#E8E8E8',
emoji: '🧥'
}, {
id: 3,
name: '帆布托特包 BG150',
price: '15.00',
color: '#F0F0F0',
emoji: '👜'
}, {
id: 4,
name: '儿童纯棉T恤 KD100',
price: '22.00',
color: '#F8F8F8',
emoji: '👶'
}],
features: [{
id: 1,
title: '设计工具',
desc: '在线设计器,海量模板自由创作',
emoji: '🎨',
bgColor: '#FFF0E5'
}, {
id: 2,
title: '自动化履约',
desc: '订单自动分配工厂生产发货',
emoji: '⚙️',
bgColor: '#E5F5FF'
}, {
id: 3,
title: '全球配送',
desc: '覆盖200+国家地区快速达',
emoji: '🌍',
bgColor: '#F0FFE5'
}, {
id: 4,
title: '店铺集成',
desc: '对接Shopify等主流平台',
emoji: '🔗',
bgColor: '#FFF5E5'
}],
reasons: [{
id: 1,
title: '零库存',
desc: '无需囤货按需生产',
emoji: '📦'
}, {
id: 2,
title: '快速生产',
desc: '48小时极速出货',
emoji: '⚡'
}, {
id: 3,
title: '优质产品',
desc: '严格品质管控',
emoji: '✨'
}, {
id: 4,
title: '全球配送',
desc: '覆盖200+国家',
emoji: '🚀'
}],
companyStats: [{
value: '5000+',
label: '合作卖家'
}, {
value: '500+',
label: '合作工厂'
}, {
value: '20+',
label: '覆盖国家'
}, {
value: '1000万+',
label: '订单履约'
}],
cases: [{
id: 1,
title: '潮牌T恤定制',
tags: ['T恤', '烫画'],
roi: '260%',
revenue: '$12K',
bgColor: '#F5F5F5',
emoji: '👕'
}, {
id: 2,
title: '连帽卫衣品牌',
tags: ['卫衣', '刺绣'],
roi: '300%',
revenue: '$25K',
bgColor: '#E8E8E8',
emoji: '🧥'
}, {
id: 3,
title: '环保帆布包',
tags: ['包包', '丝印'],
roi: '180%',
revenue: '$8K',
bgColor: '#F0F0F0',
emoji: '👜'
}],
tag: ''
trustStats: _mock.trustStats,
stepList: _mock.stepList,
featureList: _mock.featureList,
reasonList: _mock.reasonList,
companyFeatures: _mock.companyFeatures,
podCountries: [],
podProducts: []
};
},
onLoad: function onLoad() {
var app = getApp();
this.setData({
statusBarHeight: app.globalData.statusBarHeight || 20
});
var _this = this;
return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return _this.loadPodCountries();
case 2:
_context.next = 4;
return _this.loadPodProducts('');
case 4:
case "end":
return _context.stop();
}
}
}, _callee);
}))();
},
methods: {
selectStep: function selectStep(e) {
var step = e.currentTarget.dataset.step;
var stepData = {
1: {
emoji: '📦',
desc: '从全球POD货盘中选择热销产品,涵盖服装、配饰、家居等多品类'
},
2: {
emoji: '🎨',
desc: '使用在线设计工具创建你的专属图案,支持上传图片、添加文字、智能排版'
},
3: {
emoji: '🛒',
desc: '一键发布到Shopify、TikTok Shop等主流电商平台,自动同步商品信息'
},
4: {
emoji: '🚚',
desc: '订单自动分配至最近工厂生产,全球物流配送直达消费者手中'
}
};
this.setData({
currentStep: step,
stepEmoji: stepData[step].emoji,
stepDesc: stepData[step].desc
});
loadPodCountries: function loadPodCountries() {
var _this2 = this;
return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
var res, data, countries;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.prev = 0;
_context2.next = 3;
return (0, _public.getCountries)();
case 3:
res = _context2.sent;
data = res.data && res.data.data || [];
countries = [{
id: '',
name: '全部'
}];
data.forEach(function (c) {
countries.push({
id: c.id,
name: c.countryName
});
});
_this2.podCountries = countries;
_context2.next = 13;
break;
case 10:
_context2.prev = 10;
_context2.t0 = _context2["catch"](0);
console.error('[loadPodCountries Error]', _context2.t0);
case 13:
case "end":
return _context2.stop();
}
}
}, _callee2, null, [[0, 10]]);
}))();
},
selectCategory: function selectCategory(e) {
this.setData({
activeCategory: e.currentTarget.dataset.id
});
loadPodProducts: function loadPodProducts(countryId) {
var _this3 = this;
return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
var params, res, data, items;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.prev = 0;
params = {
page: 1,
pageSize: 4
};
if (countryId) {
params.countryId = countryId;
}
_context3.next = 5;
return (0, _public.getGoods)(params);
case 5:
res = _context3.sent;
data = res.data && res.data.data || {
items: []
};
items = (data.items || []).slice(0, 4);
_this3.podProducts = items.map(function (item) {
return {
id: item.goodId,
name: item.goodName,
image: item.image
};
});
_context3.next = 15;
break;
case 11:
_context3.prev = 11;
_context3.t0 = _context3["catch"](0);
console.error('[loadPodProducts Error]', _context3.t0);
_this3.podProducts = [];
case 15:
case "end":
return _context3.stop();
}
}
}, _callee3, null, [[0, 11]]);
}))();
},
goProducts: function goProducts() {
onPodCountryChange: function onPodCountryChange(id) {
var _this4 = this;
return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
return _regenerator.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return _this4.loadPodProducts(id);
case 2:
case "end":
return _context4.stop();
}
}
}, _callee4);
}))();
},
onGoProducts: function onGoProducts() {
uni.switchTab({
url: '/pages/products/products'
});
},
goHome: function goHome() {
uni.pageScrollTo({
scrollTop: 0,
duration: 300
});
},
goProductDetail: function goProductDetail(e) {
var id = e.currentTarget.dataset.id;
onGoDetail: function onGoDetail(item) {
uni.navigateTo({
url: "/pages/product-detail/product-detail?id=".concat(id)
url: '/pages/product-detail/product-detail?id=' + item.id
});
}
}
@@ -631,7 +336,7 @@ exports.default = _default;
/***/ }),
/***/ 55:
/***/ 61:
/*!****************************************************************************************************!*\
!*** C:/gs/project/官网小程序demo/官网小程序demo_uni/pages/index/index.vue?vue&type=style&index=0&lang=css& ***!
\****************************************************************************************************/
@@ -640,14 +345,14 @@ exports.default = _default;
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_index_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/stylePostLoader.js!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--6-oneOf-1-2!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/postcss-loader/src??ref--6-oneOf-1-3!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!./index.vue?vue&type=style&index=0&lang=css& */ 56);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_index_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/stylePostLoader.js!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--6-oneOf-1-2!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/postcss-loader/src??ref--6-oneOf-1-3!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!./index.vue?vue&type=style&index=0&lang=css& */ 62);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_index_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_index_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__);
/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_index_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__) if(["default"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_index_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__));
/* harmony default export */ __webpack_exports__["default"] = (_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_index_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }),
/***/ 56:
/***/ 62:
/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--6-oneOf-1-2!./node_modules/postcss-loader/src??ref--6-oneOf-1-3!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!./node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!C:/gs/project/官网小程序demo/官网小程序demo_uni/pages/index/index.vue?vue&type=style&index=0&lang=css& ***!
\********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
+8 -1
View File
@@ -1,5 +1,12 @@
{
"navigationBarTitleText": "印美达 Inkreach",
"navigationStyle": "custom",
"usingComponents": {}
"usingComponents": {
"hero-banner": "/pages/index/components/HeroBanner",
"steps-flow": "/pages/index/components/StepsFlow",
"pod-catalog": "/pages/index/components/PodCatalog",
"platform-features": "/pages/index/components/PlatformFeatures",
"why-choose": "/pages/index/components/WhyChoose",
"company-intro": "/pages/index/components/CompanyIntro"
}
}
File diff suppressed because one or more lines are too long
+4 -721
View File
@@ -1,724 +1,7 @@
/* 首页样式 - 印美达 Inkreach */
.home {
min-height: 100vh;
background: #ffffff;
overflow-x: hidden;
}
/* 导航栏 */
.nav-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
background: #ffffff;
box-shadow: 0 1rpx 0 rgba(0, 0, 0, 0.05);
}
.nav-content {
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 32rpx;
}
.nav-logo {
display: flex;
align-items: baseline;
gap: 8rpx;
}
.logo-text {
font-size: 32rpx;
font-weight: 700;
color: #ff6800;
font-style: italic;
}
.logo-cn {
font-size: 24rpx;
color: #333;
font-weight: 500;
}
.nav-actions {
display: flex;
align-items: center;
gap: 24rpx;
}
.nav-btn {
font-size: 26rpx;
color: #333;
}
.nav-login {
font-size: 24rpx;
color: #ff6800;
border: 2rpx solid #ff6800;
padding: 8rpx 24rpx;
border-radius: 32rpx;
}
/* Hero 首屏 */
.hero {
position: relative;
padding: 60rpx 32rpx 80rpx;
overflow: hidden;
background: linear-gradient(180deg, #fff5ee 0%, #ffffff 100%);
}
.hero-bg {
position: absolute;
top: -100rpx;
right: -200rpx;
width: 600rpx;
height: 600rpx;
background: radial-gradient(circle, rgba(255, 104, 0, 0.06) 0%, transparent 70%);
border-radius: 50%;
}
.hero-content {
position: relative;
z-index: 2;
}
.hero-title {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.hero-title-main {
font-size: 72rpx;
font-weight: 800;
color: #1a1a1a;
line-height: 1.2;
letter-spacing: 2rpx;
}
.hero-subtitle {
font-size: 30rpx;
color: #666;
margin-top: 24rpx;
}
.hero-tags {
display: flex;
gap: 16rpx;
margin-top: 32rpx;
}
.hero-tag {
font-size: 22rpx;
color: #ff6800;
background: rgba(255, 104, 0, 0.08);
padding: 8rpx 20rpx;
border-radius: 24rpx;
font-weight: 500;
}
.hero-cta {
display: inline-flex;
align-items: center;
justify-content: center;
background: #ff6800;
color: #ffffff;
font-size: 30rpx;
font-weight: 600;
padding: 24rpx 64rpx;
border-radius: 48rpx;
margin-top: 48rpx;
box-shadow: 0 8rpx 24rpx rgba(255, 104, 0, 0.3);
}
/* 3D插画区 */
.hero-illustration {
position: relative;
height: 400rpx;
margin-top: 40rpx;
}
.hero-illust-item {
position: absolute;
}
.hero-illist-tshirt {
top: 20rpx;
left: 20rpx;
-webkit-transform: rotate(-8deg);
transform: rotate(-8deg);
}
.hero-illist-bag {
top: 60rpx;
right: 40rpx;
-webkit-transform: rotate(12deg);
transform: rotate(12deg);
}
.hero-illist-box {
bottom: 0;
left: 50%;
-webkit-transform: translateX(-50%) rotate(-3deg);
transform: translateX(-50%) rotate(-3deg);
}
.illust-placeholder {
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 80rpx;
}
.illust-placeholder.tshirt {
width: 200rpx;
height: 220rpx;
background: linear-gradient(135deg, #ff6800 0%, #ff8c40 100%);
}
.illust-placeholder.bag {
width: 180rpx;
height: 200rpx;
background: linear-gradient(135deg, #f26522 0%, #ff8855 100%);
}
.illust-placeholder.box {
width: 240rpx;
height: 180rpx;
background: linear-gradient(135deg, #ff6800 0%, #ffa040 100%);
}
/* 通用 section */
.section-title {
font-size: 40rpx;
font-weight: 700;
color: #1a1a1a;
text-align: center;
display: block;
}
.section-subtitle {
font-size: 26rpx;
color: #999;
text-align: center;
margin-top: 12rpx;
display: block;
}
.section-title-small {
font-size: 28rpx;
color: #666;
text-align: center;
display: block;
margin-bottom: 32rpx;
}
/* 信任指标 */
.trust-section {
padding: 64rpx 32rpx;
background: #ffffff;
}
.trust-grid {
display: flex;
flex-wrap: wrap;
gap: 24rpx;
}
.trust-card {
flex: 1;
min-width: 160rpx;
background: #fff8f3;
border-radius: 16rpx;
padding: 28rpx 16rpx;
text-align: center;
}
.trust-number {
font-size: 40rpx;
font-weight: 700;
color: #ff6800;
display: block;
}
.trust-label {
font-size: 24rpx;
color: #666;
margin-top: 8rpx;
display: block;
}
/* 4步流程 */
.steps-section {
padding: 64rpx 32rpx;
background: #fafafa;
}
.steps-list {
margin-top: 40rpx;
}
.step-item {
display: flex;
align-items: center;
padding: 24rpx;
background: #ffffff;
border-radius: 16rpx;
margin-bottom: 16rpx;
transition: all 0.3s;
border: 2rpx solid transparent;
}
.step-item.active {
border-color: #ff6800;
box-shadow: 0 4rpx 16rpx rgba(255, 104, 0, 0.1);
}
.step-number {
font-size: 36rpx;
font-weight: 800;
color: #ddd;
width: 80rpx;
flex-shrink: 0;
}
.step-item.active .step-number {
color: #ff6800;
}
.step-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 6rpx;
}
.step-title {
font-size: 30rpx;
font-weight: 600;
color: #333;
}
.step-desc {
font-size: 24rpx;
color: #999;
}
.step-visual {
margin-top: 32rpx;
}
.step-visual-card {
background: #ffffff;
border-radius: 20rpx;
padding: 48rpx 32rpx;
text-align: center;
border: 2rpx solid #ff6800;
}
.step-visual-icon {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
background: #fff0e5;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 24rpx;
}
.step-visual-emoji {
font-size: 56rpx;
}
.step-visual-text {
font-size: 28rpx;
color: #666;
line-height: 1.6;
}
/* 全球POD货盘 */
.catalog-section {
padding: 64rpx 0;
background: #ffffff;
}
.catalog-section .section-title {
padding: 0 32rpx;
}
.category-tabs {
white-space: nowrap;
padding: 24rpx 32rpx;
}
.cat-tab {
display: inline-block;
padding: 12rpx 32rpx;
margin-right: 16rpx;
font-size: 26rpx;
color: #666;
background: #f5f5f5;
border-radius: 32rpx;
transition: all 0.3s;
}
.cat-tab.active {
background: #ff6800;
color: #ffffff;
}
.product-preview-grid {
display: flex;
flex-wrap: wrap;
padding: 0 32rpx;
gap: 24rpx;
}
.product-preview-card {
width: calc(50% - 12rpx);
background: #ffffff;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}
.product-preview-img {
width: 100%;
height: 280rpx;
display: flex;
align-items: center;
justify-content: center;
}
.product-preview-emoji {
font-size: 80rpx;
}
.product-preview-info {
padding: 16rpx;
}
.product-preview-name {
font-size: 26rpx;
color: #333;
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.product-preview-price {
font-size: 28rpx;
color: #ff6800;
font-weight: 600;
margin-top: 8rpx;
display: block;
}
.see-more {
display: flex;
align-items: center;
justify-content: center;
gap: 8rpx;
padding: 24rpx;
font-size: 28rpx;
color: #ff6800;
}
.see-more .arrow {
font-size: 24rpx;
}
/* 平台功能 */
.features-section {
padding: 64rpx 32rpx;
background: #fafafa;
}
.features-grid {
display: flex;
flex-wrap: wrap;
gap: 24rpx;
margin-top: 40rpx;
}
.feature-card {
width: calc(50% - 12rpx);
background: #ffffff;
border-radius: 16rpx;
padding: 32rpx 24rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 12rpx;
}
.feature-icon {
width: 80rpx;
height: 80rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
}
.feature-emoji {
font-size: 40rpx;
}
.feature-title {
font-size: 30rpx;
font-weight: 600;
color: #333;
}
.feature-desc {
font-size: 24rpx;
color: #999;
line-height: 1.5;
}
/* 为什么选择 */
.why-section {
padding: 64rpx 32rpx;
background: #ffffff;
}
.why-grid {
display: flex;
flex-wrap: wrap;
gap: 24rpx;
margin-top: 40rpx;
}
.why-card {
width: calc(50% - 12rpx);
text-align: center;
padding: 32rpx 16rpx;
background: #fff8f3;
border-radius: 16rpx;
}
.why-icon {
width: 72rpx;
height: 72rpx;
margin: 0 auto 16rpx;
display: flex;
align-items: center;
justify-content: center;
background: #ffffff;
border-radius: 50%;
}
.why-emoji {
font-size: 36rpx;
}
.why-title {
font-size: 28rpx;
font-weight: 600;
color: #333;
display: block;
margin-bottom: 8rpx;
}
.why-desc {
font-size: 22rpx;
color: #999;
display: block;
}
/* 公司简介 */
.company-section {
padding: 64rpx 32rpx;
background: #fafafa;
}
.company-card {
background: #ffffff;
border-radius: 20rpx;
padding: 40rpx 32rpx;
margin-top: 32rpx;
}
.company-headline {
display: flex;
flex-direction: column;
font-size: 32rpx;
font-weight: 600;
color: #1a1a1a;
line-height: 1.6;
margin-bottom: 32rpx;
}
.company-content {
display: flex;
flex-direction: column;
gap: 24rpx;
}
.company-block-title {
font-size: 26rpx;
font-weight: 600;
color: #ff6800;
display: block;
margin-bottom: 8rpx;
}
.company-block-text {
font-size: 24rpx;
color: #666;
line-height: 1.7;
}
.company-stats {
display: flex;
justify-content: space-around;
margin-top: 32rpx;
padding-top: 32rpx;
border-top: 1rpx solid #eee;
}
.company-stat {
text-align: center;
}
.company-stat-number {
font-size: 36rpx;
font-weight: 700;
color: #ff6800;
display: block;
}
.company-stat-label {
font-size: 22rpx;
color: #999;
margin-top: 4rpx;
display: block;
}
/* 用户案例 */
.cases-section {
padding: 64rpx 0;
background: #ffffff;
}
.cases-section .section-title {
padding: 0 32rpx;
}
.cases-scroll {
white-space: nowrap;
padding: 32rpx;
}
.case-card {
display: inline-block;
width: 480rpx;
background: #ffffff;
border-radius: 20rpx;
overflow: hidden;
margin-right: 24rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
vertical-align: top;
}
.case-image {
width: 100%;
height: 320rpx;
display: flex;
align-items: center;
justify-content: center;
}
.case-emoji {
font-size: 80rpx;
}
.case-info {
padding: 24rpx;
}
.case-title {
font-size: 28rpx;
font-weight: 600;
color: #333;
display: block;
margin-bottom: 12rpx;
}
.case-tags {
display: flex;
gap: 8rpx;
margin-bottom: 16rpx;
}
.case-tag {
font-size: 20rpx;
padding: 4rpx 12rpx;
background: #fff0e5;
color: #ff6800;
border-radius: 8rpx;
}
.case-metrics {
display: flex;
gap: 24rpx;
padding-top: 16rpx;
border-top: 1rpx solid #eee;
}
.case-metric-value {
font-size: 32rpx;
font-weight: 700;
color: #ff6800;
display: block;
}
.case-metric-label {
font-size: 22rpx;
color: #999;
display: block;
}
/* 最终CTA */
.cta-section {
position: relative;
padding: 80rpx 32rpx;
overflow: hidden;
}
.cta-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, #ff6800 0%, #ff8c40 100%);
}
.cta-content {
position: relative;
z-index: 2;
text-align: center;
}
.cta-title {
display: flex;
flex-direction: column;
font-size: 48rpx;
font-weight: 700;
color: #ffffff;
line-height: 1.4;
}
.cta-desc {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.85);
margin-top: 16rpx;
display: block;
}
.cta-input-wrap {
display: flex;
gap: 16rpx;
margin-top: 40rpx;
padding: 0 16rpx;
}
.cta-input {
flex: 1;
height: 80rpx;
background: rgba(255, 255, 255, 0.95);
border-radius: 40rpx;
padding: 0 32rpx;
font-size: 26rpx;
color: #333;
}
.cta-placeholder {
color: #ccc;
}
.cta-btn {
display: flex;
align-items: center;
justify-content: center;
background: #1a1a1a;
color: #ffffff;
font-size: 28rpx;
font-weight: 600;
padding: 0 40rpx;
border-radius: 40rpx;
}
/* 底部 */
.footer {
background: #121212;
padding: 48rpx 32rpx;
padding-bottom: calc(48rpx + env(safe-area-inset-bottom));
}
.footer-top {
text-align: center;
margin-bottom: 40rpx;
}
.footer-logo {
display: flex;
align-items: baseline;
justify-content: center;
gap: 8rpx;
margin-bottom: 16rpx;
}
.footer-logo-en {
font-size: 36rpx;
font-weight: 700;
color: #ff6800;
font-style: italic;
}
.footer-logo-cn {
font-size: 28rpx;
color: #fff;
}
.footer-slogan {
font-size: 22rpx;
color: rgba(255, 255, 255, 0.5);
}
.footer-links {
display: flex;
justify-content: space-around;
margin-bottom: 40rpx;
}
.footer-col {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.footer-col-title {
font-size: 26rpx;
font-weight: 600;
color: #fff;
margin-bottom: 8rpx;
}
.footer-link {
font-size: 22rpx;
color: rgba(255, 255, 255, 0.5);
}
.footer-bottom {
text-align: center;
padding-top: 32rpx;
border-top: 1rpx solid rgba(255, 255, 255, 0.1);
}
.footer-copyright {
font-size: 20rpx;
color: rgba(255, 255, 255, 0.3);
.index-page {
width: 100%;
min-height: 100vh;
background: #ffffff;
}
@@ -1,6 +1,6 @@
(global["webpackJsonp"] = global["webpackJsonp"] || []).push([["pages/product-detail/product-detail"],{
/***/ 65:
/***/ 71:
/*!********************************************************************************************************!*\
!*** C:/gs/project/官网小程序demo/官网小程序demo_uni/main.js?{"page":"pages%2Fproduct-detail%2Fproduct-detail"} ***!
\********************************************************************************************************/
@@ -13,7 +13,7 @@
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ 4);
__webpack_require__(/*! uni-pages */ 30);
var _vue = _interopRequireDefault(__webpack_require__(/*! vue */ 25));
var _productDetail = _interopRequireDefault(__webpack_require__(/*! ./pages/product-detail/product-detail.vue */ 66));
var _productDetail = _interopRequireDefault(__webpack_require__(/*! ./pages/product-detail/product-detail.vue */ 72));
// @ts-ignore
wx.__webpack_require_UNI_MP_PLUGIN__ = __webpack_require__;
createPage(_productDetail.default);
@@ -21,7 +21,7 @@ createPage(_productDetail.default);
/***/ }),
/***/ 66:
/***/ 72:
/*!*************************************************************************************!*\
!*** C:/gs/project/官网小程序demo/官网小程序demo_uni/pages/product-detail/product-detail.vue ***!
\*************************************************************************************/
@@ -30,10 +30,10 @@ createPage(_productDetail.default);
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _product_detail_vue_vue_type_template_id_685304e6___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./product-detail.vue?vue&type=template&id=685304e6& */ 67);
/* harmony import */ var _product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./product-detail.vue?vue&type=script&lang=js& */ 69);
/* harmony import */ var _product_detail_vue_vue_type_template_id_685304e6___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./product-detail.vue?vue&type=template&id=685304e6& */ 73);
/* harmony import */ var _product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./product-detail.vue?vue&type=script&lang=js& */ 75);
/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__) if(["default"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__[key]; }) }(__WEBPACK_IMPORT_KEY__));
/* harmony import */ var _product_detail_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./product-detail.vue?vue&type=style&index=0&lang=css& */ 71);
/* harmony import */ var _product_detail_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./product-detail.vue?vue&type=style&index=0&lang=css& */ 77);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/runtime/componentNormalizer.js */ 36);
var renderjs
@@ -62,7 +62,7 @@ component.options.__file = "pages/product-detail/product-detail.vue"
/***/ }),
/***/ 67:
/***/ 73:
/*!********************************************************************************************************************!*\
!*** C:/gs/project/官网小程序demo/官网小程序demo_uni/pages/product-detail/product-detail.vue?vue&type=template&id=685304e6& ***!
\********************************************************************************************************************/
@@ -71,7 +71,7 @@ component.options.__file = "pages/product-detail/product-detail.vue"
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_17_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_template_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_uni_app_loader_page_meta_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_template_id_685304e6___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--17-0!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/template.js!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-uni-app-loader/page-meta.js!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!./product-detail.vue?vue&type=template&id=685304e6& */ 68);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_17_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_template_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_uni_app_loader_page_meta_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_template_id_685304e6___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--17-0!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/template.js!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-uni-app-loader/page-meta.js!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!./product-detail.vue?vue&type=template&id=685304e6& */ 74);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "render", function() { return _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_17_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_template_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_uni_app_loader_page_meta_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_template_id_685304e6___WEBPACK_IMPORTED_MODULE_0__["render"]; });
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_17_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_template_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_uni_app_loader_page_meta_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_template_id_685304e6___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"]; });
@@ -84,7 +84,7 @@ __webpack_require__.r(__webpack_exports__);
/***/ }),
/***/ 68:
/***/ 74:
/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--17-0!./node_modules/@dcloudio/webpack-uni-mp-loader/lib/template.js!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-uni-app-loader/page-meta.js!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!./node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!C:/gs/project/官网小程序demo/官网小程序demo_uni/pages/product-detail/product-detail.vue?vue&type=template&id=685304e6& ***!
\********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
@@ -102,6 +102,29 @@ var render = function () {
var _vm = this
var _h = _vm.$createElement
var _c = _vm._self._c || _h
var g0 = _vm.colors.length
var g1 = _vm.colors.length
var g2 = _vm.sizes.length
var g3 = _vm.sizes.length
var g4 = _vm.productParams.length
var g5 = _vm.productParams.length
var g6 = _vm.sizeChart.rows && _vm.sizeChart.rows.length
var g7 = _vm.sizeChart.rows && _vm.sizeChart.rows.length
_vm.$mp.data = Object.assign(
{},
{
$root: {
g0: g0,
g1: g1,
g2: g2,
g3: g3,
g4: g4,
g5: g5,
g6: g6,
g7: g7,
},
}
)
}
var recyclableRender = false
var staticRenderFns = []
@@ -111,7 +134,7 @@ render._withStripped = true
/***/ }),
/***/ 69:
/***/ 75:
/*!**************************************************************************************************************!*\
!*** C:/gs/project/官网小程序demo/官网小程序demo_uni/pages/product-detail/product-detail.vue?vue&type=script&lang=js& ***!
\**************************************************************************************************************/
@@ -120,14 +143,14 @@ render._withStripped = true
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_babel_loader_lib_index_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_13_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_script_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/babel-loader/lib!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--13-1!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/script.js!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!./product-detail.vue?vue&type=script&lang=js& */ 70);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_babel_loader_lib_index_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_13_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_script_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/babel-loader/lib!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--13-1!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/script.js!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!./product-detail.vue?vue&type=script&lang=js& */ 76);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_babel_loader_lib_index_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_13_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_script_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_babel_loader_lib_index_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_13_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_script_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__);
/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_babel_loader_lib_index_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_13_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_script_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__) if(["default"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_babel_loader_lib_index_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_13_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_script_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__));
/* harmony default export */ __webpack_exports__["default"] = (_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_babel_loader_lib_index_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_13_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_script_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }),
/***/ 70:
/***/ 76:
/*!*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/babel-loader/lib!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--13-1!./node_modules/@dcloudio/webpack-uni-mp-loader/lib/script.js!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!./node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!C:/gs/project/官网小程序demo/官网小程序demo_uni/pages/product-detail/product-detail.vue?vue&type=script&lang=js& ***!
\*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
@@ -135,283 +158,442 @@ __webpack_require__.r(__webpack_exports__);
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(uni) {
var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ 4);
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
var _regenerator = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/regenerator */ 55));
var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/asyncToGenerator */ 57));
var _public = __webpack_require__(/*! @/api/public.js */ 58);
var DetailSwiper = function DetailSwiper() {
__webpack_require__.e(/*! require.ensure | pages/product-detail/components/DetailSwiper */ "pages/product-detail/components/DetailSwiper").then((function () {
return resolve(__webpack_require__(/*! ./components/DetailSwiper.vue */ 163));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var ProductInfo = function ProductInfo() {
__webpack_require__.e(/*! require.ensure | pages/product-detail/components/ProductInfo */ "pages/product-detail/components/ProductInfo").then((function () {
return resolve(__webpack_require__(/*! ./components/ProductInfo.vue */ 170));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var ColorSelector = function ColorSelector() {
__webpack_require__.e(/*! require.ensure | pages/product-detail/components/ColorSelector */ "pages/product-detail/components/ColorSelector").then((function () {
return resolve(__webpack_require__(/*! ./components/ColorSelector.vue */ 177));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var SizeSelector = function SizeSelector() {
__webpack_require__.e(/*! require.ensure | pages/product-detail/components/SizeSelector */ "pages/product-detail/components/SizeSelector").then((function () {
return resolve(__webpack_require__(/*! ./components/SizeSelector.vue */ 184));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var ParamsTable = function ParamsTable() {
__webpack_require__.e(/*! require.ensure | pages/product-detail/components/ParamsTable */ "pages/product-detail/components/ParamsTable").then((function () {
return resolve(__webpack_require__(/*! ./components/ParamsTable.vue */ 191));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var SizeChart = function SizeChart() {
__webpack_require__.e(/*! require.ensure | pages/product-detail/components/SizeChart */ "pages/product-detail/components/SizeChart").then((function () {
return resolve(__webpack_require__(/*! ./components/SizeChart.vue */ 198));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var PackagingSpec = function PackagingSpec() {
__webpack_require__.e(/*! require.ensure | pages/product-detail/components/PackagingSpec */ "pages/product-detail/components/PackagingSpec").then((function () {
return resolve(__webpack_require__(/*! ./components/PackagingSpec.vue */ 205));
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
};
var _default = {
components: {
DetailSwiper: DetailSwiper,
ProductInfo: ProductInfo,
ColorSelector: ColorSelector,
SizeSelector: SizeSelector,
ParamsTable: ParamsTable,
SizeChart: SizeChart,
PackagingSpec: PackagingSpec
},
data: function data() {
return {
productId: null,
loading: false,
product: {
name: '180G牛奶丝T恤 DG120',
code: 'DG120',
price: '28.00',
originalPrice: '35.00',
moq: 1,
leadTime: '48小时',
craft: '烫画/数码直喷'
name: '',
sku: '',
country: '',
price: {
symbol: '¥',
integer: '0',
decimal: ''
},
quickInfo: []
},
productImages: [{
bg: '#F5F5F5',
emoji: '👕'
}, {
bg: '#E8E8E8',
emoji: '👕'
}, {
bg: '#F0F0F0',
emoji: '👕'
}],
productTags: [{
text: '可定制',
bg: '#FFF0E5',
color: '#FF6800'
}, {
text: '现货',
bg: '#E5F5FF',
color: '#1890FF'
}, {
text: '快返',
bg: '#F0FFE5',
color: '#52C41A'
}],
colors: [{
name: '白色',
value: '#FFFFFF'
}, {
name: '黑色',
value: '#1a1a1a'
}, {
name: '灰色',
value: '#999999'
}, {
name: '橙色',
value: '#FF6800'
}, {
name: '藏青',
value: '#1B365D'
}, {
name: '军绿',
value: '#4A5D23'
}],
selectedColor: 0,
sizes: ['XS', 'S', 'M', 'L', 'XL', '2XL', '3XL'],
selectedSize: 'M',
productParams: [{
label: '克重',
value: '180g'
}, {
label: '材质',
value: '牛奶丝(改性聚酯纤维)'
}, {
label: '版型',
value: '常规版'
}, {
label: '领型',
value: '圆领'
}, {
label: '袖型',
value: '短袖'
}, {
label: '适用工艺',
value: '烫画、数码直喷、刺绣'
}, {
label: '可售区域',
value: '全球'
}, {
label: '洗涤说明',
value: '冷水机洗,不可漂白'
}],
crafts: [{
name: '烫画',
desc: '色彩鲜艳,适合复杂图案,成本低',
emoji: '🎨',
bg: '#FFF0E5'
}, {
name: '数码直喷',
desc: '触感柔软,透气性好,适合大面积印花',
emoji: '🖨️',
bg: '#E5F5FF'
}, {
name: '刺绣',
desc: '质感高级,经久耐用,适合logo',
emoji: '🪡',
bg: '#F0FFE5'
}],
isFav: false
productImages: [],
colors: [],
selectedColorId: '',
sizes: [],
selectedSize: '',
productParams: [],
sizeChart: {},
// 变体列表(来自接口 variants),用于校验尺码+颜色组合、获取价格、包装规格
variants: [],
packaging: null
};
},
onLoad: function onLoad(options) {
if (options.id) {
this.setData({
productId: options.id
});
if (options && options.id) {
this.productId = options.id;
this.loadDetail(options.id);
}
},
methods: {
selectColor: function selectColor(e) {
this.setData({
selectedColor: e.currentTarget.dataset.index
loadDetail: function loadDetail(goodId) {
var _this = this;
return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
var res, detail;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (goodId) {
_context.next = 2;
break;
}
return _context.abrupt("return");
case 2:
_this.loading = true;
_context.prev = 3;
_context.next = 6;
return (0, _public.getGoodsDetail)(goodId);
case 6:
res = _context.sent;
detail = res && res.data && res.data.data || {};
_this.applyDetail(detail);
_context.next = 14;
break;
case 11:
_context.prev = 11;
_context.t0 = _context["catch"](3);
console.error('[product-detail loadDetail Error]', _context.t0);
case 14:
_context.prev = 14;
_this.loading = false;
return _context.finish(14);
case 17:
case "end":
return _context.stop();
}
}
}, _callee, null, [[3, 11, 14, 17]]);
}))();
},
/**
* 将接口详情数据映射为各组件所需结构
*/
applyDetail: function applyDetail(detail) {
// 1. 产品信息:名称 / SKU / 国家 / 价格 / 4 列快捷信息
this.product = {
name: detail.goodName || '—',
sku: detail.productCode || '—',
country: detail.country && detail.country.countryName || '—',
price: this.parsePrice(detail.price),
quickInfo: [{
label: '生产工艺',
value: detail.details && detail.details.productionProcess || '—'
}, {
label: '发货时效',
value: detail.productionCycleHours ? detail.productionCycleHours + '小时' : '—'
}, {
label: '印花',
value: detail.details && detail.details.designArea || '—'
}, {
label: '产品编码',
value: detail.productCode || '—'
}]
};
// 2. 图片画廊:按 sortOrder 升序,首图置顶
var media = detail.media || {};
var images = (media.images || []).slice().sort(function (a, b) {
return (a.sortOrder || 0) - (b.sortOrder || 0);
}).map(function (img) {
return img.url;
}).filter(function (url) {
return url;
});
if (media.primaryImageUrl && images.indexOf(media.primaryImageUrl) === -1) {
images.unshift(media.primaryImageUrl);
}
if (!images.length && detail.image) {
images.push(detail.image);
}
this.productImages = images;
// 3. 颜色:仅取启用项,按 sortOrder 升序
var colors = (detail.options && detail.options.colors || []).filter(function (c) {
return c.enabled !== false;
}).slice().sort(function (a, b) {
return (a.sortOrder || 0) - (b.sortOrder || 0);
}).map(function (c) {
return {
id: c.id,
name: c.name,
value: c.hex
};
});
this.colors = colors;
this.selectedColorId = colors.length ? colors[0].id : '';
// 4. 尺码:仅取启用项,按 sortOrder 升序
var sizes = (detail.options && detail.options.sizes || []).filter(function (s) {
return s.enabled !== false;
}).slice().sort(function (a, b) {
return (a.sortOrder || 0) - (b.sortOrder || 0);
}).map(function (s) {
return s.name;
});
this.sizes = sizes;
this.selectedSize = sizes.length ? sizes[0] : '';
// 5. 产品参数(含可展开的"补充说明")
this.productParams = this.buildParams(detail);
// 6. 变体:用于尺码+颜色校验、价格联动、包装规格来源
this.variants = Array.isArray(detail.variants) ? detail.variants.slice() : [];
// 7. 尺码表
this.sizeChart = this.buildSizeChart(detail.sizeChart);
// 8. 包装规格(从 variants 按尺码去重生成)
this.packaging = this.buildPackaging(this.variants);
// 9. 初始价格(按默认选中的 尺码+颜色 匹配变体价格)
this.syncPriceByVariant();
},
/**
* 价格拆分:'35' → { symbol:'¥', integer:'35', decimal:'' }
* '35.50' → { symbol:'¥', integer:'35', decimal:'.50' }
*/
parsePrice: function parsePrice(price) {
var raw = price != null ? String(price) : '';
var integer = raw;
var decimal = '';
var dot = raw.indexOf('.');
if (dot >= 0) {
integer = raw.slice(0, dot) || '0';
decimal = raw.slice(dot);
}
return {
symbol: '¥',
integer: integer || '0',
decimal: decimal
};
},
/**
* 构造产品参数列表:克重 / 材质 / 补充说明(可展开)
*/
buildParams: function buildParams(detail) {
var d = detail.details || {};
var params = [];
if (detail.minWeightG) {
params.push({
label: '克重',
value: detail.minWeightG + 'g'
});
}
if (d.materialDescription) {
params.push({
label: '材质',
value: d.materialDescription
});
}
var expandableText = this.buildExpandableText(d);
if (expandableText) {
params.push({
label: '补充说明',
expandable: true,
value: expandableText
});
}
return params;
},
/**
* 拼接"补充说明"多段文本:材质说明/产品性能/适用情景/洗涤说明/图片要求/特殊说明/温馨提示
*/
buildExpandableText: function buildExpandableText(d) {
var lines = [];
if (d.materialDescription) lines.push('【 材质说明 】\n' + d.materialDescription);
if (d.productPerformance) lines.push('【 产品性能 】\n' + d.productPerformance);
if (d.applicableScenarios) lines.push('【 适用情景 】\n' + d.applicableScenarios);
if (d.washingInstructions) lines.push('【 洗涤说明 】\n' + d.washingInstructions);
if (d.pictureRequest) lines.push('【 图片要求 】\n' + d.pictureRequest);
if (d.specialDescription) lines.push('【 特殊说明 】\n' + d.specialDescription);
if (d.reminder) lines.push('【 温馨提醒 】\n' + d.reminder);
return lines.join('\n');
},
/**
* 构造尺码表:接口 measurements.key (chest/bodyLength/shoulder/sleeveLength) → 表格列
*/
buildSizeChart: function buildSizeChart(sizeChart) {
if (!sizeChart || !sizeChart.rows || !sizeChart.rows.length) return {};
var columns = ['尺码', '肩宽', '胸围', '衣长', '袖长'];
var rows = sizeChart.rows.map(function (row) {
var measurements = row.measurements || [];
var get = function get(key) {
var m = measurements.find(function (x) {
return x.key === key;
});
return m ? m.cm : '';
};
return {
size: row.sizeName || '',
shoulder: get('shoulder'),
chest: get('chest'),
length: get('bodyLength'),
sleeve: get('sleeveLength')
};
});
return {
unit: 'cm',
columns: columns,
rows: rows
};
},
/**
* 构建包装规格表(按尺码聚合 → 每行一个尺码)
* 数据来源:variants[].{ sizeId, sizeName, boxLengthCm, boxWidthCm, boxHeightCm, weightG }
*/
buildPackaging: function buildPackaging(variants) {
if (!Array.isArray(variants) || !variants.length) return null;
var CM_TO_IN = 0.393701;
var G_TO_LB = 0.00220462;
var map = new Map();
variants.forEach(function (v) {
if (!v || !v.sizeId) return;
if (map.has(v.sizeId)) return; // 按尺码取第一条(所有颜色的包装尺寸/重量一般相同)
var l = parseFloat(v.boxLengthCm) || 0;
var w = parseFloat(v.boxWidthCm) || 0;
var h = parseFloat(v.boxHeightCm) || 0;
var g = parseFloat(v.weightG) || 0;
var cm3 = l * w * h;
var in3 = cm3 * Math.pow(CM_TO_IN, 3);
map.set(v.sizeId, {
size: v.sizeName || '',
sizeId: v.sizeId,
dimension: {
cm: "".concat(l.toFixed(1), "*").concat(w.toFixed(1), "*").concat(h.toFixed(1), "cm"),
in: "".concat((l * CM_TO_IN).toFixed(2), "*").concat((w * CM_TO_IN).toFixed(2), "*").concat((h * CM_TO_IN).toFixed(2), "in")
},
volume: {
cm: "".concat(cm3.toFixed(2), "cm\xB3"),
in: "".concat(in3.toFixed(2), "in\xB3")
},
weight: {
cm: "".concat(g.toFixed(2), "g"),
in: "".concat((g * G_TO_LB).toFixed(2), "lb")
}
});
});
if (!map.size) return null;
// 按 sizes 顺序排序(保持 S→M→L→XL 顺序)
var orderMap = {};
this.sizes.forEach(function (s, i) {
return orderMap[s] = i;
});
var rows = Array.from(map.values()).sort(function (a, b) {
var ai = orderMap[a.size] == null ? 999 : orderMap[a.size];
var bi = orderMap[b.size] == null ? 999 : orderMap[b.size];
return ai - bi;
});
return {
unit: 'cm',
columns: ['尺码', '尺寸', '体积', '重量'],
rows: rows
};
},
/**
* 根据当前 selectedColorId + selectedSize 找到匹配的 variant
* 命中后更新 ProductInfo 的价格;找不到则保持原商品价格
*/
findVariant: function findVariant() {
var sizeName = this.selectedSize;
var colorId = this.selectedColorId;
if (!sizeName || !colorId || !this.variants.length) return null;
return this.variants.find(function (v) {
return v && String(v.colorId) === String(colorId) && String(v.sizeName) === String(sizeName);
}) || null;
},
syncPriceByVariant: function syncPriceByVariant() {
var v = this.findVariant();
if (v && v.price != null) {
this.$set(this.product, 'price', this.parsePrice(v.price));
}
},
/**
* 颜色列表 + 根据已选尺码标记该颜色是否可用(有对应启用的 variant)
* 数据项: { id, name, value, enabled }
*/
selectColor: function selectColor(id) {
this.selectedColorId = id;
this.syncPriceByVariant();
},
/**
* 尺码列表 + 根据已选颜色标记该尺码是否可用
* 数据项: 直接返回字符串(SizeSelector 兼容),不可用的对应按钮会 disabled 掉,因此用对象包一层
*/
selectSize: function selectSize(size) {
this.selectedSize = size;
this.syncPriceByVariant();
}
},
computed: {
/**
* 颜色列表 + 可用态标记(给 ColorSelector 用,用于 disabled 样式)
* - 如果没选尺码:所有已 enabled 的颜色都可选
* - 如果已选尺码:仅保留存在 (colorId + sizeName) 组合且 variant.enabled 的颜色
*/
colorListWithAvailability: function colorListWithAvailability() {
var _this2 = this;
var sizeName = this.selectedSize;
return this.colors.map(function (c) {
var enabled = c.enabled !== false;
if (sizeName && _this2.variants.length) {
enabled = _this2.variants.some(function (v) {
return v && v.enabled !== false && String(v.colorId) === String(c.id) && String(v.sizeName) === String(sizeName);
});
}
return Object.assign({}, c, {
enabled: enabled
});
});
},
selectSize: function selectSize(e) {
this.setData({
selectedSize: e.currentTarget.dataset.size
});
},
toggleFav: function toggleFav() {
this.setData({
isFav: !this.isFav
});
uni.showToast({
title: this.isFav ? '已收藏' : '已取消',
icon: 'none'
});
},
contactService: function contactService() {
uni.showToast({
title: '客服功能开发中',
icon: 'none'
});
},
addToCart: function addToCart() {
uni.showToast({
title: '已加入清单',
icon: 'success'
});
},
startDesign: function startDesign() {
uni.showToast({
title: '定制功能开发中',
icon: 'none'
/**
* 尺码列表 + 可用态标记
* SizeSelector 原始 list 是字符串数组,这里扩展为 [{ name, enabled }]
*/
sizeListWithAvailability: function sizeListWithAvailability() {
var _this3 = this;
var colorId = this.selectedColorId;
return this.sizes.map(function (s) {
var enabled = true;
if (colorId && _this3.variants.length) {
enabled = _this3.variants.some(function (v) {
return v && v.enabled !== false && String(v.colorId) === String(colorId) && String(v.sizeName) === String(s);
});
}
return {
name: s,
enabled: enabled
};
});
}
}
};
exports.default = _default;
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./node_modules/@dcloudio/uni-mp-weixin/dist/index.js */ 2)["default"]))
/***/ }),
/***/ 71:
/***/ 77:
/*!**********************************************************************************************************************!*\
!*** C:/gs/project/官网小程序demo/官网小程序demo_uni/pages/product-detail/product-detail.vue?vue&type=style&index=0&lang=css& ***!
\**********************************************************************************************************************/
@@ -420,14 +602,14 @@ exports.default = _default;
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/stylePostLoader.js!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--6-oneOf-1-2!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/postcss-loader/src??ref--6-oneOf-1-3!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!./product-detail.vue?vue&type=style&index=0&lang=css& */ 72);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/stylePostLoader.js!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--6-oneOf-1-2!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/postcss-loader/src??ref--6-oneOf-1-3!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!../../../../../app/HB/HBuilderX.5.24.2026081301/HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!./product-detail.vue?vue&type=style&index=0&lang=css& */ 78);
/* harmony import */ var _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__);
/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__) if(["default"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__));
/* harmony default export */ __webpack_exports__["default"] = (_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_loaders_stylePostLoader_js_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_webpack_preprocess_loader_index_js_ref_6_oneOf_1_2_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_3_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_vue_cli_plugin_uni_packages_vue_loader_lib_index_js_vue_loader_options_app_HB_HBuilderX_5_24_2026081301_HBuilderX_plugins_uniapp_cli_node_modules_dcloudio_webpack_uni_mp_loader_lib_style_js_product_detail_vue_vue_type_style_index_0_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }),
/***/ 72:
/***/ 78:
/*!**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader??ref--6-oneOf-1-2!./node_modules/postcss-loader/src??ref--6-oneOf-1-3!./node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib??vue-loader-options!./node_modules/@dcloudio/webpack-uni-mp-loader/lib/style.js!C:/gs/project/官网小程序demo/官网小程序demo_uni/pages/product-detail/product-detail.vue?vue&type=style&index=0&lang=css& ***!
\**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
@@ -440,5 +622,5 @@ __webpack_require__.r(__webpack_exports__);
/***/ })
},[[65,"common/runtime","common/vendor"]]]);
},[[71,"common/runtime","common/vendor"]]]);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/product-detail/product-detail.js.map
@@ -1,4 +1,12 @@
{
"navigationBarTitleText": "产品详情",
"usingComponents": {}
"usingComponents": {
"detail-swiper": "/pages/product-detail/components/DetailSwiper",
"product-info": "/pages/product-detail/components/ProductInfo",
"color-selector": "/pages/product-detail/components/ColorSelector",
"size-selector": "/pages/product-detail/components/SizeSelector",
"params-table": "/pages/product-detail/components/ParamsTable",
"size-chart": "/pages/product-detail/components/SizeChart",
"packaging-spec": "/pages/product-detail/components/PackagingSpec"
}
}
@@ -1 +1 @@
<view class="detail-page"><view class="detail-images"><swiper class="detail-swiper" indicator-dots="{{true}}" indicator-color="rgba(255,255,255,0.4)" indicator-active-color="#FF6800" circular="{{true}}"><block wx:for="{{productImages}}" wx:for-item="item" wx:for-index="index" wx:key="index"><swiper-item><view class="swiper-img" style="{{('background: '+item.bg+';')}}"><text class="swiper-emoji">{{item.emoji}}</text></view></swiper-item></block></swiper><view class="detail-badges"><block wx:for="{{productTags}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view class="detail-badge" style="{{('background: '+item.bg+'; color: '+item.color+';')}}">{{''+item.text+''}}</view></block></view></view><view class="detail-info-section"><view class="detail-header"><text class="detail-name">{{product.name}}</text><text class="detail-code">{{"SKU: "+product.code}}</text></view><view class="detail-price-row"><text class="detail-price">{{"¥"+product.price}}</text><text class="detail-price-unit">起</text><block wx:if="{{product.originalPrice}}"><text class="detail-price-original">{{"¥"+product.originalPrice}}</text></block></view><view class="detail-meta"><view class="meta-item"><text class="meta-label">起订量</text><text class="meta-value">{{product.moq+"件"}}</text></view><view class="meta-item"><text class="meta-label">生产周期</text><text class="meta-value">{{product.leadTime}}</text></view><view class="meta-item"><text class="meta-label">工艺</text><text class="meta-value">{{product.craft}}</text></view></view></view><view class="detail-section"><text class="section-label">颜色选择</text><view class="color-options"><block wx:for="{{colors}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view class="{{['color-option '+(selectedColor===index?'selected':'')]}}" data-index="{{index}}" data-event-opts="{{[['tap',[['selectColor',['$event']]]]]}}" bindtap="__e"><view class="color-dot" style="{{('background: '+item.value+';')}}"></view><text class="color-name">{{item.name}}</text></view></block></view></view><view class="detail-section"><text class="section-label">尺码选择</text><view class="size-options"><block wx:for="{{sizes}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view class="{{['size-option '+(selectedSize===item?'selected':'')]}}" data-size="{{item}}" data-event-opts="{{[['tap',[['selectSize',['$event']]]]]}}" bindtap="__e">{{''+item+''}}</view></block></view></view><view class="detail-section"><text class="section-label">产品参数</text><view class="params-table"><block wx:for="{{productParams}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view class="param-row"><text class="param-label">{{item.label}}</text><text class="param-value">{{item.value}}</text></view></block></view></view><view class="detail-section"><text class="section-label">工艺说明</text><view class="craft-info"><block wx:for="{{crafts}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view class="craft-card"><view class="craft-icon" style="{{('background: '+item.bg+';')}}"><text class="craft-emoji">{{item.emoji}}</text></view><text class="craft-name">{{item.name}}</text><text class="craft-desc">{{item.desc}}</text></view></block></view></view><view class="detail-bottom-bar safe-bottom"><view data-event-opts="{{[['tap',[['toggleFav',['$event']]]]]}}" class="bottom-btn-icon" bindtap="__e"><text class="bottom-icon">{{isFav?'❤️':'🤍'}}</text><text class="bottom-icon-text">收藏</text></view><view data-event-opts="{{[['tap',[['contactService',['$event']]]]]}}" class="bottom-btn-icon" bindtap="__e"><text class="bottom-icon">💬</text><text class="bottom-icon-text">客服</text></view><view data-event-opts="{{[['tap',[['addToCart',['$event']]]]]}}" class="bottom-btn-cart" bindtap="__e"><text>加入清单</text></view><view data-event-opts="{{[['tap',[['startDesign',['$event']]]]]}}" class="bottom-btn-design" bindtap="__e"><text>立即定制</text></view></view></view>
<view class="detail-page"><detail-swiper vue-id="bbe3ce40-1" images="{{productImages}}" bind:__l="__l"></detail-swiper><product-info vue-id="bbe3ce40-2" info="{{product}}" bind:__l="__l"></product-info><block wx:if="{{$root.g0}}"><view class="section-divider"></view></block><block wx:if="{{$root.g1}}"><color-selector vue-id="bbe3ce40-3" list="{{colorListWithAvailability}}" selected-id="{{selectedColorId}}" data-event-opts="{{[['^select',[['selectColor']]]]}}" bind:select="__e" bind:__l="__l"></color-selector></block><block wx:if="{{$root.g2}}"><view class="section-divider"></view></block><block wx:if="{{$root.g3}}"><size-selector vue-id="bbe3ce40-4" list="{{sizeListWithAvailability}}" selected="{{selectedSize}}" data-event-opts="{{[['^select',[['selectSize']]]]}}" bind:select="__e" bind:__l="__l"></size-selector></block><block wx:if="{{$root.g4}}"><view class="section-divider"></view></block><block wx:if="{{$root.g5}}"><params-table vue-id="bbe3ce40-5" list="{{productParams}}" bind:__l="__l"></params-table></block><block wx:if="{{$root.g6}}"><view class="section-divider"></view></block><block wx:if="{{$root.g7}}"><size-chart vue-id="bbe3ce40-6" data="{{sizeChart}}" bind:__l="__l"></size-chart></block><block wx:if="{{packaging}}"><view class="section-divider"></view></block><block wx:if="{{packaging}}"><packaging-spec vue-id="bbe3ce40-7" data="{{packaging}}" bind:__l="__l"></packaging-spec></block></view>
@@ -1,283 +1,13 @@
/* 产品详情页样式 */
/* 产品详情页 - 页面容器样式 */
/* 各区块样式在 pages/product-detail/components/ 下对应组件的 <style scoped> 中 */
.detail-page {
min-height: 100vh;
background: #f5f5f5;
padding-bottom: 140rpx;
min-height: 100vh;
background: #ffffff;
}
/* 图片区 */
.detail-images {
position: relative;
background: #ffffff;
}
.detail-swiper {
width: 100%;
height: 750rpx;
}
.swiper-img {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.swiper-emoji {
font-size: 160rpx;
}
.detail-badges {
position: absolute;
top: 24rpx;
left: 24rpx;
display: flex;
flex-direction: column;
gap: 8rpx;
}
.detail-badge {
font-size: 20rpx;
padding: 4rpx 12rpx;
border-radius: 6rpx;
}
/* 产品信息 */
.detail-info-section {
background: #ffffff;
padding: 32rpx 24rpx;
margin-bottom: 16rpx;
}
.detail-header {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.detail-name {
font-size: 36rpx;
font-weight: 600;
color: #1a1a1a;
line-height: 1.4;
}
.detail-code {
font-size: 24rpx;
color: #999;
}
.detail-price-row {
display: flex;
align-items: baseline;
gap: 8rpx;
margin-top: 20rpx;
}
.detail-price {
font-size: 48rpx;
font-weight: 700;
color: #ff6800;
}
.detail-price-unit {
font-size: 24rpx;
color: #ff6800;
}
.detail-price-original {
font-size: 24rpx;
color: #ccc;
text-decoration: line-through;
margin-left: 12rpx;
}
.detail-meta {
display: flex;
justify-content: space-between;
margin-top: 32rpx;
padding-top: 24rpx;
border-top: 1rpx solid #f0f0f0;
}
.meta-item {
text-align: center;
}
.meta-label {
font-size: 22rpx;
color: #999;
display: block;
margin-bottom: 8rpx;
}
.meta-value {
font-size: 26rpx;
color: #333;
font-weight: 500;
}
/* 通用section */
.detail-section {
background: #ffffff;
padding: 32rpx 24rpx;
margin-bottom: 16rpx;
}
.section-label {
font-size: 30rpx;
font-weight: 600;
color: #333;
display: block;
margin-bottom: 24rpx;
}
/* 颜色选择 */
.color-options {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
}
.color-option {
display: flex;
align-items: center;
gap: 8rpx;
padding: 12rpx 20rpx;
border-radius: 32rpx;
border: 2rpx solid #eee;
background: #fafafa;
}
.color-option.selected {
border-color: #ff6800;
background: #fff0e5;
}
.color-dot {
width: 32rpx;
height: 32rpx;
border-radius: 50%;
border: 2rpx solid #fff;
box-shadow: 0 0 0 1rpx rgba(0, 0, 0, 0.1);
}
.color-name {
font-size: 24rpx;
color: #666;
}
.color-option.selected .color-name {
color: #ff6800;
}
/* 尺码选择 */
.size-options {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
}
.size-option {
min-width: 72rpx;
text-align: center;
padding: 16rpx 24rpx;
font-size: 26rpx;
color: #666;
background: #f5f5f5;
border-radius: 8rpx;
border: 2rpx solid transparent;
}
.size-option.selected {
background: #fff0e5;
color: #ff6800;
border-color: #ff6800;
}
/* 参数表 */
.params-table {
display: flex;
flex-direction: column;
}
.param-row {
display: flex;
padding: 16rpx 0;
border-bottom: 1rpx solid #f5f5f5;
}
.param-label {
width: 200rpx;
font-size: 26rpx;
color: #999;
flex-shrink: 0;
}
.param-value {
flex: 1;
font-size: 26rpx;
color: #333;
}
/* 工艺说明 */
.craft-info {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.craft-card {
display: flex;
align-items: center;
gap: 16rpx;
padding: 20rpx;
background: #fafafa;
border-radius: 12rpx;
}
.craft-icon {
width: 64rpx;
height: 64rpx;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.craft-emoji {
font-size: 32rpx;
}
.craft-name {
font-size: 26rpx;
font-weight: 600;
color: #333;
flex-shrink: 0;
width: 120rpx;
}
.craft-desc {
flex: 1;
font-size: 22rpx;
color: #999;
line-height: 1.5;
}
/* 底部操作栏 */
.detail-bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 120rpx;
background: #ffffff;
display: flex;
align-items: center;
padding: 0 24rpx;
gap: 16rpx;
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);
z-index: 100;
}
.bottom-btn-icon {
display: flex;
flex-direction: column;
align-items: center;
gap: 4rpx;
width: 80rpx;
flex-shrink: 0;
}
.bottom-icon {
font-size: 36rpx;
}
.bottom-icon-text {
font-size: 18rpx;
color: #999;
}
.bottom-btn-cart {
flex: 1;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
background: #fff0e5;
color: #ff6800;
font-size: 28rpx;
font-weight: 600;
border-radius: 40rpx;
}
.bottom-btn-design {
flex: 1;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
background: #ff6800;
color: #ffffff;
font-size: 28rpx;
font-weight: 600;
border-radius: 40rpx;
/* 区块之间的灰色分隔条:390x6px #F5F5F5 */
.section-divider {
width: 100%;
height: 12rpx; /* 6px */
background: #f5f5f5;
}
File diff suppressed because it is too large Load Diff
+8 -1
View File
@@ -1,4 +1,11 @@
{
"navigationBarTitleText": "产品中心",
"usingComponents": {}
"usingComponents": {
"search-bar": "/pages/products/components/SearchBar",
"country-bar": "/pages/products/components/CountryBar",
"active-filters": "/pages/products/components/ActiveFilters",
"category-sidebar": "/pages/products/components/CategorySidebar",
"product-grid": "/pages/products/components/ProductGrid",
"filter-drawer": "/pages/products/components/FilterDrawer"
}
}
File diff suppressed because one or more lines are too long
+20 -441
View File
@@ -1,446 +1,25 @@
/* 产品列表页样式 */
/* 货盘页 - 页面容器样式 */
/* 各区块样式已移入 pages/products/components/ 下对应组件 */
.products-page {
min-height: 100vh;
background: #f5f5f5;
display: flex;
flex-direction: column;
display: flex;
flex-direction: column;
height: 100vh;
background: #f2f2f2;
}
/* 搜索栏 */
.search-bar {
display: flex;
align-items: center;
gap: 16rpx;
padding: 16rpx 24rpx;
background: #ffffff;
}
.search-input-wrap {
flex: 1;
display: flex;
align-items: center;
background: #f5f5f5;
border-radius: 32rpx;
padding: 0 24rpx;
height: 64rpx;
}
.search-icon {
font-size: 28rpx;
margin-right: 12rpx;
}
.search-input {
flex: 1;
font-size: 26rpx;
color: #333;
}
.search-placeholder {
color: #ccc;
}
.filter-btn {
display: flex;
align-items: center;
gap: 4rpx;
padding: 0 16rpx;
}
.filter-icon {
font-size: 28rpx;
color: #666;
}
.filter-text {
font-size: 24rpx;
color: #666;
}
/* 国家选择条 */
.country-bar {
white-space: nowrap;
background: #ffffff;
padding: 16rpx 24rpx;
border-bottom: 1rpx solid #eee;
}
.country-item {
display: inline-flex;
align-items: center;
gap: 6rpx;
padding: 8rpx 20rpx;
margin-right: 12rpx;
border-radius: 24rpx;
background: #f5f5f5;
}
.country-item.active {
background: #fff0e5;
}
.country-flag {
font-size: 28rpx;
}
.country-name {
font-size: 22rpx;
color: #666;
}
.country-item.active .country-name {
color: #ff6800;
font-weight: 500;
}
/* 已选筛选标签 */
.active-filters {
display: flex;
align-items: center;
gap: 12rpx;
padding: 12rpx 24rpx;
background: #ffffff;
overflow-x: auto;
white-space: nowrap;
}
.active-filter-tag {
display: inline-flex;
align-items: center;
gap: 8rpx;
background: #f2f2f2;
border-radius: 8rpx;
padding: 6rpx 16rpx;
font-size: 22rpx;
color: #666;
flex-shrink: 0;
}
.filter-remove {
font-size: 20rpx;
color: #ccc;
}
.clear-all {
font-size: 22rpx;
color: #ff6800;
flex-shrink: 0;
}
/* 主体内容 */
/* 主体内容 - 左右分栏 */
.content-body {
flex: 1;
display: flex;
overflow: hidden;
}
/* 左侧分类侧边栏 */
.sidebar {
width: 180rpx;
background: #ffffff;
border-right: 1rpx solid #eee;
height: 100%;
flex-shrink: 0;
}
.sidebar-item {
position: relative;
padding: 28rpx 20rpx;
font-size: 24rpx;
color: #666;
text-align: center;
}
.sidebar-item.active {
background: #f5f5f5;
color: #ff6800;
font-weight: 600;
}
.sidebar-indicator {
position: absolute;
left: 0;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
width: 6rpx;
height: 32rpx;
background: #ff6800;
border-radius: 0 4rpx 4rpx 0;
}
.sidebar-promo {
margin: 24rpx 16rpx;
padding: 20rpx 12rpx;
background: linear-gradient(135deg, #ff6800 0%, #ff8c40 100%);
border-radius: 12rpx;
text-align: center;
}
.promo-title {
font-size: 24rpx;
font-weight: 700;
color: #fff;
display: block;
}
.promo-desc {
font-size: 20rpx;
color: rgba(255, 255, 255, 0.9);
display: block;
margin-top: 4rpx;
}
/* 右侧产品列表区 */
.product-list-area {
flex: 1;
height: 100%;
}
/* 子分类 */
.sub-categories {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
padding: 16rpx 20rpx;
background: #ffffff;
}
.sub-cat-item {
font-size: 22rpx;
padding: 8rpx 20rpx;
border-radius: 24rpx;
background: #f5f5f5;
color: #666;
}
.sub-cat-item.active {
background: #ff6800;
color: #fff;
}
/* 产品网格 */
.product-grid {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
padding: 16rpx 20rpx;
}
.product-card {
width: calc(50% - 8rpx);
background: #ffffff;
border-radius: 12rpx;
overflow: hidden;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
}
.product-img {
width: 100%;
height: 300rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.product-emoji {
font-size: 80rpx;
}
.product-badges {
position: absolute;
top: 12rpx;
left: 12rpx;
display: flex;
flex-direction: column;
gap: 4rpx;
}
.product-badge {
font-size: 18rpx;
padding: 2rpx 8rpx;
border-radius: 4rpx;
}
.product-info {
padding: 16rpx;
}
.product-name {
font-size: 24rpx;
color: #333;
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.product-bottom {
margin-top: 8rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.product-price {
font-size: 30rpx;
font-weight: 700;
color: #ff6800;
}
.product-price-unit {
font-size: 20rpx;
font-weight: 400;
margin-left: 2rpx;
}
/* 分页 */
.pagination {
padding: 24rpx 20rpx;
text-align: center;
}
.page-info {
font-size: 22rpx;
color: #999;
display: block;
margin-bottom: 16rpx;
}
.page-controls {
display: flex;
align-items: center;
justify-content: center;
gap: 8rpx;
}
.page-btn {
padding: 8rpx 20rpx;
font-size: 22rpx;
color: #666;
background: #fff;
border-radius: 8rpx;
border: 1rpx solid #eee;
}
.page-btn.disabled {
color: #ccc;
}
.page-num {
min-width: 48rpx;
height: 48rpx;
line-height: 48rpx;
text-align: center;
font-size: 24rpx;
color: #666;
background: #fff;
border-radius: 8rpx;
border: 1rpx solid #eee;
}
.page-num.active {
background: #ff6800;
color: #fff;
border-color: #ff6800;
}
.page-size {
margin-top: 12rpx;
font-size: 22rpx;
color: #999;
}
.loading-more {
padding: 24rpx;
text-align: center;
font-size: 24rpx;
color: #999;
}
/* 筛选弹窗 */
.filter-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
opacity: 0;
visibility: hidden;
transition: all 0.3s;
}
.filter-overlay.show {
opacity: 1;
visibility: visible;
}
.filter-drawer {
position: fixed;
top: 0;
right: 0;
width: 80%;
height: 100%;
background: #ffffff;
z-index: 1001;
-webkit-transform: translateX(100%);
transform: translateX(100%);
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
display: flex;
flex-direction: column;
}
.filter-drawer.show {
-webkit-transform: translateX(0);
transform: translateX(0);
}
.filter-drawer-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 32rpx 24rpx;
border-bottom: 1rpx solid #eee;
}
.filter-drawer-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.filter-drawer-close {
font-size: 32rpx;
color: #999;
}
.filter-drawer-body {
flex: 1;
padding: 24rpx;
}
.filter-group {
margin-bottom: 32rpx;
}
.filter-group-title {
font-size: 28rpx;
font-weight: 600;
color: #333;
display: block;
margin-bottom: 16rpx;
}
.filter-options {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
}
.filter-option {
padding: 12rpx 24rpx;
font-size: 24rpx;
color: #666;
background: #f5f5f5;
border-radius: 8rpx;
border: 2rpx solid transparent;
}
.filter-option.selected {
background: #fff0e5;
color: #ff6800;
border-color: #ff6800;
}
.filter-price-range {
display: flex;
align-items: center;
gap: 16rpx;
}
.price-input {
flex: 1;
height: 64rpx;
background: #f5f5f5;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 24rpx;
}
.price-divider {
color: #ccc;
}
.filter-drawer-footer {
display: flex;
gap: 16rpx;
padding: 24rpx;
border-top: 1rpx solid #eee;
}
.filter-reset {
flex: 1;
text-align: center;
padding: 24rpx;
font-size: 28rpx;
color: #666;
background: #f5f5f5;
border-radius: 12rpx;
}
.filter-confirm {
flex: 1;
text-align: center;
padding: 24rpx;
font-size: 28rpx;
color: #fff;
background: #ff6800;
border-radius: 12rpx;
flex: 1;
display: flex;
overflow: hidden;
min-height: 0;
}
/* 右侧容器 - 自动占满剩余宽度(高度自动撑开,内部由 ProductGrid 自己滚动) */
.right-wrap {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}