scope-select.vue 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <script setup lang="ts">
  2. /**
  3. * 作用域选择页(views/org/scope-select.vue;守卫链第④步的落点,meta.scopeRequired=false)。
  4. *
  5. * 职责:登录态有效但 scope 未就绪时,由守卫重定向到此页;
  6. * 样例阶段仅做"机构就绪"占位交互(真实实现:调 org 域接口拉机构/校区列表联动选择,
  7. * 属 org 域开发范围,本样例不实现业务请求——页面结构 + store 写入口已示范)。
  8. *
  9. * 典型使用(由路由守卫自动进入,页面不主动跳转):
  10. *
  11. * scope.set({ institutionId, campusId }) → scope.ready = true → 守卫放行后续路由
  12. */
  13. import { useLogin } from '@/store/login';
  14. import { useScope } from '@/store/scope';
  15. const scope = useScope();
  16. const login = useLogin();
  17. /** 选择中的机构 id(真实实现替换为接口拉取的机构列表选项) */
  18. const institutionId = ref(0);
  19. /**
  20. * 确认选择(handle 前缀:用户触发提交类)。
  21. *
  22. * 入参:无(读 institutionId 当前值;campusId 样例固定 0 = 机构级)。
  23. *
  24. * 出参:
  25. * - 无返回值;成功后路由回退到原目标(此处简化为跳机构列表)。
  26. * 异常场景:
  27. * - institutionId 未选(=0):scope.set 内部拒绝并 console.error(store 层 fail-fast)。
  28. */
  29. function handleConfirm(): void {
  30. if (!institutionId.value) return;
  31. scope.set({ institutionId: institutionId.value, campusId: 0 });
  32. window.location.href = '/org/institutions';
  33. }
  34. /** 登出入口(页面右上角;调 login store 统一登出流程) */
  35. async function handleLogout(): Promise<void> {
  36. await login.doLogout();
  37. window.location.href = '/login';
  38. }
  39. </script>
  40. <template>
  41. <div class="scope-page">
  42. <el-card class="scope-card">
  43. <template #header>
  44. <div class="scope-header">
  45. <span class="scope-title">选择机构</span>
  46. <el-button link type="primary" @click="handleLogout">退出登录</el-button>
  47. </div>
  48. </template>
  49. <el-form label-width="72px">
  50. <el-form-item label="机构">
  51. <el-select v-model="institutionId" placeholder="请选择机构" style="width: 320px">
  52. <!-- 样例占位选项;org 域开发时替换为接口数据 -->
  53. <el-option :value="1" label="示例机构 A" />
  54. <el-option :value="2" label="示例机构 B" />
  55. </el-select>
  56. </el-form-item>
  57. <el-form-item>
  58. <el-button type="primary" :disabled="!institutionId" @click="handleConfirm">进入</el-button>
  59. </el-form-item>
  60. </el-form>
  61. </el-card>
  62. </div>
  63. </template>
  64. <style scoped>
  65. .scope-page {
  66. min-height: 100vh;
  67. display: flex;
  68. align-items: center;
  69. justify-content: center;
  70. background: var(--app-bg-page);
  71. }
  72. .scope-card {
  73. width: 480px;
  74. }
  75. .scope-header {
  76. display: flex;
  77. justify-content: space-between;
  78. align-items: center;
  79. }
  80. .scope-title {
  81. font-size: var(--app-font-lg);
  82. font-weight: 600;
  83. color: var(--app-text-primary);
  84. }
  85. </style>