¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <!-- 页颿 é¢ --> |
| | | <div class="page-header"> |
| | | <h2>éè´ç®¡çç³»ç»</h2> |
| | | <p>ç»ä¸ç®¡çéè´å
¨æµç¨ï¼æåéè´æçä¸è´¨é</p> |
| | | </div> |
| | | |
| | | <!-- åè½æ¨¡åå¡ç --> |
| | | <el-row :gutter="20" class="module-cards"> |
| | | <el-col :span="8"> |
| | | <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/purchaseOrder')"> |
| | | <div class="card-content"> |
| | | <div class="card-icon"> |
| | | <el-icon size="48" color="#409EFF"><Document /></el-icon> |
| | | </div> |
| | | <div class="card-info"> |
| | | <h3>éè´è®¢å管ç</h3> |
| | | <p>æ°å»ºãç¼è¾ãå é¤éè´è®¢åï¼éæ©ä¾åºåï¼å¡«åååæç»</p> |
| | | <div class="card-stats"> |
| | | <span>å¾
å®¡æ ¸: {{ stats.pendingOrders }}</span> |
| | | <span>å·²å®¡æ ¸: {{ stats.approvedOrders }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/arrivalManagement')"> |
| | | <div class="card-content"> |
| | | <div class="card-icon"> |
| | | <el-icon size="48" color="#67C23A"><Box /></el-icon> |
| | | </div> |
| | | <div class="card-info"> |
| | | <h3>å°è´§ç®¡ç</h3> |
| | | <p>èªå¨å
³èéè´è®¢åï¼å½å
¥å°è´§ååä¿¡æ¯ï¼æ¯ææå°æ¥ç</p> |
| | | <div class="card-stats"> |
| | | <span>å¾
æ¶è´§: {{ stats.pendingArrivals }}</span> |
| | | <span>å·²æ¶è´§: {{ stats.receivedArrivals }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/qualityInspection')"> |
| | | <div class="card-content"> |
| | | <div class="card-icon"> |
| | | <el-icon size="48" color="#E6A23C"><Search /></el-icon> |
| | | </div> |
| | | <div class="card-info"> |
| | | <h3>è´¨æ£ç®¡ç</h3> |
| | | <p>å°è´§åèªå¨çæè´¨æ£åï¼å¡«ååæ ¼ä¸ä¸åæ ¼ååæ°éååå </p> |
| | | <div class="card-stats"> |
| | | <span>å¾
è´¨æ£: {{ stats.pendingInspections }}</span> |
| | | <span>已宿: {{ stats.completedInspections }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20" class="module-cards"> |
| | | <el-col :span="8"> |
| | | <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/returnManagement')"> |
| | | <div class="card-content"> |
| | | <div class="card-icon"> |
| | | <el-icon size="48" color="#F56C6C"><RefreshLeft /></el-icon> |
| | | </div> |
| | | <div class="card-info"> |
| | | <h3>é货管ç</h3> |
| | | <p>çæéè´éè´§ååè´¨æ£éè´§åï¼æ¯æçéæ¥è¯¢ä¸åæ®è¯¦æ
</p> |
| | | <div class="card-stats"> |
| | | <span>å¾
å®¡æ ¸: {{ stats.pendingReturns }}</span> |
| | | <span>å·²å®¡æ ¸: {{ stats.approvedReturns }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/priceManagement')"> |
| | | <div class="card-content"> |
| | | <div class="card-icon"> |
| | | <el-icon size="48" color="#909399"><Money /></el-icon> |
| | | </div> |
| | | <div class="card-info"> |
| | | <h3>ä»·æ ¼ç®¡ç</h3> |
| | | <p>æ ¹æ®åååå¸åºä»·æ ¼ååè¿è¡éè´ä»·è°æ´ï¼èªå¨æ´æ°éè´åæ®</p> |
| | | <div class="card-stats"> |
| | | <span>ææä»·æ ¼: {{ stats.activePrices }}</span> |
| | | <span>å¾
çæ: {{ stats.pendingPrices }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-card class="module-card" shadow="hover" @click="navigateTo('/procurementManagement/procurementLedger')"> |
| | | <div class="card-content"> |
| | | <div class="card-icon"> |
| | | <el-icon size="48" color="#9C27B0"><List /></el-icon> |
| | | </div> |
| | | <div class="card-info"> |
| | | <h3>éè´å°è´¦</h3> |
| | | <p>æ¥çéè´åå²è®°å½ï¼ç»è®¡åæéè´æ°æ®ï¼çæéè´æ¥è¡¨</p> |
| | | <div class="card-stats"> |
| | | <span>æ»è®¢å: {{ stats.totalOrders }}</span> |
| | | <span>æ»éé¢: Â¥{{ stats.totalAmount.toFixed(2) }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- ç»è®¡æ¦è§ --> |
| | | <el-card class="stats-card" shadow="never"> |
| | | <template #header> |
| | | <div class="card-header"> |
| | | <span>éè´ç»è®¡æ¦è§</span> |
| | | <el-button type="primary" size="small" @click="refreshStats">å·æ°æ°æ®</el-button> |
| | | </div> |
| | | </template> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="6"> |
| | | <div class="stat-item"> |
| | | <div class="stat-number">{{ stats.totalOrders }}</div> |
| | | <div class="stat-label">éè´è®¢åæ»æ°</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="stat-item"> |
| | | <div class="stat-number">{{ stats.totalAmount.toFixed(2) }}</div> |
| | | <div class="stat-label">éè´æ»éé¢(ä¸å
)</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="stat-item"> |
| | | <div class="stat-number">{{ stats.avgDeliveryTime }}</div> |
| | | <div class="stat-label">å¹³å交ä»å¤©æ°</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="stat-item"> |
| | | <div class="stat-number">{{ stats.qualityRate }}%</div> |
| | | <div class="stat-label">è´¨æ£åæ ¼ç</div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </el-card> |
| | | |
| | | <!-- æè¿æ´»å¨ --> |
| | | <el-card class="activity-card" shadow="never"> |
| | | <template #header> |
| | | <span>æè¿æ´»å¨</span> |
| | | </template> |
| | | |
| | | <el-timeline> |
| | | <el-timeline-item |
| | | v-for="(activity, index) in recentActivities" |
| | | :key="index" |
| | | :timestamp="activity.time" |
| | | :type="activity.type" |
| | | > |
| | | {{ activity.content }} |
| | | </el-timeline-item> |
| | | </el-timeline> |
| | | </el-card> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted } from 'vue' |
| | | import { useRouter } from 'vue-router' |
| | | import { Document, Box, Search, RefreshLeft, Money, List } from '@element-plus/icons-vue' |
| | | |
| | | const router = useRouter() |
| | | |
| | | // ç»è®¡æ°æ® |
| | | const stats = ref({ |
| | | pendingOrders: 5, |
| | | approvedOrders: 25, |
| | | pendingArrivals: 3, |
| | | receivedArrivals: 18, |
| | | pendingInspections: 2, |
| | | completedInspections: 15, |
| | | pendingReturns: 1, |
| | | approvedReturns: 3, |
| | | activePrices: 45, |
| | | pendingPrices: 2, |
| | | totalOrders: 30, |
| | | totalAmount: 125.8, |
| | | avgDeliveryTime: 7, |
| | | qualityRate: 96.5 |
| | | }) |
| | | |
| | | // æè¿æ´»å¨ |
| | | const recentActivities = ref([ |
| | | { |
| | | time: '2025-12-01 18:30', |
| | | content: 'æ°å¢éè´è®¢å PO20241201004', |
| | | type: 'primary' |
| | | }, |
| | | { |
| | | time: '2025-12-01 17:45', |
| | | content: 'å®æè´¨æ£å QI20241201002', |
| | | type: 'success' |
| | | }, |
| | | { |
| | | time: '2025-12-01 16:20', |
| | | content: 'å°è´§å AR20241201003 å·²æ¶è´§', |
| | | type: 'success' |
| | | }, |
| | | { |
| | | time: '2025-12-01 15:15', |
| | | content: 'ä»·æ ¼è°æ´ï¼ååB ä» Â¥80 è°æ´ä¸º Â¥75', |
| | | type: 'warning' |
| | | }, |
| | | { |
| | | time: '2025-12-01 14:30', |
| | | content: 'éè´§å RT20241201003 å·²å®¡æ ¸', |
| | | type: 'info' |
| | | } |
| | | ]) |
| | | |
| | | // 导èªå°æå®é¡µé¢ |
| | | const navigateTo = (path) => { |
| | | router.push(path) |
| | | } |
| | | |
| | | // å·æ°ç»è®¡æ°æ® |
| | | const refreshStats = () => { |
| | | // 模æå·æ°æ°æ® |
| | | stats.value.pendingOrders = Math.floor(Math.random() * 10) + 1 |
| | | stats.value.totalAmount = (Math.random() * 100 + 100).toFixed(1) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // 页é¢å è½½å®æåçåå§åé»è¾ |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | padding: 20px; |
| | | background-color: #f5f7fa; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | .page-header { |
| | | text-align: center; |
| | | margin-bottom: 30px; |
| | | padding: 20px; |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | border-radius: 10px; |
| | | color: white; |
| | | } |
| | | |
| | | .page-header h2 { |
| | | margin: 0 0 10px 0; |
| | | font-size: 28px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .page-header p { |
| | | margin: 0; |
| | | font-size: 16px; |
| | | opacity: 0.9; |
| | | } |
| | | |
| | | .module-cards { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .module-card { |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | border: none; |
| | | border-radius: 12px; |
| | | } |
| | | |
| | | .module-card:hover { |
| | | transform: translateY(-5px); |
| | | box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | .card-content { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 20px; |
| | | } |
| | | |
| | | .card-icon { |
| | | margin-right: 20px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 80px; |
| | | height: 80px; |
| | | background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); |
| | | border-radius: 50%; |
| | | color: white; |
| | | } |
| | | |
| | | .card-info h3 { |
| | | margin: 0 0 10px 0; |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | |
| | | .card-info p { |
| | | margin: 0 0 15px 0; |
| | | font-size: 14px; |
| | | color: #606266; |
| | | line-height: 1.5; |
| | | } |
| | | |
| | | .card-stats { |
| | | display: flex; |
| | | gap: 15px; |
| | | } |
| | | |
| | | .card-stats span { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | background-color: #f5f7fa; |
| | | padding: 4px 8px; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .stats-card { |
| | | margin-bottom: 20px; |
| | | border-radius: 12px; |
| | | } |
| | | |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .stat-item { |
| | | text-align: center; |
| | | padding: 20px; |
| | | } |
| | | |
| | | .stat-number { |
| | | font-size: 32px; |
| | | font-weight: 600; |
| | | color: #409EFF; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .stat-label { |
| | | font-size: 14px; |
| | | color: #606266; |
| | | } |
| | | |
| | | .activity-card { |
| | | border-radius: 12px; |
| | | } |
| | | |
| | | .el-timeline-item { |
| | | padding-bottom: 20px; |
| | | } |
| | | |
| | | .el-timeline-item:last-child { |
| | | padding-bottom: 0; |
| | | } |
| | | </style> |