feat: 1. 数脉api鉴别身份证。 2. 后台+微信登陆优化

This commit is contained in:
李琦
2026-08-04 13:56:14 +08:00
parent effaee6229
commit fe841e772a
5 changed files with 86 additions and 49 deletions

View File

@@ -29,10 +29,11 @@ export function sendDoctorWxCode(phone, password) {
}
export function doctorWxLogin(payload) {
// client_type=mobile医生/药师/诊所管理员等统一按手机端会话管理
return req.request({
url: `${AUTH_PREFIX}/login`,
method: 'POST',
data: payload,
data: { ...(payload || {}), client_type: 'mobile' },
header: { isToken: false },
});
}
@@ -45,10 +46,11 @@ export function getDoctorWxSiblingAccounts() {
}
export function switchDoctorWxAccount(payload) {
// client_type=mobile切换账号按手机端会话管理
return doctorAuthRequest({
url: '/switch-account',
method: 'POST',
data: payload,
data: { ...(payload || {}), client_type: 'mobile' },
});
}
@@ -61,10 +63,11 @@ export function getDoctorWxAuthConfig() {
}
export function doctorWxLoginByWechat(payload) {
// 微信登录同样标记为手机端会话
return req.request({
url: `${AUTH_PREFIX}/wx-login`,
method: 'POST',
data: payload,
data: { ...(payload || {}), client_type: 'mobile' },
header: { isToken: false },
});
}

View File

@@ -88,6 +88,60 @@ const reqInterceptor = async (options) => {
return options;
}
/**
* 登录失效统一处理:弹窗提示并按 loginMode 清理 token 后跳转登录页
* @param {string} tipMsg 提示文案
* @param {*} response 原始响应
* @param {object} conf 请求配置(供 _responseLog 使用)
*/
const handleAuthExpired = (tipMsg, response, conf) => {
// 防重复弹窗:并发 401 只提示一次
if (!uni.__xkAuthModalShowing) {
uni.__xkAuthModalShowing = true
uni.showModal({
title: '登录失效',
content: tipMsg,
showCancel: false,
confirmText: '重新登录',
success() {
const loginMode = uni.getStorageSync('loginMode')
if (loginMode === 'platform_admin') {
uni.removeStorageSync('platform_admin_token')
uni.removeStorageSync('platform_admin_user')
uni.removeStorageSync('loginMode')
} else if (loginMode === 'salesperson') {
uni.removeStorageSync('salesperson_token')
uni.removeStorageSync('salesperson_user')
uni.removeStorageSync('loginMode')
} else if (loginMode === 'clinic_salesperson') {
uni.removeStorageSync('clinic_salesperson_token')
uni.removeStorageSync('clinic_salesperson_user')
uni.removeStorageSync('loginMode')
} else if (loginMode === 'clinic_admin') {
uni.removeStorageSync('clinic_admin_token')
uni.removeStorageSync('clinic_admin_user')
uni.removeStorageSync('loginMode')
} else {
uni.removeStorageSync('token')
uni.removeStorageSync('loginInfo')
uni.removeStorageSync('identity')
}
uni.__xkAuthModalShowing = false
uni.reLaunch({ url: '/pages/login/index' })
},
fail() {
uni.__xkAuthModalShowing = false
}
})
}
_responseLog(response, conf, "response 401")
return {
wakaryReqToReject: true,
msg: tipMsg,
res: response
}
}
/**
* 响应拦截器
*/
@@ -108,6 +162,11 @@ const resInterceptor = (response, conf = {}) => {
if (res.result != null) {
res.result = getRes(res.result)
}
// Laravel notAuth 返回 HTTP 200 + 业务码 401需与 HTTP 401 走同一套登录失效处理
const bizCode = Number(res.code != null ? res.code : res.errcode)
if (bizCode === 401) {
return handleAuthExpired(res.msg || res.message || '账号需重新登录', response, conf)
}
return res
} else if (statusCode === 500) {
uni.showToast({
@@ -125,45 +184,7 @@ const resInterceptor = (response, conf = {}) => {
res: response
}
} else if (statusCode === 401) {
uni.showToast({
icon: 'error',
title: response['msg'] || response['message'] || errorCode[statusCode]
})
const loginMode = uni.getStorageSync('loginMode')
if (loginMode === 'platform_admin') {
uni.removeStorageSync('platform_admin_token')
uni.removeStorageSync('platform_admin_user')
uni.removeStorageSync('loginMode')
} else if (loginMode === 'salesperson') {
uni.removeStorageSync('salesperson_token')
uni.removeStorageSync('salesperson_user')
uni.removeStorageSync('loginMode')
} else if (loginMode === 'clinic_salesperson') {
uni.removeStorageSync('clinic_salesperson_token')
uni.removeStorageSync('clinic_salesperson_user')
uni.removeStorageSync('loginMode')
} else if (loginMode === 'clinic_admin') {
uni.removeStorageSync('clinic_admin_token')
uni.removeStorageSync('clinic_admin_user')
uni.removeStorageSync('loginMode')
} else {
uni.removeStorageSync('token')
uni.removeStorageSync('loginInfo')
uni.removeStorageSync('identity')
}
setTimeout(() => {
uni.reLaunch({ url: '/pages/login/index' })
}, 1000)
_responseLog(response, conf, "response 401")
// 增加一个控制字段wakaryReqToReject 使 reject的内容更加可控
return {
// 根据当前字段来判断是否reject
wakaryReqToReject: true,
// 下面可以配置其他返回信息方便统一处理reject
// 以下内容作为reject的返回根据需求处理返回具体错误信息
msg: response['msg'] || errorCode[statusCode],
res: response
}
return handleAuthExpired(response['msg'] || response['message'] || errorCode[statusCode] || '账号需重新登录', response, conf)
} else {
uni.showToast({
icon: 'error',

View File

@@ -169,12 +169,17 @@ export default {
uni.showLoading({ title: '正在获取验证码' });
sendDoctorWxCode(this.form.mobile, this.form.password)
.then((res) => {
if (res.code === 0) {
this.$refs.uCode.start();
if (res.result && res.result.code) {
this.smsCode = res.result.code;
}
// HTTP 200 但业务 code 非 0 时 reject统一走 catch 弹 toast
if (res.code !== 0) {
return Promise.reject(new Error(res.message || res.msg || '获取验证码失败'));
}
this.$refs.uCode.start();
if (res.result && res.result.code) {
this.smsCode = res.result.code;
}
})
.catch((err) => {
this.$toast(err.message || err.msg || '获取验证码失败');
})
.finally(() => {
uni.hideLoading();

View File

@@ -126,7 +126,9 @@
<view class="info">
<text>医师</text>
<image v-if="view.doctorSignImage" :src="checkImageUrl(view.doctorSignImage)" mode="aspectFit"></image>
<text v-else class="name">{{ view.doctorName }}</text>
<!-- 二次签名与处方详情页一致doctor_second_sign=1 时再展示一张 -->
<image v-if="view.doctorSecondSign == 1 && view.doctorSignImage" :src="checkImageUrl(view.doctorSignImage)" mode="aspectFit"></image>
<text v-else-if="!view.doctorSignImage" class="name">{{ view.doctorName }}</text>
</view>
<view class="info">
<text>审核药师</text>
@@ -214,6 +216,8 @@ export default {
|| (w.data.doctor_info && w.data.doctor_info.identity_info && w.data.doctor_info.identity_info.sign_image)
|| (w.data.doctorInfo && w.data.doctorInfo.identityInfo && w.data.doctorInfo.identityInfo.sign_image)
|| ''
// 透传二次签名标记,供医师签名区双图展示
mapped.doctorSecondSign = w.data.doctor_second_sign
mapped.pharmacistSignImage =
w.data.Pharmacist_sign_image
|| (w.data.pharmacist_info && w.data.pharmacist_info.identity && w.data.pharmacist_info.identity.sign_image)

View File

@@ -118,7 +118,9 @@
<view class="info">
<text>医师</text>
<image v-if="view.doctorSignImage" :src="checkImageUrl(view.doctorSignImage)" mode="aspectFit"></image>
<text v-else class="name">{{ view.doctorName }}</text>
<!-- 二次签名与处方详情页一致doctor_second_sign=1 时再展示一张 -->
<image v-if="view.doctorSecondSign == 1 && view.doctorSignImage" :src="checkImageUrl(view.doctorSignImage)" mode="aspectFit"></image>
<text v-else-if="!view.doctorSignImage" class="name">{{ view.doctorName }}</text>
</view>
<view class="info">
<text>审核药师</text>
@@ -203,6 +205,8 @@ export default {
|| (w.data.doctor_info && w.data.doctor_info.identity_info && w.data.doctor_info.identity_info.sign_image)
|| (w.data.doctorInfo && w.data.doctorInfo.identityInfo && w.data.doctorInfo.identityInfo.sign_image)
|| ''
// 透传二次签名标记,供医师签名区双图展示
mapped.doctorSecondSign = w.data.doctor_second_sign
mapped.pharmacistSignImage =
w.data.Pharmacist_sign_image
|| (w.data.pharmacist_info && w.data.pharmacist_info.identity && w.data.pharmacist_info.identity.sign_image)