完善项目权限前置依赖保存校验

- 以接口权限定义中的 prerequisite_permissions 作为前置依赖单一事实源,生成运行时前置权限映射\n- 保存项目角色权限前预检缺失前置权限与受影响下游权限,未确认时返回 409 调整详情\n- 确认保存时自动合并补齐前置权限与取消下游权限,并提供有效权限矩阵读取接口\n- 前端角色权限编辑改为保存时执行依赖校验,弹窗展示需补充前置权限和受影响下游权限\n- 新增编辑权限取消按钮,清理权限选择即时确认弹窗残留\n- 补充后端接口测试、前端权限编辑测试与优化设计文档
This commit is contained in:
Cheng Zhou
2026-06-04 16:29:44 +08:00
parent 02f2c6660b
commit d6452e3f9d
13 changed files with 1089 additions and 80 deletions
@@ -9,7 +9,7 @@
<div class="template-grid">
<div
v-for="template in templates"
v-for="template in sortedTemplates"
:key="template.id"
class="template-card"
:class="{ inactive: template.category && !isRoleActive(template.category) }"
@@ -61,12 +61,13 @@
</template>
<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import { computed, ref, onMounted, watch } from "vue";
import { ElMessage } from "element-plus";
import {
fetchPermissionTemplates,
type PermissionTemplate,
} from "@/api/projectPermissions";
import { useRoleTemplateMeta } from "@/composables/useRoleTemplateMeta";
const props = defineProps<{
studyId: string;
@@ -80,6 +81,16 @@ const emit = defineEmits<{
}>();
const templates = ref<PermissionTemplate[]>([]);
const { compareRolesByTemplateOrder } = useRoleTemplateMeta();
const sortedTemplates = computed(() =>
[...templates.value].sort((a, b) => {
if (a.category && b.category) return compareRolesByTemplateOrder(a.category, b.category);
if (a.category) return -1;
if (b.category) return 1;
return 0;
})
);
const roleIcon = (category: string | null) => {
const icons: Record<string, string> = {