- index.vue 来源切换「系统部门|自定义部门」,SYSTEM 原 DOM 原样 v-if 包装零逻辑改动,学校上下文共用 - CustomDeptPanel/CustomDeptCard:分类增删改排序(非空禁删)、部门增改移启停软删(风险二次确认) - CustomMemberModal:候选走 CandidateUsers(服务端同口径排除学生组),搜索+勾选+批量添加 - apiDefinitions/globals.d.ts 补 17 个 /api 契约(key 与后端 operationId 严格一致) - 遗留:npm run api:gen 待后端可起环境补跑校验
This commit is contained in:
@@ -17,28 +17,40 @@
|
||||
<Select v-if="multiSchool" v-model="currentSchoolId" size="small" class="ml-8 school-select">
|
||||
<Option v-for="s in schoolOptions" :key="s.id" :value="s.id">{{ s.name }}</Option>
|
||||
</Select>
|
||||
<span class="inc-ctrl ml-auto" title="打开后列出该校下所有层级的部门" @click="toggleInclude">
|
||||
<!-- 来源切换:只切右侧管理视图,学校上下文共用,不改底层组织树 -->
|
||||
<div class="source-tabs ml-auto">
|
||||
<span class="source-tab" :class="{ 'is-active': source === 'SYSTEM' }"
|
||||
@click="source = 'SYSTEM'">系统部门 SYSTEM</span>
|
||||
<span class="source-tab" :class="{ 'is-active': source === 'CUSTOM' }"
|
||||
@click="source = 'CUSTOM'">自定义部门 CUSTOM</span>
|
||||
</div>
|
||||
<span v-if="source === 'SYSTEM'" class="inc-ctrl" title="打开后列出该校下所有层级的部门"
|
||||
@click="toggleInclude">
|
||||
<span class="inc-label">包含子组</span>
|
||||
<i class="sw-mini" :class="{ 'is-on': includeOn }"></i>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Alert show-icon type="success" class="usage-note">
|
||||
<b>设置说明:</b>
|
||||
停用只影响「选」(新建事项 / 流程绑定时选不到),不影响「看」(已有事项展示)与「办」(在途流程照常解析);
|
||||
关闭「包含子组」只展示一级部门,打开后连同下级部门(如办公室下的校办 / 宣传 / 财务 / 党建)一并列出。
|
||||
</Alert>
|
||||
<template v-if="source === 'SYSTEM'">
|
||||
<Alert show-icon type="success" class="usage-note">
|
||||
<b>设置说明:</b>
|
||||
停用只影响「选」(新建事项 / 流程绑定时选不到),不影响「看」(已有事项展示)与「办」(在途流程照常解析);
|
||||
关闭「包含子组」只展示一级部门,打开后连同下级部门(如办公室下的校办 / 宣传 / 财务 / 党建)一并列出。
|
||||
</Alert>
|
||||
|
||||
<Alert v-if="!currentSchoolName" show-icon type="info" class="state-tip">
|
||||
{{ showTree ? '请在左侧选择学校节点' : '当前账号没有可管理的学校' }}
|
||||
</Alert>
|
||||
<Alert v-else-if="!deptList.length" show-icon type="info" class="state-tip">
|
||||
该校教师组下暂无部门。部门 = 教师组的直接子节点,可前往「组,用户管理」建组。
|
||||
</Alert>
|
||||
<div v-else class="dept-grid">
|
||||
<DeptCard v-for="d in deptList" :key="d.id" :dept="d" :include-children="includeOn"
|
||||
@toggle="onToggle" />
|
||||
</div>
|
||||
<Alert v-if="!currentSchoolName" show-icon type="info" class="state-tip">
|
||||
{{ showTree ? '请在左侧选择学校节点' : '当前账号没有可管理的学校' }}
|
||||
</Alert>
|
||||
<Alert v-else-if="!deptList.length" show-icon type="info" class="state-tip">
|
||||
该校教师组下暂无部门。部门 = 教师组的直接子节点,可前往「组,用户管理」建组。
|
||||
</Alert>
|
||||
<div v-else class="dept-grid">
|
||||
<DeptCard v-for="d in deptList" :key="d.id" :dept="d" :include-children="includeOn"
|
||||
@toggle="onToggle" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<CustomDeptPanel v-else :school-id="currentSchoolId" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -51,6 +63,7 @@ import Apis from "@/api";
|
||||
import GroupTreeSearchPanel from "@/components/GroupTreeSearchPanel.vue";
|
||||
import MyConfirm from "@/components/MyConfirm";
|
||||
import DeptCard from "./DeptCard.vue";
|
||||
import CustomDeptPanel from "./CustomDeptPanel.vue";
|
||||
import { Message } from "view-ui-plus";
|
||||
import { useDefaultStore } from "@/store";
|
||||
import { UserRoleEnum } from "@/types";
|
||||
@@ -73,6 +86,8 @@ const roleReady = computed(() => store.roleLoaded);
|
||||
|
||||
const refTreePanel = ref<InstanceType<typeof GroupTreeSearchPanel>>();
|
||||
const selectedNode = ref<any>({});
|
||||
/** 部门来源页签:SYSTEM=原组织树视图(行为零改动);CUSTOM=学校自建分类/部门 */
|
||||
const source = ref<"SYSTEM" | "CUSTOM">("SYSTEM");
|
||||
/** 全量组树:右侧部门数据一律从这里按 id 回查真实 children */
|
||||
const fullTree = ref<any[]>([]);
|
||||
/** 当前学校:超管由树选中,学校管理员默认取可管理学校 */
|
||||
@@ -167,6 +182,8 @@ async function toggleInclude() {
|
||||
school.includeChildren = next ? 1 : 0;
|
||||
Message.success(next ? "已包含下级部门" : "仅显示一级部门");
|
||||
} catch (e: any) {
|
||||
// 全局 alova 拦截器(alova-iview 的 onBizError/onHttpError)已统一 Message.error,此处只记日志避免二次弹窗;
|
||||
// 本地字段只在写成功后改,失败即自然停在原值,无需回滚
|
||||
console.warn(e?.message || "设置包含子组失败");
|
||||
}
|
||||
}
|
||||
@@ -283,6 +300,34 @@ async function loadSchoolScope() {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
/* 来源切换:同页两个视图,不新增菜单项 */
|
||||
.source-tabs {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
padding: 2px;
|
||||
background: #f2f4f9;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.source-tab {
|
||||
padding: 3px 10px;
|
||||
font-size: 12.5px;
|
||||
line-height: 18px;
|
||||
border-radius: 6px;
|
||||
color: var(--text-2, #5a6478);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.source-tab.is-active {
|
||||
background: var(--panel, #fff);
|
||||
color: var(--brand, #577afb);
|
||||
font-weight: 600;
|
||||
box-shadow: 0 1px 2px rgba(30, 38, 53, .08);
|
||||
}
|
||||
|
||||
/* 右侧卡片面板撑满剩余高度(与其他页面一致),内容超出时在面板内滚动 */
|
||||
/* 面板内顶部说明条的间距(外观完全交给 iView Alert 自身,不覆写配色) */
|
||||
.usage-note {
|
||||
|
||||
Reference in New Issue
Block a user