- AppSettings.vue 应用设置页(基础/字典两 tab);修复 P86:Tabs 写 :value 而受控 prop 是 modelValue,致 ?tab=dicts 深链静默失效,改后深链实拍生效 - UserCheckModal.vue 自 notice 移植(view-ui-plus+ztree,sources 注入式数据源);public/libs 收录 jquery+ztree 本地件(index.html 引用) - api/module/admin.ts + mock/adminapi.ts + types/admin.ts;AdminListPanel/FormAdminModal 组件 - routes/menuNav/menuRoute/modulePerms 适配管理员菜单与权限位;tree-icon 图标资源
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 应用设置(`/admin/app`,T10 方案 §3/§6.1):UserBase 侧一行模块行,页内两个 tab。
|
||||
*
|
||||
* - **角色设置** = 校级表单管理员名单(`school_admin`);
|
||||
* - **字典管理** = 原 `/admin/dicts` 整页迁入(`Dicts.vue` 原样复用,守卫行随本行换到 `/admin/app`)。
|
||||
*
|
||||
* 两条口径:
|
||||
* 1. **tab 不占模块行、不进导航**(同设计器子页),所以高亮/面包屑挂本行;`?tab=dicts` 可深链,
|
||||
* 旧地址 `/admin/dicts` 由路由重定向到这里的字典 tab;
|
||||
* ——深链落在模板的 {@code :model-value} 上:view-ui-plus 的 Tabs 受控 prop 是 modelValue,
|
||||
* 写 {@code :value} 会落进 attrs 不被消费(T10 验收轮实拍证伪过一次),勿"顺手改回";
|
||||
* 2. **一行把关两个 tab 与字典 API**:能不能进来由 UserBase 的 `/admin/app` 决定,
|
||||
* 前端不做"进了页再按身份藏 tab"——藏按钮不等于授权(契约 §7 身份行)。
|
||||
*/
|
||||
import { computed } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import AdminListPanel from "@/components/admin/AdminListPanel.vue";
|
||||
import Dicts from "./Dicts.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
/** 缺省落角色设置(本页新增的主用途);只认 dicts 这一个显式值,其它 query 一律按缺省 */
|
||||
const tab = computed(() => (route.query.tab === "dicts" ? "dicts" : "roles"));
|
||||
|
||||
function change(next: string) {
|
||||
router.replace({ path: "/admin/app", query: { ...route.query, tab: next } });
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page-wrapper yh-fill">
|
||||
<div class="main-container">
|
||||
<Tabs :model-value="tab" @on-click="change">
|
||||
<TabPane label="角色设置" name="roles">
|
||||
<AdminListPanel mode="school" />
|
||||
</TabPane>
|
||||
<TabPane label="字典管理" name="dicts">
|
||||
<Dicts />
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 迁入的字典页原本是一整页(自带 page-wrapper 的填充高度),嵌进 tab 后高度要交回内容本身,
|
||||
否则 yh-fill 会把 tab 面板撑成视口高、列表区跟着溢出滚动条。 */
|
||||
:deep(.page-wrapper.yh-fill) {
|
||||
height: auto;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 选项字典管理(/admin/dicts,契约 §2.1 / 方案 §4.3③b)。
|
||||
* 选项字典管理(应用设置 /admin/app 的「字典管理」tab,契约 §2.1 / 方案 §4.3③b;
|
||||
* T10 方案 §6.1:原独立页 /admin/dicts 整体迁入本页内 tab,页面本体不改,只换宿主与守卫行)。
|
||||
*
|
||||
* 两级的落点:
|
||||
* - **本校字典**:`/dict/list` 只出本层,可增可删可改;
|
||||
|
||||
@@ -19,6 +19,7 @@ import ComponentLibrary from "@/components/designer/ComponentLibrary.vue";
|
||||
import DesignerCanvas from "@/components/designer/DesignerCanvas.vue";
|
||||
import FieldPropPanel from "@/components/designer/FieldPropPanel.vue";
|
||||
import FormConfigModal from "@/components/form/FormConfigModal.vue";
|
||||
import FormAdminModal from "@/components/admin/FormAdminModal.vue";
|
||||
import { formApi } from "@/api/module/form";
|
||||
import { dictApi } from "@/api/module/dict";
|
||||
import type { DictView, FormView, VersionView } from "@/types/form";
|
||||
@@ -58,6 +59,8 @@ const showErrors = ref(false);
|
||||
/** 装载时的 schema 原文基线:dirty 就是「与它不一致」,不用深 watcher 追 */
|
||||
const baseline = ref("");
|
||||
const configRef = ref<InstanceType<typeof FormConfigModal> | null>(null);
|
||||
/** 单表单管理员弹窗(与设计器的「表单配置」并排,方案 §6.4:与表单列表行操作同一形态) */
|
||||
const adminRef = ref<InstanceType<typeof FormAdminModal> | null>(null);
|
||||
const publishModal = reactive({ visible: false, changeLog: "" });
|
||||
|
||||
const locked = computed(() => viewingPublished.value);
|
||||
@@ -346,6 +349,7 @@ onMounted(boot);
|
||||
</div>
|
||||
<div class="head-right">
|
||||
<Button @click="configRef?.open()">表单配置</Button>
|
||||
<Button @click="adminRef?.open(uuid, form?.name)">表单管理员</Button>
|
||||
<Button @click="copyAs">另存为副本</Button>
|
||||
<Button :loading="saving" :disabled="locked" @click="save()">保存草稿</Button>
|
||||
<Button type="primary" :disabled="locked" @click="openPublish">发布</Button>
|
||||
@@ -394,6 +398,7 @@ onMounted(boot);
|
||||
</div>
|
||||
|
||||
<FormConfigModal ref="configRef" :form="form" @saved="onConfigSaved" />
|
||||
<FormAdminModal ref="adminRef" />
|
||||
|
||||
<Modal v-model="publishModal.visible" title="发布新版本" :mask-closable="false">
|
||||
<p class="publish-tip">
|
||||
|
||||
@@ -18,6 +18,7 @@ import { formApi } from "@/api/module/form";
|
||||
import { actionColumn } from "@/utils/tableActions";
|
||||
import { useElementHeight } from "@/utils/hook/useElementHeight";
|
||||
import FormConfigModal from "@/components/form/FormConfigModal.vue";
|
||||
import FormAdminModal from "@/components/admin/FormAdminModal.vue";
|
||||
import type { FormView } from "@/types/form";
|
||||
import { AUDIENCE, FORM_STATUS } from "@/types/form";
|
||||
import { CODE_PATTERN, MAX_NAME_LEN } from "@/types/formSchema";
|
||||
@@ -38,6 +39,8 @@ const copyModal = ref({ visible: false, source: null as FormView | null, code: "
|
||||
const copying = ref(false);
|
||||
/** 配置面板就地开在列表页(不进设计器也能改表单级配置,它不进版本快照) */
|
||||
const configRef = ref<InstanceType<typeof FormConfigModal> | null>(null);
|
||||
/** 单表单管理员弹窗(T10 方案 §6.4:列表行与设计器配置面板同一形态) */
|
||||
const adminRef = ref<InstanceType<typeof FormAdminModal> | null>(null);
|
||||
const activeForm = ref<FormView | null>(null);
|
||||
|
||||
const filtered = computed(() => {
|
||||
@@ -121,6 +124,7 @@ const columns = computed(() => [
|
||||
on: (row: FormView) => lifecycle(row, "enable")
|
||||
},
|
||||
{ key: "copy", label: "另存为副本", on: (row: FormView) => openCopy(row) },
|
||||
{ key: "admin", label: "管理员", on: (row: FormView) => openAdmins(row) },
|
||||
{ key: "delete", label: "删除", danger: true, on: (row: FormView) => softDelete(row) }
|
||||
],
|
||||
{ mode: "text", maxInline: 2 }
|
||||
@@ -136,6 +140,10 @@ function openConfig(row: FormView) {
|
||||
configRef.value?.open();
|
||||
}
|
||||
|
||||
function openAdmins(row: FormView) {
|
||||
adminRef.value?.open(row.formUuid, row.name);
|
||||
}
|
||||
|
||||
function onConfigSaved(res: FormView) {
|
||||
activeForm.value = res;
|
||||
load();
|
||||
@@ -335,6 +343,7 @@ onMounted(load);
|
||||
</Modal>
|
||||
|
||||
<FormConfigModal ref="configRef" :form="activeForm" @saved="onConfigSaved" />
|
||||
<FormAdminModal ref="adminRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user