tmp6
This commit is contained in:
+166
@@ -0,0 +1,166 @@
|
||||
# 陪诊小程序 配色规范
|
||||
|
||||
本文件只规定**颜色**,不涉及布局、间距、圆角、触控尺寸。那些属于界面规范,另行处理。
|
||||
|
||||
适用范围:`ui/wxapp_escort/` 下全部小程序页面。
|
||||
|
||||
---
|
||||
|
||||
## 一、总原则
|
||||
|
||||
**全站只有一个色相。**
|
||||
|
||||
- 第一色是暖橙,承载品牌、交互、强调。
|
||||
- 第二色不是另一个色相,是**暖墨文字层**(暖偏棕的深灰)。它的作用是把层级拉开,不与暖橙争彩。
|
||||
- 浅橙三档(描边、浅底、深字)都是主色的同色阶,不是新颜色。
|
||||
- 状态色只允许在**表达状态**时出现,不做装饰。
|
||||
|
||||
判断一个颜色是否该用:如果它既不是暖橙的同色阶、也不是暖墨、也不是明确的状态色,就不该出现在页面里。历史遗留的灰金 `#D4A853`、亮橙 `#FF8500`、青灰、翠绿都是这条原则的违反项。
|
||||
|
||||
---
|
||||
|
||||
## 二、核心色板
|
||||
|
||||
令牌按项目惯例定义在各页面的 `page {}` 选择器内。技术上 `app.wxss` 的 `page {}` 也能全局定义变量,但各页自带可以让页面样式自包含、互不牵连,这是本项目的约定。
|
||||
|
||||
### 2.1 第一色:暖橙色阶
|
||||
|
||||
| 令牌 | 色值 | 用途 | 对比度 |
|
||||
|---|---|---|---|
|
||||
| `--brand-strong` | `#C2410C` | 主按钮、价格数字、选中态、实心强调块 | 纸面 4.89:1,白卡 5.18:1 |
|
||||
| `--brand-ink` | `#9A3412` | 标签文字、文字链、暖色小标题、图标 | 浅橙底 6.74:1,纸面 6.89:1 |
|
||||
| `--brand-line` | `#FFE0C2` | 浅橙块描边、浅橙档的状态描边 | 仅做描边 |
|
||||
| `--brand-soft` | `#FFF4E8` | 浅橙底:说明砖、图标衬底、按钮按下态 | 仅做底 |
|
||||
|
||||
用法边界:
|
||||
|
||||
- `--brand-strong` 是唯一可以当"实心大色块"用的值。全页同类实心块建议不超过一处,避免主色泛滥。
|
||||
- `--brand-soft` 只能当底,不能当文字色,也不能当描边色(它做描边时等于没有描边)。
|
||||
- `--brand-ink` 是浅橙底上的首选强调字色。`--brand-strong` 落在 `--brand-soft` 上实测 4.77:1,过 AA 但余量小,浅橙底上的文字一律走 `--brand-ink`。
|
||||
|
||||
### 2.2 第二色:暖墨文字层
|
||||
|
||||
| 令牌 | 色值 | 用途 | 对比度 |
|
||||
|---|---|---|---|
|
||||
| `--ink` | `#2B2521` | 标题、需要最重的正文 | 纸面 14.26:1 |
|
||||
| `--ink-2` | `#4A4038` | 正文 | 纸面 9.52:1 |
|
||||
| `--muted` | `#6F655C` | 次要文字、元信息、说明、未选中态 | 纸面 5.37:1,白卡 5.69:1,浅橙底 5.24:1 |
|
||||
|
||||
用法边界:
|
||||
|
||||
- 三档只表示文字层级,不表示状态,不表示可点击性。
|
||||
- `--muted` 是最浅的一档,不得再浅。它是全站文字对比度的底线,任何比它更浅的文字色都视为不合格。
|
||||
- `--muted` 是三元色里的关键值:它在暖白纸面、白卡、浅橙底上都能过 4.5:1。历史值 `#7A7068` 压线达标但无余量(纸面 4.56:1),已废弃,所有硬编码 `#7A7068` 都要替换。
|
||||
- 注意 `t-icon` 组件的 `color` 属性读不到 CSS 变量,只能用硬编码色值。这类硬编码必须与令牌同步(当前应为 `#9A3412`、`#6F655C`、`#C2410C` 三者之一)。
|
||||
|
||||
### 2.3 底与线
|
||||
|
||||
| 令牌 | 色值 | 用途 |
|
||||
|---|---|---|
|
||||
| `--white` | `#FFFFFF` | 卡片、面板 |
|
||||
| `--paper` | `#FAF8F5` | 页面底色(暖白纸面) |
|
||||
| `--line` | `#ECE3D6` | 发丝线:卡片内部分隔、区块切分 |
|
||||
| `--sep` | `#E5DACC` | 分隔线:竖线、浅橙底上的线 |
|
||||
|
||||
用法边界:
|
||||
|
||||
- 这两组线不是装饰,是**切分工具**,本身不表意。不要给它们上主色或状态色。
|
||||
- `--line` 与 `--sep` 的分工是固定的:浅橙底上必须用 `--sep`,因为 `--brand-line` 落在 `--brand-soft` 上只有约 1.16:1,肉眼看不见;`--sep` 比 `--line` 深一档,专门负责在彩色底上还能被看到。
|
||||
- `--paper` 与 `--brand-soft` 的明度差只有约 1.03:1。所以浅橙块落在纸面上时,形状必须靠**暖色紧阴影**托出来,不能用更大的色差去解决。
|
||||
|
||||
浅橙块托形阴影(唯一允许的彩色阴影):
|
||||
|
||||
```css
|
||||
box-shadow: 0 2rpx 10rpx rgba(194, 65, 12, 0.08);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、状态色
|
||||
|
||||
状态色只在订单、记录这类**有明确状态字段**的地方使用,且同一个页面里同类状态只能有一种颜色。
|
||||
|
||||
| 状态 | 底色 | 描边 | 字色 | 对比度 |
|
||||
|---|---|---|---|---|
|
||||
| 待服务 | `#ECF7F4` | `#C7E5DF` | `#0F766E` | 5.00:1 |
|
||||
| 服务中 | `#FFF4E8` | `#FFE0C2` | `#C2410C` | 4.77:1 |
|
||||
| 已完成 | `#EAF6EE` | `#CDE9D7` | `#1F7A4D` | 4.79:1 |
|
||||
| 已取消 | `#FCF0EE` | `#F2D6D1` | `#B4231A` | 5.89:1 |
|
||||
|
||||
用法边界:
|
||||
|
||||
- **不得仅用颜色传达状态。** 状态胶囊必须带文字,颜色只做强化。这条是 WCAG 1.4.1(Use of Color,Severity: High)的要求——将来任何"纯色圆点表示状态"的写法都视为违规。
|
||||
- **青绿(待服务)是全站唯一的冷色**,也是唯一"反暖色"的特权。它只给"等你去处理"这一个语义。其他任何状态都不许用冷色,否则这个信号就废了。
|
||||
- **服务中直接复用主色浅档**,不另立色相。服务中是一个正常中间态,不需要报警感。
|
||||
- 已取消的红是状态色里唯一脱离暖色体系的。若后续想让全站色相更少,可把已取消收成 `--muted` 字 + 中性底(`#EFEFF2`),代价是列表里不易扫到。当前按上表执行。
|
||||
- 状态色不得用在:区块标题、图标衬底、按钮、装饰条。它只包住状态文字本身。
|
||||
- 表单错误提示复用已取消档(`#B4231A` 字 + `#FCF0EE` 底),不新增令牌;错误必须带文字,不能只把输入框描红。
|
||||
- 禁用态不使用暖橙(可点性由暖橙表达,禁用即收回):`--muted` 字 + `--sep` 描边 + 透明底。
|
||||
|
||||
---
|
||||
|
||||
## 四、硬约束(可验证)
|
||||
|
||||
1. 所有文字对底色的对比度必须达到 WCAG AA 4.5:1;中文最小字号不低于 24rpx(12px)。
|
||||
2. 图标对衬底的对比度必须达到 WCAG 非文本 3:1。反例:`#22A45D` 落在 `#EBF8F0` 上只有 2.94:1,不达标;同位置的合格值是 `#19814A`(4.49:1)。
|
||||
3. 不得新增色相。需要区分时先改结构(分组、加留白、换线),不要加颜色。
|
||||
4. 不得使用渐变色。历史遗留的 `#FF9B33 → #FF7A33`、`#4CAF50 → #45A049` 属于违反项。
|
||||
5. 卡片、面板、说明砖的**填充色必须中性**(`--white` / `--paper` / `--brand-soft`)。不得用 `--brand-strong` 或状态色做面填充,它们只做描边、图标、文字、mark。
|
||||
6. 暖橙以外的暖色(灰金、亮橙)不得出现。金色 `#D4A853` 属于旧体系,已废弃。
|
||||
7. 每个页面内,同一种含义只能对应一个色值。同一页出现两种"次要文字灰"即为不合格。
|
||||
8. 不得仅用颜色传达信息(WCAG 1.4.1)。状态、错误、选中态都必须有文字或图标伴随,颜色只做强化。
|
||||
|
||||
---
|
||||
|
||||
## 五、历史遗留收口清单
|
||||
|
||||
以下为当前与规范冲突的位置,**本文档阶段不执行**,仅登记,供后续代码阶段按表替换。
|
||||
|
||||
### 5.1 页面级
|
||||
|
||||
| 范围 | 现状色值 | 替换为 |
|
||||
|---|---|---|
|
||||
| `mine/mine.wxss`、`mine/about.wxss` | `#D4A853`、`#FF8500` | `--brand-strong` / `--brand-ink` |
|
||||
| `mine/about.wxss`、`mine/mine.wxss` | `#22A45D` | `--brand-strong` |
|
||||
| `mine/comp_address.wxml`(`switch` 属性) | 旧金色 | `#C2410C`(属性值需硬编码) |
|
||||
| `health/profilelist.js`(`confirmColor`) | 旧金色 | `#C2410C` |
|
||||
| `health/profilelist.wxss`、`profileedit.wxss` | `#D4A853` 系 | 暖橙令牌 |
|
||||
| `escort/recordlist.wxss` | `#D4A853` 系 | 暖橙令牌 + 状态四档 |
|
||||
| `escort/recorddetail.wxss`(12 处) | `#D4A853` 系 | 暖橙令牌 + 状态四档 |
|
||||
| `escort/agreement.wxss` | 底 `#FAF6F1`、`#D4A853` 系 | `--paper` / `--brand-soft` / 暖橙令牌 |
|
||||
| `hospital/contact.wxss`、`hospital/ranking.wxss` | 底 `#F5F7F6`,字 `#1F2937`,绿 `#6B8E7B` `#2D6A4F`,灰 `#6B7280` `#9CA3AF` `#F3F4F6` `#E5E7EB` | 整体并入暖橙体系 |
|
||||
| `pages/ai/aichat.wxss` | 金 `#D4A853`,橙渐变 `#FF9B33→#FF7A33`,绿渐变 `#4CAF50→#45A049`,中性 `#F5F5F5` `#EEEEEE` `#999999` `#333333` `#E5E5E5` | 去渐变,气泡改单色 + 浅底,中性色归入纸面与线 |
|
||||
|
||||
### 5.2 系统级(不在任何页面里,最容易漏)
|
||||
|
||||
| 位置 | 现状 | 应改为 |
|
||||
|---|---|---|
|
||||
| `app.json` tabBar 选中图标 | `images/home-green.png`、`ai-green.png`、`mine-green.png`(绿色图片) | 暖橙 `#C2410C` 版本,与 `selectedColor` 一致 |
|
||||
| `app.json` tabBar `color` | `#999999` | `--muted` 等价色 `#6F655C` |
|
||||
| `app.wxss` 全局变量 | `--td-brand-color-1..10` 整套翠绿(基准 `#22A45D`)、`--c-ink #1c1917` | 已确认业务页面零引用(页面只用了 `t-icon`),是死代码,可整体重写或删除 |
|
||||
| `custom-tab-bar/index.wxss`、`index.js` | 未选中色硬编码 `#7A7068` | `#6F655C` |
|
||||
|
||||
### 5.3 通用色值映射表
|
||||
|
||||
| 旧值 | 新值 | 说明 |
|
||||
|---|---|---|
|
||||
| `#D4A853` | `#9A3412` 或 `#C2410C` | 灰金转暖橙,按"文字/图标"或"实心"分 |
|
||||
| `#FF8500` | `#C2410C` | 亮橙转主色 |
|
||||
| `#FF9B33` / `#FF7A33` | `#C2410C` + `#FFF4E8` | 去渐变,拆成字色与底色 |
|
||||
| `#22A45D` / `#6B8E7B` / `#2D6A4F` / `#4CAF50` / `#45A049` | `#C2410C`;若语义是"已完成"则 `#1F7A4D` | 绿系全部转暖橙;仅状态语义保留绿 |
|
||||
| `#FAF6F1` / `#F5F7F6` / `#F5F5F5` | `#FAF8F5` 或 `#FFFFFF` | 旧底转纸面或卡片 |
|
||||
| `#F3F4F6` / `#EEEEEE` / `#E5E5E5` | `#ECE3D6` 或 `#E5DACC` | 冷灰线转暖线 |
|
||||
| `#E5E7EB` | `#ECE3D6`;浅橙底上用 `#E5DACC` | 同上 |
|
||||
| `#1F2937` | `#2B2521` | 冷黑转暖墨 |
|
||||
| `#333333` | `#2B2521` | 同上 |
|
||||
| `#6B7280` / `#9CA3AF` / `#999999` / `#7A7068` | `#6F655C` | 各版"次要灰"统一 |
|
||||
|
||||
---
|
||||
|
||||
## 六、一句话检验
|
||||
|
||||
改完任何页面后,用这三条自检:
|
||||
|
||||
1. 把页面截图去色(灰度化),层级还清楚吗?如果去掉颜色就散架,说明是在用颜色凑层级。
|
||||
2. 数一下页面上有几个色相。超过"暖橙 + 暖墨 + 至多一个状态色",就有问题。
|
||||
3. 页面里最浅的那行字,是 `--muted` 或更深吗?比它更浅的,都要拉回来。
|
||||
@@ -48,6 +48,12 @@ Page({
|
||||
|
||||
const serviceId = parseInt(options.id) || 1
|
||||
this.loadServiceDetail(serviceId)
|
||||
|
||||
// 从列表页的「预约」进来(?book=1)时,直接把预约单弹出来;
|
||||
// 未登录会由 openOrderPopup 拦下并提示登录
|
||||
if (options.book === '1') {
|
||||
this.openOrderPopup()
|
||||
}
|
||||
},
|
||||
|
||||
onShow() {
|
||||
|
||||
+166
-167
@@ -1,199 +1,198 @@
|
||||
<view class="container">
|
||||
<!-- 服务图片 -->
|
||||
<view class="service-image-wrap">
|
||||
<image class="service-image" src="{{service.image}}" mode="aspectFill"></image>
|
||||
</view>
|
||||
<view class="page-bg">
|
||||
<view class="container">
|
||||
|
||||
<!-- 服务基本信息 -->
|
||||
<view class="info-card">
|
||||
<view class="service-header">
|
||||
<view class="service-title-wrap">
|
||||
<text class="service-title">{{service.title}}</text>
|
||||
<view class="service-tag" wx:if="{{service.tag}}">{{service.tag}}</view>
|
||||
<!-- 头部:短横色标 + 深墨标题。原顶部 420rpx 大图已去掉:
|
||||
服务图在多条服务间复用同一张占位图,既分不出是哪项服务,又白占掉大半首屏 -->
|
||||
<view class="page-header">
|
||||
<view class="header-accent"></view>
|
||||
<view class="title-row">
|
||||
<text class="header-title">{{ service.title }}</text>
|
||||
<view class="header-tag" wx:if="{{ service.tag }}">{{ service.tag }}</view>
|
||||
</view>
|
||||
<view class="service-price-wrap">
|
||||
<text class="price-symbol">¥</text>
|
||||
<text class="service-price">{{service.price}}</text>
|
||||
<text class="price-unit">/次</text>
|
||||
<text class="header-subtitle">{{ service.subtitle }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 服务详情 -->
|
||||
<view class="section">
|
||||
<view class="section-head">
|
||||
<view class="section-bar"></view>
|
||||
<text class="section-title">服务详情</text>
|
||||
</view>
|
||||
<text class="detail-text">{{ service.description }}</text>
|
||||
</view>
|
||||
<view class="service-subtitle">{{service.subtitle}}</view>
|
||||
</view>
|
||||
|
||||
<!-- 服务详情 -->
|
||||
<view class="detail-card">
|
||||
<view class="card-title">
|
||||
<t-icon name="info-circle" class="card-icon" size="36rpx" />
|
||||
<text>服务详情</text>
|
||||
</view>
|
||||
<view class="detail-content">
|
||||
<text class="detail-text">{{service.description}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 服务流程 -->
|
||||
<view class="detail-card">
|
||||
<view class="card-title">
|
||||
<t-icon name="list" class="card-icon" size="36rpx" />
|
||||
<text>服务流程</text>
|
||||
</view>
|
||||
<view class="flow-list">
|
||||
<view class="flow-item" wx:for="{{service.flow}}" wx:key="index">
|
||||
<view class="flow-number">{{index + 1}}</view>
|
||||
<view class="flow-content">
|
||||
<text class="flow-title">{{item.title}}</text>
|
||||
<text class="flow-desc">{{item.desc}}</text>
|
||||
<!-- 服务流程:这是真序列,编号在此处合法。橙色导轨是本页唯一的结构性重音,
|
||||
实心橙仍只留给底部与弹窗的提交按钮 -->
|
||||
<view class="section">
|
||||
<view class="section-head">
|
||||
<view class="section-bar"></view>
|
||||
<text class="section-title">服务流程</text>
|
||||
</view>
|
||||
<view class="step-list">
|
||||
<view class="step" wx:for="{{ service.flow }}" wx:key="index">
|
||||
<view class="step-rail">
|
||||
<view class="step-dot">{{ index + 1 }}</view>
|
||||
<view class="step-line" wx:if="{{ index < service.flow.length - 1 }}"></view>
|
||||
</view>
|
||||
<view class="step-body">
|
||||
<text class="step-title">{{ item.title }}</text>
|
||||
<text class="step-desc">{{ item.desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 注意事项 -->
|
||||
<view class="detail-card">
|
||||
<view class="card-title">
|
||||
<t-icon name="error-circle" class="card-icon" size="36rpx" />
|
||||
<text>注意事项</text>
|
||||
</view>
|
||||
<view class="notice-list">
|
||||
<view class="notice-item" wx:for="{{service.notices}}" wx:key="index">
|
||||
<view class="notice-dot"></view>
|
||||
<text class="notice-text">{{item}}</text>
|
||||
<!-- 注意事项:与指南页同一套圆点语言 -->
|
||||
<view class="section">
|
||||
<view class="section-head">
|
||||
<view class="section-bar"></view>
|
||||
<text class="section-title">注意事项</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部占位,避免被下单栏遮挡 -->
|
||||
<view class="bottom-placeholder"></view>
|
||||
|
||||
<!-- 底部下单栏 -->
|
||||
<view class="bottom-bar">
|
||||
<view class="price-info">
|
||||
<text class="total-label">合计:</text>
|
||||
<text class="total-price">¥{{totalPrice}}</text>
|
||||
</view>
|
||||
<button class="order-btn" bindtap="openOrderPopup">预 约</button>
|
||||
</view>
|
||||
|
||||
<!-- 下单弹窗遮罩 -->
|
||||
<view class="popup-mask {{showOrderPopup ? 'show' : ''}}" bindtap="closeOrderPopup"></view>
|
||||
|
||||
<!-- 下单弹窗 -->
|
||||
<view class="popup-content {{showOrderPopup ? 'show' : ''}}">
|
||||
<view class="popup-header">
|
||||
<text class="popup-title">确认预约信息</text>
|
||||
<view class="popup-close" bindtap="closeOrderPopup">
|
||||
<t-icon name="close" size="40rpx" />
|
||||
<view class="dot-list">
|
||||
<view class="dot-item" wx:for="{{ service.notices }}" wx:key="index">
|
||||
<view class="dot"></view>
|
||||
<text class="dot-text">{{ item }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view class="popup-body" scroll-y>
|
||||
<!-- 服务信息 -->
|
||||
<view class="order-service-info">
|
||||
<image class="order-service-image" src="{{service.image}}" mode="aspectFill"></image>
|
||||
<view class="order-service-text">
|
||||
<text class="order-service-title">{{service.title}}</text>
|
||||
<text class="order-service-price">¥{{service.price}}/次</text>
|
||||
<!-- 底部占位,避免被下单栏遮挡 -->
|
||||
<view class="bottom-placeholder"></view>
|
||||
|
||||
<!-- 底部下单栏:价格只在这里出现一次(totalPrice 即服务单价,头部再放一次是纯重复) -->
|
||||
<view class="bottom-bar">
|
||||
<view class="price-info">
|
||||
<text class="total-label">合计</text>
|
||||
<text class="price-sym">¥</text>
|
||||
<text class="total-price">{{ totalPrice }}</text>
|
||||
</view>
|
||||
<button class="order-btn" bindtap="openOrderPopup">立即预约</button>
|
||||
</view>
|
||||
|
||||
<!-- 下单弹窗遮罩 -->
|
||||
<view class="popup-mask {{showOrderPopup ? 'show' : ''}}" bindtap="closeOrderPopup"></view>
|
||||
|
||||
<!-- 下单弹窗 -->
|
||||
<view class="popup-content {{showOrderPopup ? 'show' : ''}}">
|
||||
<view class="popup-header">
|
||||
<text class="popup-title">确认预约信息</text>
|
||||
<view class="popup-close" bindtap="closeOrderPopup">
|
||||
<t-icon name="close" size="40rpx" color="#6F655C" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 选择就诊人:从健康档案一键带入姓名与电话 -->
|
||||
<view class="order-row column">
|
||||
<text class="order-label">选择就诊人</text>
|
||||
<scroll-view class="patient-scroll" scroll-x wx:if="{{profiles.length > 0}}">
|
||||
<view class="patient-chips">
|
||||
<view class="patient-chip {{selectedProfileId === item._id ? 'active' : ''}}" wx:for="{{profiles}}" wx:key="_id"
|
||||
data-id="{{item._id}}" bindtap="onSelectProfile">
|
||||
<text class="patient-chip-name">{{item.name}}</text>
|
||||
<text class="patient-chip-phone">{{item.mobile}}</text>
|
||||
</view>
|
||||
<view class="patient-chip patient-chip-add" bindtap="goToAddProfile">
|
||||
<text class="patient-chip-name">+ 添加就诊人</text>
|
||||
<scroll-view class="popup-body" scroll-y>
|
||||
<!-- 服务信息 -->
|
||||
<view class="order-service-info">
|
||||
<image class="order-service-image" src="{{service.image}}" mode="aspectFill"></image>
|
||||
<view class="order-service-text">
|
||||
<text class="order-service-title">{{service.title}}</text>
|
||||
<text class="order-service-price">¥{{service.price}}/次</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 选择就诊人:从健康档案一键带入姓名与电话 -->
|
||||
<view class="order-row column">
|
||||
<text class="order-label">选择就诊人</text>
|
||||
<scroll-view class="patient-scroll" scroll-x wx:if="{{profiles.length > 0}}">
|
||||
<view class="patient-chips">
|
||||
<view class="patient-chip {{selectedProfileId === item._id ? 'active' : ''}}" wx:for="{{profiles}}" wx:key="_id"
|
||||
data-id="{{item._id}}" bindtap="onSelectProfile">
|
||||
<text class="patient-chip-name">{{item.name}}</text>
|
||||
<text class="patient-chip-phone">{{item.mobile}}</text>
|
||||
</view>
|
||||
<view class="patient-chip patient-chip-add" bindtap="goToAddProfile">
|
||||
<text class="patient-chip-name">+ 添加就诊人</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="add-profile-tip" wx:else bindtap="goToAddProfile">
|
||||
<text class="add-profile-tip-text">还没有就诊人,去添加后可一键带入</text>
|
||||
<t-icon name="chevron-right" size="24rpx" color="#9A3412" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="add-profile-tip" wx:else bindtap="goToAddProfile">
|
||||
<text class="add-profile-tip-text">还没有就诊人,去添加后可一键带入 ›</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 就诊人姓名 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">就诊人姓名</text>
|
||||
<input class="order-input" value="{{patientName}}" placeholder="请输入就诊人姓名" placeholder-class="input-placeholder" bindinput="onPatientNameChange" />
|
||||
</view>
|
||||
<!-- 就诊人姓名 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">就诊人姓名</text>
|
||||
<input class="order-input" value="{{patientName}}" placeholder="请输入就诊人姓名" placeholder-class="input-placeholder" bindinput="onPatientNameChange" />
|
||||
</view>
|
||||
|
||||
<!-- 就诊人电话 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">联系电话</text>
|
||||
<input class="order-input" value="{{patientPhone}}" placeholder="请输入联系电话" placeholder-class="input-placeholder" type="number" bindinput="onPatientPhoneChange" />
|
||||
</view>
|
||||
<!-- 就诊人电话 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">联系电话</text>
|
||||
<input class="order-input" value="{{patientPhone}}" placeholder="请输入联系电话" placeholder-class="input-placeholder" type="number" bindinput="onPatientPhoneChange" />
|
||||
</view>
|
||||
|
||||
<!-- 就诊省份 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">就诊省份</text>
|
||||
<picker mode="selector" range="{{provinces}}" value="{{provinceIndex}}" bindchange="onProvinceChange">
|
||||
<view class="picker-value {{province ? '' : 'placeholder'}}">
|
||||
{{province || '请选择省份'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<!-- 就诊省份 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">就诊省份</text>
|
||||
<picker class="order-picker" mode="selector" range="{{provinces}}" value="{{provinceIndex}}" bindchange="onProvinceChange">
|
||||
<view class="picker-value {{province ? '' : 'placeholder'}}">
|
||||
{{province || '请选择省份'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<!-- 就诊医院 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">就诊医院</text>
|
||||
<input class="order-input" value="{{hospital}}" placeholder="请输入就诊医院" placeholder-class="input-placeholder" bindinput="onHospitalChange" />
|
||||
</view>
|
||||
<!-- 就诊医院 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">就诊医院</text>
|
||||
<input class="order-input" value="{{hospital}}" placeholder="请输入就诊医院" placeholder-class="input-placeholder" bindinput="onHospitalChange" />
|
||||
</view>
|
||||
|
||||
<!-- 就诊科室 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">就诊科室</text>
|
||||
<input class="order-input" value="{{department}}" placeholder="请输入就诊科室" placeholder-class="input-placeholder" bindinput="onDepartmentChange" />
|
||||
</view>
|
||||
<!-- 就诊科室 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">就诊科室</text>
|
||||
<input class="order-input" value="{{department}}" placeholder="请输入就诊科室" placeholder-class="input-placeholder" bindinput="onDepartmentChange" />
|
||||
</view>
|
||||
|
||||
<!-- 陪诊师性别要求 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">陪诊师性别</text>
|
||||
<picker mode="selector" range="{{genderOptions}}" value="{{genderIndex}}" bindchange="onGenderChange">
|
||||
<view class="picker-value {{gender ? '' : 'placeholder'}}">
|
||||
{{gender || '请选择性别要求'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<!-- 陪诊师性别要求 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">陪诊师性别</text>
|
||||
<picker class="order-picker" mode="selector" range="{{genderOptions}}" value="{{genderIndex}}" bindchange="onGenderChange">
|
||||
<view class="picker-value {{gender ? '' : 'placeholder'}}">
|
||||
{{gender || '请选择性别要求'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<!-- 预约日期 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">预约日期</text>
|
||||
<picker mode="date" value="{{appointmentDate}}" start="{{today}}" bindchange="onDateChange">
|
||||
<view class="picker-value {{appointmentDate ? '' : 'placeholder'}}">
|
||||
{{appointmentDate || '请选择预约日期'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<!-- 预约日期 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">预约日期</text>
|
||||
<picker class="order-picker" mode="date" value="{{appointmentDate}}" start="{{today}}" bindchange="onDateChange">
|
||||
<view class="picker-value {{appointmentDate ? '' : 'placeholder'}}">
|
||||
{{appointmentDate || '请选择预约日期'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<!-- 预约时间 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">预约时间</text>
|
||||
<picker mode="time" value="{{appointmentTime}}" start="08:00" end="18:00" bindchange="onTimeChange">
|
||||
<view class="picker-value {{appointmentTime ? '' : 'placeholder'}}">
|
||||
{{appointmentTime || '请选择预约时间'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<!-- 预约时间 -->
|
||||
<view class="order-row">
|
||||
<text class="order-label">预约时间</text>
|
||||
<picker class="order-picker" mode="time" value="{{appointmentTime}}" start="08:00" end="18:00" bindchange="onTimeChange">
|
||||
<view class="picker-value {{appointmentTime ? '' : 'placeholder'}}">
|
||||
{{appointmentTime || '请选择预约时间'}}
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<!-- 备注 -->
|
||||
<view class="order-row column">
|
||||
<text class="order-label">备注说明</text>
|
||||
<textarea class="order-textarea" value="{{remark}}" placeholder="请输入其他需求或备注信息" maxlength="200" placeholder-class="input-placeholder" bindinput="onRemarkChange" />
|
||||
<text class="textarea-count">{{remark.length}}/200</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<!-- 备注 -->
|
||||
<view class="order-row column">
|
||||
<text class="order-label">备注说明</text>
|
||||
<textarea class="order-textarea" value="{{remark}}" placeholder="请输入其他需求或备注信息" maxlength="200" placeholder-class="input-placeholder" bindinput="onRemarkChange" />
|
||||
<text class="textarea-count">{{remark.length}}/200</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="popup-footer">
|
||||
<view class="popup-price">
|
||||
<text class="popup-price-label">合计:</text>
|
||||
<text class="popup-price-value">¥{{totalPrice}}</text>
|
||||
<view class="popup-footer">
|
||||
<view class="popup-price">
|
||||
<text class="popup-price-label">合计</text>
|
||||
<text class="price-sym">¥</text>
|
||||
<text class="popup-price-value">{{ totalPrice }}</text>
|
||||
</view>
|
||||
<button class="popup-submit-btn" bindtap="submitOrder">提交预约</button>
|
||||
</view>
|
||||
<button class="popup-submit-btn" bindtap="submitOrder">提交预约</button>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
+381
-280
@@ -1,220 +1,252 @@
|
||||
/* pages/escort/itemdetail.wxss
|
||||
设计方向:本页是"服务说明书",不是电商详情页。
|
||||
- 去掉了顶部 420rpx 大图:占位图在 8 条服务间复用,既无法区分服务,又抢走首屏
|
||||
- 结构重音只给一处:服务流程的时间轴橙色导轨(真序列,编号在此合法)
|
||||
- 配色锁定首页/清单页的暖白纸面 + 单一暖橙;实心橙只给两个提交按钮
|
||||
- 形状锁定:面板/卡片 28rpx、字段 12rpx、标签 10rpx、胶囊按钮 999rpx */
|
||||
page {
|
||||
background-color: #FAF6F1;
|
||||
--brand-strong: #C2410C; /* 实心块/按钮:白字 4.69:1;纸面上的文字 5.0:1,均过 AA */
|
||||
--brand-soft: #FFF4E8; /* 浅橙衬底 */
|
||||
--brand-line: #FFE0C2; /* 浅橙衬底描边 */
|
||||
--brand-ink: #9A3412; /* 浅橙衬底上的文字:6.8:1,过 AA */
|
||||
|
||||
--ink: #2B2521;
|
||||
--ink-2: #4A4038;
|
||||
--muted: #6F655C; /* 纸面 5.28:1 / 白卡 5.69:1,过 AA 正文 */
|
||||
--line: #ECE3D6; /* 米色发丝边:纸面 1.20:1 / 白卡 1.27:1 */
|
||||
--paper: #FAF8F5;
|
||||
--white: #FFFFFF;
|
||||
|
||||
--shadow-cta: 0 2rpx 8rpx rgba(194, 65, 12, 0.16);
|
||||
/* 纸面 1.05:1 / 发丝边 1.27:1 都托不住固定栏,补一道小偏移小模糊的上向阴影 */
|
||||
--shadow-bar: 0 -2rpx 8rpx rgba(63, 43, 25, 0.07);
|
||||
|
||||
background-color: var(--paper);
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.page-bg {
|
||||
min-height: 100vh;
|
||||
background: var(--paper);
|
||||
}
|
||||
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
padding: 0 32rpx calc(40rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
/* 服务图片 */
|
||||
.service-image-wrap {
|
||||
width: 100%;
|
||||
height: 420rpx;
|
||||
overflow: hidden;
|
||||
/* ===== 头部:短横色标 + 深墨标题 ===== */
|
||||
.page-header {
|
||||
padding: 32rpx 0 0;
|
||||
}
|
||||
|
||||
.service-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.header-accent {
|
||||
width: 64rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 4rpx;
|
||||
background: var(--brand-strong);
|
||||
}
|
||||
|
||||
/* 信息卡片 */
|
||||
.info-card {
|
||||
background: #FFFFFF;
|
||||
margin: -40rpx 24rpx 24rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.service-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.service-title-wrap {
|
||||
.title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
row-gap: 10rpx;
|
||||
column-gap: 16rpx;
|
||||
margin-top: 22rpx;
|
||||
}
|
||||
|
||||
.service-title {
|
||||
font-size: 36rpx;
|
||||
.header-title {
|
||||
font-size: 48rpx;
|
||||
font-weight: 700;
|
||||
color: #1F2937;
|
||||
color: var(--ink);
|
||||
letter-spacing: 1rpx;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.service-tag {
|
||||
background: linear-gradient(135deg, #D4A853 0%, #D4A853 100%);
|
||||
color: #FFFFFF;
|
||||
/* 标签:浅橙衬底 + 暖陶土字,与首页/清单页同一口径 */
|
||||
.header-tag {
|
||||
flex-shrink: 0;
|
||||
padding: 6rpx 18rpx;
|
||||
border-radius: 10rpx;
|
||||
background: var(--brand-soft);
|
||||
border: 2rpx solid var(--brand-line);
|
||||
color: var(--brand-ink);
|
||||
font-size: 22rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.service-price-wrap {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.price-symbol {
|
||||
font-size: 28rpx;
|
||||
color: #D4A853;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.service-price {
|
||||
font-size: 44rpx;
|
||||
color: #D4A853;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.price-unit {
|
||||
font-size: 24rpx;
|
||||
color: #9CA3AF;
|
||||
margin-left: 4rpx;
|
||||
.header-subtitle {
|
||||
display: block;
|
||||
margin-top: 12rpx;
|
||||
font-size: 28rpx;
|
||||
color: var(--muted);
|
||||
letter-spacing: 1rpx;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.service-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
line-height: 1.5;
|
||||
/* ===== 通用区块:靠发丝线切分,不靠白卡浮起来 ===== */
|
||||
.section {
|
||||
margin-top: 44rpx;
|
||||
padding-top: 30rpx;
|
||||
border-top: 2rpx solid var(--line);
|
||||
}
|
||||
|
||||
/* 详情卡片 */
|
||||
.detail-card {
|
||||
background: #FFFFFF;
|
||||
margin: 0 24rpx 24rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
margin-bottom: 24rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
color: #D4A853;
|
||||
margin-right: 12rpx;
|
||||
/* 区块标识:单竖条,与首页/清单页同规格 */
|
||||
.section-bar {
|
||||
width: 8rpx;
|
||||
height: 34rpx;
|
||||
border-radius: 4rpx;
|
||||
background: var(--brand-strong);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
line-height: 1.8;
|
||||
.section-title {
|
||||
margin-left: 16rpx;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: var(--ink);
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
/* ===== 服务详情 ===== */
|
||||
.detail-text {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #4B5563;
|
||||
line-height: 1.8;
|
||||
color: var(--ink-2);
|
||||
line-height: 1.85;
|
||||
letter-spacing: 0.5rpx;
|
||||
}
|
||||
|
||||
/* 服务流程 */
|
||||
.flow-list {
|
||||
/* ===== 服务流程:时间轴(本页唯一的结构性重音) ===== */
|
||||
.step-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.flow-item {
|
||||
.step {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.flow-number {
|
||||
/* 导轨需要撑满整步高度,连接线才能真的连到下一步 */
|
||||
.step-rail {
|
||||
align-self: stretch;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 44rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.step-dot {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
background: linear-gradient(135deg, #D4A853 0%, #D4A853 100%);
|
||||
color: #FFFFFF;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
background: var(--brand-soft);
|
||||
border: 2rpx solid var(--brand-line);
|
||||
color: var(--brand-ink);
|
||||
font-size: 24rpx;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.flow-content {
|
||||
/* 连接线:橙色导轨,用半透明暖橙而非实心,避免与圆点抢重音 */
|
||||
.step-line {
|
||||
flex: 1;
|
||||
width: 2rpx;
|
||||
min-height: 16rpx;
|
||||
margin: 8rpx 0;
|
||||
background: rgba(194, 65, 12, 0.28);
|
||||
}
|
||||
|
||||
.flow-title {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
margin-bottom: 8rpx;
|
||||
.step-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin-left: 20rpx;
|
||||
padding-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.flow-desc {
|
||||
.step:last-child .step-body {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.step-title {
|
||||
display: block;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: var(--ink);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.step-desc {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
line-height: 1.5;
|
||||
color: var(--muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 注意事项 */
|
||||
.notice-list {
|
||||
/* ===== 注意事项:与指南页同一套圆点语言 ===== */
|
||||
.dot-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
gap: 18rpx;
|
||||
}
|
||||
|
||||
.notice-item {
|
||||
.dot-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.notice-dot {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
background: #D4A853;
|
||||
.dot {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
border-radius: 50%;
|
||||
margin-top: 12rpx;
|
||||
background: var(--brand-strong);
|
||||
margin-top: 14rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.notice-text {
|
||||
font-size: 28rpx;
|
||||
color: #4B5563;
|
||||
line-height: 1.6;
|
||||
.dot-text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin-left: 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: var(--ink-2);
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
/* 底部占位 */
|
||||
/* ===== 底部占位 + 下单栏 ===== */
|
||||
.bottom-placeholder {
|
||||
height: 140rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
|
||||
/* 底部下单栏 */
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #FFFFFF;
|
||||
padding: 24rpx 32rpx;
|
||||
padding-bottom: calc(24rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
|
||||
padding: 20rpx 32rpx;
|
||||
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||||
background: var(--white);
|
||||
border-top: 2rpx solid var(--line);
|
||||
box-shadow: var(--shadow-bar);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
@@ -224,39 +256,63 @@ page {
|
||||
}
|
||||
|
||||
.total-label {
|
||||
margin-right: 8rpx;
|
||||
font-size: 26rpx;
|
||||
color: var(--muted);
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.price-sym {
|
||||
font-size: 28rpx;
|
||||
color: #6B7280;
|
||||
font-weight: 700;
|
||||
color: var(--brand-strong);
|
||||
}
|
||||
|
||||
.total-price {
|
||||
font-size: 40rpx;
|
||||
color: #D4A853;
|
||||
margin-left: 2rpx;
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: var(--brand-strong);
|
||||
}
|
||||
|
||||
/* 主操作:实心暖橙胶囊,与首页/清单页 CTA 同形。
|
||||
内边距把高度撑到约 86rpx(43pt),贴近 iOS 44pt 触控目标 */
|
||||
.order-btn {
|
||||
background: linear-gradient(135deg, #6B8E7B 0%, #6B8E7B 100%);
|
||||
color: #FFFFFF;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
padding: 24rpx 56rpx;
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin: 0;
|
||||
padding: 22rpx 52rpx;
|
||||
border: none;
|
||||
line-height: 1.5;
|
||||
border-radius: 999rpx;
|
||||
background: var(--brand-strong);
|
||||
box-shadow: var(--shadow-cta);
|
||||
color: var(--white);
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2rpx;
|
||||
line-height: 1.4;
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
.order-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 弹窗遮罩 */
|
||||
.order-btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
/* ===== 下单弹窗 ===== */
|
||||
/* 遮罩用暖近黑而非纯黑,避免和暖色纸面打架 */
|
||||
.popup-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
background: rgba(43, 37, 33, 0.45);
|
||||
z-index: 200;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
@@ -268,20 +324,19 @@ page {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* 弹窗内容 */
|
||||
.popup-content {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #FFFFFF;
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
z-index: 201;
|
||||
transform: translateY(100%);
|
||||
transition: transform 0.3s ease-out;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 85vh;
|
||||
background: var(--white);
|
||||
border-radius: 32rpx 32rpx 0 0;
|
||||
z-index: 201;
|
||||
transform: translateY(100%);
|
||||
transition: transform 0.3s ease-out;
|
||||
}
|
||||
|
||||
.popup-content.show {
|
||||
@@ -289,214 +344,170 @@ page {
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 32rpx;
|
||||
position: relative;
|
||||
border-bottom: 1rpx solid #F3F4F6;
|
||||
padding: 30rpx 32rpx;
|
||||
border-bottom: 2rpx solid var(--line);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.popup-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
font-weight: 700;
|
||||
color: var(--ink);
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
/* 用 padding 撑热区到约 64rpx,再用更小的 right 抵消,图标视觉位置不变 */
|
||||
.popup-close {
|
||||
position: absolute;
|
||||
right: 32rpx;
|
||||
right: 20rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #9CA3AF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12rpx;
|
||||
}
|
||||
|
||||
.popup-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 32rpx;
|
||||
max-height: 60vh;
|
||||
width: auto;
|
||||
padding: 28rpx 32rpx;
|
||||
}
|
||||
|
||||
/* 弹窗内服务信息 */
|
||||
/* 弹窗内服务信息:浅橙衬底块,与页面的重点面板语言一致 */
|
||||
.order-service-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
padding-bottom: 24rpx;
|
||||
border-bottom: 1rpx solid #F3F4F6;
|
||||
margin-bottom: 24rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
margin-bottom: 8rpx;
|
||||
border-radius: 20rpx;
|
||||
background: var(--brand-soft);
|
||||
border: 2rpx solid var(--brand-line);
|
||||
}
|
||||
|
||||
.order-service-image {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 12rpx;
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
border-radius: 14rpx;
|
||||
flex-shrink: 0;
|
||||
background: var(--white);
|
||||
}
|
||||
|
||||
.order-service-text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.order-service-title {
|
||||
display: block;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
margin-bottom: 12rpx;
|
||||
font-weight: 700;
|
||||
color: var(--ink);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.order-service-price {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
color: #D4A853;
|
||||
margin-top: 8rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: var(--brand-ink);
|
||||
}
|
||||
|
||||
/* 表单行 */
|
||||
/* ===== 表单行 ===== */
|
||||
/* 上下各 24rpx 内边距,行高约 87rpx,贴近 iOS 44pt 触控目标 */
|
||||
.order-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #F3F4F6;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 2rpx solid var(--line);
|
||||
}
|
||||
|
||||
.order-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.order-row.column {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 16rpx;
|
||||
align-items: stretch;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.order-label {
|
||||
font-size: 28rpx;
|
||||
color: #374151;
|
||||
font-weight: 500;
|
||||
flex-shrink: 0;
|
||||
font-size: 28rpx;
|
||||
color: var(--muted);
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.order-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin-left: 24rpx;
|
||||
text-align: right;
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
margin-left: 24rpx;
|
||||
font-weight: 700;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.input-placeholder {
|
||||
color: #9CA3AF;
|
||||
color: var(--muted);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* picker 需要占满剩余宽度,值才能靠右对齐 */
|
||||
.order-picker {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
|
||||
.picker-value {
|
||||
display: block;
|
||||
text-align: right;
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
font-weight: 700;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.picker-value.placeholder {
|
||||
color: #9CA3AF;
|
||||
color: var(--muted);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* 数量控制 */
|
||||
.quantity-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.quantity-btn {
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
background: #F3F4F6;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32rpx;
|
||||
color: #1F2937;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.quantity-btn.disabled {
|
||||
color: #CCCCCC;
|
||||
background: #F9FAFB;
|
||||
}
|
||||
|
||||
.quantity-value {
|
||||
font-size: 30rpx;
|
||||
color: #1F2937;
|
||||
font-weight: 600;
|
||||
min-width: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 文本域 */
|
||||
/* 备注文本域:字段用暖白纸面填充 + 发丝边,与白底弹窗拉开一层 */
|
||||
.order-textarea {
|
||||
width: 100%;
|
||||
height: 160rpx;
|
||||
background: #F9FAFB;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.textarea-count {
|
||||
font-size: 24rpx;
|
||||
color: #9CA3AF;
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
/* 弹窗底部 */
|
||||
.popup-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24rpx 32rpx;
|
||||
padding-bottom: calc(24rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
|
||||
border-top: 1rpx solid #F3F4F6;
|
||||
background: #FFFFFF;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.popup-price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.popup-price-label {
|
||||
margin-top: 16rpx;
|
||||
padding: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
background: var(--paper);
|
||||
border: 2rpx solid var(--line);
|
||||
font-size: 28rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.popup-price-value {
|
||||
font-size: 40rpx;
|
||||
color: #D4A853;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.popup-submit-btn {
|
||||
background: linear-gradient(135deg, #6B8E7B 0%, #6B8E7B 100%);
|
||||
color: #FFFFFF;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
padding: 24rpx 56rpx;
|
||||
border-radius: 20rpx;
|
||||
border: none;
|
||||
color: var(--ink);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.popup-submit-btn::after {
|
||||
border: none;
|
||||
.textarea-count {
|
||||
align-self: flex-end;
|
||||
margin-top: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
/* 就诊人选择 */
|
||||
/* ===== 就诊人选择 ===== */
|
||||
.patient-scroll {
|
||||
width: 100%;
|
||||
margin-top: 16rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -508,48 +519,138 @@ page {
|
||||
.patient-chip {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
min-width: 160rpx;
|
||||
padding: 14rpx 24rpx;
|
||||
min-width: 180rpx;
|
||||
padding: 16rpx 24rpx;
|
||||
border-radius: 16rpx;
|
||||
background: #F9FAFB;
|
||||
border: 2rpx solid #F3F4F6;
|
||||
background: var(--paper);
|
||||
border: 2rpx solid var(--line);
|
||||
box-sizing: border-box;
|
||||
transition: opacity 0.15s ease;
|
||||
}
|
||||
|
||||
.patient-chip:active {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* 选中态:浅橙衬底 + 实心橙描边(--brand-line 在浅橙底上只有 1.16:1,看不见) */
|
||||
.patient-chip.active {
|
||||
background: #FDF8EE;
|
||||
border-color: #D4A853;
|
||||
background: var(--brand-soft);
|
||||
border-color: var(--brand-strong);
|
||||
}
|
||||
|
||||
.patient-chip-name {
|
||||
font-size: 26rpx;
|
||||
color: #374151;
|
||||
font-weight: 600;
|
||||
font-weight: 700;
|
||||
color: var(--ink-2);
|
||||
}
|
||||
|
||||
.patient-chip.active .patient-chip-name {
|
||||
color: #D4A853;
|
||||
color: var(--brand-ink);
|
||||
}
|
||||
|
||||
.patient-chip-phone {
|
||||
font-size: 22rpx;
|
||||
color: #9CA3AF;
|
||||
margin-top: 6rpx;
|
||||
font-size: 22rpx;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.patient-chip-add {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.patient-chip-add .patient-chip-name {
|
||||
color: var(--brand-ink);
|
||||
}
|
||||
|
||||
/* 空态:整块可点,热区约 92rpx */
|
||||
.add-profile-tip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 18rpx 24rpx;
|
||||
margin-top: 16rpx;
|
||||
padding: 22rpx 24rpx;
|
||||
border-radius: 16rpx;
|
||||
background: #FDF8EE;
|
||||
background: var(--brand-soft);
|
||||
border: 2rpx solid var(--brand-line);
|
||||
box-sizing: border-box;
|
||||
transition: opacity 0.15s ease;
|
||||
}
|
||||
|
||||
.add-profile-tip:active {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.add-profile-tip-text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin-right: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #A1864B;
|
||||
font-weight: 700;
|
||||
color: var(--brand-ink);
|
||||
}
|
||||
|
||||
/* ===== 弹窗底部 ===== */
|
||||
.popup-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 32rpx;
|
||||
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||||
border-top: 2rpx solid var(--line);
|
||||
background: var(--white);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.popup-price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.popup-price-label {
|
||||
margin-right: 8rpx;
|
||||
font-size: 26rpx;
|
||||
color: var(--muted);
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.popup-price-value {
|
||||
margin-left: 2rpx;
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: var(--brand-strong);
|
||||
}
|
||||
|
||||
.popup-submit-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin: 0;
|
||||
padding: 22rpx 48rpx;
|
||||
border: none;
|
||||
border-radius: 999rpx;
|
||||
background: var(--brand-strong);
|
||||
box-shadow: var(--shadow-cta);
|
||||
color: var(--white);
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2rpx;
|
||||
line-height: 1.4;
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
.popup-submit-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.popup-submit-btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.popup-content,
|
||||
.popup-mask {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
+107
-15
@@ -1,6 +1,62 @@
|
||||
// 服务按"要办的事"分三组,而不是照后端返回顺序平铺。
|
||||
// 组内是能直接比较的同质选项,组间是完全不同的决定;
|
||||
// note 是每组末尾那块浅橙说明砖,只讲"什么情况适合选这一组",不重复列服务。
|
||||
// ids 对应 services.js 里的服务 id,取不到的项会被跳过
|
||||
const SERVICE_GROUPS = [{
|
||||
key: 'accompany',
|
||||
title: '要有人陪着去',
|
||||
note: '老人、异地就医,或不便独自就诊的情况都适合。陪诊师提前确认院区路线与科室位置,就诊当天全程在场。',
|
||||
ids: [1, 2] // 全天陪诊 / 半天陪诊
|
||||
},
|
||||
{
|
||||
key: 'errand',
|
||||
title: '只要有人代办',
|
||||
note: '本人不必到场。排队取号、递送材料、取报告这些跑动的事都可以交给我们,办完的结果原样带回。',
|
||||
ids: [3, 4, 5, 6] // 代问诊 / 检查预约 / 出入院代办 / 跑腿服务
|
||||
},
|
||||
{
|
||||
key: 'pack',
|
||||
// 原「打算长期使用」讲的是"买法"(打包更省),和前两组的"要办的事"不同轴。
|
||||
// 拉回同一根轴,标题只说"要办的事",优惠留给下面那块说明砖去讲
|
||||
title: '要办很多次',
|
||||
note: '需要多次复诊或长期治疗时,一次买多次,省去反复下单的麻烦,每次按次使用。',
|
||||
ids: [7, 8] // VIP 5次 半天陪诊 / VIP 5次代买药
|
||||
// 注:条目改单行横排后名称不再被半栏宽度挤压,这两个"VIP 5次 XXX"已恢复原名,
|
||||
// "买多次"由名称自己交代;组标题与说明砖仍负责讲清"什么情况选这一组"
|
||||
}
|
||||
]
|
||||
|
||||
// 规格签:把"这一单买的是什么"从说明句里提出来,八条口径一致——
|
||||
// 按时长计费的服务标出时长,按次计费的标"按次"。id 对应 services.js,取不到就不显示
|
||||
const UNIT_BY_ID = {
|
||||
1: '8小时/次',
|
||||
2: '4小时/次',
|
||||
3: '按次',
|
||||
4: '按次',
|
||||
5: '按次',
|
||||
6: '1小时/次',
|
||||
7: '4小时/次',
|
||||
8: '按次'
|
||||
}
|
||||
|
||||
// 价目表上的价格去掉无意义的 .00(八条都是整元),扫起来更快
|
||||
function formatPrice(value) {
|
||||
return String(value == null ? '' : value).replace(/\.00$/, '')
|
||||
}
|
||||
|
||||
// 说明句里与规格签重复的时长要去掉,免得同一格写两遍:
|
||||
// ① 开头的"X小时服务/次,"(全天陪诊 / 半天陪诊)
|
||||
// ② 句中的"每次X小时,"(VIP 5次 半天陪诊)
|
||||
// 规格签只回答"这一单每次买多久",不写"5次装"——"买几次"由名称承担
|
||||
function toLedgerDesc(subtitle) {
|
||||
return String(subtitle || '')
|
||||
.replace(/^[一二三四五六七八九十\d]+小时[^,]*,/, '')
|
||||
.replace(/每次[一二三四五六七八九十\d]+小时,/g, '')
|
||||
}
|
||||
|
||||
Page({
|
||||
data: {
|
||||
services: []
|
||||
groups: []
|
||||
},
|
||||
|
||||
onShareAppMessage() {
|
||||
@@ -16,24 +72,54 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
onLoad() {
|
||||
const app = getApp()
|
||||
this.setData({
|
||||
services: app.globalData.services
|
||||
// 与首页同样走 servicesReady,避免直接从详情页返回时 globalData 尚未就绪
|
||||
const ready = app.globalData.servicesReady || Promise.resolve(app.globalData.services || [])
|
||||
|
||||
ready.then((services) => {
|
||||
const list = services || []
|
||||
const serviceMap = {}
|
||||
list.forEach((service) => {
|
||||
serviceMap[service.id] = service
|
||||
})
|
||||
|
||||
// 取到服务后再加工成列表页要用的字段:desc 去掉与规格签重复的时长前缀,
|
||||
// unit 补规格签,price 去掉 .00;最后空组不展示,
|
||||
// 免得留下一个没有服务、只有标题的分组
|
||||
const groups = SERVICE_GROUPS
|
||||
.map((group) => ({
|
||||
key: group.key,
|
||||
title: group.title,
|
||||
note: group.note,
|
||||
items: group.ids
|
||||
.map((id) => serviceMap[id])
|
||||
.filter(Boolean)
|
||||
.map((srv) => ({
|
||||
...srv,
|
||||
desc: toLedgerDesc(srv.subtitle),
|
||||
unit: UNIT_BY_ID[srv.id] || '',
|
||||
price: formatPrice(srv.price)
|
||||
}))
|
||||
}))
|
||||
.filter((group) => group.items.length > 0)
|
||||
|
||||
this.setData({ groups })
|
||||
})
|
||||
},
|
||||
|
||||
// 预约:带 book=1 进详情页,详情页读完服务后会自己把预约单弹出来,
|
||||
// 用户在详情页仍可关掉预约单先看服务流程
|
||||
goToBook(e) {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: `/pages/escort/itemdetail?id=${id}&book=1`
|
||||
});
|
||||
},
|
||||
|
||||
goToDetail(e) {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
goToGuide() {
|
||||
wx.navigateTo({
|
||||
url: `/pages/escort/itemdetail?id=${id}`
|
||||
});
|
||||
},
|
||||
|
||||
onBook(e) {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: `/pages/escort/itemdetail?id=${id}`
|
||||
url: '/pages/escort/guide'
|
||||
});
|
||||
},
|
||||
|
||||
@@ -41,5 +127,11 @@ Page({
|
||||
wx.navigateTo({
|
||||
url: '/pages/escort/agreement'
|
||||
});
|
||||
},
|
||||
|
||||
goToContact() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/mine/contact'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"usingComponents": {
|
||||
"t-icon": "tdesign-miniprogram/icon/icon"
|
||||
},
|
||||
"navigationBarTitleText": "陪诊服务"
|
||||
}
|
||||
+63
-42
@@ -1,54 +1,75 @@
|
||||
<view class="container">
|
||||
<view class="page-bg">
|
||||
<view class="container">
|
||||
|
||||
<!-- 页面头部 -->
|
||||
<view class="page-header">
|
||||
<view class="header-title-wrap">
|
||||
<view class="header-accent"></view>
|
||||
<text class="header-title">陪诊服务</text>
|
||||
</view>
|
||||
<text class="header-subtitle">专业 · 贴心 · 安心</text>
|
||||
|
||||
<view class="intro-card">
|
||||
<view class="intro-content">
|
||||
<view class="intro-desc">
|
||||
<text>全国范围内的陪诊服务,全程陪同就医,让就诊更轻松、更安心。请认真阅读</text>
|
||||
<text class="link-text" bindtap="goToAgreement">《用户协议》</text>
|
||||
<text>。</text>
|
||||
<!-- 页首不重复导航栏的「陪诊服务」大标题,改成一张说明卡:
|
||||
短横色标 + 一句关键披露 + 发丝线 + 两个入口。
|
||||
卡面走"白卡 + 发丝边 + 暖色紧阴影",把首屏从纸面上拎起来 -->
|
||||
<view class="notice">
|
||||
<view class="notice-tick"></view>
|
||||
<text class="notice-text">全国接单,按次收费。费用不含挂号费、检查费、药费。</text>
|
||||
<view class="notice-hr"></view>
|
||||
<view class="notice-links">
|
||||
<view class="notice-link" bindtap="goToGuide">
|
||||
<text class="notice-link-text">服务指南</text>
|
||||
<t-icon name="chevron-right" size="24rpx" color="#6F655C" />
|
||||
</view>
|
||||
<view class="notice-sep"></view>
|
||||
<view class="notice-link" bindtap="goToAgreement">
|
||||
<text class="notice-link-text">用户协议</text>
|
||||
<t-icon name="chevron-right" size="24rpx" color="#6F655C" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 服务列表 -->
|
||||
<view class="service-list">
|
||||
<view class="section-title-wrap">
|
||||
<t-icon name="system-3" size="36rpx" color="#D4A853" />
|
||||
<text class="section-title">服务列表</text>
|
||||
</view>
|
||||
<!-- 服务按"要办的事"分三组。组头是"表头":竖条 + 40rpx 标题 + 通栏发丝线,
|
||||
整页由此读成三章的价目表。条目一律一条一行:只有规则线、没有卡片。
|
||||
从 2×2 价目表改为单行,是因为半栏只有 317rpx(说明要折行、名称要被迫缩短),
|
||||
而这份数据里真正能横向比价的只有第一组(全天/半天)两格。
|
||||
每行两列:左列名称 + 规格签 + 点线 + 价格(同一行)+ 说明;右列只剩一个预约按钮。
|
||||
每组末尾压一块浅橙说明砖,交代"什么情况适合选这一组" -->
|
||||
<view class="group" wx:for="{{ groups }}" wx:key="key">
|
||||
|
||||
<view class="service-item" wx:for="{{ services }}" wx:key="id" bindtap="goToDetail" data-id="{{ item.id }}">
|
||||
<view class="service-main">
|
||||
<view class="service-title-row">
|
||||
<view class="title-wrap">
|
||||
<view class="title-accent"></view>
|
||||
<text class="service-title">{{ item.title }}</text>
|
||||
<view class="group-head">
|
||||
<view class="group-bar"></view>
|
||||
<text class="group-title">{{ item.title }}</text>
|
||||
</view>
|
||||
|
||||
<view class="ledger">
|
||||
<view class="ledger-row" wx:for="{{ item.items }}" wx:for-item="srv" wx:key="id">
|
||||
<!-- 左列:名称 + 规格签 + 点线 + 价格同一行,下面接说明 -->
|
||||
<view class="row-main">
|
||||
<view class="row-name-wrap">
|
||||
<text class="row-name">{{ srv.title }}</text>
|
||||
<text class="unit-chip" wx:if="{{ srv.unit }}">{{ srv.unit }}</text>
|
||||
<view class="row-leader"></view>
|
||||
<view class="price">
|
||||
<text class="price-sym">¥</text>
|
||||
<text class="price-num">{{ srv.price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="row-desc">{{ srv.desc }}</text>
|
||||
</view>
|
||||
<!-- 右列:只剩一个预约按钮,垂直居中 -->
|
||||
<view class="book-btn" catchtap="goToBook" data-id="{{ srv.id }}">
|
||||
<text class="book-btn-text">预约</text>
|
||||
</view>
|
||||
<view class="service-tag" wx:if="{{ item.tag }}">{{ item.tag }}</view>
|
||||
</view>
|
||||
<view class="subtitle-wrap">
|
||||
<text class="service-subtitle">{{ item.subtitle }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="service-footer">
|
||||
<view class="price-wrap">
|
||||
<text class="price-symbol">¥</text>
|
||||
<text class="service-price">{{ item.price }}</text>
|
||||
</view>
|
||||
<view class="btn-book" catchtap="onBook" data-id="{{ item.id }}">
|
||||
<text>立即预约</text>
|
||||
<t-icon name="chevron-right" size="24rpx" color="#FFFFFF" />
|
||||
</view>
|
||||
|
||||
<view class="group-note">
|
||||
<text class="group-note-text">{{ item.note }}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 页脚:翻完三组仍未决定的兜底出口 -->
|
||||
<view class="page-footer">
|
||||
<text class="footer-text">没有合适的?</text>
|
||||
<view class="footer-link" bindtap="goToContact">
|
||||
<text class="footer-link-text">联系人工客服</text>
|
||||
<t-icon name="chevron-right" size="22rpx" color="#9A3412" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
+305
-160
@@ -1,217 +1,362 @@
|
||||
/* pages/escort/itemlist.wxss
|
||||
设计方向:本页是一张"按要办的事挑服务"的价目单,8 条服务同一个形状才方便扫读。
|
||||
- 页首说明做成一张白卡(短横色标 → 关键披露 → 发丝线 → 两个入口),
|
||||
让首屏从纸面上拎起一个落点,而不是三段裸字
|
||||
- 八条服务按"要办的事"分三组,组头做成"表头":竖条 + 40rpx 标题 + 通栏发丝线,
|
||||
下面接清单,整页读起来像三章的价目表;组与组之间仍只用留白,不叠第二道横线
|
||||
- 条目一律一条一行:只有规则线没有卡片。
|
||||
原先是 2×2 价目表,但半栏只有 317rpx——说明句要折行、名称要被迫缩短,
|
||||
而这份数据里真正能横向比价的只有第一组(全天/半天)两格,代价不值,故改单行
|
||||
- 每行:左侧名称 + 规格签 + 点线 + 价格(同一行)+ 说明 / 右侧一个预约按钮
|
||||
- 点线(--sep)把名称与价格之间的空档连起来,是这一页最像"价目单"的那一笔;
|
||||
它 flex-basis 为 0,空间紧时自己缩到没有,不会把名称挤折行
|
||||
- 按钮走 --brand-strong 描边(不填充):与首页主 CTA 同一套按钮语言,
|
||||
描边不构成 DESIGN.md §2.1 说的"实心大色块",8 个也不会把暖橙铺成面
|
||||
- 价格按用户要求弱化:--muted + 字重 500(本页对 §2.1「价格数字」的例外,已登记)
|
||||
- 字号阶梯:组标题 40 / 名称 30 / 说明 26 / 签与页脚 24(rpx)
|
||||
- 形状锁定:说明砖 28rpx、页首说明卡 20rpx、预约按钮 12rpx、
|
||||
规格签只在右侧 6rpx 做圆角(色标式),其余圆角一律不做 */
|
||||
page {
|
||||
background-color: #F5F7F6;
|
||||
--brand-strong: #C2410C; /* 按钮描边/文字、区块竖条:纸面上 4.89:1,过 AA 与非文本 3:1 */
|
||||
--brand-soft: #FFF4E8; /* 浅橙衬底,暖色的第二档;也是按钮按下态 */
|
||||
--brand-line: #FFE0C2; /* 浅橙衬底描边 */
|
||||
--brand-ink: #9A3412; /* 浅橙衬底/纸面上的文字链:6.8:1,过 AA */
|
||||
|
||||
--ink: #2B2521;
|
||||
--ink-2: #4A4038;
|
||||
--muted: #6F655C; /* 纸面 5.28:1 / 白卡 5.69:1,过 AA 正文 */
|
||||
--line: #ECE3D6; /* 米色发丝边:纸面 1.20:1 */
|
||||
--sep: #E5DACC; /* 分隔线专用:竖分隔线
|
||||
(比 --line 深一档才看得见) */
|
||||
--paper: #FAF8F5;
|
||||
--white: #FFFFFF;
|
||||
|
||||
background-color: var(--paper);
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.container {
|
||||
.page-bg {
|
||||
min-height: 100vh;
|
||||
padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
|
||||
background: var(--paper);
|
||||
}
|
||||
|
||||
/* 页面头部 */
|
||||
.page-header {
|
||||
background: #FFFFFF;
|
||||
padding: 48rpx 32rpx 32rpx;
|
||||
.container {
|
||||
padding: 0 32rpx calc(40rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.header-title-wrap {
|
||||
/* ===== 说明卡:页首第一块 =====
|
||||
页内大标题与导航栏的「陪诊服务」重复,不重复写;
|
||||
说明做成一张白卡(发丝边 + 暖色紧阴影 = DESIGN.md §2.3 的托形写法),
|
||||
卡内三段:短横色标 → 一句关键披露 → 发丝线 → 两个入口 */
|
||||
.notice {
|
||||
margin-top: 32rpx;
|
||||
padding: 30rpx 28rpx 14rpx;
|
||||
background: var(--white);
|
||||
border: 2rpx solid var(--line);
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(194, 65, 12, 0.08);
|
||||
}
|
||||
|
||||
/* 短横色标:与详情页页首同一种品牌标记语言,比区块竖条更"抬头" */
|
||||
.notice-tick {
|
||||
width: 48rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 3rpx;
|
||||
background: var(--brand-strong);
|
||||
}
|
||||
|
||||
/* 这句是费用披露,不是可有可无的说明,所以白卡上给 --ink-2 而不是 --muted */
|
||||
.notice-text {
|
||||
display: block;
|
||||
margin-top: 18rpx;
|
||||
font-size: 26rpx;
|
||||
color: var(--ink-2);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* 卡内的横向分隔线,与入口行之间那根竖分隔线不是同一个东西 */
|
||||
.notice-hr {
|
||||
height: 2rpx;
|
||||
margin-top: 20rpx;
|
||||
background: var(--line);
|
||||
}
|
||||
|
||||
/* 入口另起一行:细竖线分隔,与首页场景行同一套写法
|
||||
(2rpx × 20rpx、#E5DACC,不用中点字符)。
|
||||
链接语言对齐首页 .section-link:muted + 右侧 chevron,不用橙色下划线。
|
||||
行距不另加上边距——.notice-link 自己的 padding 就是与分隔线之间的空隙 */
|
||||
.notice-links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.header-accent {
|
||||
/* 文字只有 26rpx 高,用 padding 撑热区到 58rpx(29px),再用等量负外边距抵消,行距不变 */
|
||||
.notice-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16rpx 0;
|
||||
margin: -16rpx 0;
|
||||
}
|
||||
|
||||
.notice-link:active {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.notice-link-text {
|
||||
margin-right: 4rpx;
|
||||
font-size: 26rpx;
|
||||
color: var(--muted);
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.notice-sep {
|
||||
width: 2rpx;
|
||||
height: 20rpx;
|
||||
margin: 0 20rpx;
|
||||
background: var(--sep);
|
||||
}
|
||||
|
||||
/* ===== 分组 =====
|
||||
组头做成"表头":竖条 + 大号标题 + 通栏发丝线,给这 2~4 条服务一个明确的"章"边界。
|
||||
组与组之间仍只用留白(与首页 .section 同一种分离方式),不叠第二道横线 */
|
||||
.group {
|
||||
margin-top: 64rpx;
|
||||
}
|
||||
|
||||
.group-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 18rpx;
|
||||
border-bottom: 2rpx solid var(--line);
|
||||
}
|
||||
|
||||
/* 区块标识:单竖条,与首页 .section-bar 同形(这里随 40rpx 标题一起放大) */
|
||||
.group-bar {
|
||||
width: 8rpx;
|
||||
height: 40rpx;
|
||||
background: #2D6A4F;
|
||||
border-radius: 4rpx;
|
||||
background: var(--brand-strong);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
/* 组标题抬到 40rpx:与服务名 30rpx 拉开一档,页面由此有了"章 / 条"两级,
|
||||
而不是通篇一个字号 */
|
||||
.group-title {
|
||||
margin-left: 16rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
color: #1F2937;
|
||||
letter-spacing: 2rpx;
|
||||
color: var(--ink);
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
/* ===== 价格:按用户要求弱化,只作信息展示 =====
|
||||
--muted + 字重 500:比说明只靠字号(32 vs 26rpx)与字重分开一档,
|
||||
既不抢名称的重心,也不走 --brand-strong。
|
||||
这是本页对 DESIGN.md §2.1「价格数字」用途的例外,已在页首注释登记 */
|
||||
.price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.price-sym {
|
||||
font-size: 26rpx;
|
||||
color: #6B8E7B;
|
||||
margin-left: 24rpx;
|
||||
letter-spacing: 4rpx;
|
||||
margin-bottom: 24rpx;
|
||||
font-weight: 500;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.intro-card {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
background: #FAFAFA;
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx;
|
||||
.price-num {
|
||||
margin-left: 2rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.intro-icon-wrap {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 20rpx;
|
||||
background: #6B8E7B;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 24rpx;
|
||||
/* ===== 规格签:色标式(左侧暖橙竖条 + 浅橙底 + 右侧圆角) =====
|
||||
整圈描边会让每行出现两个橙框(签 + 按钮),右侧橙色密度过高;
|
||||
改成色标后只留一道左竖条,辨识靠"条 + 暖陶土字",视觉更安静。
|
||||
底仍是 --brand-soft(落在暖白纸面上约 1:1,托不出形状),
|
||||
形状由 4rpx 的 --brand-strong 左竖条给出(纸面上 4.89:1,过非文本 3:1),
|
||||
字用 --brand-ink(6.8:1,过 AA)。只在右侧做 6rpx 圆角,已写进页首的形状锁 */
|
||||
.unit-chip {
|
||||
padding: 2rpx 10rpx;
|
||||
border-left: 4rpx solid var(--brand-strong);
|
||||
border-radius: 0 6rpx 6rpx 0;
|
||||
background: var(--brand-soft);
|
||||
font-size: 24rpx;
|
||||
color: var(--brand-ink);
|
||||
letter-spacing: 1rpx;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.intro-content {
|
||||
/* ===== 清单:一条一行,只有规则线没有卡片 ===== */
|
||||
.ledger {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 每行两列:左列是"名称 + 规格签 + 价格"一行 + 说明,右列只剩预约按钮。
|
||||
价格不再单独占一行,行高因此由左列决定;上下 padding 按用户
|
||||
"过于紧凑"的反馈由 24rpx 放开到 32rpx,行高约 158rpx。
|
||||
align-items:center 让按钮在行内垂直居中 */
|
||||
.ledger-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 32rpx;
|
||||
padding-bottom: 32rpx;
|
||||
border-bottom: 2rpx solid var(--line);
|
||||
}
|
||||
|
||||
/* 最后一行不封底:下面的说明砖已经把它收住了 */
|
||||
.ledger-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* 左列:名称 + 说明。min-width:0 让长名称与长说明正常折行,不撑破行宽 */
|
||||
.row-main {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.intro-title {
|
||||
font-size: 32rpx;
|
||||
/* 名称 + 规格签在左,价格 margin-left:auto 顶到最右 */
|
||||
.row-name-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 名称给 min-width:0 兜底:名称过长时折行,不会把后面的签与价格挤出去 */
|
||||
.row-name {
|
||||
flex: 0 1 auto;
|
||||
min-width: 0;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: #1F2937;
|
||||
margin-bottom: 12rpx;
|
||||
color: var(--ink);
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.intro-desc {
|
||||
.row-name-wrap .unit-chip {
|
||||
flex-shrink: 0;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
|
||||
/* 价格顶到左列最右侧,8 条价格因此对齐成一列,不再跟着名称长短漂移。
|
||||
与签之间的空隙交给下面的 .row-leader,这里不再自己留 padding */
|
||||
.row-name-wrap .price {
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
/* 菜单点线:把名称/规格与价格之间的空档连起来,这是本页最像"价目单"的一笔。
|
||||
flex-basis 为 0、min-width 为 0,空间紧时它自己缩到没有(VIP 那行就是),
|
||||
所以不会把名称挤到折行;两条 8rpx 外边距是它缩没之后仍保留的最小间隙。
|
||||
align-self:flex-end + margin-bottom 让点线落在文字基线附近,而不是穿过文字中线。
|
||||
最长的一行(VIP 5次 半天陪诊 + 4小时/次 + ¥1350)约 499rpx,左列可用 518rpx,
|
||||
余量约 19rpx 正好被点线吃掉——真机若折行,把 .price-num 从 32rpx 降到 28rpx */
|
||||
.row-leader {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
height: 0;
|
||||
margin: 0 8rpx 10rpx;
|
||||
border-bottom: 2rpx dotted var(--sep);
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.row-desc {
|
||||
display: block;
|
||||
margin-top: 12rpx;
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
color: var(--muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
color: #D4A853;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 服务列表 */
|
||||
.service-list {
|
||||
padding: 32rpx 12rpx;
|
||||
}
|
||||
|
||||
.section-title-wrap {
|
||||
/* ===== 预约:--brand-strong 描边,不填充 =====
|
||||
与首页主 CTA(实心胶囊)同一套按钮语言,但描边形式比实心安静一档,
|
||||
8 个并排也不会像实心块那样把主色铺开。
|
||||
描边与文字都用 --brand-strong(纸面上 4.89:1,过 AA 与非文本 3:1);
|
||||
按下落 --brand-soft(DESIGN.md §2.1 指定)。
|
||||
尺寸按用户要求调成"扁一点、宽一点":高 80 → 72rpx(36px)、
|
||||
最小宽 128 → 144rpx。注意 36px 低于 iOS 44px 的建议触控高度。
|
||||
margin-left 与左列拉开距离,垂直位置由 .ledger-row 的 align-items:center 居中 */
|
||||
.book-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.service-item {
|
||||
background: #FFFFFF;
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx 32rpx 22rpx 32rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.04);
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.service-item:active {
|
||||
transform: translateY(2rpx);
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.service-main {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.service-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.title-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.title-accent {
|
||||
width: 6rpx;
|
||||
height: 32rpx;
|
||||
background: #2D6A4F;
|
||||
border-radius: 3rpx;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
min-width: 144rpx;
|
||||
height: 72rpx;
|
||||
padding: 0 30rpx;
|
||||
margin-left: 24rpx;
|
||||
border: 2rpx solid var(--brand-strong);
|
||||
border-radius: 12rpx;
|
||||
background: transparent;
|
||||
flex-shrink: 0;
|
||||
transition: background-color 0.15s ease;
|
||||
}
|
||||
|
||||
.service-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #1F2937;
|
||||
.book-btn:active {
|
||||
background: var(--brand-soft);
|
||||
}
|
||||
|
||||
.service-tag {
|
||||
background: #D4A853;
|
||||
color: #FFFFFF;
|
||||
font-size: 22rpx;
|
||||
padding: 6rpx 16rpx;
|
||||
border-radius: 8rpx;
|
||||
font-weight: 500;
|
||||
flex-shrink: 0;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
.subtitle-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.service-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.service-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-top: 14rpx;
|
||||
border-top: 1rpx solid #F3F4F6;
|
||||
}
|
||||
|
||||
.price-wrap {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.price-symbol {
|
||||
.book-btn-text {
|
||||
font-size: 28rpx;
|
||||
color: #D4A853;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.service-price {
|
||||
font-size: 32rpx;
|
||||
color: #D4A853;
|
||||
font-weight: 700;
|
||||
margin-left: 4rpx;
|
||||
color: var(--brand-strong);
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.btn-book {
|
||||
/* ===== 组说明砖:浅橙衬底 + 暖色紧阴影(DESIGN.md §2.3 指定写法) =====
|
||||
浅橙底与暖白纸面只差约 1.03:1,光靠底色托不出形状,
|
||||
再补一道暖色紧阴影把这块砖拎起来 */
|
||||
.group-note {
|
||||
margin-top: 32rpx;
|
||||
padding: 28rpx;
|
||||
border-radius: 28rpx;
|
||||
background: var(--brand-soft);
|
||||
border: 2rpx solid var(--brand-line);
|
||||
box-shadow: 0 2rpx 10rpx rgba(194, 65, 12, 0.08);
|
||||
}
|
||||
|
||||
.group-note-text {
|
||||
font-size: 26rpx;
|
||||
color: var(--ink-2);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* ===== 页脚 ===== */
|
||||
.page-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
background: #6B8E7B;
|
||||
color: #FFFFFF;
|
||||
font-size: 26rpx;
|
||||
padding: 16rpx 28rpx;
|
||||
border-radius: 20rpx;
|
||||
font-weight: 500;
|
||||
transition: transform 0.2s;
|
||||
justify-content: center;
|
||||
margin-top: 64rpx;
|
||||
padding-top: 28rpx;
|
||||
border-top: 2rpx solid var(--line);
|
||||
}
|
||||
|
||||
.btn-book:active {
|
||||
transform: scale(0.96);
|
||||
.footer-text {
|
||||
font-size: 24rpx;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
/* 文字只有 24rpx 高,用 padding 撑热区到 56rpx(28px),再用等量负外边距抵消,行高不变 */
|
||||
.footer-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16rpx 0;
|
||||
margin: -16rpx 0;
|
||||
}
|
||||
|
||||
.footer-link:active {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.footer-link-text {
|
||||
font-size: 24rpx;
|
||||
font-weight: 700;
|
||||
color: var(--brand-ink);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.book-btn {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user