|
|
@@ -13,54 +13,14 @@
|
|
|
|
|
|
<!-- Main Content -->
|
|
|
<div class="main-content">
|
|
|
- <!-- Recently Used Section -->
|
|
|
- <div class="section">
|
|
|
- <h2 class="section-title">最近使用</h2>
|
|
|
+ <div class="section" v-for="app in appList" :key="app.appId">
|
|
|
+ <h2 class="section-title">{{ app.appName }}</h2>
|
|
|
<div class="icon-grid">
|
|
|
- <div class="icon-item" v-for="item in recentlyUsed" :key="item.name" @click="handleClick(item)">
|
|
|
- <div class="icon-wrapper" >
|
|
|
- <img :src="item.icon" :alt="item.name" />
|
|
|
+ <div class="icon-item" v-for="page in app.appPages" :key="page.pageId" @click="handleClick(page)">
|
|
|
+ <div class="icon-wrapper">
|
|
|
+ <img :src="getIconPath(page.appName)" :alt="page.appName" />
|
|
|
</div>
|
|
|
- <span class="icon-label">{{ item.name }}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- Pending My Approval Section -->
|
|
|
- <div class="section">
|
|
|
- <h2 class="section-title">待我审批</h2>
|
|
|
- <div class="icon-grid">
|
|
|
- <div class="icon-item" v-for="item in pendingApproval" :key="item.name" @click="handleClick(item)">
|
|
|
- <div class="icon-wrapper" >
|
|
|
- <img :src="item.icon" :alt="item.name" />
|
|
|
- </div>
|
|
|
- <span class="icon-label">{{ item.name }}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- My Approvals Section -->
|
|
|
- <div class="section">
|
|
|
- <h2 class="section-title">我的审批</h2>
|
|
|
- <div class="icon-grid">
|
|
|
- <div class="icon-item" v-for="item in myApprovals" :key="item.name" @click="handleClick(item)">
|
|
|
- <div class="icon-wrapper" >
|
|
|
- <img :src="item.icon" :alt="item.name" />
|
|
|
- </div>
|
|
|
- <span class="icon-label">{{ item.name }}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- My Tasks Section -->
|
|
|
- <div class="section">
|
|
|
- <h2 class="section-title">我的任务</h2>
|
|
|
- <div class="icon-grid">
|
|
|
- <div class="icon-item" v-for="item in myTasks" :key="item.name" @click="handleClick(item)">
|
|
|
- <div class="icon-wrapper" :style="{ backgroundColor: item.color }">
|
|
|
- <img :src="item.icon" :alt="item.name" />
|
|
|
- </div>
|
|
|
- <span class="icon-label">{{ item.name }}</span>
|
|
|
+ <span class="icon-label">{{ page.appName }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -69,66 +29,70 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup name="Index" lang="ts">
|
|
|
-import { ref } from 'vue';
|
|
|
+import { ref, onMounted } from 'vue';
|
|
|
+import { getHomeApp, jumpToPage } from '@/api/app';
|
|
|
|
|
|
-interface MenuItem {
|
|
|
- name: string;
|
|
|
- icon: string;
|
|
|
- color: string;
|
|
|
- route?: string;
|
|
|
+interface AppPage {
|
|
|
+ pageId: number;
|
|
|
+ appName: string;
|
|
|
}
|
|
|
|
|
|
-// Recently Used Items
|
|
|
-const recentlyUsed = ref<MenuItem[]>([
|
|
|
- { name: '立项', icon: '/src/assets/images/home/立项@2x.png', color: '#5DCDFF' },
|
|
|
- { name: '项目变更', icon: '/src/assets/images/home/项目变更@2x.png', color: '#6B8CFF' },
|
|
|
- { name: '进出场单', icon: '/src/assets/images/home/进出场单@2x.png', color: '#FF9F5A' },
|
|
|
- { name: '文档', icon: '/src/assets/images/home/文档@2x.png', color: '#5FD4A8' },
|
|
|
- { name: '申购', icon: '/src/assets/images/home/申购@2x.png', color: '#7B6CFF' },
|
|
|
- { name: 'BOM变更', icon: '/src/assets/images/home/BOM变更@2x.png', color: '#FF6B9D' },
|
|
|
- { name: '兑换', icon: '/src/assets/images/home/兑换@2x.png', color: '#C77CFF' },
|
|
|
- { name: '兑换付款', icon: '/src/assets/images/home/兑换付款@2x.png', color: '#FFB84D' },
|
|
|
-]);
|
|
|
+interface AppInfo {
|
|
|
+ appId: number;
|
|
|
+ appName: string;
|
|
|
+ appPages: AppPage[];
|
|
|
+}
|
|
|
|
|
|
-// Pending My Approval Items
|
|
|
-const pendingApproval = ref<MenuItem[]>([
|
|
|
- { name: '立项', icon: '/src/assets/images/home/project_initiation.png', color: '#5DCDFF' },
|
|
|
- { name: '项目变更', icon: '/src/assets/images/home/project_change.png', color: '#6B8CFF' },
|
|
|
- { name: '进出场单', icon: '/src/assets/images/home/entry_exit_form.png', color: '#FF9F5A' },
|
|
|
- { name: '文档', icon: '/src/assets/images/home/document.png', color: '#5FD4A8' },
|
|
|
- { name: '申购', icon: '/src/assets/images/home/purchase_request.png', color: '#7B6CFF' },
|
|
|
- { name: 'BOM变更', icon: '/src/assets/images/home/bom_change.png', color: '#FF6B9D' },
|
|
|
- { name: '兑换', icon: '/src/assets/images/home/redeem.png', color: '#C77CFF' },
|
|
|
- { name: '兑换付款', icon: '/src/assets/images/home/redeem_payment.png', color: '#FFB84D' },
|
|
|
-]);
|
|
|
+const appList = ref<AppInfo[]>([]);
|
|
|
+
|
|
|
+// Icon Mapping
|
|
|
+const iconMap: Record<string, string> = {
|
|
|
+ '立项': 'project_initiation.png',
|
|
|
+ '项目变更': 'project_change.png',
|
|
|
+ '进出场单': 'entry_exit_form.png',
|
|
|
+ '文档': 'document.png',
|
|
|
+ '申购': 'purchase_request.png',
|
|
|
+ 'BOM变更': 'bom_change.png',
|
|
|
+ '兑换': 'redeem.png',
|
|
|
+ '兑换付款': 'redeem_payment.png',
|
|
|
+ '配置品审批': 'configuration_approval.png',
|
|
|
+ '投标入场': 'entry_approval.png',
|
|
|
+ '配置付款': 'configuration_payment.png',
|
|
|
+ '项目汇总': 'project_summary.png',
|
|
|
+ '工单生成': 'work_order_service.png',
|
|
|
+};
|
|
|
|
|
|
-// My Approvals Items
|
|
|
-const myApprovals = ref<MenuItem[]>([
|
|
|
- { name: '配置品审批', icon: '/src/assets/images/home/configuration_approval.png', color: '#6B8CFF' },
|
|
|
- { name: '投标入场', icon: '/src/assets/images/home/entry_approval.png', color: '#5FD4A8' },
|
|
|
- { name: '投标入场', icon: '/src/assets/images/home/entry_approval.png', color: '#7B6CFF' },
|
|
|
- { name: '配置付款', icon: '/src/assets/images/home/configuration_payment.png', color: '#FFB84D' },
|
|
|
- { name: '项目汇总', icon: '/src/assets/images/home/project_summary.png', color: '#5DCDFF' },
|
|
|
- { name: '工单生成', icon: '/src/assets/images/home/work_order_service.png', color: '#5FD4A8' },
|
|
|
-]);
|
|
|
+// Helper to get icon path
|
|
|
+const getIconPath = (name: string) => {
|
|
|
+ const filename = iconMap[name] || 'document.png'; // Default icon
|
|
|
+ return new URL(`/src/assets/images/home/${filename}`, import.meta.url).href;
|
|
|
+};
|
|
|
|
|
|
-// My Tasks Items
|
|
|
-const myTasks = ref<MenuItem[]>([
|
|
|
- { name: '配置付款', icon: '/src/assets/images/home/configuration_payment.png', color: '#FFB84D' },
|
|
|
- { name: '项目汇总', icon: '/src/assets/images/home/project_summary.png', color: '#5DCDFF' },
|
|
|
- { name: '工单生成', icon: '/src/assets/images/home/work_order_service.png', color: '#5FD4A8' },
|
|
|
-]);
|
|
|
+const handleClick = async (item: AppPage) => {
|
|
|
+ console.log('Clicked:', item.appName, item.pageId);
|
|
|
+ try {
|
|
|
+ const res = await jumpToPage(item.pageId);
|
|
|
+ if (res.result) {
|
|
|
+ window.open(res.result, '_blank');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Jump to page failed:', error);
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
-const handleClick = (item: MenuItem) => {
|
|
|
- console.log('Clicked:', item.name);
|
|
|
- // Add navigation logic here
|
|
|
- if (item.route) {
|
|
|
- // router.push(item.route);
|
|
|
+const initData = async () => {
|
|
|
+ try {
|
|
|
+ const res = await getHomeApp();
|
|
|
+ if (res.result) {
|
|
|
+ appList.value = res.result;
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Failed to get home app list:', error);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
onMounted(() => {
|
|
|
- console.log('Home page mounted');
|
|
|
+ initData();
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
@@ -140,6 +104,11 @@ onMounted(() => {
|
|
|
}
|
|
|
|
|
|
.header {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ z-index: 100;
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
@@ -177,7 +146,7 @@ onMounted(() => {
|
|
|
.main-content {
|
|
|
max-width: 1400px;
|
|
|
margin: 0 auto;
|
|
|
- padding: 40px 20px;
|
|
|
+ padding: 92px 20px 40px 20px; // 72px header height + 20px spacing
|
|
|
}
|
|
|
|
|
|
.section {
|
|
|
@@ -224,10 +193,6 @@ onMounted(() => {
|
|
|
|
|
|
&:hover {
|
|
|
transform: translateY(-4px);
|
|
|
-
|
|
|
- .icon-wrapper {
|
|
|
- // box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
.icon-wrapper {
|
|
|
@@ -238,7 +203,6 @@ onMounted(() => {
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
transition: all 0.3s ease;
|
|
|
- // box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
img {
|
|
|
width: 64px;
|