优化小程序登录工作空间与法律协议
This commit is contained in:
1 parent
2e2b837a20
commit
1eace4c082
6 files changed
+1084
-673
No files matched your search
+223
-13
@@ -3,10 +3,35 @@
|
||||
<!-- 顶部信息:融入页面背景,不再单独做彩色抬头 -->
|
||||
<view class="head" :style="headPad">
|
||||
<view class="head-row">
|
||||
<text class="head-title">选择子系统</text>
|
||||
<text class="head-count">{{ enabledCount }}/{{ cards.length }} 已开通</text>
|
||||
<view>
|
||||
<text class="head-title">工作空间</text>
|
||||
<text class="head-caption">选择一个应用,开始今天的工作</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tenant-switcher" :class="{ selectable: tenants.length > 1 }" @tap="openTenantPicker">
|
||||
<view class="tenant-mark"><FaIcon name="building" color="#3689d6" :size="17" /></view>
|
||||
<view class="tenant-current">
|
||||
<text class="tenant-label">当前公司</text>
|
||||
<text class="head-sub">{{ user.tenant || '云泽平台' }}</text>
|
||||
</view>
|
||||
<text v-if="user.account" class="tenant-account">{{ user.account }}</text>
|
||||
<FaIcon v-if="tenants.length > 1" name="chevron-right" color="#83a2be" :size="13" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="tenantPickerVisible" class="tenant-mask" @tap="closeTenantPicker">
|
||||
<view class="tenant-sheet" @tap.stop>
|
||||
<view class="sheet-head">
|
||||
<text class="sheet-title">切换公司</text>
|
||||
<text class="sheet-close" @tap="closeTenantPicker">完成</text>
|
||||
</view>
|
||||
<text class="sheet-sub">选择后将切换当前工作空间</text>
|
||||
<view v-for="item in tenants" :key="item.tid" class="tenant-option" :class="{ current: Number(item.tid) === currentTid, disabled: switchingTenant }" @tap="changeTenant(item)">
|
||||
<view class="tenant-option-icon"><FaIcon name="building" color="#398fe7" :size="16" /></view>
|
||||
<view class="tenant-option-info"><text class="tenant-option-name">{{ item.tenant_name || `企业${item.tid}` }}</text><text class="tenant-option-meta">{{ Number(item.tid) === currentTid ? '当前工作空间' : '切换到此公司' }}</text></view>
|
||||
<FaIcon v-if="Number(item.tid) === currentTid" name="circle-check" color="#398fe7" :size="18" />
|
||||
</view>
|
||||
</view>
|
||||
<text class="head-sub">{{ user.tenant || '云泽平台' }}<text v-if="user.account"> · {{ user.account }}</text></text>
|
||||
</view>
|
||||
|
||||
<view class="body">
|
||||
@@ -53,7 +78,8 @@ import { mpHeadPad } from '@/utils/mpHead.js'
|
||||
|
||||
const headPad = mpHeadPad()
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { isLoggedIn } from '@/utils/auth.js'
|
||||
import { isLoggedIn, getTenants, getTid, setAuthTokens, setTid, setTenantName } from '@/utils/auth.js'
|
||||
import { switchTenant } from '@/api/auth.js'
|
||||
import { fetchHome } from '@/api/workspace.js'
|
||||
import { openMenu } from '@/utils/nav.js'
|
||||
import { getSubsystemByModule, goSubsystem } from '@/config/subsystems.js'
|
||||
@@ -80,6 +106,10 @@ const loadError = ref('')
|
||||
const user = ref({})
|
||||
const modules = ref([])
|
||||
const menus = ref([])
|
||||
const tenants = ref([])
|
||||
const currentTid = ref(0)
|
||||
const tenantPickerVisible = ref(false)
|
||||
const switchingTenant = ref(false)
|
||||
|
||||
/** 叶子菜单(可直接跳转的功能页),已锁定的过滤掉 */
|
||||
const leafMenus = computed(() => menus.value.filter((m) => m.leaf !== false && !m.locked))
|
||||
@@ -125,6 +155,8 @@ async function load(force = false) {
|
||||
try {
|
||||
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 = ''
|
||||
@@ -159,6 +191,43 @@ function enter(card) {
|
||||
uni.showToast({ title: card.name + '暂未开放', icon: 'none' })
|
||||
}
|
||||
|
||||
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(() => {
|
||||
@@ -200,23 +269,70 @@ onShow(() => {
|
||||
}
|
||||
|
||||
.head-title {
|
||||
font-size: 42rpx;
|
||||
font-weight: 600;
|
||||
color: $color-text;
|
||||
font-size: 46rpx;
|
||||
font-weight: 700;
|
||||
color: #193d61;
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.head-count {
|
||||
font-size: 23rpx;
|
||||
color: $color-text-muted;
|
||||
.head-caption {
|
||||
display: block;
|
||||
margin-top: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: #8aa2b8;
|
||||
}
|
||||
|
||||
.tenant-switcher {
|
||||
margin-top: 28rpx;
|
||||
padding: 20rpx 22rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.92);
|
||||
border-radius: 24rpx;
|
||||
background: rgba(255, 255, 255, 0.78);
|
||||
box-shadow: 0 12rpx 32rpx rgba(81, 133, 176, 0.08);
|
||||
|
||||
&.selectable:active { background: #f4faff; }
|
||||
}
|
||||
|
||||
.tenant-mark {
|
||||
width: 68rpx;
|
||||
height: 68rpx;
|
||||
flex-shrink: 0;
|
||||
border-radius: 20rpx;
|
||||
background: #eaf5ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tenant-current {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.tenant-label {
|
||||
display: block;
|
||||
margin-bottom: 5rpx;
|
||||
font-size: 20rpx;
|
||||
color: #94aabe;
|
||||
}
|
||||
|
||||
.head-sub {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 23rpx;
|
||||
color: $color-text-muted;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #294a68;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tenant-account {
|
||||
max-width: 180rpx;
|
||||
font-size: 21rpx;
|
||||
color: #8da3b7;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@@ -231,6 +347,100 @@ onShow(() => {
|
||||
padding: 8rpx $page-padding-x 0;
|
||||
}
|
||||
|
||||
.tenant-mask {
|
||||
position: fixed;
|
||||
z-index: 99;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(18, 42, 68, 0.32);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.tenant-sheet {
|
||||
width: 100%;
|
||||
max-height: 72vh;
|
||||
overflow-y: auto;
|
||||
padding: 38rpx 32rpx calc(env(safe-area-inset-bottom, 0px) + 40rpx);
|
||||
box-sizing: border-box;
|
||||
border-radius: 36rpx 36rpx 0 0;
|
||||
background: linear-gradient(180deg, #f5faff 0%, #ffffff 24%);
|
||||
}
|
||||
|
||||
.sheet-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.sheet-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #203b56;
|
||||
}
|
||||
|
||||
.sheet-close {
|
||||
font-size: 25rpx;
|
||||
color: #398fe7;
|
||||
padding: 10rpx;
|
||||
}
|
||||
|
||||
.sheet-sub {
|
||||
display: block;
|
||||
margin: 8rpx 0 20rpx;
|
||||
font-size: 23rpx;
|
||||
color: #8aa0b4;
|
||||
}
|
||||
|
||||
.tenant-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18rpx;
|
||||
padding: 20rpx 16rpx;
|
||||
border-radius: 18rpx;
|
||||
border: 1rpx solid #edf3f8;
|
||||
margin-top: 12rpx;
|
||||
|
||||
&.current {
|
||||
background: #f2f8ff;
|
||||
border-color: #cfe5fa;
|
||||
}
|
||||
|
||||
&.disabled { opacity: 0.6; }
|
||||
}
|
||||
|
||||
.tenant-option-icon {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 18rpx;
|
||||
background: #eaf5ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tenant-option-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.tenant-option-name,
|
||||
.tenant-option-meta { display: block; }
|
||||
|
||||
.tenant-option-name {
|
||||
font-size: 27rpx;
|
||||
font-weight: 500;
|
||||
color: #294763;
|
||||
}
|
||||
|
||||
.tenant-option-meta {
|
||||
margin-top: 5rpx;
|
||||
font-size: 22rpx;
|
||||
color: #91a5b8;
|
||||
}
|
||||
|
||||
/* ============ 失败提示 ============ */
|
||||
.err-box {
|
||||
display: flex;
|
||||
|
||||
Reference in new issue
Block a user