|
@@ -27,6 +27,12 @@
|
|
|
<WorkbenchTaskSection @select-task="handleSelectTask" />
|
|
<WorkbenchTaskSection @select-task="handleSelectTask" />
|
|
|
<!--廉洁协议 -->
|
|
<!--廉洁协议 -->
|
|
|
<HonestAgreementGate v-model="isHonestAgreementVisible" />
|
|
<HonestAgreementGate v-model="isHonestAgreementVisible" />
|
|
|
|
|
+
|
|
|
|
|
+ <LivenessReminderDialog
|
|
|
|
|
+ v-model="isLivenessReminderVisible"
|
|
|
|
|
+ :type="livenessReminderType"
|
|
|
|
|
+ :expire-date-text="livenessExpireDateText"
|
|
|
|
|
+ />
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -34,6 +40,7 @@
|
|
|
import { computed, ref } from 'vue'
|
|
import { computed, ref } from 'vue'
|
|
|
|
|
|
|
|
import { onShow } from '@dcloudio/uni-app'
|
|
import { onShow } from '@dcloudio/uni-app'
|
|
|
|
|
+import dayjs from 'dayjs'
|
|
|
|
|
|
|
|
import {
|
|
import {
|
|
|
getQuizPltTestResultApi,
|
|
getQuizPltTestResultApi,
|
|
@@ -44,6 +51,7 @@ import {
|
|
|
import { useUserStore } from '@/stores/modules/user'
|
|
import { useUserStore } from '@/stores/modules/user'
|
|
|
|
|
|
|
|
import HonestAgreementGate from './components/HonestAgreementGate.vue'
|
|
import HonestAgreementGate from './components/HonestAgreementGate.vue'
|
|
|
|
|
+import LivenessReminderDialog from './components/LivenessReminderDialog.vue'
|
|
|
import WorkbenchCard from './components/WorkbenchCard.vue'
|
|
import WorkbenchCard from './components/WorkbenchCard.vue'
|
|
|
import WorkbenchTaskSection from './components/WorkbenchTaskSection.vue'
|
|
import WorkbenchTaskSection from './components/WorkbenchTaskSection.vue'
|
|
|
import type { TASK_TYPE } from './workbench/workbench.config'
|
|
import type { TASK_TYPE } from './workbench/workbench.config'
|
|
@@ -58,11 +66,14 @@ const onTheWay = ref('0')
|
|
|
onShow(async () => {
|
|
onShow(async () => {
|
|
|
// 每次进入页面时刷新用户状态
|
|
// 每次进入页面时刷新用户状态
|
|
|
if (!userStore.isLoggedIn) return
|
|
if (!userStore.isLoggedIn) return
|
|
|
|
|
+
|
|
|
const userInfo = await userStore.getUserInfoByCode()
|
|
const userInfo = await userStore.getUserInfoByCode()
|
|
|
|
|
|
|
|
if (!userInfo) return
|
|
if (!userInfo) return
|
|
|
|
|
+
|
|
|
waitApprove.value = userInfo.waitApprove ?? '0'
|
|
waitApprove.value = userInfo.waitApprove ?? '0'
|
|
|
onTheWay.value = userInfo.onTheWay ?? '0'
|
|
onTheWay.value = userInfo.onTheWay ?? '0'
|
|
|
|
|
+
|
|
|
// 未签署廉洁协议
|
|
// 未签署廉洁协议
|
|
|
if (!userInfo.signedAgreement?.includes('HONEST_AGREEMENT_V2')) {
|
|
if (!userInfo.signedAgreement?.includes('HONEST_AGREEMENT_V2')) {
|
|
|
uni.hideTabBar()
|
|
uni.hideTabBar()
|
|
@@ -73,20 +84,31 @@ onShow(async () => {
|
|
|
// 超龄退出
|
|
// 超龄退出
|
|
|
if (userInfo.ageLimit) {
|
|
if (userInfo.ageLimit) {
|
|
|
isAgeOverLimit()
|
|
isAgeOverLimit()
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
// 超龄提醒
|
|
// 超龄提醒
|
|
|
if (userInfo.ageReminder) {
|
|
if (userInfo.ageReminder) {
|
|
|
notifyUpcomingAgeLimit()
|
|
notifyUpcomingAgeLimit()
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
// 平台合规测试
|
|
// 平台合规测试
|
|
|
- const res = await getPltQuizResult()
|
|
|
|
|
- if (!res) return
|
|
|
|
|
|
|
+ const quizPassed = await getPltQuizResult()
|
|
|
|
|
+ if (!quizPassed) return
|
|
|
|
|
+
|
|
|
|
|
+ // 活体验证提醒:本次登录只弹一次
|
|
|
|
|
+ const hasOpenedLivenessReminder = checkLivenessReminder(userInfo)
|
|
|
|
|
+ if (hasOpenedLivenessReminder) {
|
|
|
|
|
+ uni.showTabBar()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 密码修改提醒
|
|
// 密码修改提醒
|
|
|
checkLastChangePassword()
|
|
checkLastChangePassword()
|
|
|
|
|
+
|
|
|
// 兜底处理
|
|
// 兜底处理
|
|
|
uni.showTabBar()
|
|
uni.showTabBar()
|
|
|
})
|
|
})
|
|
|
-
|
|
|
|
|
const ensureCanOperate = (): boolean => {
|
|
const ensureCanOperate = (): boolean => {
|
|
|
if (!userStore.isLoggedIn) {
|
|
if (!userStore.isLoggedIn) {
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
@@ -247,6 +269,53 @@ const checkLastChangePassword = async () => {
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+type LivenessReminderType = 'expiring' | 'expired' | ''
|
|
|
|
|
+
|
|
|
|
|
+const LIVENESS_VALID_DAYS = 182
|
|
|
|
|
+const LIVENESS_REMIND_BEFORE_DAYS = 7
|
|
|
|
|
+
|
|
|
|
|
+const isLivenessReminderVisible = ref(false)
|
|
|
|
|
+const livenessReminderType = ref<LivenessReminderType>('')
|
|
|
|
|
+const livenessExpireDateText = ref('')
|
|
|
|
|
+
|
|
|
|
|
+const checkLivenessReminder = (userInfo: Record<string, any>): boolean => {
|
|
|
|
|
+ if (userStore.hasShownLivenessReminder) return false
|
|
|
|
|
+
|
|
|
|
|
+ const { faceAuthTime, faceExpireTime } = userInfo || {}
|
|
|
|
|
+
|
|
|
|
|
+ if (!faceAuthTime && !faceExpireTime) return false
|
|
|
|
|
+
|
|
|
|
|
+ const expireTime = faceExpireTime
|
|
|
|
|
+ ? dayjs(faceExpireTime)
|
|
|
|
|
+ : dayjs(faceAuthTime).add(LIVENESS_VALID_DAYS, 'day')
|
|
|
|
|
+
|
|
|
|
|
+ if (!expireTime.isValid()) return false
|
|
|
|
|
+
|
|
|
|
|
+ const now = dayjs()
|
|
|
|
|
+ const remindStartTime = expireTime.subtract(LIVENESS_REMIND_BEFORE_DAYS, 'day')
|
|
|
|
|
+
|
|
|
|
|
+ if (now.isSame(expireTime) || now.isAfter(expireTime)) {
|
|
|
|
|
+ openLivenessReminder('expired', expireTime)
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (now.isSame(remindStartTime) || now.isAfter(remindStartTime)) {
|
|
|
|
|
+ openLivenessReminder('expiring', expireTime)
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return false
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const openLivenessReminder = (type: Exclude<LivenessReminderType, ''>, expireTime: dayjs.Dayjs) => {
|
|
|
|
|
+ livenessReminderType.value = type
|
|
|
|
|
+ livenessExpireDateText.value = expireTime.format('YYYY年MM月DD日')
|
|
|
|
|
+ isLivenessReminderVisible.value = true
|
|
|
|
|
+
|
|
|
|
|
+ // 关键:弹出即标记,避免关闭后 onShow 再次弹
|
|
|
|
|
+ userStore.markLivenessReminderShown()
|
|
|
|
|
+}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|