From bfa7d3b23e526809b04299d9c2719c3449aba3be Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期二, 28 四月 2026 10:32:42 +0800
Subject: [PATCH] 小程序图片压缩
---
yuyueMiniProgram/src/static/mine/bg.png | 0
yuyueMiniProgram/src/static/mine/record.png | 0
yuyueMiniProgram/src/static/appointment/woman.png | 0
yuyueMiniProgram/src/static/review/contentbg.png | 0
yuyueMiniProgram/src/static/appointment/company.png | 0
yuyueMiniProgram/src/static/appointment/delete.png | 0
yuyueMiniProgram/src/static/review/pass.png | 0
yuyueMiniProgram/src/static/home/download.png | 0
yuyueMiniProgram/src/static/home/chevron_left.png | 0
yuyueMiniProgram/src/static/mine/edit.png | 0
yuyueMiniProgram/src/static/appointment/man.png | 0
yuyueMiniProgram/src/static/choosePerson/add.png | 0
yuyueMiniProgram/src/static/choosePerson/bg@2x.png | 0
yuyueMiniProgram/src/static/review/reduce.png | 0
yuyueMiniProgram/src/static/home/wait.png | 0
yuyueMiniProgram/src/static/review/greenpass.png | 0
yuyueMiniProgram/src/router/index.ts | 15
yuyueMiniProgram/src/static/home/bg.png | 0
yuyueMiniProgram/src/static/appointment/idCard.png | 0
yuyueMiniProgram/src/static/home/record.png | 0
yuyueMiniProgram/src/static/home/toDo.png | 0
yuyueMiniProgram/src/static/mine/aboutUs.png | 0
yuyueMiniProgram/src/static/review/close.png | 0
yuyueMiniProgram/src/layouts/tabbar.vue | 10 +
yuyueMiniProgram/src/components.d.ts | 1
yuyueMiniProgram/src/static/review/Pending.png | 0
yuyueMiniProgram/src/static/home/成都喜望科技有限公司.png | 0
yuyueMiniProgram/src/static/review/arrow.png | 0
yuyueMiniProgram/src/components/MiniLoginPrompt.vue | 162 ++++++++++++++++
yuyueMiniProgram/src/static/home/hi.png | 0
yuyueMiniProgram/src/static/review/cancel.png | 0
yuyueMiniProgram/src/types/auth.ts | 8
yuyueMiniProgram/src/static/home/left.png | 0
yuyueMiniProgram/src/api/core/handlers.ts | 2
yuyueMiniProgram/src/static/review/refueReview.png | 0
yuyueMiniProgram/src/static/home/visitor.png | 0
yuyueMiniProgram/src/static/review/applay.png | 0
yuyueMiniProgram/src/static/review/cancelReview.png | 0
yuyueMiniProgram/src/static/review/underReview.png | 0
yuyueMiniProgram/src/static/review/fail.png | 0
yuyueMiniProgram/src/static/review/circle.png | 0
frontend-admin/src/layouts/MainLayout.vue | 78 ++++---
yuyueMiniProgram/src/static/review/bg-grey.png | 0
yuyueMiniProgram/src/static/choosePerson/noData.png | 0
yuyueMiniProgram/src/store/auth.ts | 67 ++++++
yuyueMiniProgram/src/main.ts | 39 +++
yuyueMiniProgram/src/static/mine/logout.png | 0
yuyueMiniProgram/src/pages/index/index.vue | 102 ++++++++-
yuyueMiniProgram/src/static/mine/change.png | 0
yuyueMiniProgram/src/static/home/wait_bg.png | 0
yuyueMiniProgram/src/static/home/right.png | 0
yuyueMiniProgram/src/static/viewCode/Download@2x.png | 0
yuyueMiniProgram/src/static/home/chevron_right.png | 0
yuyueMiniProgram/src/static/review/success.png | 0
yuyueMiniProgram/src/static/review/add.png | 0
yuyueMiniProgram/src/static/home/share.png | 0
yuyueMiniProgram/src/static/review/cancelIcon.png | 0
yuyueMiniProgram/src/pages/mine/index.vue | 11 +
yuyueMiniProgram/src/static/mine/bgmask.png | 0
yuyueMiniProgram/src/static/home/tips.png | 0
yuyueMiniProgram/src/static/mine/review.png | 0
yuyueMiniProgram/src/static/review/close@2x.png | 0
yuyueMiniProgram/src/static/review/chapter.png | 0
yuyueMiniProgram/src/static/review/refesh.png | 0
yuyueMiniProgram/src/static/mine/header.png | 0
yuyueMiniProgram/src/static/review/review.png | 0
yuyueMiniProgram/src/static/choosePerson/edit.png | 0
yuyueMiniProgram/src/static/review/passReview.png | 0
yuyueMiniProgram/src/auto-imports.d.ts | 18 +
yuyueMiniProgram/src/static/appointment/plate.png | 0
yuyueMiniProgram/src/static/review/bg-t.png | 0
yuyueMiniProgram/src/static/appointment/bg.png | 0
yuyueMiniProgram/src/static/viewCode/bg@2x.png | 0
yuyueMiniProgram/src/utils/mini-login.ts | 75 +++++++
yuyueMiniProgram/src/static/home/process.png | 0
yuyueMiniProgram/src/static/home/appointment.png | 0
yuyueMiniProgram/src/static/home/toDo_bg.png | 0
77 files changed, 518 insertions(+), 70 deletions(-)
diff --git a/frontend-admin/src/layouts/MainLayout.vue b/frontend-admin/src/layouts/MainLayout.vue
index 632a048..03fd19e 100644
--- a/frontend-admin/src/layouts/MainLayout.vue
+++ b/frontend-admin/src/layouts/MainLayout.vue
@@ -1,6 +1,6 @@
<template>
<el-container class="layout">
- <el-aside width="248px" class="side-wrap">
+ <el-aside width="15.98vw" class="side-wrap">
<div class="brand-block">
<div class="brand-icon"></div>
<div class="brand-name">运维运营管理平台</div>
@@ -11,9 +11,9 @@
unique-opened
router
class="side-menu"
- background-color="#2f63d4"
+ background-color="#245ECC"
text-color="#dce8ff"
- active-text-color="#2f63d4"
+ active-text-color="#245ECC"
>
<el-menu-item v-if="auth.hasPermission('dashboard:page')" index="/dashboard" class="home-item">
<el-icon><House /></el-icon>
@@ -100,22 +100,19 @@
<el-container class="main-shell">
<div class="top-wrap">
<el-header class="header">
- <div class="header-left">
- <div class="header-title">
- <span class="header-dot"></span>
- <span>运维运营管理平台</span>
- </div>
- </div>
+ <div class="header-spacer"></div>
<div class="header-right">
<el-button class="menu-trigger" text>
<el-icon><Operation /></el-icon>
</el-button>
<div class="user-box">
- <el-avatar v-if="auth.avatarUrl" :size="28" :src="auth.avatarUrl" class="hdr-av" />
- <el-avatar v-else :size="28" class="hdr-av">{{ nameInitial }}</el-avatar>
+ <el-avatar v-if="auth.avatarUrl" :size="30" :src="auth.avatarUrl" class="hdr-av" />
+ <el-avatar v-else :size="30" class="hdr-av">{{ nameInitial }}</el-avatar>
<span class="user-name">{{ auth.displayName }}</span>
+ <el-button class="logout-trigger" text @click="confirmLogout">
+ <el-icon><SwitchButton /></el-icon>
+ </el-button>
</div>
- <el-button type="primary" link @click="logout">退出</el-button>
</div>
</el-header>
@@ -161,7 +158,8 @@
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, reactive, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
-import { Document, Grid, House, Operation, Setting, User, UserFilled, Wallet } from "@element-plus/icons-vue";
+import { ElMessageBox } from "element-plus";
+import { Document, Grid, House, Operation, Setting, SwitchButton, User, UserFilled, Wallet } from "@element-plus/icons-vue";
import { useAuthStore } from "../stores/auth";
import http from "../api/http";
@@ -175,6 +173,10 @@
const router = useRouter();
const auth = useAuthStore();
const active = computed(() => route.path);
+const nameInitial = computed(() => {
+ const n = auth.displayName;
+ return n && n.length ? n.slice(0, 1) : "?";
+});
const defaultOpeneds = computed(() => {
const path = route.path;
if (path.startsWith("/system/")) return ["system"];
@@ -210,11 +212,6 @@
"/region/local-units": "属地单位管理",
};
const hiddenTabRouteNames = new Set(["staff-group-detail", "role-detail"]);
-const nameInitial = computed(() => {
- const n = auth.displayName;
- return n && n.length ? n.slice(0, 1) : "?";
-});
-
function resolveRouteTitle() {
if (typeof route.meta.title === "string" && route.meta.title) {
return route.meta.title;
@@ -342,6 +339,19 @@
auth.clear();
router.push("/login");
}
+
+async function confirmLogout() {
+ try {
+ await ElMessageBox.confirm("确认退出当前账号吗?", "退出确认", {
+ confirmButtonText: "确认",
+ cancelButtonText: "取消",
+ type: "warning",
+ });
+ } catch {
+ return;
+ }
+ await logout();
+}
</script>
<style scoped>
@@ -356,7 +366,7 @@
}
.side-wrap {
- background: linear-gradient(180deg, #2f63d4 0%, #2d5fce 100%);
+ background: #245ECC;
color: #fff;
padding: 0 10px 12px;
box-sizing: border-box;
@@ -411,7 +421,7 @@
.side-menu :deep(.el-menu-item.is-active) {
background: #ffffff !important;
- color: #2f63d4 !important;
+ color: #245ECC !important;
}
.side-menu :deep(.el-sub-menu .el-menu-item) {
@@ -449,34 +459,23 @@
display: flex;
align-items: center;
justify-content: space-between;
- height: 44px;
- width: 100%;
+ height: 60px;
+ width: 84vw;
padding: 0 12px 0 14px;
background: #ffffff;
border-bottom: 1px solid #e7edf8;
box-sizing: border-box;
}
-.header-left,
+.header-spacer,
.header-right,
-.user-box,
-.header-title {
+.user-box {
display: flex;
align-items: center;
}
-.header-title {
- gap: 10px;
- color: #3d5d9e;
- font-size: 14px;
- font-weight: 600;
-}
-
-.header-dot {
- width: 18px;
- height: 18px;
- border-radius: 50%;
- background: linear-gradient(135deg, #7ca9ff, #4f7dff);
+.header-spacer {
+ flex: 1 1 auto;
}
.header-right {
@@ -491,6 +490,11 @@
gap: 8px;
}
+.logout-trigger {
+ color: #5e6f95;
+ padding: 0;
+}
+
.user-name {
color: #47587c;
font-size: 13px;
diff --git a/yuyueMiniProgram/src/api/core/handlers.ts b/yuyueMiniProgram/src/api/core/handlers.ts
index fe7e14d..90a47c6 100644
--- a/yuyueMiniProgram/src/api/core/handlers.ts
+++ b/yuyueMiniProgram/src/api/core/handlers.ts
@@ -38,8 +38,6 @@
clearMiniAuthSession()
if (!redirectingToLogin) {
redirectingToLogin = true
- const globalToast = useGlobalToast()
- globalToast.error({ msg: message || '登录已过期,请重新登录!', duration: 1200 })
const timer = setTimeout(() => {
clearTimeout(timer)
redirectingToLogin = false
diff --git a/yuyueMiniProgram/src/auto-imports.d.ts b/yuyueMiniProgram/src/auto-imports.d.ts
index 3dcfdb0..60676c4 100644
--- a/yuyueMiniProgram/src/auto-imports.d.ts
+++ b/yuyueMiniProgram/src/auto-imports.d.ts
@@ -9,8 +9,10 @@
const $$userConfigMap: typeof import('./api/index')['$$userConfigMap']
const Apis: typeof import('./api/index')['Apis']
const CommonUtil: typeof import('wot-design-uni')['CommonUtil']
+ const EMPLOYEE_SUBSCRIBE_TEMPLATE_IDS: typeof import('./utils/mini-login')['EMPLOYEE_SUBSCRIBE_TEMPLATE_IDS']
const EffectScope: typeof import('vue')['EffectScope']
const MINI_AUTH_STORAGE_KEY: typeof import('./store/auth')['MINI_AUTH_STORAGE_KEY']
+ const MINI_PHONE_AUTH_REQUIRED: typeof import('./utils/mini-login')['MINI_PHONE_AUTH_REQUIRED']
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
const alovaInstance: typeof import('./api/index')['alovaInstance']
const api: typeof import('./api/index')['default']
@@ -67,13 +69,17 @@
const fetchVisitReasons: typeof import('./api/lookup')['fetchVisitReasons']
const fetchVisitRecords: typeof import('./api/appointment')['fetchVisitRecords']
const fetchVisitorDetail: typeof import('./api/visitor')['fetchVisitorDetail']
+ const finishMiniLogin: typeof import('./utils/mini-login')['finishMiniLogin']
const getActivePinia: typeof import('pinia')['getActivePinia']
+ const getApiErrorCode: typeof import('./utils/mini-login')['getApiErrorCode']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentPath: typeof import('./utils/index')['getCurrentPath']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const getPersistedAuthState: typeof import('./store/auth')['getPersistedAuthState']
const getPersistedToken: typeof import('./store/auth')['getPersistedToken']
+ const getWxLoginCode: typeof import('./utils/mini-login')['getWxLoginCode']
const h: typeof import('vue')['h']
+ const hideMiniLoginPrompt: typeof import('./store/auth')['hideMiniLoginPrompt']
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
const inject: typeof import('vue')['inject']
const injectLocal: typeof import('@vueuse/core')['injectLocal']
@@ -153,6 +159,7 @@
const refDefault: typeof import('@vueuse/core')['refDefault']
const refThrottled: typeof import('@vueuse/core')['refThrottled']
const refWithControl: typeof import('@vueuse/core')['refWithControl']
+ const requestEmployeeSubscribeAuthorization: typeof import('./utils/mini-login')['requestEmployeeSubscribeAuthorization']
const requestMiniSubscribeMessages: typeof import('./utils/subscribeMessage')['requestMiniSubscribeMessages']
const resolveComponent: typeof import('vue')['resolveComponent']
const resolveRef: typeof import('@vueuse/core')['resolveRef']
@@ -161,9 +168,11 @@
const searchVisitedUsersByExactName: typeof import('./api/lookup')['searchVisitedUsersByExactName']
const setActivePinia: typeof import('pinia')['setActivePinia']
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
+ const setMiniPhoneAuthorizeRequired: typeof import('./store/auth')['setMiniPhoneAuthorizeRequired']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
+ const showMiniLoginPrompt: typeof import('./store/auth')['showMiniLoginPrompt']
const storeToRefs: typeof import('pinia')['storeToRefs']
const submitGeneralApproval: typeof import('./api/appointment')['submitGeneralApproval']
const submitHandlerApproval: typeof import('./api/appointment')['submitHandlerApproval']
@@ -401,8 +410,10 @@
readonly $$userConfigMap: UnwrapRef<typeof import('./api/index')['$$userConfigMap']>
readonly Apis: UnwrapRef<typeof import('./api/index')['Apis']>
readonly CommonUtil: UnwrapRef<typeof import('wot-design-uni')['CommonUtil']>
+ readonly EMPLOYEE_SUBSCRIBE_TEMPLATE_IDS: UnwrapRef<typeof import('./utils/mini-login')['EMPLOYEE_SUBSCRIBE_TEMPLATE_IDS']>
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly MINI_AUTH_STORAGE_KEY: UnwrapRef<typeof import('./store/auth')['MINI_AUTH_STORAGE_KEY']>
+ readonly MINI_PHONE_AUTH_REQUIRED: UnwrapRef<typeof import('./utils/mini-login')['MINI_PHONE_AUTH_REQUIRED']>
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
readonly alovaInstance: UnwrapRef<typeof import('./api/index')['alovaInstance']>
readonly api: UnwrapRef<typeof import('./api/index')['default']>
@@ -458,13 +469,17 @@
readonly fetchVisitReasons: UnwrapRef<typeof import('./api/lookup')['fetchVisitReasons']>
readonly fetchVisitRecords: UnwrapRef<typeof import('./api/appointment')['fetchVisitRecords']>
readonly fetchVisitorDetail: UnwrapRef<typeof import('./api/visitor')['fetchVisitorDetail']>
+ readonly finishMiniLogin: UnwrapRef<typeof import('./utils/mini-login')['finishMiniLogin']>
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
+ readonly getApiErrorCode: UnwrapRef<typeof import('./utils/mini-login')['getApiErrorCode']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentPath: UnwrapRef<typeof import('./utils/index')['getCurrentPath']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly getPersistedAuthState: UnwrapRef<typeof import('./store/auth')['getPersistedAuthState']>
readonly getPersistedToken: UnwrapRef<typeof import('./store/auth')['getPersistedToken']>
+ readonly getWxLoginCode: UnwrapRef<typeof import('./utils/mini-login')['getWxLoginCode']>
readonly h: UnwrapRef<typeof import('vue')['h']>
+ readonly hideMiniLoginPrompt: UnwrapRef<typeof import('./store/auth')['hideMiniLoginPrompt']>
readonly ignorableWatch: UnwrapRef<typeof import('@vueuse/core')['ignorableWatch']>
readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly injectLocal: UnwrapRef<typeof import('@vueuse/core')['injectLocal']>
@@ -543,6 +558,7 @@
readonly refDefault: UnwrapRef<typeof import('@vueuse/core')['refDefault']>
readonly refThrottled: UnwrapRef<typeof import('@vueuse/core')['refThrottled']>
readonly refWithControl: UnwrapRef<typeof import('@vueuse/core')['refWithControl']>
+ readonly requestEmployeeSubscribeAuthorization: UnwrapRef<typeof import('./utils/mini-login')['requestEmployeeSubscribeAuthorization']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly resolveRef: UnwrapRef<typeof import('@vueuse/core')['resolveRef']>
readonly resolveUnref: UnwrapRef<typeof import('@vueuse/core')['resolveUnref']>
@@ -550,9 +566,11 @@
readonly searchVisitedUsersByExactName: UnwrapRef<typeof import('./api/lookup')['searchVisitedUsersByExactName']>
readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
+ readonly setMiniPhoneAuthorizeRequired: UnwrapRef<typeof import('./store/auth')['setMiniPhoneAuthorizeRequired']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
+ readonly showMiniLoginPrompt: UnwrapRef<typeof import('./store/auth')['showMiniLoginPrompt']>
readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
readonly submitGeneralApproval: UnwrapRef<typeof import('./api/appointment')['submitGeneralApproval']>
readonly submitHandlerApproval: UnwrapRef<typeof import('./api/appointment')['submitHandlerApproval']>
diff --git a/yuyueMiniProgram/src/components.d.ts b/yuyueMiniProgram/src/components.d.ts
index adae7ac..6089e6a 100644
--- a/yuyueMiniProgram/src/components.d.ts
+++ b/yuyueMiniProgram/src/components.d.ts
@@ -11,6 +11,7 @@
GlobalLoading: typeof import('./components/GlobalLoading.vue')['default']
GlobalMessage: typeof import('./components/GlobalMessage.vue')['default']
GlobalToast: typeof import('./components/GlobalToast.vue')['default']
+ MiniLoginPrompt: typeof import('./components/MiniLoginPrompt.vue')['default']
PrivacyPopup: typeof import('./components/PrivacyPopup.vue')['default']
WdButton: typeof import('wot-design-uni/components/wd-button/wd-button.vue')['default']
WdCell: typeof import('wot-design-uni/components/wd-cell/wd-cell.vue')['default']
diff --git a/yuyueMiniProgram/src/components/MiniLoginPrompt.vue b/yuyueMiniProgram/src/components/MiniLoginPrompt.vue
new file mode 100644
index 0000000..b7f6d0d
--- /dev/null
+++ b/yuyueMiniProgram/src/components/MiniLoginPrompt.vue
@@ -0,0 +1,162 @@
+<script setup lang="ts">
+import { loginByWx } from '@/api/auth'
+import { useMiniAuthStore } from '@/store/auth'
+import { finishMiniLogin, getApiErrorCode, getWxLoginCode, MINI_PHONE_AUTH_REQUIRED } from '@/utils/mini-login'
+import { normalizeProfileDisplayName } from '@/types/auth'
+
+const emit = defineEmits<{
+ (e: 'login-success'): void
+}>()
+
+const authStore = useMiniAuthStore()
+const router = useRouter()
+const loginSubmitting = ref(false)
+
+const visible = computed(() => authStore.loginPromptVisible)
+const needPhoneAuthorize = computed(() => authStore.needPhoneAuthorize)
+const message = computed(() => {
+ if (needPhoneAuthorize.value) {
+ return '首次登录需授权手机号完成身份识别'
+ }
+ return authStore.authPromptMessage || '您还未登录,请先登录'
+})
+
+function hideLoginPrompt() {
+ authStore.hideLoginPrompt()
+}
+
+function shouldForceEditProfile() {
+ return !normalizeProfileDisplayName(authStore.profile?.displayName)
+}
+
+function openProfileEditorIfNeeded() {
+ if (!shouldForceEditProfile()) {
+ return false
+ }
+ uni.showToast({
+ title: '请先完善个人资料',
+ icon: 'none',
+ })
+ router.push({ name: 'profile' })
+ return true
+}
+
+async function handleStartLogin() {
+ if (loginSubmitting.value) {
+ return
+ }
+
+ loginSubmitting.value = true
+ try {
+ const wxCode = await getWxLoginCode()
+ const loginData = await loginByWx({ wxCode })
+ await finishMiniLogin(loginData)
+ hideLoginPrompt()
+ uni.$emit('mini-login-success')
+ emit('login-success')
+ if (openProfileEditorIfNeeded()) {
+ return
+ }
+ uni.showToast({
+ title: '登录成功',
+ icon: 'success',
+ })
+ }
+ catch (error) {
+ if (getApiErrorCode(error) === MINI_PHONE_AUTH_REQUIRED) {
+ authStore.setNeedPhoneAuthorize(true)
+ return
+ }
+ uni.showToast({
+ title: error instanceof Error ? error.message : '登录失败',
+ icon: 'none',
+ })
+ }
+ finally {
+ loginSubmitting.value = false
+ }
+}
+
+async function handlePhoneAuthorize(event: any) {
+ if (loginSubmitting.value) {
+ return
+ }
+ const phoneCode = event?.detail?.code
+ if (!phoneCode) {
+ uni.showToast({
+ title: '未获取到手机号授权',
+ icon: 'none',
+ })
+ return
+ }
+
+ loginSubmitting.value = true
+ try {
+ const wxCode = await getWxLoginCode()
+ const loginData = await loginByWx({ wxCode, phoneCode })
+ await finishMiniLogin(loginData)
+ hideLoginPrompt()
+ uni.$emit('mini-login-success')
+ emit('login-success')
+ if (openProfileEditorIfNeeded()) {
+ return
+ }
+ uni.showToast({
+ title: '登录成功',
+ icon: 'success',
+ })
+ }
+ catch (error) {
+ uni.showToast({
+ title: error instanceof Error ? error.message : '登录失败',
+ icon: 'none',
+ })
+ }
+ finally {
+ loginSubmitting.value = false
+ }
+}
+</script>
+
+<template>
+ <view v-if="visible" class="fixed inset-0 z-40 bg-[rgba(0,0,0,0.55)]" @click="!needPhoneAuthorize && hideLoginPrompt()" />
+
+ <view
+ v-if="visible"
+ class="fixed left-[50%] top-[50%] z-50 w-[520rpx] translate-x-[-50%] translate-y-[-50%] rounded-[28rpx] bg-white px-[40rpx] pb-[36rpx] pt-[28rpx]"
+ >
+ <view class="mb-[16rpx] text-center text-[34rpx] text-[#1A1A1A] font-medium">
+ 提示
+ </view>
+ <view class="flex flex-col items-center">
+ <image src="/static/home/tips.png" class="mb-[24rpx] h-[144rpx] w-[144rpx]" mode="aspectFit" />
+ <text class="mb-[44rpx] text-[28rpx] text-[#4A4A4A]">
+ {{ message }}
+ </text>
+ </view>
+ <view class="flex items-center justify-between gap-[20rpx]">
+ <view
+ class="h-[80rpx] flex flex-1 items-center justify-center rounded-full bg-[#F2F2F2] text-[30rpx] text-[#666666]"
+ @click="hideLoginPrompt"
+ >
+ 再想想
+ </view>
+ <button
+ v-if="needPhoneAuthorize"
+ class="m-0 h-[80rpx] flex flex-1 items-center justify-center rounded-full border-none bg-[#0C6FFF] p-0 text-[30rpx] text-white after:border-none"
+ :disabled="loginSubmitting"
+ open-type="getPhoneNumber"
+ @getphonenumber="handlePhoneAuthorize"
+ >
+ {{ loginSubmitting ? '授权中...' : '授权手机号' }}
+ </button>
+ <view
+ v-else
+ class="h-[80rpx] flex flex-1 items-center justify-center rounded-full bg-[#0C6FFF] text-[30rpx] text-white"
+ @click="handleStartLogin"
+ >
+ {{ loginSubmitting ? '登录中...' : '去登录' }}
+ </view>
+ </view>
+ </view>
+</template>
diff --git a/yuyueMiniProgram/src/layouts/tabbar.vue b/yuyueMiniProgram/src/layouts/tabbar.vue
index f5e0f48..adf3a5b 100644
--- a/yuyueMiniProgram/src/layouts/tabbar.vue
+++ b/yuyueMiniProgram/src/layouts/tabbar.vue
@@ -2,10 +2,19 @@
const router = useRouter()
const route = useRoute()
+const authStore = useMiniAuthStore()
const { activeTabbar, getTabbarItemValue, setTabbarItemActive, tabbarList } = useTabbar()
function handleTabbarChange({ value }: { value: string }) {
+ if (value === 'mine' && !authStore.isLoggedIn) {
+ authStore.showLoginPrompt('您还未登录,请先登录')
+ setTabbarItemActive('home')
+ if (route.name !== 'home') {
+ router.replaceAll({ name: 'home' })
+ }
+ return
+ }
setTabbarItemActive(value)
router.pushTab({ name: value })
}
@@ -34,6 +43,7 @@
<template>
<slot />
+ <MiniLoginPrompt />
<wd-gap safe-area-bottom height="var(--wot-tabbar-height, 50px)" />
<wd-tabbar
:model-value="activeTabbar.name" active-color="#0068FF" inactive-color="#1A1A1A" bordered safe-area-inset-bottom fixed custom-class="custom-tabbar-bg"
diff --git a/yuyueMiniProgram/src/main.ts b/yuyueMiniProgram/src/main.ts
index dca7cf8..6172d55 100644
--- a/yuyueMiniProgram/src/main.ts
+++ b/yuyueMiniProgram/src/main.ts
@@ -3,6 +3,45 @@
import router from './router'
import 'uno.css'
+if (typeof globalThis.TextEncoder === 'undefined') {
+ class MiniTextEncoder {
+ encode(input = '') {
+ const bytes: number[] = []
+ for (const char of input) {
+ const codePoint = char.codePointAt(0) ?? 0
+ if (codePoint <= 0x7F) {
+ bytes.push(codePoint)
+ continue
+ }
+ if (codePoint <= 0x7FF) {
+ bytes.push(
+ 0xC0 | (codePoint >> 6),
+ 0x80 | (codePoint & 0x3F),
+ )
+ continue
+ }
+ if (codePoint <= 0xFFFF) {
+ bytes.push(
+ 0xE0 | (codePoint >> 12),
+ 0x80 | ((codePoint >> 6) & 0x3F),
+ 0x80 | (codePoint & 0x3F),
+ )
+ continue
+ }
+ bytes.push(
+ 0xF0 | (codePoint >> 18),
+ 0x80 | ((codePoint >> 12) & 0x3F),
+ 0x80 | ((codePoint >> 6) & 0x3F),
+ 0x80 | (codePoint & 0x3F),
+ )
+ }
+ return new Uint8Array(bytes)
+ }
+ }
+
+ globalThis.TextEncoder = MiniTextEncoder as typeof TextEncoder
+}
+
const pinia = createPinia()
pinia.use(persistPlugin)
export function createApp() {
diff --git a/yuyueMiniProgram/src/pages/index/index.vue b/yuyueMiniProgram/src/pages/index/index.vue
index 1c21593..b3be601 100644
--- a/yuyueMiniProgram/src/pages/index/index.vue
+++ b/yuyueMiniProgram/src/pages/index/index.vue
@@ -3,6 +3,7 @@
import { fetchMyApprovalTodos, fetchMyVisitorCodes, fetchVisitRecords } from '@/api/appointment'
import { useMiniAuthStore } from '@/store/auth'
import type { MiniMyVisitorCodeOrderItem, MiniMyVisitorCodeTicketItem } from '@/types/appointment'
+import { getApiErrorCode } from '@/utils/mini-login'
interface VisitorCodeDisplayTicket extends MiniMyVisitorCodeTicketItem {
qrCode: string
@@ -27,9 +28,12 @@
const visitRecordCount = ref(0)
const profile = computed(() => authStore.profile)
+const isLoggedIn = computed(() => authStore.isLoggedIn)
const isEmployee = computed(() => profile.value?.userType === 'EMPLOYEE')
+const showEmployeeDashboard = computed(() => !isLoggedIn.value || isEmployee.value)
+const welcomeName = computed(() => profile.value?.displayName || '欢迎使用,请登录')
const userRoleText = computed(() => {
- if (!profile.value) {
+ if (!profile.value || !isLoggedIn.value) {
return ''
}
if (profile.value.userType === 'EMPLOYEE') {
@@ -38,7 +42,7 @@
return '普通访客'
})
const secondaryText = computed(() => {
- if (!profile.value) {
+ if (!profile.value || !isLoggedIn.value) {
return ''
}
if (profile.value.userType === 'EMPLOYEE') {
@@ -46,6 +50,8 @@
}
return profile.value.companyName || ''
})
+const approvalTodoDisplay = computed(() => isLoggedIn.value ? String(approvalTodoCount.value) : '-')
+const visitRecordDisplay = computed(() => isLoggedIn.value ? String(visitRecordCount.value) : '-')
const currentOrder = computed(() => visitorOrders.value[currentOrderIndex.value] || null)
const currentTicket = computed(() => {
if (!currentOrder.value) {
@@ -102,6 +108,10 @@
return order.visitTimeText || '暂无有效期'
}
+function isUnauthorizedError(error: unknown) {
+ return getApiErrorCode(error) === 401 || getApiErrorCode(error) === 403
+}
+
function formatDateTime(value?: string | null) {
if (!value) {
return ''
@@ -121,6 +131,13 @@
}
async function loadVisitorCodes() {
+ if (!isLoggedIn.value) {
+ visitorOrders.value = []
+ ticketIndexMap.value = {}
+ currentOrderIndex.value = 0
+ loadingVisitorCodes.value = false
+ return
+ }
loadingVisitorCodes.value = true
const currentToken = qrRenderToken.value + 1
qrRenderToken.value = currentToken
@@ -145,6 +162,9 @@
catch (error) {
visitorOrders.value = []
ticketIndexMap.value = {}
+ if (isUnauthorizedError(error)) {
+ return
+ }
uni.showToast({
title: error instanceof Error ? error.message : '加载访客码失败',
icon: 'none',
@@ -158,7 +178,7 @@
}
async function loadEmployeeDashboardCounts() {
- if (!isEmployee.value) {
+ if (!isLoggedIn.value || !isEmployee.value) {
approvalTodoCount.value = 0
visitRecordCount.value = 0
return
@@ -335,14 +355,50 @@
})
}
+function showLoginPrompt(message?: string) {
+ authStore.showLoginPrompt(message)
+}
+
+function hideLoginPrompt() {
+ authStore.hideLoginPrompt()
+}
+
+function ensureLoggedIn(action?: () => void, message?: string) {
+ if (isLoggedIn.value) {
+ action?.()
+ return true
+ }
+ showLoginPrompt(message)
+ return false
+}
+
+async function reloadHomeData() {
+ if (!isLoggedIn.value) {
+ visitorOrders.value = []
+ ticketIndexMap.value = {}
+ currentOrderIndex.value = 0
+ approvalTodoCount.value = 0
+ visitRecordCount.value = 0
+ return
+ }
+ await Promise.all([
+ loadVisitorCodes(),
+ loadEmployeeDashboardCounts(),
+ ])
+}
+
function handleOpenApprovalTodo() {
- uni.navigateTo({ url: '/pages/reviewList/index' })
+ ensureLoggedIn(() => {
+ uni.navigateTo({ url: '/pages/reviewList/index' })
+ }, '您还未登录,请先登录')
}
function handleOpenVisitRecords() {
- uni.navigateTo({
- url: '/pages/reception/index',
- })
+ ensureLoggedIn(() => {
+ uni.navigateTo({
+ url: '/pages/reception/index',
+ })
+ }, '您还未登录,请先登录')
}
function buildVisitorCodeSharePath(orderUuid?: string | null) {
@@ -361,8 +417,15 @@
onShow(() => {
authStore.restoreSession()
- void loadVisitorCodes()
- void loadEmployeeDashboardCounts()
+ void reloadHomeData()
+})
+
+onMounted(() => {
+ uni.$on('mini-login-success', reloadHomeData)
+})
+
+onUnmounted(() => {
+ uni.$off('mini-login-success', reloadHomeData)
})
definePage({
@@ -385,19 +448,19 @@
</text>
</view>
- <view class="mb-[36rpx] flex items-center pl-[26rpx] pr-[22rpx]">
+ <view class="mb-[36rpx] flex items-center pl-[26rpx] pr-[22rpx]" @click="!isLoggedIn && showLoginPrompt('您还未登录,请先登录')">
<image src="/static/home/hi.png" class="mr-[24rpx] h-[96rpx] w-[212rpx]" mode="aspectFit" />
<view class="flex flex-col">
<view class="welcome-title flex items-center text-[56rpx] text-white font-[600]">
- <text>{{ profile?.displayName || '用户' }}</text>
+ <text>{{ welcomeName }}</text>
</view>
- <text class="mt-[8rpx] text-[24rpx] text-white/90">
+ <text v-if="isLoggedIn && userRoleText" class="mt-[8rpx] text-[24rpx] text-white/90">
{{ userRoleText }}<template v-if="secondaryText"> · {{ secondaryText }}</template>
</text>
</view>
</view>
- <view v-if="isEmployee" class="mb-[32rpx] w-full pl-[26rpx] pr-[22rpx]" style="box-sizing: border-box;">
+ <view v-if="showEmployeeDashboard" class="mb-[32rpx] w-full pl-[26rpx] pr-[22rpx]" style="box-sizing: border-box;">
<view
class="rounded-[16rpx] p-[24rpx] pb-[26rpx]"
style="background: linear-gradient(180deg, #CCE4FE 0%, #FAFCFD 40%, #FDFDFD 100%); box-shadow: 0 4rpx 8rpx 0 rgba(0, 104, 255, 0.2);border: 1rpx solid #fff;"
@@ -416,7 +479,7 @@
待办
</text>
<text class="text-[32rpx] text-[#056DFF] font-bold">
- {{ approvalTodoCount }}
+ {{ approvalTodoDisplay }}
</text>
</view>
</view>
@@ -433,7 +496,7 @@
待接待
</text>
<text class="text-[32rpx] text-[#F86911] font-bold">
- {{ visitRecordCount }}
+ {{ visitRecordDisplay }}
</text>
</view>
</view>
@@ -445,7 +508,7 @@
<view
class="h-[240rpx] w-[344rpx] flex flex-1 flex-col items-center justify-center rounded-[20rpx]"
style="background: linear-gradient(180deg, #DEF4FF 0%, #FFFFFF 100%);border: 1rpx solid #fff;box-shadow: 0 4rpx 10rpx 0 rgba(0, 104, 255, 0.16)"
- @click="() => { router.push({ name: 'appointment' }) }"
+ @click="ensureLoggedIn(() => { router.push({ name: 'appointment' }) })"
>
<image src="/static/home/appointment.png" class="mb-[12rpx] h-[96rpx] w-[96rpx]" />
<text class="text-[28rpx] text-[#1a1a1a]">
@@ -456,7 +519,7 @@
<view
class="flex flex-1 items-center rounded-[20rpx] px-[40rpx]"
style="background: linear-gradient(180deg, #FFF7E0 0%, #FFFFFF 100%);box-shadow: 0 4rpx 10rpx 0 rgba(0, 104, 255, 0.16)"
- @click="() => { router.push({ name: 'record' }) }"
+ @click="ensureLoggedIn(() => { router.push({ name: 'record' }) })"
>
<image src="/static/home/record.png" class="mr-[16rpx] h-[64rpx] w-[64rpx]" />
<text class="text-[28rpx] text-[#000000]">
@@ -466,7 +529,7 @@
<view
class="flex flex-1 items-center rounded-[20rpx] px-[40rpx]"
style="background: linear-gradient(180deg, #E0FAEE 0%, #FFFFFF 100%);border: 1rpx solid #fff;box-shadow: 0 4rpx 10rpx 0 rgba(0, 104, 255, 0.16)"
- @click="uni.navigateTo({ url: '/pages/choosePerson/index?mode=manage' })"
+ @click="ensureLoggedIn(() => { uni.navigateTo({ url: '/pages/choosePerson/index?mode=manage' }) })"
>
<image src="/static/home/visitor.png" class="mr-[16rpx] h-[64rpx] w-[64rpx]" />
<text class="text-[28rpx] text-[#000000]">
@@ -476,7 +539,7 @@
</view>
</view>
- <view class="mt-[32rpx] px-[24rpx]">
+ <view v-if="isLoggedIn" class="mt-[32rpx] px-[24rpx]">
<view class="mb-[20rpx] flex items-center justify-between">
<text class="text-[34rpx] text-[#1a1a1a]">
我的访客码
@@ -610,6 +673,7 @@
</view>
<image
+ v-if="isLoggedIn"
src="/static/home/process.png"
class="fixed right-[-42rpx] z-5 h-[128rpx] w-[128rpx]"
:style="{ bottom: `${parkFlowBottomPx}px` }"
diff --git a/yuyueMiniProgram/src/pages/mine/index.vue b/yuyueMiniProgram/src/pages/mine/index.vue
index 2ef937c..8ed955b 100644
--- a/yuyueMiniProgram/src/pages/mine/index.vue
+++ b/yuyueMiniProgram/src/pages/mine/index.vue
@@ -24,6 +24,7 @@
const navBarHeight = 44
const profile = computed(() => authStore.profile)
+const isLoggedIn = computed(() => authStore.isLoggedIn)
const userRole = computed<'employee' | 'normal'>(() => profile.value?.userType === 'EMPLOYEE' ? 'employee' : 'normal')
const roleLabel = computed(() => {
if (userRole.value === 'employee') {
@@ -49,6 +50,10 @@
const visibleMenus = computed(() => menuList.value.filter(item => item.showFor.includes(userRole.value)))
function handleEditProfile() {
+ if (!isLoggedIn.value) {
+ authStore.showLoginPrompt('您还未登录,请先登录')
+ return
+ }
uni.navigateTo({ url: '/pages/profile/index' })
}
@@ -61,11 +66,15 @@
}
finally {
authStore.clearSession()
- router.replaceAll({ name: 'login' })
+ router.replaceAll({ name: 'home' })
}
}
function handleMenuClick(item: MenuItem) {
+ if (!isLoggedIn.value) {
+ authStore.showLoginPrompt('您还未登录,请先登录')
+ return
+ }
if (item.title === '退出登录') {
void handleLogout()
return
diff --git a/yuyueMiniProgram/src/router/index.ts b/yuyueMiniProgram/src/router/index.ts
index c888450..d0f4898 100644
--- a/yuyueMiniProgram/src/router/index.ts
+++ b/yuyueMiniProgram/src/router/index.ts
@@ -2,7 +2,7 @@
import { pages, subPackages } from 'virtual:uni-pages'
import { fetchMiniMe } from '@/api/auth'
import { setUnauthorizedRedirectHandler } from './authRedirect'
-import { clearMiniAuthSession, getPersistedAuthState, updateMiniAuthProfile } from '@/store/auth'
+import { clearMiniAuthSession, getPersistedAuthState, showMiniLoginPrompt, updateMiniAuthProfile } from '@/store/auth'
import { normalizeMeProfile } from '@/types/auth'
function generateRoutes() {
@@ -27,10 +27,11 @@
})
setUnauthorizedRedirectHandler(() => {
- router.replaceAll({ name: 'login' })
+ showMiniLoginPrompt('登录已失效,请重新登录')
+ router.replaceAll({ name: 'home' })
})
-const PUBLIC_ROUTE_NAMES = new Set(['login', 'visitorCode'])
+const PUBLIC_ROUTE_NAMES = new Set(['home', 'login', 'visitorCode'])
const HOME_ROUTE_NAME = 'home'
function isPublicRoute(name?: string) {
@@ -48,7 +49,8 @@
next()
return
}
- next({ name: 'login' })
+ showMiniLoginPrompt('您还未登录,请先登录')
+ next({ name: HOME_ROUTE_NAME })
return
}
@@ -64,16 +66,17 @@
catch (error) {
console.warn('mini auth guard fetch /me failed', error)
clearMiniAuthSession()
+ showMiniLoginPrompt('登录已失效,请重新登录')
return false
}
}
return Promise.resolve(ensureProfile()).then((ok) => {
if (!ok) {
- next({ name: 'login' })
+ next({ name: HOME_ROUTE_NAME })
return
}
- if (publicRoute) {
+ if (to.name === 'login') {
next({ name: HOME_ROUTE_NAME })
return
}
diff --git a/yuyueMiniProgram/src/static/appointment/bg.png b/yuyueMiniProgram/src/static/appointment/bg.png
index a0b42ad..c88e130 100644
--- a/yuyueMiniProgram/src/static/appointment/bg.png
+++ b/yuyueMiniProgram/src/static/appointment/bg.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/appointment/company.png b/yuyueMiniProgram/src/static/appointment/company.png
index 6692833..144829c 100644
--- a/yuyueMiniProgram/src/static/appointment/company.png
+++ b/yuyueMiniProgram/src/static/appointment/company.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/appointment/delete.png b/yuyueMiniProgram/src/static/appointment/delete.png
index 82920d7..6e9610a 100644
--- a/yuyueMiniProgram/src/static/appointment/delete.png
+++ b/yuyueMiniProgram/src/static/appointment/delete.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/appointment/idCard.png b/yuyueMiniProgram/src/static/appointment/idCard.png
index e21cf2e..d912169 100644
--- a/yuyueMiniProgram/src/static/appointment/idCard.png
+++ b/yuyueMiniProgram/src/static/appointment/idCard.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/appointment/man.png b/yuyueMiniProgram/src/static/appointment/man.png
index 534ed0b..c074d89 100644
--- a/yuyueMiniProgram/src/static/appointment/man.png
+++ b/yuyueMiniProgram/src/static/appointment/man.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/appointment/plate.png b/yuyueMiniProgram/src/static/appointment/plate.png
index d9fa83c..e0ef63a 100644
--- a/yuyueMiniProgram/src/static/appointment/plate.png
+++ b/yuyueMiniProgram/src/static/appointment/plate.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/appointment/woman.png b/yuyueMiniProgram/src/static/appointment/woman.png
index d4c4772..956d909 100644
--- a/yuyueMiniProgram/src/static/appointment/woman.png
+++ b/yuyueMiniProgram/src/static/appointment/woman.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/choosePerson/add.png b/yuyueMiniProgram/src/static/choosePerson/add.png
index fad42ac..43a26e9 100644
--- a/yuyueMiniProgram/src/static/choosePerson/add.png
+++ b/yuyueMiniProgram/src/static/choosePerson/add.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/choosePerson/bg@2x.png b/yuyueMiniProgram/src/static/choosePerson/bg@2x.png
index fd65fbd..d69f6e1 100644
--- a/yuyueMiniProgram/src/static/choosePerson/bg@2x.png
+++ b/yuyueMiniProgram/src/static/choosePerson/bg@2x.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/choosePerson/edit.png b/yuyueMiniProgram/src/static/choosePerson/edit.png
index edabf2b..fcb9719 100644
--- a/yuyueMiniProgram/src/static/choosePerson/edit.png
+++ b/yuyueMiniProgram/src/static/choosePerson/edit.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/choosePerson/noData.png b/yuyueMiniProgram/src/static/choosePerson/noData.png
index 9cf1b79..64260ab 100644
--- a/yuyueMiniProgram/src/static/choosePerson/noData.png
+++ b/yuyueMiniProgram/src/static/choosePerson/noData.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/appointment.png b/yuyueMiniProgram/src/static/home/appointment.png
index befa562..ea4aeeb 100644
--- a/yuyueMiniProgram/src/static/home/appointment.png
+++ b/yuyueMiniProgram/src/static/home/appointment.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/bg.png b/yuyueMiniProgram/src/static/home/bg.png
index 4c46072..1ca836a 100644
--- a/yuyueMiniProgram/src/static/home/bg.png
+++ b/yuyueMiniProgram/src/static/home/bg.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/chevron_left.png b/yuyueMiniProgram/src/static/home/chevron_left.png
index 9707c38..a3c9225 100644
--- a/yuyueMiniProgram/src/static/home/chevron_left.png
+++ b/yuyueMiniProgram/src/static/home/chevron_left.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/chevron_right.png b/yuyueMiniProgram/src/static/home/chevron_right.png
index 2698ffa..c35d183 100644
--- a/yuyueMiniProgram/src/static/home/chevron_right.png
+++ b/yuyueMiniProgram/src/static/home/chevron_right.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/download.png b/yuyueMiniProgram/src/static/home/download.png
index 4f95376..e018277 100644
--- a/yuyueMiniProgram/src/static/home/download.png
+++ b/yuyueMiniProgram/src/static/home/download.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/hi.png b/yuyueMiniProgram/src/static/home/hi.png
index ccfd23f..276d957 100644
--- a/yuyueMiniProgram/src/static/home/hi.png
+++ b/yuyueMiniProgram/src/static/home/hi.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/left.png b/yuyueMiniProgram/src/static/home/left.png
index 896a407..f29508b 100644
--- a/yuyueMiniProgram/src/static/home/left.png
+++ b/yuyueMiniProgram/src/static/home/left.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/process.png b/yuyueMiniProgram/src/static/home/process.png
index 01f5a49..35b8f2d 100644
--- a/yuyueMiniProgram/src/static/home/process.png
+++ b/yuyueMiniProgram/src/static/home/process.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/record.png b/yuyueMiniProgram/src/static/home/record.png
index 0016e14..e6149c3 100644
--- a/yuyueMiniProgram/src/static/home/record.png
+++ b/yuyueMiniProgram/src/static/home/record.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/right.png b/yuyueMiniProgram/src/static/home/right.png
index e317163..e6ea05e 100644
--- a/yuyueMiniProgram/src/static/home/right.png
+++ b/yuyueMiniProgram/src/static/home/right.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/share.png b/yuyueMiniProgram/src/static/home/share.png
index dd8904b..43bc9bf 100644
--- a/yuyueMiniProgram/src/static/home/share.png
+++ b/yuyueMiniProgram/src/static/home/share.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/tips.png b/yuyueMiniProgram/src/static/home/tips.png
index 39ece9a..e195ecb 100644
--- a/yuyueMiniProgram/src/static/home/tips.png
+++ b/yuyueMiniProgram/src/static/home/tips.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/toDo.png b/yuyueMiniProgram/src/static/home/toDo.png
index ecdeeb4..3ce78aa 100644
--- a/yuyueMiniProgram/src/static/home/toDo.png
+++ b/yuyueMiniProgram/src/static/home/toDo.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/toDo_bg.png b/yuyueMiniProgram/src/static/home/toDo_bg.png
index 2334b14..d0180e8 100644
--- a/yuyueMiniProgram/src/static/home/toDo_bg.png
+++ b/yuyueMiniProgram/src/static/home/toDo_bg.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/visitor.png b/yuyueMiniProgram/src/static/home/visitor.png
index 3eb3bad..8b2615a 100644
--- a/yuyueMiniProgram/src/static/home/visitor.png
+++ b/yuyueMiniProgram/src/static/home/visitor.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/wait.png b/yuyueMiniProgram/src/static/home/wait.png
index 44a6dbf..1283053 100644
--- a/yuyueMiniProgram/src/static/home/wait.png
+++ b/yuyueMiniProgram/src/static/home/wait.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/home/wait_bg.png b/yuyueMiniProgram/src/static/home/wait_bg.png
index c3c4252..fd15c65 100644
--- a/yuyueMiniProgram/src/static/home/wait_bg.png
+++ b/yuyueMiniProgram/src/static/home/wait_bg.png
Binary files differ
diff --git "a/yuyueMiniProgram/src/static/home/\346\210\220\351\203\275\345\226\234\346\234\233\347\247\221\346\212\200\346\234\211\351\231\220\345\205\254\345\217\270.png" "b/yuyueMiniProgram/src/static/home/\346\210\220\351\203\275\345\226\234\346\234\233\347\247\221\346\212\200\346\234\211\351\231\220\345\205\254\345\217\270.png"
index 85eb53c..803301f 100644
--- "a/yuyueMiniProgram/src/static/home/\346\210\220\351\203\275\345\226\234\346\234\233\347\247\221\346\212\200\346\234\211\351\231\220\345\205\254\345\217\270.png"
+++ "b/yuyueMiniProgram/src/static/home/\346\210\220\351\203\275\345\226\234\346\234\233\347\247\221\346\212\200\346\234\211\351\231\220\345\205\254\345\217\270.png"
Binary files differ
diff --git a/yuyueMiniProgram/src/static/mine/aboutUs.png b/yuyueMiniProgram/src/static/mine/aboutUs.png
index 9f49742..d928f17 100644
--- a/yuyueMiniProgram/src/static/mine/aboutUs.png
+++ b/yuyueMiniProgram/src/static/mine/aboutUs.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/mine/bg.png b/yuyueMiniProgram/src/static/mine/bg.png
index 8a5e7d9..86da02a 100644
--- a/yuyueMiniProgram/src/static/mine/bg.png
+++ b/yuyueMiniProgram/src/static/mine/bg.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/mine/bgmask.png b/yuyueMiniProgram/src/static/mine/bgmask.png
index 94e052d..083eec1 100644
--- a/yuyueMiniProgram/src/static/mine/bgmask.png
+++ b/yuyueMiniProgram/src/static/mine/bgmask.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/mine/change.png b/yuyueMiniProgram/src/static/mine/change.png
index f50f16f..f0914a1 100644
--- a/yuyueMiniProgram/src/static/mine/change.png
+++ b/yuyueMiniProgram/src/static/mine/change.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/mine/edit.png b/yuyueMiniProgram/src/static/mine/edit.png
index 0ea3abd..63d4bd9 100644
--- a/yuyueMiniProgram/src/static/mine/edit.png
+++ b/yuyueMiniProgram/src/static/mine/edit.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/mine/header.png b/yuyueMiniProgram/src/static/mine/header.png
index a03d8d1..a977f22 100644
--- a/yuyueMiniProgram/src/static/mine/header.png
+++ b/yuyueMiniProgram/src/static/mine/header.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/mine/logout.png b/yuyueMiniProgram/src/static/mine/logout.png
index 04ef7d7..8651a98 100644
--- a/yuyueMiniProgram/src/static/mine/logout.png
+++ b/yuyueMiniProgram/src/static/mine/logout.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/mine/record.png b/yuyueMiniProgram/src/static/mine/record.png
index 5a1ac49..56c5208 100644
--- a/yuyueMiniProgram/src/static/mine/record.png
+++ b/yuyueMiniProgram/src/static/mine/record.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/mine/review.png b/yuyueMiniProgram/src/static/mine/review.png
index 1bf23ad..948b905 100644
--- a/yuyueMiniProgram/src/static/mine/review.png
+++ b/yuyueMiniProgram/src/static/mine/review.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/Pending.png b/yuyueMiniProgram/src/static/review/Pending.png
index 32fe6d2..1be987a 100644
--- a/yuyueMiniProgram/src/static/review/Pending.png
+++ b/yuyueMiniProgram/src/static/review/Pending.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/add.png b/yuyueMiniProgram/src/static/review/add.png
index fd395c1..dad7d33 100644
--- a/yuyueMiniProgram/src/static/review/add.png
+++ b/yuyueMiniProgram/src/static/review/add.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/applay.png b/yuyueMiniProgram/src/static/review/applay.png
index df22956..533a0a0 100644
--- a/yuyueMiniProgram/src/static/review/applay.png
+++ b/yuyueMiniProgram/src/static/review/applay.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/arrow.png b/yuyueMiniProgram/src/static/review/arrow.png
index cc1dbbc..2d4bdf0 100644
--- a/yuyueMiniProgram/src/static/review/arrow.png
+++ b/yuyueMiniProgram/src/static/review/arrow.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/bg-grey.png b/yuyueMiniProgram/src/static/review/bg-grey.png
index 4554c18..63d1320 100644
--- a/yuyueMiniProgram/src/static/review/bg-grey.png
+++ b/yuyueMiniProgram/src/static/review/bg-grey.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/bg-t.png b/yuyueMiniProgram/src/static/review/bg-t.png
index 788eddb..0267265 100644
--- a/yuyueMiniProgram/src/static/review/bg-t.png
+++ b/yuyueMiniProgram/src/static/review/bg-t.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/cancel.png b/yuyueMiniProgram/src/static/review/cancel.png
index 9ea31cd..e2788ee 100644
--- a/yuyueMiniProgram/src/static/review/cancel.png
+++ b/yuyueMiniProgram/src/static/review/cancel.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/cancelIcon.png b/yuyueMiniProgram/src/static/review/cancelIcon.png
index bd3c766..eafcbf0 100644
--- a/yuyueMiniProgram/src/static/review/cancelIcon.png
+++ b/yuyueMiniProgram/src/static/review/cancelIcon.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/cancelReview.png b/yuyueMiniProgram/src/static/review/cancelReview.png
index cd75787..d723574 100644
--- a/yuyueMiniProgram/src/static/review/cancelReview.png
+++ b/yuyueMiniProgram/src/static/review/cancelReview.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/chapter.png b/yuyueMiniProgram/src/static/review/chapter.png
index cbc4a88..c43e3da 100644
--- a/yuyueMiniProgram/src/static/review/chapter.png
+++ b/yuyueMiniProgram/src/static/review/chapter.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/circle.png b/yuyueMiniProgram/src/static/review/circle.png
index 200b17f..777fa38 100644
--- a/yuyueMiniProgram/src/static/review/circle.png
+++ b/yuyueMiniProgram/src/static/review/circle.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/close.png b/yuyueMiniProgram/src/static/review/close.png
index 4d2e756..108c446 100644
--- a/yuyueMiniProgram/src/static/review/close.png
+++ b/yuyueMiniProgram/src/static/review/close.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/close@2x.png b/yuyueMiniProgram/src/static/review/close@2x.png
index bef3083..74db53c 100644
--- a/yuyueMiniProgram/src/static/review/close@2x.png
+++ b/yuyueMiniProgram/src/static/review/close@2x.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/contentbg.png b/yuyueMiniProgram/src/static/review/contentbg.png
index 94e052d..083eec1 100644
--- a/yuyueMiniProgram/src/static/review/contentbg.png
+++ b/yuyueMiniProgram/src/static/review/contentbg.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/fail.png b/yuyueMiniProgram/src/static/review/fail.png
index 0fc75a6..4209f5e 100644
--- a/yuyueMiniProgram/src/static/review/fail.png
+++ b/yuyueMiniProgram/src/static/review/fail.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/greenpass.png b/yuyueMiniProgram/src/static/review/greenpass.png
index d4ae026..85eb235 100644
--- a/yuyueMiniProgram/src/static/review/greenpass.png
+++ b/yuyueMiniProgram/src/static/review/greenpass.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/pass.png b/yuyueMiniProgram/src/static/review/pass.png
index d85fc15..3a3fc55 100644
--- a/yuyueMiniProgram/src/static/review/pass.png
+++ b/yuyueMiniProgram/src/static/review/pass.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/passReview.png b/yuyueMiniProgram/src/static/review/passReview.png
index 021e345..492fe7b 100644
--- a/yuyueMiniProgram/src/static/review/passReview.png
+++ b/yuyueMiniProgram/src/static/review/passReview.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/reduce.png b/yuyueMiniProgram/src/static/review/reduce.png
index 254d7e5..880fff8 100644
--- a/yuyueMiniProgram/src/static/review/reduce.png
+++ b/yuyueMiniProgram/src/static/review/reduce.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/refesh.png b/yuyueMiniProgram/src/static/review/refesh.png
index 1b4c0d5..87bc799 100644
--- a/yuyueMiniProgram/src/static/review/refesh.png
+++ b/yuyueMiniProgram/src/static/review/refesh.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/refueReview.png b/yuyueMiniProgram/src/static/review/refueReview.png
index 0180b0f..63cc989 100644
--- a/yuyueMiniProgram/src/static/review/refueReview.png
+++ b/yuyueMiniProgram/src/static/review/refueReview.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/review.png b/yuyueMiniProgram/src/static/review/review.png
index 9199f5c..075e271 100644
--- a/yuyueMiniProgram/src/static/review/review.png
+++ b/yuyueMiniProgram/src/static/review/review.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/success.png b/yuyueMiniProgram/src/static/review/success.png
index d97e862..8d9bb36 100644
--- a/yuyueMiniProgram/src/static/review/success.png
+++ b/yuyueMiniProgram/src/static/review/success.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/review/underReview.png b/yuyueMiniProgram/src/static/review/underReview.png
index fc4c446..1bd02bd 100644
--- a/yuyueMiniProgram/src/static/review/underReview.png
+++ b/yuyueMiniProgram/src/static/review/underReview.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/viewCode/Download@2x.png b/yuyueMiniProgram/src/static/viewCode/Download@2x.png
index 83d6a86..13d3891 100644
--- a/yuyueMiniProgram/src/static/viewCode/Download@2x.png
+++ b/yuyueMiniProgram/src/static/viewCode/Download@2x.png
Binary files differ
diff --git a/yuyueMiniProgram/src/static/viewCode/bg@2x.png b/yuyueMiniProgram/src/static/viewCode/bg@2x.png
index fd65fbd..d69f6e1 100644
--- a/yuyueMiniProgram/src/static/viewCode/bg@2x.png
+++ b/yuyueMiniProgram/src/static/viewCode/bg@2x.png
Binary files differ
diff --git a/yuyueMiniProgram/src/store/auth.ts b/yuyueMiniProgram/src/store/auth.ts
index 2320da0..5846b14 100644
--- a/yuyueMiniProgram/src/store/auth.ts
+++ b/yuyueMiniProgram/src/store/auth.ts
@@ -8,10 +8,26 @@
profile: MiniUserProfile | null
}
+export interface MiniAuthUiState {
+ loginPromptVisible: boolean
+ needPhoneAuthorize: boolean
+ authPromptMessage: string
+}
+
+type MiniAuthStoreState = MiniAuthState & MiniAuthUiState
+
function createInitialState(): MiniAuthState {
return {
token: '',
profile: null,
+ }
+}
+
+function createInitialUiState(): MiniAuthUiState {
+ return {
+ loginPromptVisible: false,
+ needPhoneAuthorize: false,
+ authPromptMessage: '',
}
}
@@ -38,7 +54,7 @@
uni.setStorageSync(MINI_AUTH_STORAGE_KEY, state)
}
-function patchActiveStore(state: MiniAuthState) {
+function patchActiveStore(state: Partial<MiniAuthStoreState>) {
const pinia = getActivePinia()
if (!pinia) {
return
@@ -50,7 +66,10 @@
export function clearMiniAuthSession() {
const state = createInitialState()
uni.removeStorageSync(MINI_AUTH_STORAGE_KEY)
- patchActiveStore(state)
+ patchActiveStore({
+ ...state,
+ ...createInitialUiState(),
+ })
}
export function updateMiniAuthProfile(profile: MiniUserProfile) {
@@ -62,8 +81,32 @@
patchActiveStore(state)
}
+export function showMiniLoginPrompt(message = '') {
+ patchActiveStore({
+ loginPromptVisible: true,
+ authPromptMessage: message,
+ })
+}
+
+export function hideMiniLoginPrompt() {
+ patchActiveStore({
+ loginPromptVisible: false,
+ authPromptMessage: '',
+ needPhoneAuthorize: false,
+ })
+}
+
+export function setMiniPhoneAuthorizeRequired(required: boolean) {
+ patchActiveStore({
+ needPhoneAuthorize: required,
+ })
+}
+
export const useMiniAuthStore = defineStore('miniAuth', {
- state: (): MiniAuthState => createInitialState(),
+ state: (): MiniAuthStoreState => ({
+ ...createInitialState(),
+ ...createInitialUiState(),
+ }),
getters: {
isLoggedIn: state => Boolean(state.token),
},
@@ -71,6 +114,9 @@
setSession(payload: MiniAuthState) {
this.token = payload.token
this.profile = payload.profile
+ this.loginPromptVisible = false
+ this.needPhoneAuthorize = false
+ this.authPromptMessage = ''
writePersistedAuthState({
token: payload.token,
profile: payload.profile,
@@ -86,6 +132,9 @@
clearSession() {
this.token = ''
this.profile = null
+ this.loginPromptVisible = false
+ this.needPhoneAuthorize = false
+ this.authPromptMessage = ''
uni.removeStorageSync(MINI_AUTH_STORAGE_KEY)
},
restoreSession() {
@@ -94,5 +143,17 @@
this.profile = state.profile
return state
},
+ showLoginPrompt(message = '') {
+ this.loginPromptVisible = true
+ this.authPromptMessage = message
+ },
+ hideLoginPrompt() {
+ this.loginPromptVisible = false
+ this.needPhoneAuthorize = false
+ this.authPromptMessage = ''
+ },
+ setNeedPhoneAuthorize(required: boolean) {
+ this.needPhoneAuthorize = required
+ },
},
})
diff --git a/yuyueMiniProgram/src/types/auth.ts b/yuyueMiniProgram/src/types/auth.ts
index 85847e0..0396ac9 100644
--- a/yuyueMiniProgram/src/types/auth.ts
+++ b/yuyueMiniProgram/src/types/auth.ts
@@ -43,6 +43,10 @@
avatarUrl?: string | null
}
+export function normalizeProfileDisplayName(value?: string | null) {
+ return (value || '').trim()
+}
+
export function normalizeLoginProfile(data: MiniLoginResponse): MiniUserProfile {
return {
mpUserId: data.mpUserId,
@@ -51,7 +55,7 @@
deptName: data.deptName ?? null,
deptLeaderFlag: Boolean(data.deptLeader),
avatarUrl: data.avatarUrl ?? null,
- displayName: data.displayName,
+ displayName: normalizeProfileDisplayName(data.displayName),
mobile: null,
gender: null,
companyName: data.companyName ?? null,
@@ -66,7 +70,7 @@
deptName: data.deptName ?? null,
deptLeaderFlag: Boolean(data.deptLeaderFlag),
avatarUrl: data.avatarUrl ?? null,
- displayName: data.nickName,
+ displayName: normalizeProfileDisplayName(data.nickName),
mobile: data.mobile ?? null,
gender: data.gender ?? null,
companyName: data.companyName ?? null,
diff --git a/yuyueMiniProgram/src/utils/mini-login.ts b/yuyueMiniProgram/src/utils/mini-login.ts
new file mode 100644
index 0000000..bf01296
--- /dev/null
+++ b/yuyueMiniProgram/src/utils/mini-login.ts
@@ -0,0 +1,75 @@
+import type { ApiError } from '@/api/core/handlers'
+import { fetchMiniMe, loginByWx } from '@/api/auth'
+import { normalizeLoginProfile, normalizeMeProfile } from '@/types/auth'
+import { useMiniAuthStore } from '@/store/auth'
+
+export const EMPLOYEE_SUBSCRIBE_TEMPLATE_IDS = [
+ 'BX49OBHvRcoYiCw0ZLqx04BiWQ9KaEQwuVth_Lh_M2A',
+ 'GC1S3T2qHCbz8ow130u7elRczuqW6Z8q54mKRCYE-xo',
+]
+
+export const MINI_PHONE_AUTH_REQUIRED = 10008
+
+export function getApiErrorCode(error: unknown) {
+ return typeof error === 'object' && error != null && 'code' in error
+ ? Number((error as ApiError).code)
+ : NaN
+}
+
+export async function getWxLoginCode() {
+ // #ifdef MP-WEIXIN
+ return await new Promise<string>((resolve, reject) => {
+ uni.login({
+ provider: 'weixin',
+ success: (res) => {
+ if (res.code) {
+ resolve(res.code)
+ return
+ }
+ reject(new Error('获取微信登录凭证失败'))
+ },
+ fail: () => reject(new Error('获取微信登录凭证失败')),
+ })
+ })
+ // #endif
+ // #ifndef MP-WEIXIN
+ throw new Error('当前环境暂不支持微信授权登录')
+ // #endif
+}
+
+export async function requestEmployeeSubscribeAuthorization(userType?: string | null) {
+ if (userType !== 'EMPLOYEE') {
+ return
+ }
+ // #ifdef MP-WEIXIN
+ try {
+ await new Promise<void>((resolve) => {
+ uni.requestSubscribeMessage({
+ tmplIds: EMPLOYEE_SUBSCRIBE_TEMPLATE_IDS,
+ complete: () => resolve(),
+ })
+ })
+ }
+ catch (error) {
+ console.warn('request employee subscribe message failed', error)
+ }
+ // #endif
+}
+
+export async function finishMiniLogin(loginData: Awaited<ReturnType<typeof loginByWx>>) {
+ const authStore = useMiniAuthStore()
+ authStore.setSession({
+ token: loginData.token,
+ profile: normalizeLoginProfile(loginData),
+ })
+
+ try {
+ const profile = await fetchMiniMe(loginData.token)
+ authStore.setProfile(normalizeMeProfile(profile))
+ }
+ catch (error) {
+ console.warn('load mini profile failed after login', error)
+ }
+
+ await requestEmployeeSubscribeAuthorization(authStore.profile?.userType)
+}
--
Gitblit v1.7.1