feat(selectMemberDrawer): 用户列表新增本人/员工/家庭用户标签展示

- ExistingMember 补充 dataType/relationType 字段
- API 映射层透传 dataType 与 relationType
- member-type 区域按类型展示对应颜色标签

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
17792275749
2026-06-10 17:16:22 +08:00
co-authored by Claude Opus 4.7
parent 0fab5259c9
commit 44659a6ae4
3 changed files with 274 additions and 244 deletions
@@ -1,248 +1,263 @@
/* 遮罩层 */ /* 遮罩层 */
.drawer-mask { .drawer-mask {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: rgba(37, 37, 53, 0.6); background-color: rgba(37, 37, 53, 0.6);
z-index: 100; z-index: 100;
opacity: 0; opacity: 0;
transition: opacity 0.3s ease; transition: opacity 0.3s ease;
&--visible { &--visible {
opacity: 1; opacity: 1;
} }
} }
/* 抽屉面板 */ /* 抽屉面板 */
.drawer-panel { .drawer-panel {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
/* 最大高度约 75% 屏幕 */ /* 最大高度约 75% 屏幕 */
height: 85vh; height: 85vh;
background-color: #FFFFFF; background-color: #FFFFFF;
border-radius: 24rpx 24rpx 0 0; border-radius: 24rpx 24rpx 0 0;
z-index: 101; z-index: 101;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
transform: translateY(100%); transform: translateY(100%);
transition: transform 0.3s ease; transition: transform 0.3s ease;
&--visible { &--visible {
transform: translateY(0); transform: translateY(0);
} }
} }
/* 拖拽把手 */ /* 拖拽把手 */
.drawer-handle { .drawer-handle {
width: 72rpx; width: 72rpx;
height: 6rpx; height: 6rpx;
background-color: #77849E; background-color: #77849E;
border-radius: 3rpx; border-radius: 3rpx;
margin: 32rpx auto 40rpx; margin: 32rpx auto 40rpx;
} }
/* 标题栏 */ /* 标题栏 */
.drawer-header { .drawer-header {
width: 100%; width: 100%;
height: 32rpx;
padding: 0 30rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
.drawer-title {
color: #252535;
height: 32rpx;
font-size: 32rpx;
font-weight: 700;
line-height: 32rpx;
}
/* 关闭按钮 */
.drawer-close {
width: 32rpx;
height: 32rpx; height: 32rpx;
padding: 0 30rpx;
box-sizing: border-box;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: space-between;
.drawer-close-icon { .drawer-title {
width: 28rpx; color: #252535;
height: 28rpx; height: 32rpx;
position: relative; font-size: 32rpx;
font-weight: 700;
line-height: 32rpx;
}
&::before, /* 关闭按钮 */
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 3rpx;
background-color: #252535;
border-radius: 2rpx;
}
&::before { .drawer-close {
transform: translate(-50%, -50%) rotate(45deg); width: 32rpx;
} height: 32rpx;
display: flex;
align-items: center;
justify-content: center;
&::after { .drawer-close-icon {
transform: translate(-50%, -50%) rotate(-45deg); width: 28rpx;
} height: 28rpx;
position: relative;
&::before,
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 3rpx;
background-color: #252535;
border-radius: 2rpx;
}
&::before {
transform: translate(-50%, -50%) rotate(45deg);
}
&::after {
transform: translate(-50%, -50%) rotate(-45deg);
}
}
} }
}
} }
/* 顶部分隔线 */ /* 顶部分隔线 */
.drawer-divider { .drawer-divider {
width: 690rpx; width: 690rpx;
height: 2rpx; height: 2rpx;
background-color: #EAEDF1; background-color: #EAEDF1;
margin: 39rpx 30rpx 0; margin: 39rpx 30rpx 0;
flex-shrink: 0; flex-shrink: 0;
} }
/* 用户滚动列表 */ /* 用户滚动列表 */
.drawer-list { .drawer-list {
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
padding-bottom: env(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);
} }
/* 用户行 */ /* 用户行 */
.member-item { .member-item {
width: 100%; width: 100%;
height: 90rpx;
padding: 0 30rpx;
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
margin-top: 24rpx;
/* 有图片头像 */
.member-avatar {
width: 90rpx;
height: 90rpx; height: 90rpx;
border-radius: 24rpx; padding: 0 30rpx;
flex-shrink: 0; box-sizing: border-box;
&--selected {
border: 3rpx solid #50A6FF;
}
}
/* 纯色占位头像 */
.member-avatar-placeholder {
width: 90rpx;
height: 90rpx;
border-radius: 24rpx;
flex-shrink: 0;
/* 男:蓝色 */
&--male {
background-color: #C6E6FF;
}
/* 女:粉色 */
&--female {
background-color: #FFD5E3;
}
/* 选中男 */
&--selected-male {
border: 3rpx solid #50A6FF;
width: 96rpx;
height: 96rpx;
margin: -3rpx 0 0 -3rpx;
}
/* 选中女 */
&--selected-female {
border: 3rpx solid #FF8FB5;
width: 96rpx;
height: 96rpx;
margin: -3rpx 0 0 -3rpx;
}
}
/* 姓名 + 副标题 */
.member-info {
flex: 1;
height: 78rpx;
display: flex; display: flex;
flex-direction: column; flex-direction: row;
justify-content: space-between; align-items: center;
margin-left: 23rpx; margin-top: 24rpx;
.member-name { /* 有图片头像 */
color: #333333;
font-size: 32rpx; .member-avatar {
font-weight: 500; width: 90rpx;
line-height: 32rpx; height: 90rpx;
white-space: nowrap; border-radius: 24rpx;
flex-shrink: 0;
&--selected {
border: 3rpx solid #50A6FF;
}
} }
.member-sub { /* 纯色占位头像 */
color: #77849E;
font-size: 26rpx; .member-avatar-placeholder {
line-height: 34rpx; width: 90rpx;
white-space: nowrap; height: 90rpx;
border-radius: 24rpx;
flex-shrink: 0;
/* 男:蓝色 */
&--male {
background-color: #C6E6FF;
}
/* 女:粉色 */
&--female {
background-color: #FFD5E3;
}
/* 选中男 */
&--selected-male {
border: 3rpx solid #50A6FF;
width: 96rpx;
height: 96rpx;
margin: -3rpx 0 0 -3rpx;
}
/* 选中女 */
&--selected-female {
border: 3rpx solid #FF8FB5;
width: 96rpx;
height: 96rpx;
margin: -3rpx 0 0 -3rpx;
}
} }
}
/* 竖向分隔线 */ /* 姓名 + 副标题 */
.member-divider {
width: 2rpx;
height: 24rpx;
background-color: #EAEDF1;
border-radius: 1rpx;
margin-left: 17rpx;
flex-shrink: 0;
}
/* 身高 */ .member-info {
.member-height { flex: 1;
color: #77849E; height: 78rpx;
font-size: 26rpx; display: flex;
line-height: 34rpx; flex-direction: column;
white-space: nowrap; justify-content: space-between;
margin-left: 19rpx; margin-left: 23rpx;
width: 76rpx;
flex-shrink: 0; .member-name {
} color: #333333;
font-size: 32rpx;
font-weight: 500;
line-height: 32rpx;
white-space: nowrap;
}
.member-sub {
color: #77849E;
font-size: 26rpx;
line-height: 34rpx;
white-space: nowrap;
}
}
.member-type {
height: 40rpx;
flex-shrink: 0;
.member-type-tag {
height: 40rpx;
padding: 0 14rpx;
font-size: 22rpx;
line-height: 40rpx;
border-radius: 6rpx;
}
.member-type-tag--self {
color: #1385FA;
background-color: rgba(19, 133, 250, 0.12);
}
.member-type-tag--employee {
color: #10B981;
background-color: rgba(16, 185, 129, 0.12);
}
.member-type-tag--family {
color: #F59E0B;
background-color: rgba(245, 158, 11, 0.12);
}
}
} }
/* 行间水平分隔线 */ /* 行间水平分隔线 */
.member-separator { .member-separator {
width: 690rpx; width: 690rpx;
height: 2rpx; height: 2rpx;
background-color: #EAEDF1; background-color: #EAEDF1;
margin: 24rpx 30rpx 0; margin: 24rpx 30rpx 0;
} }
/* 空态占位 */ /* 空态占位 */
.drawer-empty { .drawer-empty {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding-top: 80rpx; padding-top: 80rpx;
.drawer-empty-icon { .drawer-empty-icon {
width: 193rpx; width: 193rpx;
height: 138rpx; height: 138rpx;
margin-bottom: 30rpx; margin-bottom: 30rpx;
} }
.drawer-empty-text { .drawer-empty-text {
color: #808080; color: #808080;
font-size: 28rpx; font-size: 28rpx;
line-height: 28rpx; line-height: 28rpx;
} }
} }
@@ -11,6 +11,8 @@ interface AddMemberApiItem {
weight: number weight: number
idCard: string | null idCard: string | null
avatar: string | null avatar: string | null
dataType?: number
relationType?: number | string | null
} }
/** GET /weighingScale/v3/select/history/user 返回的单条结构 */ /** GET /weighingScale/v3/select/history/user 返回的单条结构 */
@@ -23,6 +25,7 @@ interface HistoryApiItem {
birthday: string birthday: string
avatar: string | null avatar: string | null
relationType: number | string | null relationType: number | string | null
dataType?: number
} }
/** 抽屉内部用户项(含回填所需全量字段) */ /** 抽屉内部用户项(含回填所需全量字段) */
@@ -41,6 +44,8 @@ interface ExistingMember {
sex?: number sex?: number
birthday?: string birthday?: string
relationType?: number | string | null relationType?: number | string | null
/** 0=员工 1=家庭成员 */
dataType?: number
} }
/** /**
@@ -136,6 +141,7 @@ Component({
sex: item.sex, sex: item.sex,
birthday: item.birthday, birthday: item.birthday,
relationType: item.relationType, relationType: item.relationType,
dataType: item.dataType,
})) }))
this.setData({ members }) this.setData({ members })
}) })
@@ -155,6 +161,8 @@ Component({
weight: item.weight, weight: item.weight,
idCard: item.idCard ?? '', idCard: item.idCard ?? '',
avatar: item.avatar ?? '', avatar: item.avatar ?? '',
relationType: item.relationType,
dataType: item.dataType,
})) }))
this.setData({ members }) this.setData({ members })
}) })
@@ -1,63 +1,70 @@
<!-- 选择已有用户抽屉 --> <!-- 选择已有用户抽屉 -->
<block wx:if="{{ innerShow }}"> <block wx:if="{{ innerShow }}">
<!-- 遮罩 --> <!-- 遮罩 -->
<view class="drawer-mask {{ animVisible ? 'drawer-mask--visible' : '' }}" bind:tap="onTapMask"></view> <view class="drawer-mask {{ animVisible ? 'drawer-mask--visible' : '' }}" bind:tap="onTapMask"></view>
<!-- 抽屉面板 --> <!-- 抽屉面板 -->
<view class="drawer-panel {{ animVisible ? 'drawer-panel--visible' : '' }}"> <view class="drawer-panel {{ animVisible ? 'drawer-panel--visible' : '' }}">
<!-- 顶部拖拽把手 --> <!-- 顶部拖拽把手 -->
<view class="drawer-handle"></view> <view class="drawer-handle"></view>
<!-- 标题栏 --> <!-- 标题栏 -->
<view class="drawer-header"> <view class="drawer-header">
<text class="drawer-title">选择已有用户</text> <text class="drawer-title">选择已有用户</text>
<view class="drawer-close" bind:tap="onTapClose"> <view class="drawer-close" bind:tap="onTapClose">
<view class="drawer-close-icon"></view> <view class="drawer-close-icon"></view>
</view>
</view>
<!-- 分隔线 -->
<view class="drawer-divider"></view>
<!-- 用户列表 -->
<block wx:if="{{ members.length }}">
<scroll-view class="drawer-list" scroll-y>
<block wx:for="{{ members }}" wx:key="id">
<view class="member-item" bind:tap="onTapMember" data-member="{{ item }}">
<!-- 头像 -->
<block wx:if="{{ item.avatar }}">
<image class="member-avatar {{ item.selected ? 'member-avatar--selected' : '' }}" src="{{ item.avatar }}" mode="aspectFill"></image>
</block>
<block wx:else>
<view class="member-avatar-placeholder {{ item.gender === '女' ? 'member-avatar-placeholder--female' : 'member-avatar-placeholder--male' }} {{ item.selected ? 'member-avatar-placeholder--selected-male' : '' }} {{ item.selected && item.gender === '女' ? 'member-avatar-placeholder--selected-female' : '' }}"></view>
</block>
<!-- 姓名 + 性别·年龄 -->
<view class="member-info">
<text class="member-name">{{ item.name }}</text>
<text class="member-sub">{{ item.gender }}·{{ item.age }}岁</text>
</view> </view>
</view>
<!-- 竖向分隔线 --> <!-- 分隔线 -->
<view class="member-divider"></view> <view class="drawer-divider"></view>
<!-- 身高 --> <!-- 用户列表 -->
<text class="member-height">{{ item.height }}cm</text> <block wx:if="{{ members.length }}">
</view> <scroll-view class="drawer-list" scroll-y>
<block wx:for="{{ members }}" wx:key="id">
<view class="member-item" bind:tap="onTapMember" data-member="{{ item }}">
<!-- 头像 -->
<block wx:if="{{ item.avatar }}">
<image class="member-avatar {{ item.selected ? 'member-avatar--selected' : '' }}"
src="{{ item.avatar }}" mode="aspectFill"></image>
</block>
<block wx:else>
<view class="member-avatar-placeholder {{ item.gender === '女' ? 'member-avatar-placeholder--female' : 'member-avatar-placeholder--male' }} {{ item.selected ? 'member-avatar-placeholder--selected-male' : '' }} {{ item.selected && item.gender === '女' ? 'member-avatar-placeholder--selected-female' : '' }}"></view>
</block>
<!-- 水平分隔线 --> <!-- 姓名 + 性别·年龄 -->
<view class="member-separator"></view> <view class="member-info">
<text class="member-name">{{ item.name }}</text>
<text class="member-sub">{{ item.gender }}·{{ item.age }}岁 丨 {{ item.height }}cm</text>
</view>
<view class="member-type">
<block wx:if="{{ item.relationType == 1 }}">
<view class="member-type-tag member-type-tag--self">本人</view>
</block>
<block wx:elif="{{ item.dataType === 0 }}">
<view class="member-type-tag member-type-tag--employee">员工</view>
</block>
<block wx:elif="{{ item.dataType === 1 }}">
<view class="member-type-tag member-type-tag--family">家庭用户</view>
</block>
</view>
</view>
<!-- 水平分隔线 -->
<view class="member-separator"></view>
</block>
</scroll-view>
</block> </block>
</scroll-view>
</block>
<!-- 无用户:占位 --> <!-- 无用户:占位 -->
<block wx:else> <block wx:else>
<view class="drawer-empty"> <view class="drawer-empty">
<image class="drawer-empty-icon" src="/images/selectMemberDrawer/noData.png" mode="aspectFit"/> <image class="drawer-empty-icon" src="/images/selectMemberDrawer/noData.png" mode="aspectFit"/>
<text class="drawer-empty-text">暂无可选用户</text> <text class="drawer-empty-text">暂无可选用户</text>
</view> </view>
</block> </block>
</view> </view>
</block> </block>