ow
This commit is contained in:
1 parent
08a11abb30
commit
61869f1af0
3 files changed
+174
-53
No files matched your search
@@ -10,7 +10,7 @@
|
||||
"DbContexts": {
|
||||
"MasterDbContext": {
|
||||
"DbContextTypeName": "MasterDbContext",
|
||||
"ConnectionString": "server=nas.youjiala.com;port=3307;database=Furion;uid=root;pwd=Root@1237890;CharSet=utf8mb4;",
|
||||
"ConnectionString": "server=nas.youjiala.com;port=3307;database=builder;uid=root;pwd=Root@1237890;CharSet=utf8mb4;",
|
||||
"DatabaseType": "MySql",
|
||||
"LazyLoadingProxiesEnabled": true,
|
||||
"AuditEntityEnabled": true,
|
||||
|
||||
@@ -39,17 +39,28 @@ export async function setupRouter(app: App) {
|
||||
meta: {
|
||||
title: "首页",
|
||||
},
|
||||
children: [...chs],
|
||||
});
|
||||
// 欢迎页使用独立外壳,不套用后台的侧边菜单 / 顶栏 / 面包屑
|
||||
router.addRoute({
|
||||
path: "/dashboard",
|
||||
name: "dashboard",
|
||||
component: () => import("../layout/home.vue"),
|
||||
meta: {
|
||||
title: "首页",
|
||||
role: "*",
|
||||
description: "欢迎页",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard",
|
||||
name: "dashboard",
|
||||
path: "",
|
||||
name: "dashboardWelcome",
|
||||
meta: {
|
||||
role: "*",
|
||||
description: "欢迎页",
|
||||
},
|
||||
component: () => import("../views/dashboard.vue"),
|
||||
},
|
||||
...chs,
|
||||
],
|
||||
});
|
||||
} else {
|
||||
|
||||
+159
-49
@@ -1,64 +1,174 @@
|
||||
<template>
|
||||
<div class="page" :style="{
|
||||
height: bsInfo.height - 120 + 'px',
|
||||
}">
|
||||
<div v-for="(item, index) in fd?.SecurityFunctionDisplayDatas" :key="index">
|
||||
<a-row style="margin-bottom: 10px;">
|
||||
<a-col :span="12">
|
||||
<a-button type="default"
|
||||
style="max-width: 200px;text-align: left;opacity:.6; align-items: center;justify-content: flex-start;display: flex;"
|
||||
size="large" :style="'width:' + (bsInfo.width - 100) + 'px;'"
|
||||
@click.prevent="onpush(item.ApiRoute)">
|
||||
<cust-icon-font size="26" :type="'icon-' + item.Icon" />
|
||||
<span style="font-weight: 600;color:black;"> {{ item.FunctionLocalName }}</span>
|
||||
</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-spin :spinning="loading" :delay="200">
|
||||
<div class="page-container dash-page">
|
||||
<!-- 顶部欢迎区:通栏,滚动时随内容一起上移 -->
|
||||
<DashboardHero />
|
||||
|
||||
<!-- 功能分组:卡片外壳 / 标题字号沿用 ft-page 体系 -->
|
||||
<div class="page-main ft-page">
|
||||
<DashboardGroupCard v-for="grp in groups" :id="'grp-' + grp.key" :key="grp.key" :name="grp.name"
|
||||
:color="grp.color" :soft="grp.soft" :icon="grp.icon" :layout="grp.layout" :items="grp.items"
|
||||
@navigate="onpush" />
|
||||
|
||||
<a-empty v-if="!groups.length && !loading" description="没有匹配的功能" />
|
||||
</div>
|
||||
|
||||
<!-- 底部快捷栏:与其它页面一致,固定在底部 -->
|
||||
<div class="page-footer dash-footer">
|
||||
<DashboardBottomNav :items="navItems" @jump="onNavClick" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</a-spin>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, inject, defineComponent, onMounted, onUnmounted, ref, unref, provide, h, computed } from "vue";
|
||||
import {
|
||||
DeleteOutlined, EditOutlined, LoginOutlined, CloseCircleOutlined, LaptopOutlined, ShareAltOutlined, ScissorOutlined, UploadOutlined, FolderAddOutlined, DownloadOutlined,
|
||||
FolderOutlined, FileImageOutlined, NotificationOutlined, CrownOutlined, ArrowUpOutlined, PictureOutlined, UnorderedListOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import securityUserService from "@/service/security/securityUserService";
|
||||
import { SecurityFunctionResultData } from "@/data/auto/securityFunctionResultData";
|
||||
import { bsInfo } from "@/utils/browser"
|
||||
|
||||
const route = useRoute();
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import securityUserService from "@/service/security/securityUserService";
|
||||
import type { SecurityFunctionDisplayData } from "@/data/auto/securityFunctionDisplayData";
|
||||
import DashboardHero from "@/components/dashboard/DashboardHero.vue";
|
||||
import DashboardGroupCard from "@/components/dashboard/DashboardGroupCard.vue";
|
||||
import DashboardBottomNav from "@/components/dashboard/DashboardBottomNav.vue";
|
||||
|
||||
interface NavItem {
|
||||
key: string;
|
||||
label: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const fd = ref<SecurityFunctionResultData>();
|
||||
const loading = ref(false);
|
||||
const allItems = ref<SecurityFunctionDisplayData[]>([]);
|
||||
|
||||
onMounted(async () => {
|
||||
/* ==================== 分组定义 ==================== */
|
||||
type GroupKey = "disk" | "share" | "photo" | "audio" | "video" | "family" | "other";
|
||||
|
||||
fd.value = await securityUserService.FindMenuByUsername();
|
||||
const groupDefs: {
|
||||
key: GroupKey;
|
||||
name: string;
|
||||
color: string;
|
||||
soft: string;
|
||||
icon: string;
|
||||
layout: 2 | 3;
|
||||
}[] = [
|
||||
{ key: "disk", name: "网盘", color: "#1677ff", soft: "#e6f4ff", icon: "dbank", layout: 2 },
|
||||
{ key: "share", name: "共享中心", color: "#fa8c16", soft: "#fff7e6", icon: "dgroup", layout: 2 },
|
||||
{ key: "photo", name: "相册", color: "#722ed1", soft: "#f9f0ff", icon: "picture", layout: 3 },
|
||||
{ key: "audio", name: "音乐", color: "#eb2f96", soft: "#fff0f6", icon: "foldermp3", layout: 3 },
|
||||
{ key: "video", name: "视频", color: "#13c2c2", soft: "#e6fffb", icon: "foldervideo", layout: 3 },
|
||||
{ key: "family", name: "族谱管理", color: "#52c41a", soft: "#f6ffed", icon: "family", layout: 2 },
|
||||
{ key: "other", name: "更多", color: "#8a919f", soft: "#f5f6f8", icon: "gailan", layout: 3 },
|
||||
];
|
||||
|
||||
if (fd.value && fd.value.SecurityFunctionDisplayDatas && fd.value.SecurityFunctionDisplayDatas.length > 0) {
|
||||
fd.value.SecurityFunctionDisplayDatas = fd.value.SecurityFunctionDisplayDatas.filter(item => item.FunctionIndc !== "N" && item.PageUrl?.indexOf('master') > 0);
|
||||
}
|
||||
});
|
||||
|
||||
const onpush = (apiRoute: string) => {
|
||||
router.push(apiRoute);
|
||||
const GROUP_OF: Record<string, GroupKey> = {
|
||||
DmsFileEnquiry: "disk",
|
||||
DmsFileDeleteEnquiry: "disk",
|
||||
FamilyGroupShare: "share",
|
||||
FamilyShareOperation: "share",
|
||||
FamilyGroupOperation: "share",
|
||||
FamilyGroupEnquiry: "share",
|
||||
Preview: "photo",
|
||||
PublishPhotoOperation: "photo",
|
||||
PublishPhotoEnquiry: "photo",
|
||||
PreviewAudio: "audio",
|
||||
PublishAudioOperation: "audio",
|
||||
PublishAudioEnquiry: "audio",
|
||||
PreviewVideo: "video",
|
||||
PublishVideoOperation: "video",
|
||||
PublishVideoEnquiry: "video",
|
||||
FamilyPersonEnquiry: "family",
|
||||
FamilyPersonOperation: "family",
|
||||
FamilyTreeEnquiry: "family",
|
||||
FamilyTreeOperation: "family",
|
||||
};
|
||||
|
||||
const resolveGroup = (it: SecurityFunctionDisplayData): GroupKey =>
|
||||
GROUP_OF[it.FunctionName] ?? "other";
|
||||
|
||||
/* ==================== 分组结果 ==================== */
|
||||
const groups = computed(() => {
|
||||
const taken = new Set<string>();
|
||||
const result: { key: GroupKey; name: string; color: string; soft: string; icon: string; layout: 2 | 3; items: SecurityFunctionDisplayData[] }[] = [];
|
||||
|
||||
for (const g of groupDefs) {
|
||||
const items: SecurityFunctionDisplayData[] = [];
|
||||
for (const it of allItems.value) {
|
||||
if (resolveGroup(it) !== g.key) continue;
|
||||
const label = it.FunctionLocalName || it.FunctionName;
|
||||
if (taken.has(label)) continue;
|
||||
taken.add(label);
|
||||
items.push(it);
|
||||
}
|
||||
if (items.length) result.push({ ...g, items });
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
/** 底部快捷栏只保留五大高频域 */
|
||||
const navItems = computed<NavItem[]>(() =>
|
||||
groupDefs
|
||||
.filter(g => ["disk", "photo", "audio", "video", "family"].includes(g.key))
|
||||
.map(g => {
|
||||
let label = g.name;
|
||||
if (label === "共享中心") label = "共享";
|
||||
if (label === "族谱管理") label = "族谱";
|
||||
return { key: g.key, label, icon: g.icon };
|
||||
})
|
||||
);
|
||||
|
||||
/* ==================== 交互 ==================== */
|
||||
const onpush = (apiRoute: string) => {
|
||||
if (apiRoute) router.push(apiRoute);
|
||||
};
|
||||
const onNavClick = (key: string) => {
|
||||
document.getElementById("grp-" + key)?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const fd = await securityUserService.FindMenuByUsername();
|
||||
const raw = fd?.SecurityFunctionDisplayDatas ?? [];
|
||||
allItems.value = raw.filter(
|
||||
it => it.FunctionIndc !== "N" && (it.PageUrl?.indexOf("master") ?? -1) > 0
|
||||
);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page {
|
||||
overflow: auto;
|
||||
background-color: bisque;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
padding-top: 8px;
|
||||
margin-right: 8px;
|
||||
background-image: url('/images/main/p3.png');
|
||||
background-size: cover;
|
||||
width: 100%;
|
||||
z-index: -999;
|
||||
/* a-spin 会插入两层容器,把高度透传下去,height: 100% 才会生效 */
|
||||
.ant-spin-nested-loading {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-spin-container) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 独立外壳(layout/home.vue)下没有侧边菜单与面包屑,页面自己撑满整屏 */
|
||||
.dash-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 卡片区独占剩余高度并内部滚动,底栏因此始终贴底 */
|
||||
.dash-page .page-main {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
/* 底栏已是列内固定项,不再需要为 fixed 预留的 96px */
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
/* 底部快捷栏:沿用 .page-footer,仅取消 fixed,改由 flex 列天然贴底 */
|
||||
.dash-footer {
|
||||
position: relative;
|
||||
bottom: auto;
|
||||
flex: none;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user