Files
xk-client-wx/subPackages/special-prescription/detail.vue

907 lines
23 KiB
Vue
Raw Normal View History

2026-07-02 14:11:24 +08:00
<template>
<view class="container safe-area-inset-bottom">
<MessageNotification />
<view v-if="loading" class="loading-wrap">
2026-07-03 16:48:46 +08:00
<u-loading mode="circle" size="48" color="#4175EE"></u-loading>
2026-07-02 14:11:24 +08:00
</view>
<block v-else-if="detail.id">
2026-07-03 16:48:46 +08:00
<!-- STREAMING_CHUNK:渲染顶部轮播图 -->
2026-07-02 14:11:24 +08:00
<view class="swiper-section">
<swiper
class="swiper"
indicator-dots
autoplay
circular
2026-07-03 16:48:46 +08:00
indicator-color="rgba(255,255,255,0.6)"
indicator-active-color="#ffffff"
2026-07-02 14:11:24 +08:00
>
<swiper-item v-for="(img, index) in displayImages" :key="index">
<image
class="swiper-image"
:src="img"
mode="aspectFill"
@click="previewImage(index)"
/>
</swiper-item>
</swiper>
</view>
2026-07-03 16:48:46 +08:00
<!-- STREAMING_CHUNK:渲染上浮卡片式基本信息 -->
<view class="info-container-price">
<view class="basic-info">
<!-- 价格区渐变背景装饰 -->
<view class="price-panel">
<view class="price-bg-decor"></view>
<view class="price-content">
<view class="price-left" v-if="detail.price_available !== false">
<text class="symbol">¥</text>
<text class="amount">{{ detail.price_per_dose }}</text>
<text class="unit">/</text>
</view>
<view class="price-left price-left--unavailable" v-else>
<text class="amount">暂无报价</text>
</view>
<view class="sales-box" v-if="detail.sales_count">
<u-icon name="shopping-cart" size="24" color="#FF8D1A"></u-icon>
<text class="sales-text">已售 {{ detail.sales_count }}</text>
</view>
</view>
2026-07-02 14:11:24 +08:00
</view>
2026-07-03 16:48:46 +08:00
<!-- 标题与标签区 -->
<view class="title-panel">
<view class="title">
<text class="title-text">{{ detail.name }}</text>
</view>
<view class="tag-row" v-if="detail.tags && detail.tags.length">
<view class="tag-item" v-for="(tag, idx) in detail.tags" :key="idx">
<text class="tag-text">{{ tag }}</text>
</view>
</view>
</view>
2026-07-02 14:11:24 +08:00
</view>
</view>
2026-07-03 16:48:46 +08:00
<view class="info-container">
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
<!-- STREAMING_CHUNK:渲染图文介绍 -->
<view class="intro-section" v-if="detail.intro_text || (detail.introduction_images && detail.introduction_images.length)">
<view class="section-title">
<view class="title-decor-line"></view>
<text class="title-text">详情介绍</text>
</view>
<view class="intro-text" v-if="detail.intro_text">
<u-parse :html="detail.intro_text"></u-parse>
</view>
<view class="intro-images" v-if="detail.introduction_images && detail.introduction_images.length">
<image
v-for="(img, idx) in detail.introduction_images"
:key="idx"
:src="img"
mode="widthFix"
class="intro-img"
@click="previewIntroImage(idx)"
/>
</view>
2026-07-02 14:11:24 +08:00
</view>
</view>
2026-07-03 16:48:46 +08:00
<!-- STREAMING_CHUNK:渲染适度抬高的悬浮操作按钮 -->
2026-07-02 14:11:24 +08:00
<view class="footer-spacer"></view>
2026-07-03 16:48:46 +08:00
<view class="floating-action-bar safe-area-inset-bottom">
2026-07-02 14:11:24 +08:00
<button
2026-07-03 16:48:46 +08:00
class="register-btn-float"
:class="{ 'register-btn-float--disabled': detail.price_available === false }"
2026-07-02 14:11:24 +08:00
:disabled="detail.price_available === false"
@click="goRegister"
2026-07-03 16:48:46 +08:00
>
<text>去挂号选方</text>
</button>
2026-07-02 14:11:24 +08:00
</view>
</block>
<view v-else class="empty-wrap">
<u-empty text="特色方不存在或已下架" mode="page" margin-top="120"></u-empty>
</view>
<!-- #ifdef MP-WEIXIN -->
2026-07-03 16:48:46 +08:00
<page-container :v-if="registerDrawerShow" :overlay="false" @leave="onPageBackGuardLeave" />
2026-07-02 14:11:24 +08:00
<!-- #endif -->
2026-07-03 16:48:46 +08:00
<!-- STREAMING_CHUNK:渲染包含自定义项的SKU抽屉 -->
2026-07-02 14:11:24 +08:00
<u-popup
v-model="registerDrawerShow"
mode="bottom"
2026-07-03 16:48:46 +08:00
border-radius="32"
2026-07-02 14:11:24 +08:00
safe-area-inset-bottom
2026-07-03 16:48:46 +08:00
closeable
close-icon-color="#999"
2026-07-02 14:11:24 +08:00
@close="onRegisterDrawerClose"
>
<view class="register-drawer">
<view class="drawer-header">
2026-07-03 16:48:46 +08:00
<image class="header-img" :src="displayImages[0]" mode="aspectFill"></image>
<view class="header-info">
<view class="header-price">
<text class="symbol">¥</text>
<text class="amount">{{ unitPrice }}</text>
<text class="unit">/</text>
</view>
<text class="header-stock">
已选{{ selectedSkuId === 0 ? '自定义贴数' : (selectedSku ? selectedSku.sku_name : '') }} {{ doseCount }}
</text>
2026-07-02 14:11:24 +08:00
</view>
</view>
2026-07-03 16:48:46 +08:00
<scroll-view scroll-y class="drawer-scroll-area">
<view class="drawer-section">
<text class="section-label">规格选择</text>
<view class="sku-list">
<!-- STREAMING_CHUNK:自定义贴数 SKU 胶囊 (带动态价格) -->
<view
class="sku-item"
:class="{ 'sku-item--active': Number(selectedSkuId) === 0 }"
@tap="selectCustomSku"
>
<text class="sku-name">自定义贴数</text>
<text class="sku-price" v-if="detail.price_available !== false && customSkuDisplayPrice > 0">
¥{{ customSkuDisplayPrice }}
</text>
<view class="active-triangle" v-if="Number(selectedSkuId) === 0">
<u-icon name="checkbox-mark" size="16" color="#fff" class="triangle-icon"></u-icon>
</view>
</view>
<!-- 真实的 SKU 列表 -->
<view
v-for="sku in detail.skus"
:key="sku.id"
class="sku-item"
:class="{ 'sku-item--active': Number(selectedSkuId) === Number(sku.id) }"
@tap="selectSku(sku)"
>
<text class="sku-name">{{ sku.sku_name }}</text>
<text class="sku-price" v-if="sku.sale_price > 0">¥{{ sku.sale_price }}</text>
<view class="active-triangle" v-if="Number(selectedSkuId) === Number(sku.id)">
<u-icon name="checkbox-mark" size="16" color="#fff" class="triangle-icon"></u-icon>
</view>
</view>
</view>
</view>
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
<!-- 步进器部分 -->
<view class="drawer-section dose-section">
<text class="section-label">贴数</text>
<u-number-box
v-model="doseCount"
:min="1"
:max="99"
integer
:input-width="90"
:input-height="56"
bg-color="#F5F7FA"
@change="onDoseCountChange"
></u-number-box>
</view>
</scroll-view>
<view class="drawer-footer">
<view class="total-info">
<text class="total-label">预估金额</text>
<view class="total-price-box">
<text class="total-symbol">¥</text>
<text class="total-price">{{ totalPrice }}</text>
</view>
</view>
<button class="confirm-btn" @click="confirmRegister">确认挂号</button>
2026-07-02 14:11:24 +08:00
</view>
</view>
</u-popup>
<u-toast ref="uToast" />
</view>
</template>
<script>
2026-07-03 16:48:46 +08:00
/* STREAMING_CHUNK:引入依赖文件 */
2026-07-02 14:11:24 +08:00
import {
getSpecialPrescriptionDetailApi,
saveSpecialPrescriptionRegisterContext,
} from '@/request/api/specialPrescription'
2026-07-03 12:33:18 +08:00
import { calculateSpecialPrescriptionEstimatedTotal } from '@/utils/formatPrice'
2026-07-02 14:11:24 +08:00
export default {
data() {
return {
id: '',
detail: {},
doseCount: 1,
2026-07-03 16:48:46 +08:00
selectedSkuId: 0,
2026-07-02 14:11:24 +08:00
loading: true,
registerDrawerShow: false,
defaultCover: 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/mine/avatar_1.png',
}
},
computed: {
2026-07-03 16:48:46 +08:00
/* STREAMING_CHUNK:计算属性 */
2026-07-02 14:11:24 +08:00
displayImages() {
const images = []
if (this.detail.cover_image) {
images.push(this.detail.cover_image)
}
if (this.detail.introduction_images && this.detail.introduction_images.length) {
this.detail.introduction_images.forEach((img) => {
if (img && images.indexOf(img) === -1) {
images.push(img)
}
})
}
return images.length ? images : [this.defaultCover]
},
2026-07-03 16:48:46 +08:00
hasSkus() {
return Array.isArray(this.detail.skus) && this.detail.skus.length > 0
},
selectedSku() {
if (!this.hasSkus || Number(this.selectedSkuId) === 0) return null
return this.detail.skus.find((item) => Number(item.id) === Number(this.selectedSkuId)) || null
},
unitPrice() {
return parseFloat(this.detail.price_per_dose || 0).toFixed(2)
},
// 为自定义贴数单独提供展示价格
customSkuDisplayPrice() {
return parseFloat(this.detail.price_per_dose || 0).toFixed(2)
},
2026-07-02 14:11:24 +08:00
totalPrice() {
if (this.detail.price_available === false) {
return '0.00'
}
2026-07-03 16:48:46 +08:00
if (this.selectedSku && Number(this.selectedSku.sale_price) > 0) {
return parseFloat(this.selectedSku.sale_price || 0).toFixed(2)
}
2026-07-03 12:33:18 +08:00
return calculateSpecialPrescriptionEstimatedTotal(
2026-07-03 16:48:46 +08:00
this.detail.price_per_dose,
this.doseCount,
2026-07-03 12:33:18 +08:00
)
2026-07-02 14:11:24 +08:00
},
},
2026-07-03 16:48:46 +08:00
watch: {
/* STREAMING_CHUNK:监听器处理 */
doseCount(newVal) {
if (this._suppressDoseSkuClear) {
return
}
this.selectedSkuId = 0
},
},
2026-07-02 14:11:24 +08:00
onLoad(e) {
this.id = e.id || ''
if (this.id) {
this.fetchDetail()
} else {
this.loading = false
}
},
methods: {
2026-07-03 16:48:46 +08:00
/* STREAMING_CHUNK:核心方法与生命周期 */
2026-07-02 14:11:24 +08:00
getStoreId() {
return uni.getStorageSync('store_id') || '11001'
},
async fetchDetail() {
this.loading = true
try {
const res = await getSpecialPrescriptionDetailApi({
id: this.id,
store_id: this.getStoreId(),
})
if (res.data?.code === 0 || res.data?.code === '0') {
this.detail = res.data.result || {}
2026-07-03 16:48:46 +08:00
this.initSkuSelection()
2026-07-02 14:11:24 +08:00
} else {
this.$refs.uToast && this.$refs.uToast.show({
title: res.data?.message || '加载失败',
type: 'default',
icon: false,
})
}
} catch (e) {
console.error('fetchDetail', e)
} finally {
this.loading = false
}
},
2026-07-03 16:48:46 +08:00
initSkuSelection() {
const skus = this.detail.skus || []
if (skus.length > 0 && this.detail.default_sku_id) {
const defaultId = Number(this.detail.default_sku_id || 0)
const defaultSku = skus.find((item) => Number(item.is_default) === 1)
|| skus.find((item) => Number(item.id) === defaultId)
if (defaultSku) {
this._suppressDoseSkuClear = true
this.selectedSkuId = Number(defaultSku.id)
this.doseCount = defaultSku.dose_count || 1
this.$nextTick(() => {
this._suppressDoseSkuClear = false
})
return
}
}
this.selectedSkuId = 0
this.doseCount = 1
},
selectCustomSku() {
this.selectedSkuId = 0
},
selectSku(sku) {
this._suppressDoseSkuClear = true
if (Number(this.selectedSkuId) === Number(sku.id)) {
this.selectedSkuId = 0
} else {
this.selectedSkuId = Number(sku.id)
this.doseCount = sku.dose_count || 1
}
this.$nextTick(() => {
this._suppressDoseSkuClear = false
})
},
onDoseCountChange(e) {
if (this._suppressDoseSkuClear) return
this.selectedSkuId = 0
},
2026-07-02 14:11:24 +08:00
previewImage(index) {
uni.previewImage({
urls: this.displayImages,
current: this.displayImages[index],
})
},
previewIntroImage(index) {
const urls = this.detail.introduction_images || []
if (!urls.length) return
uni.previewImage({
urls,
current: urls[index],
})
},
goRegister() {
if (this.detail.price_available === false) {
this.$refs.uToast.show({
title: '当前诊所暂无法报价,请联系诊所',
type: 'default',
icon: false,
})
return
}
const doctorId = this.detail.doctor_id
if (!doctorId) {
this.$refs.uToast.show({
title: '诊所未配置特色方挂号医生',
type: 'default',
icon: false,
})
return
}
this.registerDrawerShow = true
},
closeRegisterDrawer() {
this.registerDrawerShow = false
},
onRegisterDrawerClose() {
this.registerDrawerShow = false
},
onPageBackGuardLeave() {
if (this._suppressPageBackGuardLeave) {
this._suppressPageBackGuardLeave = false
return
}
if (this.registerDrawerShow) {
this._suppressPageBackGuardLeave = true
this.registerDrawerShow = false
}
},
confirmRegister() {
const doctorId = this.detail.doctor_id
if (!doctorId) {
this.$refs.uToast.show({
title: '诊所未配置特色方挂号医生',
type: 'default',
icon: false,
})
return
}
2026-07-03 16:48:46 +08:00
const skuId = this.selectedSku
? Number(this.selectedSku.id)
: 0
2026-07-02 14:11:24 +08:00
const ctx = {
special_prescription_id: this.detail.id,
dose_count: this.doseCount,
2026-07-03 16:48:46 +08:00
sku_id: skuId,
2026-07-02 14:11:24 +08:00
doctor_id: doctorId,
}
saveSpecialPrescriptionRegisterContext(ctx)
this._suppressPageBackGuardLeave = true
this.registerDrawerShow = false
2026-07-03 16:48:46 +08:00
let url = `/subPackages/doctor/doctor-userinfo?id=${doctorId}&r_type=0&special_prescription_id=${ctx.special_prescription_id}&special_prescription_dose_count=${ctx.dose_count}`
if (ctx.sku_id) {
url += `&special_prescription_sku_id=${ctx.sku_id}`
}
uni.navigateTo({ url })
2026-07-02 14:11:24 +08:00
},
},
}
</script>
<style lang="scss" scoped>
2026-07-03 16:48:46 +08:00
/* STREAMING_CHUNK:定义全局样式与主题变量 */
2026-07-02 14:11:24 +08:00
$sp-primary: #4175EE;
2026-07-03 16:48:46 +08:00
$sp-primary-light: #EBF1FF;
$sp-price: #FF4F23;
$sp-price-bg: linear-gradient(135deg, #FFF1EB 0%, #FFFAFA 100%);
$sp-text-main: #222222;
$sp-text-sub: #666666;
$sp-text-muted: #999999;
$sp-bg: #F4F5F7;
$sp-gradient-btn: linear-gradient(90deg, #5C8CFF 0%, #3567E8 100%);
view, text, scroll-view {
box-sizing: border-box;
}
2026-07-02 14:11:24 +08:00
.container {
min-height: 100vh;
2026-07-03 16:48:46 +08:00
background: $sp-bg;
/* 调整底部留白,适应稍微降低的悬浮按钮 */
padding-bottom: calc(150rpx + env(safe-area-inset-bottom));
//padding-bottom: 50rpx;
2026-07-02 14:11:24 +08:00
}
.loading-wrap,
.empty-wrap {
display: flex;
align-items: center;
justify-content: center;
2026-07-03 16:48:46 +08:00
min-height: 70vh;
2026-07-02 14:11:24 +08:00
}
2026-07-03 16:48:46 +08:00
/* 轮播图样式 */
2026-07-02 14:11:24 +08:00
.swiper-section {
.swiper {
height: 750rpx;
width: 100%;
2026-07-03 16:48:46 +08:00
background-color: #f8f8f8;
2026-07-02 14:11:24 +08:00
}
.swiper-image {
width: 100%;
height: 100%;
}
}
2026-07-03 16:48:46 +08:00
/* 详情页面装饰增强 */
.info-container-price {
position: relative;
margin-top: -32rpx;
z-index: 10;
padding: 0 24rpx;
}
/* 详情页面装饰增强 */
.info-container {
position: relative;
margin-top: -32rpx;
z-index: 10;
}
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.basic-info {
background: #ffffff;
border-radius: 24rpx;
overflow: hidden;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.04);
margin-bottom: 24rpx;
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.price-panel {
position: relative;
padding: 32rpx 24rpx;
background: $sp-price-bg;
.price-bg-decor {
position: absolute;
right: 0;
top: 0;
width: 200rpx;
height: 100%;
background: radial-gradient(circle at 100% 0%, rgba(255, 79, 35, 0.08) 0%, transparent 70%);
pointer-events: none;
2026-07-02 14:11:24 +08:00
}
2026-07-03 16:48:46 +08:00
.price-content {
position: relative;
display: flex;
align-items: flex-end;
justify-content: space-between;
z-index: 2;
2026-07-02 14:11:24 +08:00
}
2026-07-03 16:48:46 +08:00
.price-left {
color: $sp-price;
display: flex;
align-items: baseline;
.symbol {
font-size: 32rpx;
font-weight: 700;
margin-right: 4rpx;
}
.amount {
font-size: 56rpx;
font-weight: 800;
font-family: 'DIN Alternate', sans-serif;
line-height: 1;
}
.unit {
font-size: 24rpx;
margin-left: 8rpx;
}
&--unavailable .amount {
font-size: 36rpx;
color: $sp-text-muted;
}
2026-07-02 14:11:24 +08:00
}
2026-07-03 16:48:46 +08:00
.sales-box {
display: flex;
align-items: center;
background: rgba(255, 141, 26, 0.1);
padding: 6rpx 16rpx;
border-radius: 24rpx;
.sales-text {
font-size: 22rpx;
color: #E67A15;
margin-left: 6rpx;
font-weight: 500;
}
2026-07-02 14:11:24 +08:00
}
}
2026-07-03 16:48:46 +08:00
.title-panel {
padding: 24rpx;
2026-07-02 14:11:24 +08:00
}
.title {
2026-07-03 16:48:46 +08:00
font-size: 34rpx;
2026-07-02 14:11:24 +08:00
font-weight: 700;
2026-07-03 16:48:46 +08:00
color: $sp-text-main;
line-height: 1.5;
2026-07-02 14:11:24 +08:00
margin-bottom: 16rpx;
}
.tag-row {
display: flex;
flex-wrap: wrap;
2026-07-03 16:48:46 +08:00
gap: 16rpx;
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.tag-item {
position: relative;
background: #FAFAFA;
border: 1rpx solid #EBEBEB;
padding: 6rpx 16rpx;
2026-07-02 14:11:24 +08:00
border-radius: 8rpx;
2026-07-03 16:48:46 +08:00
.tag-text {
font-size: 22rpx;
color: $sp-text-sub;
}
2026-07-02 14:11:24 +08:00
}
}
}
.intro-section {
2026-07-03 16:48:46 +08:00
background: #ffffff;
border-radius: 24rpx;
padding: 32rpx 24rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.04);
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.section-title {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 32rpx;
position: relative;
.title-decor-line {
position: absolute;
bottom: 4rpx;
width: 120rpx;
height: 12rpx;
background: linear-gradient(90deg, rgba(65, 117, 238, 0.3) 0%, transparent 100%);
border-radius: 6rpx;
z-index: 1;
}
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.title-text {
font-size: 32rpx;
font-weight: 700;
color: $sp-text-main;
z-index: 2;
}
}
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.intro-images {
font-size: 0;
line-height: 0;
border-radius: 12rpx;
overflow: hidden;
.intro-img {
width: 100%;
display: block;
}
2026-07-02 14:11:24 +08:00
}
2026-07-03 16:48:46 +08:00
.intro-text {
font-size: 28rpx;
color: $sp-text-sub;
line-height: 1.7;
margin-bottom: 20rpx;
}
2026-07-02 14:11:24 +08:00
}
2026-07-03 16:48:46 +08:00
/* STREAMING_CHUNK:底部适度抬高悬浮操作按钮 */
2026-07-02 14:11:24 +08:00
.footer-spacer {
2026-07-03 16:48:46 +08:00
height: 20rpx;
2026-07-02 14:11:24 +08:00
}
2026-07-03 16:48:46 +08:00
.floating-action-bar {
2026-07-02 14:11:24 +08:00
position: fixed;
2026-07-03 16:48:46 +08:00
left: 32rpx;
right: 32rpx;
/* 调整悬浮高度:降低到 16rpx更加稳重 */
//bottom: calc(16rpx + env(safe-area-inset-bottom));
bottom: 50rpx;
2026-07-02 14:11:24 +08:00
z-index: 100;
2026-07-03 16:48:46 +08:00
display: flex;
justify-content: center;
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.register-btn-float {
2026-07-02 14:11:24 +08:00
width: 100%;
2026-07-03 16:48:46 +08:00
height: 96rpx;
background: $sp-gradient-btn;
2026-07-02 14:11:24 +08:00
color: #fff;
font-size: 32rpx;
font-weight: 600;
2026-07-03 16:48:46 +08:00
border-radius: 48rpx;
display: flex;
align-items: center;
justify-content: center;
2026-07-02 14:11:24 +08:00
border: none;
2026-07-03 16:48:46 +08:00
box-shadow: 0 12rpx 24rpx rgba(65, 117, 238, 0.3);
transition: all 0.3s;
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
&::after { border: none; }
&:active {
transform: scale(0.98);
box-shadow: 0 6rpx 12rpx rgba(65, 117, 238, 0.2);
2026-07-02 14:11:24 +08:00
}
&--disabled {
2026-07-03 16:48:46 +08:00
background: #E2E4E8;
color: #B0B5C1;
box-shadow: none;
2026-07-02 14:11:24 +08:00
}
}
}
2026-07-03 16:48:46 +08:00
/* 抽屉与包含自定义的精简版SKU样式 */
2026-07-02 14:11:24 +08:00
.register-drawer {
2026-07-03 16:48:46 +08:00
width: 100%;
2026-07-02 14:11:24 +08:00
background: #fff;
2026-07-03 16:48:46 +08:00
border-radius: 32rpx 32rpx 0 0;
display: flex;
flex-direction: column;
max-height: 75vh;
2026-07-02 14:11:24 +08:00
.drawer-header {
2026-07-03 16:48:46 +08:00
width: 100%;
padding: 32rpx;
border-bottom: 1rpx solid #F2F3F5;
2026-07-02 14:11:24 +08:00
display: flex;
2026-07-03 16:48:46 +08:00
position: relative;
padding-right: 80rpx;
.header-img {
width: 160rpx;
height: 160rpx;
border-radius: 12rpx;
background: $sp-bg;
margin-right: 24rpx;
border: 1rpx solid #EBEBEB;
}
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.header-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: flex-end;
padding-bottom: 12rpx;
.header-price {
color: $sp-price;
display: flex;
align-items: baseline;
margin-bottom: 12rpx;
.symbol { font-size: 28rpx; font-weight: 600; }
.amount { font-size: 48rpx; font-weight: 800; font-family: 'DIN Alternate', sans-serif;}
.unit { font-size: 24rpx; color: $sp-text-muted; margin-left: 4rpx;}
}
.header-stock {
font-size: 24rpx;
color: $sp-text-sub;
background: #F7F7F7;
padding: 4rpx 12rpx;
border-radius: 8rpx;
display: inline-block;
align-self: flex-start;
}
}
2026-07-02 14:11:24 +08:00
}
2026-07-03 16:48:46 +08:00
.drawer-scroll-area {
width: 100%;
max-height: 50vh;
padding: 0 32rpx 40rpx;
2026-07-02 14:11:24 +08:00
}
2026-07-03 16:48:46 +08:00
.drawer-section {
margin-top: 32rpx;
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.section-label {
2026-07-02 14:11:24 +08:00
font-size: 28rpx;
2026-07-03 16:48:46 +08:00
font-weight: 600;
color: $sp-text-main;
margin-bottom: 20rpx;
display: block;
2026-07-02 14:11:24 +08:00
}
}
2026-07-03 16:48:46 +08:00
.sku-list {
2026-07-02 14:11:24 +08:00
display: flex;
2026-07-03 16:48:46 +08:00
flex-wrap: wrap;
gap: 20rpx;
}
.sku-item {
position: relative;
display: inline-flex;
2026-07-02 14:11:24 +08:00
align-items: center;
2026-07-03 16:48:46 +08:00
background: #F5F6F8;
border: 2rpx solid transparent;
padding: 14rpx 28rpx;
border-radius: 40rpx;
transition: all 0.2s;
overflow: hidden;
.sku-name {
font-size: 26rpx;
color: $sp-text-main;
}
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.sku-name + .sku-price {
margin-left: 8rpx;
2026-07-02 14:11:24 +08:00
}
2026-07-03 16:48:46 +08:00
.sku-price {
font-size: 24rpx;
color: $sp-text-sub;
font-weight: 500;
}
&--active {
background: $sp-primary-light;
border-color: $sp-primary;
.sku-name {
color: $sp-primary;
font-weight: 600;
}
.sku-price {
color: $sp-primary;
}
}
.active-triangle {
position: absolute;
right: -2rpx;
bottom: -2rpx;
width: 0;
height: 0;
border-bottom: 32rpx solid $sp-primary;
border-left: 32rpx solid transparent;
.triangle-icon {
position: absolute;
right: 2rpx;
bottom: -28rpx;
transform: scale(0.6);
}
2026-07-02 14:11:24 +08:00
}
}
2026-07-03 16:48:46 +08:00
.dose-section {
2026-07-02 14:11:24 +08:00
display: flex;
align-items: center;
justify-content: space-between;
2026-07-03 16:48:46 +08:00
padding-top: 16rpx;
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.section-label {
margin-bottom: 0;
2026-07-02 14:11:24 +08:00
}
}
2026-07-03 16:48:46 +08:00
.drawer-footer {
2026-07-02 14:11:24 +08:00
width: 100%;
2026-07-03 16:48:46 +08:00
padding: 20rpx 32rpx;
background: #fff;
border-top: 1rpx solid #F2F3F5;
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
.total-info {
display: flex;
flex-direction: column;
.total-label {
font-size: 24rpx;
color: $sp-text-sub;
}
2026-07-02 14:11:24 +08:00
2026-07-03 16:48:46 +08:00
.total-price-box {
display: flex;
align-items: baseline;
color: $sp-price;
}
.total-symbol {
font-size: 28rpx;
font-weight: 600;
}
.total-price {
font-size: 44rpx;
font-weight: 800;
font-family: 'DIN Alternate', sans-serif;
}
}
.confirm-btn {
margin: 0;
width: 280rpx;
height: 80rpx;
line-height: 80rpx;
background: $sp-gradient-btn;
color: #fff;
font-size: 30rpx;
font-weight: 600;
border-radius: 40rpx;
2026-07-02 14:11:24 +08:00
border: none;
2026-07-03 16:48:46 +08:00
&::after { border: none; }
2026-07-02 14:11:24 +08:00
}
}
}
2026-07-03 16:48:46 +08:00
</style>