This commit is contained in:
lik
2026-10-06 21:19:20 +08:00
parent 40d0df3330
commit 509a10e4f1
12 changed files with 440 additions and 314 deletions
+22 -18
View File
@@ -1,14 +1,18 @@
<view class="container">
<!-- 基本信息:通栏白块(白面 + 上下 2rpx 发丝线 + 中性阴影,圆角 0),
行内标签左走 --muted、值右走 --ink 700,与「个人信息」「邮寄地址」同一表单语言 -->
<view class="form-card">
<view class="form-item">
<text class="form-label">姓名<text class="required">*</text></text>
<input class="form-input" value="{{form.name}}" placeholder="请输入就诊人姓名" placeholder-class="input-placeholder"
<view class="form-row">
<text class="form-label">姓名</text>
<input class="form-input" value="{{form.name}}" placeholder="请输入就诊人姓名" placeholder-class="form-placeholder"
maxlength="20" data-field="name" bindinput="onFieldInput" />
</view>
<view class="form-item">
<view class="form-row">
<text class="form-label">性别</text>
<!-- 选中态用软橙底 + 实心橙描边(项目既有档),未选中是纸面底 + 发丝边,
不引入第二个色相 -->
<view class="sex-wrap">
<view class="sex-tag {{form.sex === item.value ? 'sex-tag-active' : ''}}" wx:for="{{sexOptions}}" wx:key="value"
data-sex="{{item.value}}" bindtap="onSexSelect">
@@ -17,46 +21,46 @@
</view>
</view>
<view class="form-item">
<view class="form-row">
<text class="form-label">出生年月</text>
<picker mode="date" value="{{form.birth}}" start="1900-01-01" end="{{today}}" bindchange="onBirthChange">
<picker class="form-picker" mode="date" value="{{form.birth}}" start="1900-01-01" end="{{today}}" bindchange="onBirthChange">
<view class="picker-value {{form.birth ? '' : 'picker-placeholder'}}">
{{form.birth || '请选择出生年月'}}
</view>
</picker>
</view>
<view class="form-item">
<text class="form-label">联系电话<text class="required">*</text></text>
<input class="form-input" value="{{form.mobile}}" type="number" placeholder="用于陪诊师联系您" placeholder-class="input-placeholder"
<view class="form-row">
<text class="form-label">联系电话</text>
<input class="form-input" value="{{form.mobile}}" type="number" placeholder="用于陪诊师联系您" placeholder-class="form-placeholder"
maxlength="11" data-field="mobile" bindinput="onFieldInput" />
</view>
<view class="form-item">
<view class="form-row form-row-last">
<text class="form-label">证件号</text>
<input class="form-input" value="{{form.idnumber}}" placeholder="选填,用于医院建档取号" placeholder-class="input-placeholder"
<input class="form-input" value="{{form.idnumber}}" placeholder="选填,用于医院建档取号" placeholder-class="form-placeholder"
maxlength="30" data-field="idnumber" bindinput="onFieldInput" />
</view>
</view>
<!-- 健康备注:多行输入无法与标签同排,单独一块——标签在上、文本域在下、字数右下 -->
<view class="form-card">
<view class="form-item form-item-remark">
<view class="form-remark">
<text class="form-label">健康备注</text>
<textarea class="form-textarea" value="{{form.remark}}" placeholder="选填,如过敏史、慢病、行动不便等情况,便于陪诊师提前准备"
placeholder-class="input-placeholder" maxlength="200" data-field="remark" bindinput="onFieldInput" />
placeholder-class="form-placeholder" maxlength="200" data-field="remark" bindinput="onFieldInput" />
<text class="remark-count">{{form.remark.length}}/200</text>
</view>
</view>
<view class="tips">
<t-icon name="lock-on" size="26rpx" color="#B0B7C3" />
<t-icon name="lock-on" class="tips-icon" size="26rpx" />
<text class="tips-text">信息仅用于陪诊服务,我们会严格保密</text>
</view>
<!-- 保存是本页唯一的实心暖橙块,独占「全页同类实心块不超过一处」的额度 -->
<view class="footer-bar">
<view class="submit-btn {{saving ? 'submit-btn-disabled' : ''}}" bindtap="onSave">
<text class="submit-btn-text">保存</text>
</view>
<button class="primary-btn {{saving ? 'primary-btn-disabled' : ''}}" bindtap="onSave">保存</button>
</view>
</view>
</view>
+109 -79
View File
@@ -1,77 +1,94 @@
page {
background-color: #FAF6F1;
/* 配色令牌来自 app.wxss(全站唯一来源),本页不留副本 */
background-color: var(--paper);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
.container {
min-height: 100vh;
padding: 24rpx 24rpx 200rpx;
box-sizing: border-box;
/* 底部留出固定保存栏的高度 + 安全区,避免最后一行被盖住 */
padding: 40rpx 32rpx calc(180rpx + env(safe-area-inset-bottom));
}
/* ===== 通栏白块 =====
白面 + 上下各 2rpx 发丝线 + 中性阴影,圆角 0;
负向 margin 抵消容器 32rpx 内距后左右顶到屏幕两侧,
行内再用 32rpx 内距回到同一左基线,行分隔线因此自动通到底 */
.form-card {
background: #FFFFFF;
border-radius: 20rpx;
padding: 8rpx 28rpx;
margin-bottom: 24rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.04);
margin: 0 -32rpx;
background: var(--white);
border-top: 2rpx solid var(--line);
border-bottom: 2rpx solid var(--line);
box-shadow: var(--shadow-card);
}
.form-item {
/* 两块之间用 24rpx 纸面留白分界(与「我的」页菜单组间距同值) */
.form-card + .form-card {
margin-top: 24rpx;
}
/* 行高约 87rpx(28rpx×1.4 + 上下 24rpx),贴近 iOS 44pt 触控目标 */
.form-row {
display: flex;
align-items: center;
min-height: 108rpx;
border-bottom: 1rpx solid #F3F4F6;
justify-content: space-between;
padding: 24rpx 32rpx;
border-bottom: 2rpx solid var(--line);
}
.form-item:last-child {
.form-row-last {
border-bottom: none;
}
.form-item-remark {
flex-direction: column;
align-items: stretch;
padding: 28rpx 0;
}
/* 标签走 --muted、值走 --ink 700:层级靠明度与字重拉开,
不给可点性上色(DESIGN.md §2.2「三档只表示文字层级」) */
.form-label {
width: 160rpx;
flex-shrink: 0;
margin-right: 24rpx;
font-size: 28rpx;
color: #374151;
}
.required {
color: #EF4444;
margin-left: 4rpx;
color: var(--muted);
letter-spacing: 1rpx;
}
.form-input {
flex: 1;
font-size: 28rpx;
color: #1F2937;
min-width: 0;
text-align: right;
font-size: 28rpx;
font-weight: 700;
color: var(--ink);
}
.input-placeholder {
color: #C4C9D2;
.form-placeholder {
color: var(--muted);
font-weight: 400;
}
/* picker 需占满剩余宽度,值才能靠右对齐 */
.form-picker {
flex: 1;
min-width: 0;
}
.picker-value {
flex: 1;
font-size: 28rpx;
color: #1F2937;
display: block;
text-align: right;
font-size: 28rpx;
font-weight: 700;
color: var(--ink);
}
.picker-placeholder {
color: #C4C9D2;
color: var(--muted);
font-weight: 400;
}
/* 性别选择 */
/* ===== 性别选择 =====
未选中是纸面底 + 发丝边 + --muted 字,
选中翻转成软橙底 + 实心橙描边 + --brand-ink 字 */
.sex-wrap {
flex: 1;
display: flex;
justify-content: flex-end;
gap: 20rpx;
}
@@ -79,87 +96,100 @@ page {
display: flex;
align-items: center;
justify-content: center;
width: 120rpx;
height: 64rpx;
border-radius: 32rpx;
background: #F3F4F6;
transition: all 0.2s;
}
.sex-tag-active {
background: #FDF8EE;
border: 2rpx solid #D4A853;
min-width: 120rpx;
padding: 12rpx 0;
border-radius: 999rpx;
background: var(--paper);
border: 2rpx solid var(--line);
}
.sex-text {
font-size: 28rpx;
color: #6B7280;
color: var(--muted);
}
.sex-tag-active {
background: var(--brand-soft);
border-color: var(--brand-strong);
}
.sex-tag-active .sex-text {
color: #D4A853;
font-weight: 600;
color: var(--brand-ink);
font-weight: 700;
}
/* ===== 健康备注 ===== */
.form-remark {
display: flex;
flex-direction: column;
padding: 24rpx 32rpx;
}
/* 健康备注 */
.form-textarea {
width: 100%;
height: 160rpx;
margin-top: 16rpx;
font-size: 28rpx;
color: #1F2937;
color: var(--ink);
line-height: 1.6;
}
/* 24rpx 是中文最小字号下限 */
.remark-count {
align-self: flex-end;
font-size: 22rpx;
color: #C4C9D2;
font-size: 24rpx;
color: var(--muted);
}
/* 隐私提示 */
/* ===== 隐私提示 ===== */
.tips {
display: flex;
align-items: center;
padding: 0 12rpx;
margin-top: 24rpx;
}
.tips-icon {
flex-shrink: 0;
color: var(--muted);
}
.tips-text {
margin-left: 10rpx;
font-size: 24rpx;
color: #B0B7C3;
color: var(--muted);
}
/* 底部固定保存按钮 */
/* ===== 底部固定保存栏 =====
纸面与白面填充差只有 1.05:1,靠一道小偏移小模糊的上向暖墨阴影托住边界 */
.footer-bar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 20rpx 24rpx calc(20rpx + env(safe-area-inset-bottom));
background: rgba(255, 255, 255, 0.96);
box-shadow: 0 -2rpx 16rpx rgba(0, 0, 0, 0.05);
padding: 20rpx 32rpx calc(20rpx + env(safe-area-inset-bottom));
background: var(--white);
box-shadow: 0 -2rpx 8rpx rgba(63, 43, 25, 0.07);
}
.submit-btn {
display: flex;
align-items: center;
justify-content: center;
height: 88rpx;
border-radius: 44rpx;
background: #D4A853;
}
.submit-btn:active {
opacity: 0.85;
}
.submit-btn-disabled {
opacity: 0.6;
}
.submit-btn-text {
/* 保存是本页唯一的实心暖橙块,独占「全页同类实心块不超过一处」的额度 */
.primary-btn {
margin: 0;
padding: 24rpx 0;
border: none;
border-radius: 999rpx;
background: var(--brand-strong);
box-shadow: var(--shadow-cta);
color: var(--white);
font-size: 30rpx;
font-weight: 600;
color: #FFFFFF;
font-weight: 700;
letter-spacing: 2rpx;
line-height: 1.4;
}
.primary-btn::after {
border: none;
}
.primary-btn-disabled {
opacity: 0.6;
}
+2 -1
View File
@@ -101,7 +101,8 @@ Page({
wx.showModal({
title: '删除确认',
content: '删除后该就诊人信息将无法恢复,确定删除吗?',
confirmColor: '#D4A853',
// confirmColor 是属性值,读不到 CSS 变量,取值须与令牌同步(DESIGN.md §5.1)
confirmColor: '#B8520A',
success: (res) => {
if (!res.confirm) {
return
+3 -2
View File
@@ -1,8 +1,9 @@
{
"navigationBarTitleText": "就诊人",
"usingComponents": {
"t-icon": "tdesign-miniprogram/icon/icon"
"t-icon": "tdesign-miniprogram/icon/icon",
"t-loading": "tdesign-miniprogram/loading/loading"
},
"enablePullDownRefresh": true,
"backgroundTextStyle": "dark"
}
}
+46 -42
View File
@@ -1,50 +1,60 @@
<view class="container">
<!-- 顶部说明 -->
<view class="page-tip" wx:if="{{profiles.length > 0}}">
<t-icon name="info-circle" size="28rpx" color="#D4A853" />
<text class="page-tip-text">下单时可直接选择已保存的就诊人,无需重复填写</text>
<!-- 说明砖:浅橙底 + 2rpx --brand-line 描边托形(不加阴影),走全站「说明砖」档;
文案说明就诊人的用途 -->
<view class="tip-card" wx:if="{{profiles.length > 0}}">
<t-icon name="info-circle" class="tip-icon" size="28rpx" />
<text class="tip-text">下单时可直接选择已保存的就诊人,无需重复填写</text>
</view>
<!-- 就诊人列表 -->
<!-- 就诊人列表:通栏白块(白面 + 上下 2rpx 发丝线 + 中性阴影,圆角 0),
与「邮寄地址」列表同源。每条主体可点进编辑(右侧 chevron 是点击暗示),
不做无暗示的整卡可点;删除动作单独一行、走 --muted -->
<view class="profile-list" wx:if="{{profiles.length > 0}}">
<view class="profile-card" wx:for="{{profiles}}" wx:key="_id" data-id="{{item._id}}" bindtap="onEdit">
<view class="card-header">
<view class="name-wrap">
<text class="profile-name">{{item.name}}</text>
<text class="sex-tag" wx:if="{{item.sexText}}">{{item.sexText}}</text>
</view>
<view class="delete-btn" data-id="{{item._id}}" catchtap="onDelete">
<t-icon name="delete" size="32rpx" color="#9CA3AF" />
<view
class="profile-card {{index === profiles.length - 1 ? 'profile-card-last' : ''}}"
wx:for="{{profiles}}"
wx:key="_id"
>
<view class="profile-main" data-id="{{item._id}}" bindtap="onEdit" hover-class="profile-main-hover">
<view class="profile-info">
<view class="profile-top">
<text class="profile-name">{{item.name}}</text>
<text class="sex-tag" wx:if="{{item.sexText}}">{{item.sexText}}</text>
</view>
<view class="info-row">
<text class="info-label">出生年月</text>
<text class="info-value">{{item.birth || '未填写'}}</text>
</view>
<view class="info-row">
<text class="info-label">联系电话</text>
<text class="info-value">{{item.mobile || '未填写'}}</text>
</view>
<view class="info-row">
<text class="info-label">证件号</text>
<text class="info-value">{{item.idnumberText}}</text>
</view>
<view class="info-row" wx:if="{{item.remark}}">
<text class="info-label">健康备注</text>
<text class="info-value">{{item.remark}}</text>
</view>
</view>
<t-icon name="chevron-right" class="profile-arrow" size="32rpx" />
</view>
<view class="card-body">
<view class="info-row">
<text class="info-label">出生年月</text>
<text class="info-value">{{item.birth || '未填写'}}</text>
</view>
<view class="info-row">
<text class="info-label">联系电话</text>
<text class="info-value">{{item.mobile || '未填写'}}</text>
</view>
<view class="info-row">
<text class="info-label">证件号</text>
<text class="info-value">{{item.idnumberText}}</text>
</view>
<view class="info-row" wx:if="{{item.remark}}">
<text class="info-label">健康备注</text>
<text class="info-value">{{item.remark}}</text>
<view class="profile-actions">
<view class="profile-action" data-id="{{item._id}}" bindtap="onDelete">
<t-icon name="delete" class="profile-action-icon" size="32rpx" />
<text class="profile-action-text">删除</text>
</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" wx:if="{{!loading && profiles.length === 0}}">
<t-icon name="file-safety" size="120rpx" color="#D1D5DB" />
<text class="empty-text">还没有就诊人</text>
<text class="empty-subtext">添加就诊人后,下单时可一键带入信息</text>
<view class="profile-empty" wx:if="{{!loading && profiles.length === 0}}">
<t-icon name="user-checked" class="profile-empty-icon" size="80rpx" />
<text class="profile-empty-text">还没有就诊人,添加后下单即可一键带入</text>
</view>
<!-- 加载中 -->
@@ -52,15 +62,9 @@
<t-loading theme="circular" size="40rpx" text="加载中..." />
</view>
<!-- 底部留白,避免被固定按钮遮挡 -->
<view class="bottom-space"></view>
<!-- 新增按钮 -->
<!-- 底部固定操作栏 -->
<view class="footer-bar">
<view class="add-btn" bindtap="onAdd">
<t-icon name="add" size="34rpx" color="#FFFFFF" />
<text class="add-btn-text">新增就诊人</text>
</view>
<button class="primary-btn" bindtap="onAdd">新增就诊人</button>
</view>
</view>
</view>
+147 -93
View File
@@ -1,166 +1,220 @@
page {
background-color: #FAF6F1;
/* 配色令牌来自 app.wxss(全站唯一来源),本页不留副本 */
background-color: var(--paper);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
.container {
min-height: 100vh;
box-sizing: border-box;
/* 底部留出固定操作栏的高度 + 安全区,避免最后一条被盖住 */
padding: 40rpx 32rpx calc(180rpx + env(safe-area-inset-bottom));
}
/* 顶部说明条 */
.page-tip {
/* ===== 说明砖 =====
浅橙底走「说明砖」档:--brand-soft + 2rpx --brand-line 描边托形、不加阴影。
--paper 与 --brand-soft 明度差仅约 1.03:1,不靠描边托不出形 */
.tip-card {
display: flex;
align-items: center;
margin: 24rpx 24rpx 0;
margin-bottom: 24rpx;
padding: 20rpx 24rpx;
border-radius: 16rpx;
background: #FDF8EE;
border-radius: 20rpx;
background: var(--brand-soft);
border: 2rpx solid var(--brand-line);
}
.page-tip-text {
/* t-icon 未传 color,用 CSS 变量着色即可(读不到变量的只有 color 属性写法) */
.tip-icon {
flex-shrink: 0;
color: var(--brand-ink);
}
.tip-text {
margin-left: 12rpx;
font-size: 24rpx;
color: #A1864B;
color: var(--brand-ink);
line-height: 1.5;
}
/* 就诊人列表 */
/* ===== 通栏白块 =====
白面 + 上下各 2rpx 发丝线 + 中性阴影,圆角 0;
负向 margin 抵消容器 32rpx 内距后左右顶到屏幕两侧,
卡内再用 32rpx 内距回到同一左基线,卡间发丝线因此通到底。
圆角必须为 0,否则满宽块的圆角会切在屏幕边上 */
.profile-list {
padding: 20rpx 24rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
margin: 0 -32rpx;
background: var(--white);
border-top: 2rpx solid var(--line);
border-bottom: 2rpx solid var(--line);
box-shadow: var(--shadow-card);
}
.profile-card {
background: #FFFFFF;
border-radius: 20rpx;
padding: 28rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.04);
padding: 28rpx 32rpx;
border-bottom: 2rpx solid var(--line);
}
.profile-card:active {
background: #FDFCFA;
.profile-card-last {
border-bottom: none;
}
.card-header {
/* 主体整块可点进编辑,右侧 chevron 即点击暗示 */
.profile-main {
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: 20rpx;
margin-bottom: 20rpx;
border-bottom: 1rpx solid #F3F4F6;
}
.name-wrap {
display: flex;
align-items: center;
.profile-main-hover {
opacity: 0.7;
}
.profile-name {
font-size: 32rpx;
font-weight: 600;
color: #1F2937;
}
.sex-tag {
margin-left: 16rpx;
padding: 2rpx 14rpx;
border-radius: 8rpx;
background: #FDF8EE;
color: #D4A853;
font-size: 22rpx;
font-weight: 600;
}
.delete-btn {
padding: 8rpx 0 8rpx 24rpx;
}
.card-body {
.profile-info {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 16rpx;
}
.profile-top {
display: flex;
align-items: center;
margin-bottom: 12rpx;
}
/* 姓名是本页最重的字,走 --ink 700(标题档) */
.profile-name {
font-size: 32rpx;
font-weight: 700;
color: var(--ink);
}
/* 性别签:浅橙衬底档(--brand-soft + 2rpx --brand-line + --brand-ink),
字号 24rpx 是中文最小字号下限,不得再小 */
.sex-tag {
margin-left: 16rpx;
padding: 4rpx 12rpx;
border-radius: 6rpx;
background: var(--brand-soft);
border: 2rpx solid var(--brand-line);
font-size: 24rpx;
color: var(--brand-ink);
}
/* 标签走 --muted、值走 --ink-2:只表示文字层级,不给可点性上色 */
.info-row {
display: flex;
align-items: flex-start;
}
.info-row + .info-row {
margin-top: 8rpx;
}
.info-label {
font-size: 26rpx;
color: #9CA3AF;
width: 140rpx;
flex-shrink: 0;
width: 140rpx;
font-size: 26rpx;
color: var(--muted);
}
.info-value {
font-size: 26rpx;
color: #374151;
flex: 1;
min-width: 0;
font-size: 28rpx;
color: var(--ink-2);
word-break: break-all;
}
/* 空状态 */
.empty-state {
.profile-arrow {
flex-shrink: 0;
margin-left: 16rpx;
color: var(--muted);
}
/* 卡片操作行:与主体隔一条发丝线,删除靠右排(与「邮寄地址」卡同一位置) */
.profile-actions {
display: flex;
align-items: center;
justify-content: flex-end;
margin-top: 24rpx;
padding-top: 20rpx;
border-top: 2rpx solid var(--line);
}
/* 文字只有 26rpx 高,用 padding 撑热区、等量负外边距抵消,不改变行高 */
.profile-action {
display: flex;
align-items: center;
padding: 16rpx 0;
margin: -16rpx 0;
}
.profile-action-icon {
margin-right: 10rpx;
color: var(--muted);
}
.profile-action-text {
font-size: 26rpx;
color: var(--muted);
}
/* ===== 空态 ===== */
.profile-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-top: 200rpx;
padding: 140rpx 32rpx;
}
.empty-text {
font-size: 30rpx;
color: #9CA3AF;
/* --faint 仅用于非文字装饰(空态图标),不承载信息 */
.profile-empty-icon {
color: var(--faint);
}
.profile-empty-text {
margin-top: 24rpx;
font-size: 28rpx;
color: var(--muted);
}
.empty-subtext {
font-size: 26rpx;
color: #D1D5DB;
margin-top: 12rpx;
}
/* 加载中 */
/* ===== 加载中 ===== */
.loading-wrap {
display: flex;
align-items: center;
justify-content: center;
padding: 40rpx;
padding: 60rpx;
}
.bottom-space {
height: 180rpx;
}
/* 底部固定新增按钮 */
/* ===== 底部固定操作栏 =====
纸面与白面填充差只有 1.05:1,靠一道小偏移小模糊的上向暖墨阴影托住边界 */
.footer-bar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 20rpx 24rpx calc(20rpx + env(safe-area-inset-bottom));
background: rgba(255, 255, 255, 0.96);
box-shadow: 0 -2rpx 16rpx rgba(0, 0, 0, 0.05);
padding: 20rpx 32rpx calc(20rpx + env(safe-area-inset-bottom));
background: var(--white);
box-shadow: 0 -2rpx 8rpx rgba(63, 43, 25, 0.07);
}
.add-btn {
display: flex;
align-items: center;
justify-content: center;
height: 88rpx;
border-radius: 44rpx;
background: #D4A853;
}
.add-btn:active {
opacity: 0.85;
}
.add-btn-text {
margin-left: 8rpx;
/* 新增是本页唯一的实心暖橙块,独占「全页同类实心块不超过一处」的额度 */
.primary-btn {
margin: 0;
padding: 24rpx 0;
border: none;
border-radius: 999rpx;
background: var(--brand-strong);
box-shadow: var(--shadow-cta);
color: var(--white);
font-size: 30rpx;
font-weight: 600;
color: #FFFFFF;
font-weight: 700;
letter-spacing: 2rpx;
line-height: 1.4;
}
.primary-btn::after {
border: none;
}