修复
This commit is contained in:
1 parent
d16dbc69b4
commit
fc8c3ee3ad
2 files changed
+370
-113
No files matched your search
+98
-95
@@ -56,16 +56,11 @@
|
||||
</view>
|
||||
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- 游客冷启动授权引导:手机号授权后签发游客令牌,免登录模块数据才能保存 -->
|
||||
<!-- 游客无感授权:无弹窗,全屏透明按钮——首次点按即拉起微信原生手机号确认层;
|
||||
后端按手机号自动判定:绑定过租户→直接登录,否则→游客令牌 -->
|
||||
<view v-if="guestAuthVisible" class="guest-auth-mask">
|
||||
<view class="guest-auth-card">
|
||||
<text class="guest-auth-title">开启免登录保存</text>
|
||||
<text class="guest-auth-desc">授权手机号后,记事本、日程提醒、密码库等免登录功能的数据即可保存;正式登录后会自动并入账号,不会丢失。</text>
|
||||
<button class="guest-auth-btn" open-type="getPhoneNumber" :disabled="guestAuthLoading" @getphonenumber="onGuestPhone">
|
||||
{{ guestAuthLoading ? '授权中…' : '立即授权' }}
|
||||
</button>
|
||||
<text class="guest-auth-skip" @tap="skipGuestAuth">暂不授权(使用将无法保存数据)</text>
|
||||
</view>
|
||||
<button class="guest-auth-full" open-type="getPhoneNumber" :disabled="guestAuthLoading" @getphonenumber="onGuestPhone" />
|
||||
<text class="guest-auth-later" @tap="skipGuestAuth">暂不,先浏览</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
@@ -77,13 +72,13 @@ import { mpHeadPad } from '@/utils/mpHead.js'
|
||||
|
||||
const headPad = mpHeadPad()
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { isLoggedIn, getTenants, getTid, setAuthTokens, setTid, setTenantName, getUser, setUser } from '@/utils/auth.js'
|
||||
import { isLoggedIn, getTenants, getTid, setAuthTokens, setTenants, setTid, setTenantName, getUser, setUser } from '@/utils/auth.js'
|
||||
import { switchTenant } from '@/api/auth.js'
|
||||
import { fetchHome, fetchPublicModules, fetchPublicMenus } from '@/api/workspace.js'
|
||||
import { openMenu } from '@/utils/nav.js'
|
||||
import { getSubsystemByModule, goSubsystem } from '@/config/subsystems.js'
|
||||
import { getGuestToken, setGuestToken } from '@/utils/guest.js'
|
||||
import { guestMiniLogin } from '@/api/guest.js'
|
||||
import { getGuestToken, setGuestToken, clearGuestToken } from '@/utils/guest.js'
|
||||
import { guestMiniLogin, guestMerge } from '@/api/guest.js'
|
||||
|
||||
/* ==================== 游客手机号授权(免登录保存) ==================== */
|
||||
|
||||
@@ -137,6 +132,12 @@ async function onGuestPhone(e) {
|
||||
appid = ''
|
||||
}
|
||||
const res = await guestMiniLogin({ code, phoneCode: detail.code, appid })
|
||||
// 已注册手机号:后端已签发正式令牌,直接按登录处理(不再当作游客)
|
||||
if (res && res.type === 'user') {
|
||||
guestAuthVisible.value = false
|
||||
await completeUserLogin(res)
|
||||
return
|
||||
}
|
||||
if (!res || !res.token) throw new Error('未返回游客令牌')
|
||||
setGuestToken(res.token)
|
||||
guestAuthVisible.value = false
|
||||
@@ -149,11 +150,74 @@ async function onGuestPhone(e) {
|
||||
}
|
||||
}
|
||||
|
||||
/** 手机号识别为正式账号:落登录态;多企业先选企业再进入 */
|
||||
async function completeUserLogin(res) {
|
||||
const list = Array.isArray(res.tenants) ? res.tenants : []
|
||||
setAuthTokens(res.tokens || {})
|
||||
if (res.need_choose_tenant && list.length > 1) {
|
||||
askChooseTenant(list)
|
||||
return
|
||||
}
|
||||
const t0 = list[0] || {}
|
||||
setTenants(list)
|
||||
if (t0.tid) {
|
||||
setTid(t0.tid)
|
||||
setTenantName(t0.tenant_name || '')
|
||||
}
|
||||
// 先游客后转正:企业落定后把游客数据移植到正式账号
|
||||
await mergeGuestIfAny()
|
||||
await load(true)
|
||||
uni.showToast({ title: '已登录,欢迎回来', icon: 'none' })
|
||||
}
|
||||
|
||||
/** 待选状态下必须选一个企业才能继续,关闭选择器后再次拉起 */
|
||||
function askChooseTenant(list) {
|
||||
uni.showActionSheet({
|
||||
itemList: list.map((t) => t.tenant_name || `企业${t.tid}`),
|
||||
success: async ({ tapIndex }) => {
|
||||
const tenant = list[tapIndex]
|
||||
if (!tenant) return
|
||||
uni.showLoading({ title: '登录中...', mask: true })
|
||||
try {
|
||||
const sw = await switchTenant({ tid: tenant.tid })
|
||||
if (!sw || !sw.tokens) throw new Error((sw && sw.msg) || '进入企业失败')
|
||||
setAuthTokens(sw.tokens)
|
||||
setTenants(list)
|
||||
setTid(tenant.tid)
|
||||
setTenantName(tenant.tenant_name || '')
|
||||
// 先游客后转正:选定企业后移植游客数据
|
||||
await mergeGuestIfAny()
|
||||
await load(true)
|
||||
uni.showToast({ title: '已登录,欢迎回来', icon: 'none' })
|
||||
} catch (e) {
|
||||
uni.showToast({ title: (e && e.message) || '进入失败,请重试', icon: 'none' })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: '请选择要进入的企业', icon: 'none' })
|
||||
setTimeout(() => askChooseTenant(list), 800)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function skipGuestAuth() {
|
||||
guestAuthDismissed.value = true
|
||||
guestAuthVisible.value = false
|
||||
}
|
||||
|
||||
/** 存有游客令牌时静默移植数据(登录链路已带正式令牌);失败保留令牌下次登录重试 */
|
||||
async function mergeGuestIfAny() {
|
||||
if (!getGuestToken()) return
|
||||
try {
|
||||
await guestMerge()
|
||||
clearGuestToken()
|
||||
} catch (e) {
|
||||
console.warn('[nav] guest merge failed:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/** 模块 code → 子系统 slug → 进入其概览页;未注册返回 false */
|
||||
function goSubsystemByModule(code) {
|
||||
const sub = getSubsystemByModule(code)
|
||||
@@ -273,7 +337,6 @@ async function load(force = false) {
|
||||
const data = await fetchHome(force)
|
||||
user.value = data.user || {}
|
||||
tenants.value = getTenants()
|
||||
currentTid.value = getTid()
|
||||
modules.value = Array.isArray(data.modules) ? data.modules : []
|
||||
menus.value = Array.isArray(data.menus) ? data.menus : []
|
||||
loadError.value = ''
|
||||
@@ -356,43 +419,6 @@ function goLogin(name = '') {
|
||||
uni.navigateTo({ url: '/pages/login/login' })
|
||||
}
|
||||
|
||||
function openTenantPicker() {
|
||||
if (tenants.value.length < 2) return
|
||||
tenantPickerVisible.value = true
|
||||
}
|
||||
|
||||
function closeTenantPicker() {
|
||||
if (!switchingTenant.value) tenantPickerVisible.value = false
|
||||
}
|
||||
|
||||
async function changeTenant(item) {
|
||||
const tid = Number(item && item.tid)
|
||||
if (!tid || tid === currentTid.value || switchingTenant.value) {
|
||||
tenantPickerVisible.value = false
|
||||
return
|
||||
}
|
||||
switchingTenant.value = true
|
||||
uni.showLoading({ title: '正在切换...', mask: true })
|
||||
try {
|
||||
const result = await switchTenant({ tid })
|
||||
if (!result || !result.tokens) throw new Error((result && result.msg) || '切换公司失败')
|
||||
setAuthTokens(result.tokens)
|
||||
setTid(tid)
|
||||
const tenantName = item.tenant_name || `企业${tid}`
|
||||
setTenantName(tenantName)
|
||||
user.value = Object.assign({}, user.value, { tenant: tenantName, tid })
|
||||
currentTid.value = tid
|
||||
tenantPickerVisible.value = false
|
||||
await load(true)
|
||||
uni.showToast({ title: '已切换公司', icon: 'success' })
|
||||
} catch (err) {
|
||||
uni.showToast({ title: (err && err.message) || '切换公司失败', icon: 'none' })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
switchingTenant.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================== 生命周期 ==================== */
|
||||
|
||||
onMounted(() => {
|
||||
@@ -627,7 +653,7 @@ onShow(() => {
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
/* ============ 游客授权引导弹窗 ============ */
|
||||
/* ============ 游客无感授权层(无弹窗,首次点按即拉起微信原生确认) ============ */
|
||||
.guest-auth-mask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
@@ -635,58 +661,35 @@ onShow(() => {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 99;
|
||||
background: rgba(15, 23, 42, 0.55);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 56rpx;
|
||||
}
|
||||
|
||||
.guest-auth-card {
|
||||
.guest-auth-full {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
max-width: 560rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 28rpx;
|
||||
padding: 44rpx 36rpx 32rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
box-shadow: 0 24rpx 64rpx rgba(15, 23, 42, 0.22);
|
||||
}
|
||||
|
||||
.guest-auth-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: #17345f;
|
||||
}
|
||||
|
||||
.guest-auth-desc {
|
||||
font-size: 24rpx;
|
||||
line-height: 1.65;
|
||||
color: #64748b;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.guest-auth-btn {
|
||||
width: 100%;
|
||||
margin-top: 8rpx;
|
||||
background: linear-gradient(145deg, #69a5ff, #3478f6);
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
border-radius: 44rpx;
|
||||
line-height: 2.6;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
opacity: 0;
|
||||
|
||||
&[disabled] {
|
||||
opacity: 0.6;
|
||||
&::after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.guest-auth-skip {
|
||||
font-size: 22rpx;
|
||||
.guest-auth-later {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 64rpx;
|
||||
z-index: 100;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #94a3b8;
|
||||
padding: 8rpx 16rpx;
|
||||
padding: 16rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user