From 898f5d86916876ac75adf7707c096d20762cf98d Mon Sep 17 00:00:00 2001 From: leiyun Date: Sat, 28 Mar 2026 00:27:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=BC=E5=AE=B9H5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/router.js | 1 + src/controller/mp.js | 72 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/config/router.js b/src/config/router.js index 2a81f69..bd5eca8 100644 --- a/src/config/router.js +++ b/src/config/router.js @@ -58,6 +58,7 @@ module.exports = [ // 小程序接口 ['/api/mp/login', 'mp/login', 'post'], + ['/api/mp/phoneLogin', 'mp/phoneLogin', 'post'], ['/api/mp/userinfo', 'mp/userinfo'], ['/api/mp/upload', 'mp/upload', 'post'], ['/api/mp/sendSmsCode', 'mp/sendSmsCode', 'post'], diff --git a/src/controller/mp.js b/src/controller/mp.js index df3be58..56cd4f9 100644 --- a/src/controller/mp.js +++ b/src/controller/mp.js @@ -49,6 +49,62 @@ module.exports = class extends Base { return this.json({ code: 1, msg: error.message || '登录失败' }); } } + + // POST /api/mp/phoneLogin - H5 手机号验证码登录 + async phoneLoginAction() { + const { mobile, code } = this.post(); + if (!mobile || !/^1[3-9]\d{9}$/.test(mobile)) { + return this.json({ code: 1, msg: '请输入正确的手机号' }); + } + if (!code || !/^\d{6}$/.test(code)) { + return this.json({ code: 1, msg: '请输入6位验证码' }); + } + const verifyResult = await this.verifySmsCode(mobile, 'login', code); + if (!verifyResult.success) return this.json({ code: 1, msg: verifyResult.message }); + + try { + const userModel = this.model('wechat_user'); + // 查找已有的 H5 用户(open_id 以 h5_ 开头) + let user = await userModel.where({ + open_id: 'h5_' + mobile, app_remark: APP_REMARK, status: 1 + }).find(); + + if (think.isEmpty(user)) { + // 没有 H5 用户记录,创建一条新的 + // 同时查找该手机号是否已有 patient(可能在小程序端已认证) + let patientId = null; + const patient = await this.model('patient').where({ phone: mobile, is_deleted: 0 }).find(); + if (!think.isEmpty(patient)) patientId = patient.id; + + const id = await userModel.createUser({ + open_id: 'h5_' + mobile, union_id: '', app_remark: APP_REMARK, + nickname: '', phone: mobile, patient_id: patientId, status: 1 + }); + user = await userModel.where({ id }).find(); + } + if (user.status !== 1) return this.json({ code: 1, msg: '账号已被停用' }); + + const token = jwt.sign( + { id: user.id, open_id: user.open_id || '', type: 'mp' }, + Base.JWT_SECRET, { expiresIn: 7 * 24 * 60 * 60 } + ); + let patient = null; + if (user.patient_id) { + patient = await this.model('patient') + .field('id, patient_no, name, phone, status, auth_status') + .where({ id: user.patient_id, is_deleted: 0 }).find(); + if (think.isEmpty(patient)) patient = null; + } + return this.json({ code: 0, data: { token, userInfo: { + id: user.id, nickname: user.nickname || '', avatar: user.avatar || '', + phone: user.phone || mobile, patient_id: user.patient_id || null, patient + }}}); + } catch (error) { + think.logger.error('phoneLogin error:', error); + return this.json({ code: 1, msg: error.message || '登录失败' }); + } + } + // GET /api/mp/userinfo async userinfoAction() { const mpUser = this.mpUser; @@ -117,9 +173,12 @@ module.exports = class extends Base { } // POST /api/mp/sendSmsCode async sendSmsCodeAction() { - const mpUser = this.mpUser; - if (!mpUser) return this.json({ code: 1009, msg: '请先登录' }); const { mobile, bizType = 'real_name_auth' } = this.post(); + // login 场景不需要登录态 + if (bizType !== 'login') { + const mpUser = this.mpUser; + if (!mpUser) return this.json({ code: 1009, msg: '请先登录' }); + } if (!mobile || !/^1[3-9]\d{9}$/.test(mobile)) { return this.json({ code: 1, msg: '请输入正确的手机号' }); } @@ -203,8 +262,13 @@ module.exports = class extends Base { msg: '该用户信息已存在' }); } - // 用户确认绑定:检查该 patient 是否已被其他微信用户绑定 - const boundUser = await userModel.where({ patient_id: existPatient.id, id: ['!=', mpUser.id], status: 1 }).find(); + // 用户确认绑定:检查该 patient 是否已被其他真实微信用户绑定(排除 H5 登录渠道) + const boundUser = await userModel.where({ + patient_id: existPatient.id, + id: ['!=', mpUser.id], + open_id: ['NOT LIKE', 'h5_%'], + status: 1 + }).find(); if (!think.isEmpty(boundUser)) { return this.json({ code: 1, msg: '该患者信息已被其他微信账号绑定' }); }