feat(addUser): 添加用户模块接入员工查询与身份证复用
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
a80a5cd939
commit
4b61c882a1
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"usingComponents": {
|
||||
"user-info-confirm-modal": "/components/userInfoConfirmModal/userInfoConfirmModal"
|
||||
},
|
||||
"navigationBarTitleText": "添加用户",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#FFFFFF"
|
||||
|
||||
@@ -1,16 +1,55 @@
|
||||
// pages/addUser/addUser.ts
|
||||
import { get, put } from '../../utils/request/index'
|
||||
import { getUserInfoByIdCard, type UserInfo } from '../../api/index'
|
||||
import { parseIdCard, isIdCardValid } from '../../utils/idCard/index'
|
||||
|
||||
/** 表单数据模型 */
|
||||
interface MemberForm {
|
||||
workNo: string
|
||||
name: string
|
||||
idCard: string
|
||||
gender: string
|
||||
age: string
|
||||
height: string
|
||||
weight: string
|
||||
sex: number
|
||||
}
|
||||
|
||||
/** 员工编号查询接口(页面私有) */
|
||||
const getEmployeeByWorkNo = (sn: string, workNo: string) =>
|
||||
get<any>('weighingScale/v5/getUserInfoByWkno', { sn, workNo })
|
||||
|
||||
/** 添加/编辑用户接口(页面私有) */
|
||||
const addUser = (data: Record<string, any>) =>
|
||||
put('weighingScale/v5/edit/user', data)
|
||||
|
||||
/** 目标设备 SN(由 userManagement 跳转传入) */
|
||||
let targetSn = ''
|
||||
|
||||
Page({
|
||||
data: {
|
||||
userType: 'employee',
|
||||
employeeId: '9527',
|
||||
employeeInfo: {
|
||||
name: '王旭',
|
||||
company: '技术部·研发组',
|
||||
gender: '男',
|
||||
age: '32岁'
|
||||
},
|
||||
height: '',
|
||||
weight: ''
|
||||
userType: 'employee' as 'employee' | 'family',
|
||||
form: {
|
||||
workNo: '',
|
||||
name: '',
|
||||
idCard: '',
|
||||
gender: '',
|
||||
age: '',
|
||||
height: '',
|
||||
weight: '',
|
||||
sex: 0,
|
||||
} as MemberForm,
|
||||
birthday: '',
|
||||
readonly: false,
|
||||
showConfirmModal: false,
|
||||
serverResult: null as UserInfo | null,
|
||||
employeeQueried: false,
|
||||
employeeNotFound: false,
|
||||
unitDisplay: '',
|
||||
employeeQueryResult: null as Record<string, any> | null,
|
||||
},
|
||||
|
||||
onLoad(options: Record<string, string>) {
|
||||
targetSn = decodeURIComponent(options.sn || '')
|
||||
},
|
||||
|
||||
/** tabs 切换:清空查询结果、重置表单 */
|
||||
@@ -18,21 +57,268 @@ Page({
|
||||
const tab = e.currentTarget.dataset.value as string
|
||||
this.setData({
|
||||
userType: tab as 'employee' | 'family',
|
||||
employeeQueried: false,
|
||||
employeeNotFound: false,
|
||||
unitDisplay: '',
|
||||
employeeQueryResult: null,
|
||||
readonly: false,
|
||||
serverResult: null,
|
||||
form: { workNo: '', name: '', idCard: '', gender: '', age: '', height: '', weight: '', sex: 0 },
|
||||
birthday: '',
|
||||
})
|
||||
},
|
||||
|
||||
onTapType(e: WechatMiniprogram.TouchEvent) {
|
||||
const type = e.currentTarget.dataset.type as string
|
||||
this.setData({ userType: type })
|
||||
/** 员工编号变更:清空查询状态与表单 */
|
||||
onWorkNoInput(e: WechatMiniprogram.Input) {
|
||||
this.setData({
|
||||
'form.workNo': e.detail.value,
|
||||
employeeQueried: false,
|
||||
employeeNotFound: false,
|
||||
unitDisplay: '',
|
||||
employeeQueryResult: null,
|
||||
'form.name': '',
|
||||
'form.gender': '',
|
||||
'form.age': '',
|
||||
'form.height': '',
|
||||
'form.weight': '',
|
||||
})
|
||||
},
|
||||
|
||||
/** 员工编号查询 */
|
||||
onQueryEmployee() {
|
||||
const workNo = this.data.form.workNo.trim()
|
||||
if (!workNo) {
|
||||
wx.showToast({ title: '请填写员工编号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
this.setData({ employeeQueried: false, employeeNotFound: false })
|
||||
getEmployeeByWorkNo(targetSn, workNo)
|
||||
.then((res) => {
|
||||
const result = res.result
|
||||
if (!result) {
|
||||
this.setData({
|
||||
employeeQueried: true,
|
||||
employeeNotFound: true,
|
||||
unitDisplay: '',
|
||||
employeeQueryResult: null,
|
||||
'form.name': '',
|
||||
'form.gender': '',
|
||||
'form.age': '',
|
||||
'form.height': '',
|
||||
'form.weight': '',
|
||||
})
|
||||
return
|
||||
}
|
||||
const idCard = result.idCard || ''
|
||||
const parsed = parseIdCard(idCard)
|
||||
const sex = result.sex || parsed.sex
|
||||
this.setData({
|
||||
employeeQueried: true,
|
||||
employeeNotFound: false,
|
||||
employeeQueryResult: result,
|
||||
unitDisplay: [result.secondDepart, result.thirdDepart].filter(Boolean).join(' / '),
|
||||
'form.name': result.realname || '',
|
||||
'form.idCard': idCard,
|
||||
'form.gender': sex === 1 ? '男' : (sex === 2 ? '女' : parsed.gender),
|
||||
'form.age': parsed.age,
|
||||
'form.sex': sex,
|
||||
'form.height': result.height ? String(result.height) : '',
|
||||
'form.weight': result.weight ? String(result.weight) : '',
|
||||
birthday: result.birthday || '',
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
this.setData({ employeeQueried: true, employeeNotFound: true, unitDisplay: '', employeeQueryResult: null })
|
||||
})
|
||||
},
|
||||
|
||||
/** 家庭用户:姓名变更清空查询结果 */
|
||||
onNameInput(e: WechatMiniprogram.Input) {
|
||||
this.setData({
|
||||
'form.name': e.detail.value.trim(),
|
||||
serverResult: null,
|
||||
'form.gender': '',
|
||||
'form.age': '',
|
||||
'form.sex': 0,
|
||||
'form.height': '',
|
||||
'form.weight': '',
|
||||
birthday: '',
|
||||
readonly: false,
|
||||
})
|
||||
},
|
||||
|
||||
/** 失焦重新校验 */
|
||||
onNameBlur() {
|
||||
if (!this.data.form.name) return
|
||||
this.validateIdCard()
|
||||
},
|
||||
|
||||
/** 家庭用户:身份证变更清空查询结果 */
|
||||
onIdCardInput(e: WechatMiniprogram.Input) {
|
||||
const idCard = (e.detail.value || '').trim().toUpperCase()
|
||||
this.setData({
|
||||
'form.idCard': idCard,
|
||||
serverResult: null,
|
||||
'form.gender': '',
|
||||
'form.age': '',
|
||||
'form.sex': 0,
|
||||
'form.height': '',
|
||||
'form.weight': '',
|
||||
birthday: '',
|
||||
readonly: false,
|
||||
})
|
||||
if (idCard.length === 18) this.validateIdCard()
|
||||
},
|
||||
|
||||
/** 身份证合法且姓名已填则查询 */
|
||||
validateIdCard() {
|
||||
const { idCard, name } = this.data.form
|
||||
if (isIdCardValid(idCard) && name) this.fetchUser()
|
||||
},
|
||||
|
||||
/** 查询身份证对应的用户信息,101 复用 */
|
||||
fetchUser() {
|
||||
getUserInfoByIdCard({
|
||||
sn: targetSn,
|
||||
idCard: this.data.form.idCard,
|
||||
realname: this.data.form.name,
|
||||
}).then((res) => {
|
||||
const serverResult = res.result
|
||||
const { gender, age, sex, birthday } = parseIdCard(serverResult?.idCard || this.data.form.idCard)
|
||||
this.setData({ 'form.gender': gender, 'form.age': age, 'form.sex': sex, birthday })
|
||||
if (!serverResult) {
|
||||
wx.showToast({ title: res.msg || '未查询到用户信息', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (serverResult.flag === 101) {
|
||||
this.setData({
|
||||
serverResult,
|
||||
'form.name': serverResult.realname ?? '',
|
||||
'form.idCard': serverResult.idCard ?? '',
|
||||
'form.height': serverResult.height ? String(serverResult.height) : '',
|
||||
'form.weight': serverResult.weight ? String(serverResult.weight) : '',
|
||||
readonly: true,
|
||||
showConfirmModal: true,
|
||||
})
|
||||
return
|
||||
}
|
||||
if (serverResult.flag === null) {
|
||||
this.setData({
|
||||
serverResult,
|
||||
'form.height': serverResult.height ? String(serverResult.height) : '',
|
||||
'form.weight': serverResult.weight ? String(serverResult.weight) : '',
|
||||
})
|
||||
return
|
||||
}
|
||||
}).catch(() => {})
|
||||
},
|
||||
|
||||
/** 家庭用户:性别切换 */
|
||||
onGenderTap(e: WechatMiniprogram.TouchEvent) {
|
||||
const value = e.currentTarget.dataset.value as string
|
||||
this.setData({ 'form.gender': value, 'form.sex': value === '男' ? 1 : 2 })
|
||||
},
|
||||
|
||||
/** 出生年月变更 */
|
||||
onBirthdayChange(e: WechatMiniprogram.PickerChange) {
|
||||
this.setData({ birthday: e.detail.value as string })
|
||||
},
|
||||
|
||||
onHeightInput(e: WechatMiniprogram.Input) {
|
||||
this.setData({ 'form.height': e.detail.value })
|
||||
},
|
||||
|
||||
onWeightInput(e: WechatMiniprogram.Input) {
|
||||
this.setData({ 'form.weight': e.detail.value })
|
||||
},
|
||||
|
||||
/** 复用已有信息:关弹框直接提交 */
|
||||
onConfirmModalConfirm() {
|
||||
this.setData({ showConfirmModal: false })
|
||||
this.onSubmit()
|
||||
},
|
||||
|
||||
/** 不复用:清空整个表单 */
|
||||
onConfirmModalCancel() {
|
||||
this.setData({
|
||||
showConfirmModal: false,
|
||||
readonly: false,
|
||||
serverResult: null,
|
||||
form: { workNo: '', name: '', idCard: '', gender: '', age: '', height: '', weight: '', sex: 0 },
|
||||
birthday: '',
|
||||
})
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
wx.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
wx.navigateBack()
|
||||
},
|
||||
|
||||
onSave() {
|
||||
// 保存用户信息(待接入)
|
||||
}
|
||||
/** 提交用户 */
|
||||
onSubmit() {
|
||||
const { name, idCard, gender, height, weight, sex } = this.data.form
|
||||
const { userType } = this.data
|
||||
const heightNum = parseFloat(height)
|
||||
const weightNum = parseFloat(weight)
|
||||
|
||||
if (userType === 'employee') {
|
||||
if (!this.data.employeeQueried || this.data.employeeNotFound) {
|
||||
wx.showToast({ title: '请先查询员工信息', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!height || isNaN(heightNum) || heightNum <= 0) {
|
||||
wx.showToast({ title: '请填写身高', icon: 'none' })
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (!name.trim()) {
|
||||
wx.showToast({ title: '请填写昵称', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!gender) {
|
||||
wx.showToast({ title: '请选择性别', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!this.data.birthday.trim()) {
|
||||
wx.showToast({ title: '请填写出生年月', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!height || isNaN(heightNum) || heightNum <= 0) {
|
||||
wx.showToast({ title: '请填写身高', icon: 'none' })
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const userInfo = wx.getStorageSync('userInfo') as Record<string, any> | null
|
||||
// 员工:以查询接口返回为 base;家庭:以身份证查询结果为 base
|
||||
const baseSpread = userType === 'employee'
|
||||
? (this.data.employeeQueryResult ?? {})
|
||||
: (this.data.serverResult ?? {})
|
||||
|
||||
const payload: Record<string, any> = {
|
||||
...baseSpread,
|
||||
dataType: userType === 'family' ? 1 : 0,
|
||||
parentUserId: userInfo?.userId ?? '',
|
||||
sn: targetSn,
|
||||
scaleDeviceId: targetSn,
|
||||
realname: name.trim(),
|
||||
idCard: idCard || null,
|
||||
sex,
|
||||
birthday: this.data.birthday,
|
||||
height: heightNum,
|
||||
weight: isNaN(weightNum) ? 0 : weightNum,
|
||||
}
|
||||
|
||||
addUser(payload)
|
||||
.then(() => {
|
||||
wx.showToast({ title: '添加成功', icon: 'success' })
|
||||
// 调用上一个页面(userManagement)刷新成员列表
|
||||
const pages = getCurrentPages()
|
||||
const prevPage = pages[pages.length - 2] as any
|
||||
prevPage?._loadMembers?.()
|
||||
setTimeout(() => wx.navigateBack(), 1500)
|
||||
})
|
||||
.catch(() => {
|
||||
wx.showToast({ title: '添加失败,请重试', icon: 'none' })
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
</view>
|
||||
|
||||
<!-- 未查询 -->
|
||||
<view class="workNoDesc">输入员工编号后自动查询员工信息</view>
|
||||
<view class="workNoDesc" wx:if="{{ !employeeQueried }}">输入员工编号后自动查询员工信息</view>
|
||||
|
||||
<!-- 查询未找到 -->
|
||||
<view class="workNoNull">未查询到员工信息,请确认员工编号是否正确</view>
|
||||
<view class="workNoNull" wx:if="{{ employeeQueried && employeeNotFound }}">未查询到员工信息,请确认员工编号是否正确</view>
|
||||
|
||||
<!-- 查询成功 -->
|
||||
<view class="workNoInfo">
|
||||
<view class="workNoInfo" wx:if="{{ employeeQueried && !employeeNotFound }}">
|
||||
<view class="workNoInfo_">
|
||||
<view class="workNoInfoTitle">用户信息</view>
|
||||
<view class="workNoInfoContent">
|
||||
@@ -182,6 +182,8 @@
|
||||
<!-- 保存按钮 -->
|
||||
<view class="save-btn">
|
||||
<view class="btn-cancel" bind:tap="onCancel">取消</view>
|
||||
<view class="btn-primary" bind:tap="onSave">保存用户信息</view>
|
||||
<view class="btn-primary" bind:tap="onSubmit">保存用户信息</view>
|
||||
</view>
|
||||
|
||||
<user-info-confirm-modal show="{{ showConfirmModal }}" userInfo="{{ serverResult }}" bind:confirm="onConfirmModalConfirm" bind:cancel="onConfirmModalCancel" />
|
||||
</view>
|
||||
|
||||
@@ -291,7 +291,8 @@ Page({
|
||||
|
||||
/** 添加用户 */
|
||||
onTapAddUser() {
|
||||
wx.navigateTo({ url: '/pages/addUser/addUser' })
|
||||
const sn = targetDevice?.sn || ''
|
||||
wx.navigateTo({ url: `/pages/addUser/addUser?sn=${encodeURIComponent(sn)}` })
|
||||
},
|
||||
|
||||
/** 一键添加本人 */
|
||||
|
||||
Reference in New Issue
Block a user