| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- <script setup lang="ts">
- /**
- * 作用域选择页(views/org/scope-select.vue;守卫链第④步的落点,meta.scopeRequired=false)。
- *
- * 职责:登录态有效但 scope 未就绪时,由守卫重定向到此页;
- * 样例阶段仅做"机构就绪"占位交互(真实实现:调 org 域接口拉机构/校区列表联动选择,
- * 属 org 域开发范围,本样例不实现业务请求——页面结构 + store 写入口已示范)。
- *
- * 典型使用(由路由守卫自动进入,页面不主动跳转):
- *
- * scope.set({ institutionId, campusId }) → scope.ready = true → 守卫放行后续路由
- */
- import { useLogin } from '@/store/login';
- import { useScope } from '@/store/scope';
- const scope = useScope();
- const login = useLogin();
- /** 选择中的机构 id(真实实现替换为接口拉取的机构列表选项) */
- const institutionId = ref(0);
- /**
- * 确认选择(handle 前缀:用户触发提交类)。
- *
- * 入参:无(读 institutionId 当前值;campusId 样例固定 0 = 机构级)。
- *
- * 出参:
- * - 无返回值;成功后路由回退到原目标(此处简化为跳机构列表)。
- * 异常场景:
- * - institutionId 未选(=0):scope.set 内部拒绝并 console.error(store 层 fail-fast)。
- */
- function handleConfirm(): void {
- if (!institutionId.value) return;
- scope.set({ institutionId: institutionId.value, campusId: 0 });
- window.location.href = '/org/institutions';
- }
- /** 登出入口(页面右上角;调 login store 统一登出流程) */
- async function handleLogout(): Promise<void> {
- await login.doLogout();
- window.location.href = '/login';
- }
- </script>
- <template>
- <div class="scope-page">
- <el-card class="scope-card">
- <template #header>
- <div class="scope-header">
- <span class="scope-title">选择机构</span>
- <el-button link type="primary" @click="handleLogout">退出登录</el-button>
- </div>
- </template>
- <el-form label-width="72px">
- <el-form-item label="机构">
- <el-select v-model="institutionId" placeholder="请选择机构" style="width: 320px">
- <!-- 样例占位选项;org 域开发时替换为接口数据 -->
- <el-option :value="1" label="示例机构 A" />
- <el-option :value="2" label="示例机构 B" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" :disabled="!institutionId" @click="handleConfirm">进入</el-button>
- </el-form-item>
- </el-form>
- </el-card>
- </div>
- </template>
- <style scoped>
- .scope-page {
- min-height: 100vh;
- display: flex;
- align-items: center;
- justify-content: center;
- background: var(--app-bg-page);
- }
- .scope-card {
- width: 480px;
- }
- .scope-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .scope-title {
- font-size: var(--app-font-lg);
- font-weight: 600;
- color: var(--app-text-primary);
- }
- </style>
|