diff --git a/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.json b/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.json
new file mode 100644
index 0000000..ac28323
--- /dev/null
+++ b/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
diff --git a/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.less b/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.less
new file mode 100644
index 0000000..53f8f43
--- /dev/null
+++ b/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.less
@@ -0,0 +1,139 @@
+.confirm-modal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 1000;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.modal-mask {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0.5);
+ opacity: 0;
+ transition: opacity 0.3s ease;
+
+ &.anim-visible {
+ opacity: 1;
+ }
+}
+
+.modal-content {
+ position: relative;
+ width: 660rpx;
+ background-color: #ffffff;
+ border-radius: 24rpx;
+ overflow: hidden;
+ transform: scale(0.9);
+ opacity: 0;
+ transition: all 0.3s ease;
+
+ &.anim-visible {
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+
+.modal-header {
+ padding-top: 50rpx;
+ width: 100%;
+ margin-bottom: 30rpx;
+
+ .modal-title {
+ width: 100%;
+ height: 36rpx;
+ font-weight: bolder;
+ font-size: 36rpx;
+ color: #252535;
+ line-height: 36rpx;
+ text-align: center;
+ margin-bottom: 24rpx;
+ }
+
+ .modal-sub-title {
+ width: 100%;
+ height: 32rpx;
+ font-weight: 400;
+ font-size: 32rpx;
+ color: #1385FA;
+ line-height: 32rpx;
+ text-align: center;
+ }
+}
+
+.modal-body {
+ width: 100%;
+ box-sizing: border-box;
+ padding: 0 30rpx;
+ margin-bottom: 30rpx;
+
+ .modal-body-box {
+ width: 100%;
+ padding: 0 30rpx;
+ box-sizing: border-box;
+ border-radius: 16rpx;
+ background-color: #F6F6F6;
+
+ .info-row {
+ width: 100%;
+ height: 80rpx;
+ display: flex;
+ padding: 10rpx 0;
+ align-items: center;
+ justify-content: space-between;
+ box-sizing: border-box;
+ border-bottom: 1px solid #EAECF1;
+
+ .info-label {
+ color: #77849E;
+ height: 80rpx;
+ font-size: 28rpx;
+ line-height: 80rpx;
+ }
+
+ .info-value {
+ color: #252535;
+ height: 80rpx;
+ font-weight: 500;
+ font-size: 28rpx;
+ line-height: 80rpx;
+ }
+
+ &:last-of-type {
+ border-bottom: none;
+ }
+ }
+ }
+}
+
+.modal-footer {
+ width: 100%;
+ height: 110rpx;
+ display: flex;
+ border-top: 1rpx solid #EAECF1;
+
+ .modal-btn {
+ flex: 1;
+ height: 110rpx;
+ line-height: 110rpx;
+ font-size: 36rpx;
+ text-align: center;
+ }
+
+ .modal-btn-cancel {
+ color: #77849E;
+ border-right: 1rpx solid #EAECF1;
+ }
+
+ .modal-btn-confirm {
+ color: #1385FA;
+ font-weight: 500;
+ }
+}
diff --git a/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.ts b/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.ts
new file mode 100644
index 0000000..850a43e
--- /dev/null
+++ b/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.ts
@@ -0,0 +1,63 @@
+/**
+ * 用户信息确认弹框组件
+ * Properties: show(控制显示), userInfo(用户信息)
+ * Events: confirm(确认), cancel(取消)
+ */
+Component({
+ properties: {
+ /** 是否显示弹框 */
+ show: {
+ type: Boolean,
+ value: false
+ },
+ /** 用户信息数据 */
+ userInfo: {
+ type: Object,
+ value: {}
+ }
+ },
+
+ data: {
+ /** 控制 wx:if,DOM 是否存在 */
+ innerShow: false,
+ /** 控制 --visible 类,触发 CSS transition */
+ animVisible: false
+ },
+
+ observers: {
+ /**
+ * 监听外部 show 变化:
+ * 打开时先展示弹框再执行动画;关闭时移除动画类后移除 DOM
+ */
+ show(val: boolean) {
+ if (val) {
+ this.setData({ innerShow: true })
+ setTimeout(() => {
+ this.setData({ animVisible: true })
+ }, 20)
+ } else {
+ this.setData({ animVisible: false })
+ setTimeout(() => {
+ this.setData({ innerShow: false })
+ }, 300)
+ }
+ }
+ },
+
+ methods: {
+ /** 点击遮罩关闭 */
+ onTapMask() {
+ this.triggerEvent('cancel')
+ },
+
+ /** 点击取消按钮 */
+ onTapCancel() {
+ this.triggerEvent('cancel')
+ },
+
+ /** 点击确认按钮 */
+ onTapConfirm() {
+ this.triggerEvent('confirm')
+ }
+ }
+})
diff --git a/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.wxml b/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.wxml
new file mode 100644
index 0000000..b24c0fa
--- /dev/null
+++ b/miniprogram/components/userInfoConfirmModal/userInfoConfirmModal.wxml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 姓名:
+ {{ userInfo.realname }}
+
+
+ 身份证号:
+ {{ userInfo.idCard }}
+
+
+ 性别:
+ {{ userInfo.sex_dictText }}
+
+
+ 身高:
+ {{ userInfo.height }}cm
+
+
+ 体重:
+ {{ userInfo.weight }}kg
+
+
+
+
+
+
+
+
diff --git a/miniprogram/pages/addMember/addMember.json b/miniprogram/pages/addMember/addMember.json
index a5b5e26..b1ea48e 100644
--- a/miniprogram/pages/addMember/addMember.json
+++ b/miniprogram/pages/addMember/addMember.json
@@ -1,6 +1,7 @@
{
"navigationBarTitleText": "添加成员",
"usingComponents": {
- "select-member-drawer": "/components/selectMemberDrawer/selectMemberDrawer"
+ "select-member-drawer": "/components/selectMemberDrawer/selectMemberDrawer",
+ "user-info-confirm-modal": "/components/userInfoConfirmModal/userInfoConfirmModal"
}
}
diff --git a/miniprogram/pages/addMember/addMember.ts b/miniprogram/pages/addMember/addMember.ts
index ffc8b35..f49c133 100644
--- a/miniprogram/pages/addMember/addMember.ts
+++ b/miniprogram/pages/addMember/addMember.ts
@@ -106,6 +106,10 @@ Page({
hasQueried: false,
/** 接口返回的用户信息,姓名 + 身份证联动校正性别年龄 */
serverResult: null as UserInfoFromServer | null,
+ /** 表单只读状态(code=101 时置为 true) */
+ readonly: false,
+ /** 是否显示确认弹框 */
+ showConfirmModal: false,
},
onLoad(options: Record) {
@@ -133,29 +137,30 @@ Page({
onNameInput(e: WechatMiniprogram.Input) {
const name = e.detail.value
- this.setData({ 'form.name': name })
- if (!name.trim()) {
- this.setData({ serverResult: null, hasQueried: false })
- return
- }
- if (this.isIdCardValid(this.data.form.idCard)) {
+ this.setData({
+ 'form.name': name,
+ 'form.gender': '',
+ 'form.age': '',
+ serverResult: null,
+ hasQueried: false,
+ readonly: false
+ })
+ if (name.trim() && this.isIdCardValid(this.data.form.idCard)) {
this.fetchUserInfoByIdCard(name.trim(), this.data.form.idCard)
}
},
onIdCardInput(e: WechatMiniprogram.Input) {
const idCard = (e.detail.value || '').trim().toUpperCase()
- const parsed = this.parseIdCard(idCard)
this.setData({
'form.idCard': idCard,
- 'form.gender': parsed.gender,
- 'form.age': parsed.age
+ 'form.gender': '',
+ 'form.age': '',
+ serverResult: null,
+ hasQueried: false,
+ readonly: false
})
- if (!parsed.gender) {
- this.setData({ serverResult: null, hasQueried: false })
- return
- }
- if (this.data.form.name.trim()) {
+ if (this.data.form.name.trim() && this.isIdCardValid(idCard)) {
this.fetchUserInfoByIdCard(this.data.form.name.trim(), idCard)
}
},
@@ -204,12 +209,14 @@ Page({
/**
* 调用服务端接口校验身份证与姓名,成功后用接口返回的身份证重新计算性别年龄
* result 为 null 视为「查无此人」,标记 hasQueried 允许新增提交
+ * result.code 101 视为「信息已存在」,弹框提示并锁定表单
+ * result.code 102 视为正常,走原有逻辑
*/
fetchUserInfoByIdCard(name: string, idCard: string) {
if (this.data.querying) return
this.setData({ querying: true, serverResult: null, hasQueried: false })
- get('weighingScale/v3/getUserInfoByIdcard', {
+ get('weighingScale/v3/getUserInfoByIdcard', {
sn: lefuService.deviceInfo?.serialNumber ?? '',
idCard,
realname: name
@@ -220,13 +227,38 @@ Page({
this.setData({ hasQueried: true })
return
}
- const parsed = this.parseIdCard(serverResult.idCard)
- this.setData({
- serverResult,
- hasQueried: true,
- 'form.gender': parsed.gender,
- 'form.age': parsed.age
- })
+ if (serverResult.code === 101) {
+ const parsed = this.parseIdCard(serverResult.idCard)
+ this.setData({
+ serverResult,
+ hasQueried: true,
+ readonly: true,
+ showConfirmModal: true,
+ 'form.name': serverResult.realname ?? '',
+ 'form.idCard': serverResult.idCard ?? '',
+ 'form.gender': parsed.gender,
+ 'form.age': parsed.age,
+ 'form.height': serverResult.height ? String(serverResult.height) : '',
+ 'form.weight': serverResult.weight ? String(serverResult.weight) : ''
+ })
+ return
+ }
+ if (serverResult.code === 102) {
+ const parsed = this.parseIdCard(serverResult.idCard)
+ const data: Record = {
+ serverResult,
+ hasQueried: true,
+ 'form.gender': parsed.gender,
+ 'form.age': parsed.age
+ }
+ if (serverResult.height) {
+ data['form.height'] = String(serverResult.height)
+ }
+ if (serverResult.weight) {
+ data['form.weight'] = String(serverResult.weight)
+ }
+ this.setData(data)
+ }
})
.catch(() => {
// 查询失败保留本地解析结果,hasQueried 维持 false 以便用户重试时再次触发
@@ -259,6 +291,28 @@ Page({
})
},
+ /** 确认弹框 - 确认 */
+ onConfirmModalConfirm() {
+ this.setData({ showConfirmModal: false })
+ this.onSubmit()
+ },
+
+ /** 确认弹框 - 取消 */
+ onConfirmModalCancel() {
+ this.setData({
+ showConfirmModal: false,
+ readonly: false,
+ form: {
+ name: '',
+ idCard: '',
+ gender: '',
+ age: '',
+ height: '',
+ weight: ''
+ }
+ })
+ },
+
onCancel() {
wx.navigateBack()
},
diff --git a/miniprogram/pages/addMember/addMember.wxml b/miniprogram/pages/addMember/addMember.wxml
index 8ad52af..946e787 100644
--- a/miniprogram/pages/addMember/addMember.wxml
+++ b/miniprogram/pages/addMember/addMember.wxml
@@ -23,6 +23,7 @@
placeholder="请填写真实姓名"
placeholder-class="form-placeholder"
value="{{ form.name }}"
+ disabled="{{ readonly }}"
bind:input="onNameInput" />
@@ -40,6 +41,7 @@
placeholder="请填写身份证号"
placeholder-class="form-placeholder"
value="{{ form.idCard }}"
+ disabled="{{ readonly }}"
bind:input="onIdCardInput" />
@@ -93,6 +95,7 @@
placeholder="请填写身高"
placeholder-class="form-placeholder"
value="{{ form.height }}"
+ disabled="{{ readonly }}"
bind:input="onHeightInput" />
cm
@@ -113,6 +116,7 @@
placeholder="请填写体重"
placeholder-class="form-placeholder"
value="{{ form.weight }}"
+ disabled="{{ readonly }}"
bind:input="onWeightInput" />
kg
@@ -138,4 +142,12 @@
bind:close="onSelectMemberClose"
bind:select="onSelectMember">
+
+
+
+