9f39a822f7
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
138 lines
5.6 KiB
Vue
138 lines
5.6 KiB
Vue
<template>
|
|
<router-view />
|
|
<van-tabbar route v-if="!hide_bottom_tab && user.enabled && user.is_registered && current_role && user.real_name" :before-change="tab_change_check">
|
|
<van-tabbar-item name="首页" replace :to="home_tab_path" icon="home-o">首页</van-tabbar-item>
|
|
<template v-if="is_student">
|
|
<van-tabbar-item name="排课" replace to="/clazz" icon="calendar-o">排课</van-tabbar-item>
|
|
<van-tabbar-item name="打卡" replace to="/daka" icon="completed-o">打卡</van-tabbar-item>
|
|
</template>
|
|
<template v-if="is_teacher || is_supervisor">
|
|
<van-tabbar-item name="排课" replace to="/clazz" icon="calendar-o">排课</van-tabbar-item>
|
|
<van-tabbar-item name="教学资源库" replace to="/course/summary" icon="music-o">教学资源库</van-tabbar-item>
|
|
<van-tabbar-item name="打卡" replace to="/daka" icon="completed-o">打卡</van-tabbar-item>
|
|
</template>
|
|
<template v-if="is_admin">
|
|
<van-tabbar-item name="教师管理" replace to="/admin/teachers" icon="manager-o">教师管理</van-tabbar-item>
|
|
<van-tabbar-item name="课程体系类型" replace to="/admin/course-category" icon="music-o">课程体系类型</van-tabbar-item>
|
|
</template>
|
|
<template v-if="is_tester">
|
|
</template>
|
|
<van-tabbar-item name="我的" replace :to="`/${current_role}/profile`" :badge="user.unread_tongzhi_count" :badge-props="badge_props" icon="user-o">我的</van-tabbar-item>
|
|
</van-tabbar>
|
|
<van-tabbar route v-else-if="is_guest" :before-change="tab_change_check">
|
|
<van-tabbar-item name="首页" replace to="/" icon="home-o">首页</van-tabbar-item>
|
|
<van-tabbar-item name="我的" replace to="/guest/profile" icon="user-o">我的</van-tabbar-item>
|
|
</van-tabbar>
|
|
<van-overlay :show="!!loading" :style="{zIndex: 3000}">
|
|
<div class="loading">
|
|
<van-loading type="spinner" color="#ffffff" />
|
|
</div>
|
|
</van-overlay>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import {computed, defineComponent, onMounted, watch} from 'vue';
|
|
import {Tabbar, TabbarItem, Overlay, Loading, BadgeProps, showConfirmDialog} from 'vant';
|
|
import useUser from "~/store/user";
|
|
import {isIOS, WebViewEntryUrl} from '~/utils';
|
|
import {HtyBaseRoles, HtyStates, HtySuperRoles} from "~/types";
|
|
import useLoading from "~/store/loading";
|
|
import usePool from "~/store/pool";
|
|
|
|
export default defineComponent({
|
|
name: "App",
|
|
components: {
|
|
[Tabbar.name!]: Tabbar,
|
|
[TabbarItem.name!]: TabbarItem,
|
|
[Overlay.name!]: Overlay,
|
|
[Loading.name!]: Loading
|
|
},
|
|
setup() {
|
|
let {store} = useUser();
|
|
const { loading } = useLoading();
|
|
const {getKey} = usePool()
|
|
if (isIOS()) {
|
|
console.log('href...', window.location.href)
|
|
window.localStorage.setItem(WebViewEntryUrl, window.location.href);
|
|
}
|
|
|
|
const user = computed(() => store.current)
|
|
const is_student = computed(() => store.currentRole === HtyBaseRoles.STUDENT);
|
|
const is_teacher = computed(() => store.currentRole === HtyBaseRoles.TEACHER);
|
|
const is_admin = computed(() => store.currentRole === HtySuperRoles.ADMIN)
|
|
const is_tester = computed(() => store.currentRole === HtySuperRoles.TESTER);
|
|
const is_supervisor = computed(() => store.currentRole === HtySuperRoles.SUPERVISOR);
|
|
const current_role = computed(() => store.currentRole?.toLowerCase())
|
|
const is_guest = computed(() => {
|
|
return !user.value.is_registered || !user.value.enabled;
|
|
})
|
|
|
|
const badge_props: Partial<BadgeProps> = { showZero: false, max: 99 }
|
|
|
|
onMounted(() => {
|
|
console.debug('[App.vue] deploy_ver=20260503');
|
|
let vconsole = document.getElementById("__vconsole");
|
|
if (vconsole) {
|
|
vconsole.hidden = true;
|
|
}
|
|
})
|
|
|
|
watch(() => store.current, () => {
|
|
updateVConsoleVisibility();
|
|
}, { deep: true })
|
|
|
|
function updateVConsoleVisibility() {
|
|
// vConsole 仅对 sudoer(有 SYS_CAN_SUDO tag)用户可见
|
|
let showVConsole = store.current.tags?.some(t => t.tag_name === 'SYS_CAN_SUDO') ?? false;
|
|
console.log('vconsole visibility (sudoer only)...', { showVConsole, tags: store.current.tags });
|
|
let vconsole = document.getElementById("__vconsole");
|
|
if (vconsole) {
|
|
vconsole.hidden = !showVConsole;
|
|
}
|
|
}
|
|
|
|
// 同时监听 tags 的独立变化(getTags 异步加载完成后触发)
|
|
watch(() => store.current.tags, (val) => {
|
|
if (val && val.length > 0) {
|
|
updateVConsoleVisibility();
|
|
}
|
|
})
|
|
|
|
const tab_change_check = (name: number | string) => {
|
|
console.log('tab change...', name, is_guest.value, is_teacher.value, store.currentRole)
|
|
if (store.editing) {
|
|
return showConfirmDialog({
|
|
title: "注意!",
|
|
message: `您正在编辑的内容将会丢失,确认跳转到【${name}】页面?`
|
|
})
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const hide_bottom_tab = computed(() => getKey("hide_bottom_tab"))
|
|
|
|
const home_tab_path = computed(() => {
|
|
const role = store.currentRole
|
|
if (!role) return '/'
|
|
if (role === HtyBaseRoles.STUDENT) return '/student/home'
|
|
if (role === HtyBaseRoles.TEACHER) return '/teacher/home'
|
|
if (role === HtySuperRoles.ADMIN) return '/admin/teachers'
|
|
if (role === HtySuperRoles.TESTER) return '/tester'
|
|
if (role === HtySuperRoles.SUPERVISOR) return '/teacher/home'
|
|
return '/'
|
|
})
|
|
|
|
return {user, is_student, is_teacher, is_supervisor, is_admin, is_tester, is_guest, current_role, loading, badge_props, tab_change_check, hide_bottom_tab, home_tab_path}
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.loading {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100%;
|
|
}
|
|
</style>
|