gengx
This commit is contained in:
@@ -778,6 +778,7 @@ const showDatePicker = ref(false)
|
||||
const diagnosisId = ref(null)
|
||||
const patientId = ref(null)
|
||||
const isAddMode = ref(false) // 新建模式
|
||||
const returnUrl = ref('') // 保存成功后跳回(如日常记录页)
|
||||
|
||||
// 表单数据
|
||||
const formData = ref({
|
||||
@@ -1023,6 +1024,13 @@ const loadCardDetail = async () => {
|
||||
const options = currentPage.options || {}
|
||||
diagnosisId.value = options.id
|
||||
isAddMode.value = options.add === '1' || options.add === 1
|
||||
if (options.returnUrl) {
|
||||
try {
|
||||
returnUrl.value = decodeURIComponent(String(options.returnUrl))
|
||||
} catch (e) {
|
||||
returnUrl.value = String(options.returnUrl)
|
||||
}
|
||||
}
|
||||
|
||||
const userData = uni.getStorageSync('userData')
|
||||
patientId.value = userData?.diagnosis?.patient_id
|
||||
@@ -1302,7 +1310,12 @@ const submitForm = async () => {
|
||||
}
|
||||
uni.showToast({ title: isAddMode.value ? '创建成功' : '保存成功', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
const back = returnUrl.value
|
||||
if (back && back.startsWith('/')) {
|
||||
uni.redirectTo({ url: back })
|
||||
} else {
|
||||
uni.navigateBack()
|
||||
}
|
||||
}, 1500)
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '保存失败', icon: 'none' })
|
||||
|
||||
@@ -212,7 +212,11 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<block v-if="!isInviteViewer">
|
||||
<view v-if="authChecking && !isInviteViewer" class="page-gate-loading">
|
||||
<text class="page-gate-loading-text">正在登录…</text>
|
||||
</view>
|
||||
|
||||
<block v-if="!isInviteViewer && !authChecking">
|
||||
<!-- 顶部 Hero(智能问候 + 今日状态)-->
|
||||
<view class="hero">
|
||||
<view class="hero-bg" />
|
||||
@@ -1384,6 +1388,10 @@ const patientName = ref('')
|
||||
const age = ref(0)
|
||||
const gender = ref(0)
|
||||
|
||||
/** 登录 / 就诊卡门禁校验中(避免未登录时闪屏) */
|
||||
const authChecking = ref(false)
|
||||
let gateRedirected = false
|
||||
|
||||
const loading = ref(false)
|
||||
const cardsLoading = ref(false)
|
||||
const cards = ref([])
|
||||
@@ -1767,10 +1775,104 @@ function getDayBpTrend(date) {
|
||||
return makeTrend(cur, prev.systolic, 0)
|
||||
}
|
||||
|
||||
// ============ 登录 / 就诊卡门禁 ============
|
||||
/** 进行中的登录任务(避免与 App.onLaunch 重复发起 mnpLogin,并保证业务接口在其之后) */
|
||||
let authSessionPromise = null
|
||||
|
||||
function hasAuthToken() {
|
||||
return !!String(uni.getStorageSync('token') || '').trim()
|
||||
}
|
||||
|
||||
function clearAuthStorage() {
|
||||
uni.removeStorageSync('token')
|
||||
authSessionPromise = null
|
||||
}
|
||||
|
||||
function wxLoginGetCode() {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success: (res) => {
|
||||
if (res && res.code) resolve(res.code)
|
||||
else reject(new Error('微信登录未返回 code'))
|
||||
},
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function mnpLoginWithCode(code) {
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/login/mnpLogin',
|
||||
method: 'POST',
|
||||
data: { code }
|
||||
}, false)
|
||||
if (res && res.code === 1 && res.data && res.data.token) {
|
||||
uni.setStorageSync('token', res.data.token)
|
||||
uni.setStorageSync('userData', res.data)
|
||||
return res.data
|
||||
}
|
||||
clearAuthStorage()
|
||||
throw new Error(formatUserMessage(res?.msg, '登录失败'))
|
||||
}
|
||||
|
||||
async function doWxLogin() {
|
||||
const code = await wxLoginGetCode()
|
||||
await mnpLoginWithCode(code)
|
||||
return hasAuthToken()
|
||||
}
|
||||
|
||||
/** 校验 token 有效;无效则清除并重新 mnpLogin(缺 token 时后端 code=0,不能当作已登录) */
|
||||
async function verifyOrLogin() {
|
||||
if (!hasAuthToken()) {
|
||||
return doWxLogin()
|
||||
}
|
||||
try {
|
||||
const res = await proxy.apiUrl({ url: '/api/user/info', method: 'POST' }, false)
|
||||
if (res && res.code === 1 && res.data) {
|
||||
uni.setStorageSync('userData', res.data)
|
||||
return true
|
||||
}
|
||||
} catch (e) {
|
||||
/* 网络异常走重新登录 */
|
||||
}
|
||||
clearAuthStorage()
|
||||
try {
|
||||
return await doWxLogin()
|
||||
} catch (e2) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/** 登录完成后再调业务接口;并发调用共享同一 Promise */
|
||||
async function ensureLoggedIn() {
|
||||
if (authSessionPromise) {
|
||||
return authSessionPromise
|
||||
}
|
||||
authSessionPromise = verifyOrLogin()
|
||||
.then((ok) => {
|
||||
if (!ok) authSessionPromise = null
|
||||
return !!ok
|
||||
})
|
||||
.catch(() => {
|
||||
authSessionPromise = null
|
||||
return false
|
||||
})
|
||||
return authSessionPromise
|
||||
}
|
||||
|
||||
function redirectToCardEntry() {
|
||||
if (gateRedirected) return
|
||||
gateRedirected = true
|
||||
const returnUrl = encodeURIComponent('/tongji/pages/index')
|
||||
uni.redirectTo({
|
||||
url: `/pages/Card/edit_card?add=1&returnUrl=${returnUrl}`
|
||||
})
|
||||
}
|
||||
|
||||
// ============ 就诊卡 ============
|
||||
async function fetchCardList() {
|
||||
const token = uni.getStorageSync('token')
|
||||
if (!token) return
|
||||
if (!hasAuthToken()) return []
|
||||
cardsLoading.value = true
|
||||
try {
|
||||
const res = await proxy.apiUrl({
|
||||
@@ -1793,7 +1895,7 @@ async function fetchCardList() {
|
||||
}
|
||||
|
||||
async function applyCard(card) {
|
||||
if (!card) return
|
||||
if (!card || !hasAuthToken()) return
|
||||
diagnosisId.value = Number(card.id) || 0
|
||||
patientId.value = Number(card.patient_id) || 0
|
||||
patientName.value = card.patient_name || ''
|
||||
@@ -1822,7 +1924,7 @@ async function onSelectCard(card) {
|
||||
|
||||
// ============ 接口请求 ============
|
||||
async function fetchAll() {
|
||||
if (!diagnosisId.value) return
|
||||
if (!hasAuthToken() || !diagnosisId.value) return
|
||||
loading.value = true
|
||||
const { start, end } = currentRange.value
|
||||
try {
|
||||
@@ -3095,24 +3197,33 @@ async function bootstrap(options) {
|
||||
options = options || {}
|
||||
const inviteCode = String(options.invite_code || '').trim()
|
||||
if (options.from === 'share' && inviteCode) {
|
||||
authChecking.value = false
|
||||
await bootstrapInviteViewer(inviteCode)
|
||||
return
|
||||
}
|
||||
|
||||
isInviteViewer.value = false
|
||||
const passedDiagnosisId = Number(options.diagnosis_id || options.id || 0)
|
||||
diagnosisId.value = passedDiagnosisId
|
||||
patientId.value = Number(options.patient_id || 0)
|
||||
if (options.patient_name) patientName.value = decodeURIComponent(options.patient_name)
|
||||
if (options.age) age.value = Number(options.age) || 0
|
||||
if (options.gender) gender.value = Number(options.gender) || 0
|
||||
gateRedirected = false
|
||||
authChecking.value = true
|
||||
|
||||
const token = uni.getStorageSync('token')
|
||||
if (!token) {
|
||||
showUserToast('请先登录')
|
||||
// 登录完成前不写 diagnosisId,避免模板/子流程提前打业务接口
|
||||
const passedDiagnosisId = Number(options.diagnosis_id || options.id || 0)
|
||||
const passedPatientId = Number(options.patient_id || 0)
|
||||
const passedPatientName = options.patient_name
|
||||
? decodeURIComponent(String(options.patient_name))
|
||||
: ''
|
||||
const passedAge = Number(options.age) || 0
|
||||
const passedGender = Number(options.gender) || 0
|
||||
|
||||
const loggedIn = await ensureLoggedIn()
|
||||
if (!loggedIn || !hasAuthToken()) {
|
||||
authChecking.value = false
|
||||
showUserToast('登录失败,请稍后重试')
|
||||
return
|
||||
}
|
||||
|
||||
readUserContext()
|
||||
|
||||
const list = await fetchCardList()
|
||||
|
||||
if (Array.isArray(list) && list.length > 0) {
|
||||
@@ -3123,16 +3234,23 @@ async function bootstrap(options) {
|
||||
if (!target) target = list[0]
|
||||
await applyCard(target)
|
||||
} else {
|
||||
if (passedDiagnosisId) diagnosisId.value = passedDiagnosisId
|
||||
if (passedPatientId) patientId.value = passedPatientId
|
||||
if (passedPatientName) patientName.value = passedPatientName
|
||||
if (passedAge) age.value = passedAge
|
||||
if (passedGender) gender.value = passedGender
|
||||
if (!diagnosisId.value || !patientId.value) {
|
||||
readUserContext()
|
||||
}
|
||||
if (!diagnosisId.value) {
|
||||
showUserToast('暂无就诊卡,请先创建')
|
||||
authChecking.value = false
|
||||
redirectToCardEntry()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fetchAll()
|
||||
authChecking.value = false
|
||||
await fetchAll()
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
@@ -3152,6 +3270,7 @@ onShareAppMessage(() => {
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
if (authChecking.value || gateRedirected) return
|
||||
if (!isInviteViewer.value && diagnosisId.value) {
|
||||
loadFamilyLikeSummary()
|
||||
}
|
||||
@@ -3162,7 +3281,7 @@ onPullDownRefresh(async () => {
|
||||
if (isInviteViewer.value) {
|
||||
const code = invitePreview.value.invite_code
|
||||
if (code) await bootstrapInviteViewer(code)
|
||||
} else {
|
||||
} else if (await ensureLoggedIn()) {
|
||||
await fetchAll()
|
||||
}
|
||||
uni.stopPullDownRefresh()
|
||||
@@ -3215,7 +3334,7 @@ function applyGamifyPayload(data) {
|
||||
}
|
||||
|
||||
async function fetchGamifyState() {
|
||||
if (!diagnosisId.value) return
|
||||
if (!hasAuthToken() || !diagnosisId.value) return
|
||||
try {
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/tcm/dailyGetGamify',
|
||||
@@ -3725,7 +3844,7 @@ function closeWeeklyReport() {
|
||||
}
|
||||
|
||||
async function loadFamilyLikeSummary() {
|
||||
if (!diagnosisId.value || isInviteViewer.value) return
|
||||
if (!hasAuthToken() || !diagnosisId.value || isInviteViewer.value) return
|
||||
const token = uni.getStorageSync('token')
|
||||
if (!token) return
|
||||
try {
|
||||
@@ -3846,6 +3965,17 @@ async function onFamilyLike() {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-gate-loading {
|
||||
min-height: 60vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 80rpx 40rpx;
|
||||
}
|
||||
.page-gate-loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #64748b;
|
||||
}
|
||||
.daily-page {
|
||||
/* Premium UI Color System & Variables - Teal-Emerald Healing Redesign */
|
||||
--primary: #0d9488;
|
||||
|
||||
Reference in New Issue
Block a user