finish
This commit is contained in:
parent
4edf954980
commit
8e39e66ce8
6
package-lock.json
generated
6
package-lock.json
generated
@ -58,7 +58,6 @@
|
||||
"integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.3",
|
||||
@ -1336,7 +1335,6 @@
|
||||
"integrity": "sha512-anNG/V/Efn/YZY4pRzbACnKxNKoBng2VTFydVu8RRs5hQjikP8CQfaeAV59VFSCzKNp90mXiVXW2QzV56rwMrg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
@ -1755,7 +1753,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.8.9",
|
||||
"caniuse-lite": "^1.0.30001746",
|
||||
@ -2843,7 +2840,6 @@
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@ -2926,7 +2922,6 @@
|
||||
"integrity": "sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.5.0",
|
||||
@ -3153,7 +3148,6 @@
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.22.tgz",
|
||||
"integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.22",
|
||||
"@vue/compiler-sfc": "3.5.22",
|
||||
|
||||
185
src/App.vue
185
src/App.vue
@ -1,17 +1,194 @@
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
// @ts-ignore
|
||||
import { reactive, ref, watch } from 'vue';
|
||||
import CardViews from './components/CardViews.vue';
|
||||
import TabList from './components/TabList.vue';
|
||||
import HeaderView from './components/HeaderView.vue';
|
||||
|
||||
const tabs = reactive([
|
||||
{
|
||||
id: 'common',
|
||||
name: '通用',
|
||||
tag: 'common'
|
||||
},
|
||||
{
|
||||
id: 'dev',
|
||||
name: '开发',
|
||||
tag: 'dev'
|
||||
},
|
||||
{
|
||||
id: 'office',
|
||||
name: '办公',
|
||||
tag: 'office'
|
||||
},
|
||||
{
|
||||
id: 'resources',
|
||||
name: '资源',
|
||||
tag: 'resources'
|
||||
}
|
||||
]);
|
||||
|
||||
const simulateData = reactive({
|
||||
common: [
|
||||
{
|
||||
id: 1,
|
||||
title: "企业邮箱",
|
||||
description: "公司官方邮件系统,支持多设备同步",
|
||||
icon: "fa-envelope",
|
||||
network: "public",
|
||||
networkName: "StarNet (182.132.22.150)",
|
||||
visits: 1280
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "内部通讯",
|
||||
description: "企业内部即时通讯工具,支持群组聊天",
|
||||
icon: "fa-comments",
|
||||
network: "internal",
|
||||
networkName: "IntraNet (10.225.10.123)",
|
||||
visits: 2450
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "云文档",
|
||||
description: "企业文档协作平台,支持多人实时编辑",
|
||||
icon: "fa-file-alt",
|
||||
network: "public",
|
||||
networkName: "StarNet (182.132.22.151)",
|
||||
visits: 1876
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "项目管理系统",
|
||||
description: "全流程项目管理工具,支持敏捷开发",
|
||||
icon: "fa-tasks",
|
||||
network: "internal",
|
||||
networkName: "DevNet (10.215.10.124)",
|
||||
visits: 932
|
||||
}
|
||||
],
|
||||
dev: [
|
||||
{
|
||||
id: 5,
|
||||
title: "代码仓库",
|
||||
description: "企业级代码版本控制系统",
|
||||
icon: "fa-code-branch",
|
||||
network: "internal",
|
||||
networkName: "DevNet (10.215.10.125)",
|
||||
visits: 1542
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: "CI/CD平台",
|
||||
description: "持续集成与持续部署自动化平台",
|
||||
icon: "fa-rocket",
|
||||
network: "internal",
|
||||
networkName: "DevNet (10.215.10.126)",
|
||||
visits: 876
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
title: "API网关",
|
||||
description: "统一API管理与监控平台",
|
||||
icon: "fa-plug",
|
||||
network: "public",
|
||||
networkName: "StarNet",
|
||||
visits: 1203
|
||||
}
|
||||
],
|
||||
office: [
|
||||
{
|
||||
id: 8,
|
||||
title: "人力资源系统",
|
||||
description: "员工信息、考勤、绩效管理平台",
|
||||
icon: "fa-users",
|
||||
network: "internal",
|
||||
networkName: "IntraNet",
|
||||
visits: 2105
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
title: "财务系统",
|
||||
description: "企业财务核算与报销管理系统",
|
||||
icon: "fa-calculator",
|
||||
network: "internal",
|
||||
networkName: "FinanceNet",
|
||||
visits: 1876
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
title: "合同管理",
|
||||
description: "企业合同全生命周期管理系统",
|
||||
icon: "fa-file-contract",
|
||||
network: "internal",
|
||||
networkName: "IntraNet",
|
||||
visits: 945
|
||||
}
|
||||
],
|
||||
resources: [
|
||||
{
|
||||
id: 11,
|
||||
title: "知识库",
|
||||
description: "企业知识管理与文档共享平台",
|
||||
icon: "fa-book",
|
||||
network: "public",
|
||||
networkName: "StarNet",
|
||||
visits: 3241
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
title: "培训中心",
|
||||
description: "员工在线学习与技能提升平台",
|
||||
icon: "fa-graduation-cap",
|
||||
network: "public",
|
||||
networkName: "StarNet",
|
||||
visits: 1876
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
title: "资源下载",
|
||||
description: "软件、模板、文档资源下载中心",
|
||||
icon: "fa-download",
|
||||
network: "internal",
|
||||
networkName: "IntraNet",
|
||||
visits: 2654
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const activeTab = ref('common');
|
||||
|
||||
watch(activeTab, (newTab) => {
|
||||
console.log("activeTab changed to", newTab);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>You did it!</h1>
|
||||
<!-- <h1>You did it!</h1>
|
||||
<p>
|
||||
Visit <a href="https://vuejs.org/" target="_blank" rel="noopener">vuejs.org</a> to read the
|
||||
documentation
|
||||
</p>
|
||||
<CardViews />
|
||||
</p> -->
|
||||
<HeaderView />
|
||||
<TabList :tabs="tabs" v-bind:active-tab="activeTab" @update:activeTab="activeTab = $event" />
|
||||
<CardViews :portalData="simulateData[activeTab]" />
|
||||
</template>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
min-height: 100vh;
|
||||
color: #2C3E50;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
/* 工具提示 */
|
||||
.tooltip {
|
||||
position: relative;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div class="cards-container" id="cards-container">
|
||||
<!-- 卡片将通过JavaScript动态生成 -->
|
||||
<LinkCardItem
|
||||
v-for="it in portalData.common"
|
||||
v-for="it in props.portalData"
|
||||
:key="it.id"
|
||||
:title="it.title"
|
||||
:description="it.description"
|
||||
@ -13,174 +13,16 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import LinkCardItem from './LinkCardItem.vue';
|
||||
import { reactive } from 'vue';
|
||||
<script setup lang="ts">
|
||||
import { type CardItem } from '@/types/CardItems';
|
||||
import LinkCardItem from './LinkCardItem.vue';
|
||||
|
||||
// 模拟数据
|
||||
const portalData = reactive({
|
||||
common: [
|
||||
{
|
||||
id: 1,
|
||||
title: "企业邮箱",
|
||||
description: "公司官方邮件系统,支持多设备同步",
|
||||
icon: "fa-envelope",
|
||||
network: "public",
|
||||
networkName: "StarNet",
|
||||
visits: 1280
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "内部通讯",
|
||||
description: "企业内部即时通讯工具,支持群组聊天",
|
||||
icon: "fa-comments",
|
||||
network: "internal",
|
||||
networkName: "IntraNet",
|
||||
visits: 2450
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "云文档",
|
||||
description: "企业文档协作平台,支持多人实时编辑",
|
||||
icon: "fa-file-alt",
|
||||
network: "public",
|
||||
networkName: "StarNet",
|
||||
visits: 1876
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "项目管理系统",
|
||||
description: "全流程项目管理工具,支持敏捷开发",
|
||||
icon: "fa-tasks",
|
||||
network: "internal",
|
||||
networkName: "DevNet",
|
||||
visits: 932
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
title: "企业邮箱",
|
||||
description: "公司官方邮件系统,支持多设备同步",
|
||||
icon: "fa-envelope",
|
||||
network: "public",
|
||||
networkName: "StarNet",
|
||||
visits: 1280
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "内部通讯",
|
||||
description: "企业内部即时通讯工具,支持群组聊天",
|
||||
icon: "fa-comments",
|
||||
network: "internal",
|
||||
networkName: "IntraNet",
|
||||
visits: 2450
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "云文档",
|
||||
description: "企业文档协作平台,支持多人实时编辑",
|
||||
icon: "fa-file-alt",
|
||||
network: "public",
|
||||
networkName: "StarNet",
|
||||
visits: 1876
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "项目管理系统",
|
||||
description: "全流程项目管理工具,支持敏捷开发",
|
||||
icon: "fa-tasks",
|
||||
network: "internal",
|
||||
networkName: "DevNet",
|
||||
visits: 932
|
||||
}
|
||||
],
|
||||
dev: [
|
||||
{
|
||||
id: 5,
|
||||
title: "代码仓库",
|
||||
description: "企业级代码版本控制系统",
|
||||
icon: "fa-code-branch",
|
||||
network: "internal",
|
||||
networkName: "DevNet",
|
||||
visits: 1542
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: "CI/CD平台",
|
||||
description: "持续集成与持续部署自动化平台",
|
||||
icon: "fa-rocket",
|
||||
network: "internal",
|
||||
networkName: "DevNet",
|
||||
visits: 876
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
title: "API网关",
|
||||
description: "统一API管理与监控平台",
|
||||
icon: "fa-plug",
|
||||
network: "public",
|
||||
networkName: "StarNet",
|
||||
visits: 1203
|
||||
}
|
||||
],
|
||||
office: [
|
||||
{
|
||||
id: 8,
|
||||
title: "人力资源系统",
|
||||
description: "员工信息、考勤、绩效管理平台",
|
||||
icon: "fa-users",
|
||||
network: "internal",
|
||||
networkName: "IntraNet",
|
||||
visits: 2105
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
title: "财务系统",
|
||||
description: "企业财务核算与报销管理系统",
|
||||
icon: "fa-calculator",
|
||||
network: "internal",
|
||||
networkName: "FinanceNet",
|
||||
visits: 1876
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
title: "合同管理",
|
||||
description: "企业合同全生命周期管理系统",
|
||||
icon: "fa-file-contract",
|
||||
network: "internal",
|
||||
networkName: "IntraNet",
|
||||
visits: 945
|
||||
}
|
||||
],
|
||||
resources: [
|
||||
{
|
||||
id: 11,
|
||||
title: "知识库",
|
||||
description: "企业知识管理与文档共享平台",
|
||||
icon: "fa-book",
|
||||
network: "public",
|
||||
networkName: "StarNet",
|
||||
visits: 3241
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
title: "培训中心",
|
||||
description: "员工在线学习与技能提升平台",
|
||||
icon: "fa-graduation-cap",
|
||||
network: "public",
|
||||
networkName: "StarNet",
|
||||
visits: 1876
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
title: "资源下载",
|
||||
description: "软件、模板、文档资源下载中心",
|
||||
icon: "fa-download",
|
||||
network: "internal",
|
||||
networkName: "IntraNet",
|
||||
visits: 2654
|
||||
}
|
||||
]
|
||||
});
|
||||
const props = withDefaults(defineProps<{
|
||||
portalData: Array<CardItem>
|
||||
}>(), {
|
||||
portalData: () => []
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -188,6 +30,6 @@ import { reactive } from 'vue';
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 50px;
|
||||
row-gap: 80px;
|
||||
/* row-gap: 80px; */
|
||||
}
|
||||
</style>
|
||||
79
src/components/HeaderView.vue
Normal file
79
src/components/HeaderView.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<script setup lang="ts">
|
||||
import { useUserStore } from '@/stores/user';
|
||||
const { username, imageUrl } = useUserStore();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header>
|
||||
<div class="logo">
|
||||
<i class="fas fa-cube"></i>
|
||||
<h1>StarNet 综合管理平台</h1>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-avatar">{{ username.charAt(0) }}</div>
|
||||
<div class="user-name">{{ username }}</div>
|
||||
<button class="logout-btn"><i class="fas fa-sign-out-alt"></i></button>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
header {
|
||||
background-color: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
padding: 16px 24px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo h1 {
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size: 24px;
|
||||
color: #2C3E50;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background-color: #3498DB;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-weight: 600;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #95A5A6;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.logout-btn:hover {
|
||||
color: #E74C3C;
|
||||
}
|
||||
</style>
|
||||
77
src/components/TabList.vue
Normal file
77
src/components/TabList.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="tabs">
|
||||
<div class="tab-list">
|
||||
<div v-for="tab in props.tabs"
|
||||
:key="tab.id"
|
||||
class="tab-item"
|
||||
:class="{'active': tab.id === props.activeTab}"
|
||||
:data-tab="tab.id"
|
||||
@click="updateActiveTab(tab.tag)"
|
||||
>
|
||||
{{ tab.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { type TabItem } from '@/types/TabItems';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
tabs: Array<TabItem>,
|
||||
activeTab: string
|
||||
}>(), {
|
||||
tabs: () => [],
|
||||
activeTab: 'common'
|
||||
})
|
||||
console.log(props.activeTab);
|
||||
const emit = defineEmits(['update:activeTab']);
|
||||
// 更新活动Tab
|
||||
function updateActiveTab(tabTag: string) {
|
||||
console.log("clicked", tabTag);
|
||||
emit('update:activeTab', tabTag);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tabs {
|
||||
background-color: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
margin-bottom: 24px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tab-list {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #ECF0F1;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
padding: 16px 24px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
color: #95A5A6;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab-item:hover {
|
||||
color: #3498DB;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
color: #3498DB;
|
||||
}
|
||||
|
||||
.tab-item.active::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background-color: #3498DB;
|
||||
}
|
||||
</style>
|
||||
14
src/stores/user.ts
Normal file
14
src/stores/user.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
const username = ref('用户名');
|
||||
const imageUrl = ref('');
|
||||
function setUsername(name: string) {
|
||||
username.value = name;
|
||||
}
|
||||
function setImageUrl(url: string) {
|
||||
imageUrl.value = url;
|
||||
}
|
||||
return { username, imageUrl, setUsername, setImageUrl };
|
||||
});
|
||||
9
src/types/CardItems.ts
Normal file
9
src/types/CardItems.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export interface CardItem {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
network: string;
|
||||
networkName: string;
|
||||
visits: number;
|
||||
}
|
||||
5
src/types/TabItems.ts
Normal file
5
src/types/TabItems.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface TabItem {
|
||||
id: string;
|
||||
name: string;
|
||||
tag: string;
|
||||
}
|
||||
Reference in New Issue
Block a user