Browse Source

:update page

0235699曾露 13 hours ago
parent
commit
8c6a34d7cf

+ 55 - 11
.gitignore

@@ -1,3 +1,28 @@
+# Logs
+# Dependencies
+node_modules
+.pnp
+.pnp.js
+
+# Testing
+coverage
+*.lcov
+.nyc_output
+
+# Production builds
+dist
+dist-ssr
+build
+builds
+
+# Environment variables
+.env
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+.env.*.local
+
 # Logs
 logs
 *.log
@@ -7,24 +32,43 @@ yarn-error.log*
 pnpm-debug.log*
 lerna-debug.log*
 
-node_modules
-.DS_Store
-dist
-dist-ssr
-coverage
-*.local
-
-/cypress/videos/
-/cypress/screenshots/
-
 # Editor directories and files
 .vscode/*
 !.vscode/extensions.json
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
 .idea
 *.suo
 *.ntvs*
 *.njsproj
 *.sln
-*.sw?
+*.sw*
+*.swp
+*.swo
+*~
+
+# OS generated files
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
+*.pem
 
+# Build cache
+.parcel-cache
+.eslintcache
+.stylelintcache
+.next
+.nuxt
+.vuepress/dist
+.serverless/
+.fusebox/
+.dynamodb/
+.tern-port
+.vscode-test
+.yarn-integrity
 *.tsbuildinfo

+ 13 - 0
.vscode/settings.json

@@ -0,0 +1,13 @@
+{
+  "explorer.fileNesting.enabled": true,
+  "explorer.fileNesting.patterns": {
+    "tsconfig.json": "tsconfig.*.json, env.d.ts",
+    "vite.config.*": "jsconfig*, vitest.config.*, cypress.config.*, playwright.config.*",
+    "package.json": "package-lock.json, pnpm*, .yarnrc*, yarn*, .eslint*, eslint*, .oxlint*, oxlint*, .prettier*, prettier*, .editorconfig"
+  },
+  "editor.codeActionsOnSave": {
+    "source.fixAll": "explicit"
+  },
+  "editor.formatOnSave": true,
+  "editor.defaultFormatter": "esbenp.prettier-vscode"
+}

+ 6 - 0
env.d.ts

@@ -1 +1,7 @@
 /// <reference types="vite/client" />
+
+declare module '*.vue' {
+  import type { DefineComponent } from 'vue'
+  const component: DefineComponent<{}, {}, any>
+  export default component
+}

+ 306 - 0
src/components/ActionCard.vue

@@ -0,0 +1,306 @@
+<template>
+  <div
+    class="action-card"
+    :class="{
+      'action-card--clickable': clickable,
+      'action-card--disabled': disabled,
+      'action-card--active': active,
+      'action-card--small': size === 'small'
+    }"
+    @click="handleClick"
+  >
+    <div class="card-icon" v-if="icon">
+      <el-icon>
+        <component :is="icon" />
+      </el-icon>
+    </div>
+
+    <div class="card-content">
+      <h4 class="card-title">{{ title }}</h4>
+      <p class="card-description" v-if="description">{{ description }}</p>
+
+      <div class="card-meta" v-if="$slots.meta">
+        <slot name="meta"></slot>
+      </div>
+
+      <div class="card-content-slot" v-if="$slots.content">
+        <slot name="content"></slot>
+      </div>
+
+      <div class="card-stats" v-if="stats && stats.length > 0">
+        <div
+          v-for="(stat, index) in stats"
+          :key="index"
+          class="stat-item"
+        >
+          <span class="stat-value">{{ stat.value }}</span>
+          <span class="stat-label">{{ stat.label }}</span>
+        </div>
+      </div>
+    </div>
+
+    <div class="card-actions" v-if="$slots.actions">
+      <slot name="actions"></slot>
+    </div>
+
+    <div class="card-badge" v-if="badge">
+      <el-tag :type="badge.type" size="small">{{ badge.text }}</el-tag>
+    </div>
+
+    <div class="card-arrow" v-if="clickable && !disabled">
+      <el-icon>
+        <ArrowRight />
+      </el-icon>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ArrowRight } from '@element-plus/icons-vue'
+
+interface Stat {
+  value: string | number
+  label: string
+}
+
+interface Badge {
+  text: string
+  type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
+}
+
+const props = defineProps<{
+  title: string
+  description?: string
+  icon?: any
+  clickable?: boolean
+  disabled?: boolean
+  active?: boolean
+  stats?: Stat[]
+  badge?: Badge
+  size?: 'default' | 'small'
+}>()
+
+const emit = defineEmits<{
+  click: []
+}>()
+
+const handleClick = () => {
+  if (props.clickable && !props.disabled) {
+    emit('click')
+  }
+}
+</script>
+
+<style scoped>
+.action-card {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+  transition: all 0.3s ease;
+  position: relative;
+  overflow: hidden;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+
+.action-card--small {
+  padding: 16px;
+}
+
+.action-card--clickable {
+  cursor: pointer;
+}
+
+.action-card--clickable:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+  border-color: #4facfe;
+}
+
+.action-card--active {
+  border-color: #4facfe;
+  background: linear-gradient(135deg, #f8fbff, #ffffff);
+}
+
+.action-card--active::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 4px;
+  height: 100%;
+  background: #4facfe;
+}
+
+.action-card--disabled {
+  opacity: 0.6;
+  cursor: not-allowed;
+}
+
+.action-card--disabled:hover {
+  transform: none;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border-color: #e4e7ed;
+}
+
+.card-icon {
+  width: 48px;
+  height: 48px;
+  border-radius: 12px;
+  background: linear-gradient(135deg, #4facfe, #00f2fe);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 16px;
+  font-size: 24px;
+  color: white;
+  flex-shrink: 0;
+}
+
+.action-card--small .card-icon {
+  width: 40px;
+  height: 40px;
+  font-size: 20px;
+  margin-bottom: 12px;
+}
+
+.card-content {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+}
+
+.card-title {
+  margin: 0 0 8px 0;
+  color: #2c3e50;
+  font-size: 18px;
+  font-weight: 600;
+  line-height: 1.3;
+}
+
+.action-card--small .card-title {
+  font-size: 16px;
+}
+
+.card-description {
+  margin: 0 0 16px 0;
+  color: #7f8c8d;
+  font-size: 14px;
+  line-height: 1.5;
+  flex: 1;
+}
+
+.action-card--small .card-description {
+  font-size: 13px;
+  margin-bottom: 12px;
+}
+
+.card-meta {
+  margin-bottom: 16px;
+}
+
+.card-content-slot {
+  margin-bottom: 16px;
+  flex: 1;
+}
+
+.card-stats {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 16px;
+  flex-wrap: wrap;
+}
+
+.action-card--small .card-stats {
+  gap: 12px;
+  margin-bottom: 12px;
+}
+
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  text-align: center;
+  min-width: 60px;
+}
+
+.stat-value {
+  font-size: 20px;
+  font-weight: 600;
+  color: #2c3e50;
+  line-height: 1;
+}
+
+.action-card--small .stat-value {
+  font-size: 16px;
+}
+
+.stat-label {
+  font-size: 12px;
+  color: #7f8c8d;
+  margin-top: 4px;
+}
+
+.card-actions {
+  margin-top: auto;
+  display: flex;
+  gap: 8px;
+  flex-wrap: wrap;
+}
+
+.card-badge {
+  position: absolute;
+  top: 16px;
+  right: 16px;
+}
+
+.card-arrow {
+  position: absolute;
+  top: 50%;
+  right: 16px;
+  transform: translateY(-50%);
+  color: #7f8c8d;
+  font-size: 16px;
+  transition: all 0.3s ease;
+}
+
+.action-card--clickable:hover .card-arrow {
+  color: #4facfe;
+  transform: translateY(-50%) translateX(4px);
+}
+
+.action-card--disabled .card-arrow {
+  display: none;
+}
+
+/* 特色列表样式 */
+:deep(.feature-list) {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+
+:deep(.feature-list li) {
+  position: relative;
+  padding-left: 16px;
+  margin-bottom: 8px;
+  font-size: 14px;
+  color: #666;
+  line-height: 1.4;
+}
+
+:deep(.feature-list li::before) {
+  content: '•';
+  position: absolute;
+  left: 0;
+  color: #4facfe;
+  font-weight: bold;
+}
+
+:deep(.feature-list li:last-child) {
+  margin-bottom: 0;
+}
+</style>

+ 112 - 0
src/components/PageHeader.vue

@@ -0,0 +1,112 @@
+<template>
+  <div class="page-header">
+    <div class="header-content">
+      <div class="header-left">
+        <el-breadcrumb separator="/" v-if="breadcrumbs && breadcrumbs.length > 0">
+          <el-breadcrumb-item
+            v-for="(item, index) in breadcrumbs"
+            :key="index"
+            :to="item.path"
+          >
+            {{ item.label }}
+          </el-breadcrumb-item>
+        </el-breadcrumb>
+        <h1 class="page-title">
+          <el-icon class="title-icon" v-if="icon">
+            <component :is="icon" />
+          </el-icon>
+          {{ title }}
+        </h1>
+        <p class="page-description" v-if="description">
+          {{ description }}
+        </p>
+      </div>
+      <div class="header-right" v-if="$slots.actions">
+        <slot name="actions"></slot>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+interface Breadcrumb {
+  label: string
+  path?: string
+}
+
+defineProps<{
+  title: string
+  description?: string
+  icon?: any
+  breadcrumbs?: Breadcrumb[]
+}>()
+</script>
+
+<style scoped>
+.page-header {
+  background: white;
+  border-radius: 12px;
+  padding: 16px 20px;
+  margin-bottom: 16px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+}
+
+.header-content {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+}
+
+.header-left {
+  flex: 1;
+}
+
+.page-title {
+  display: flex;
+  align-items: center;
+  font-size: 28px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin: 8px 0 12px 0;
+  line-height: 1.2;
+}
+
+.title-icon {
+  margin-right: 12px;
+  font-size: 32px;
+  color: #4facfe;
+}
+
+.page-description {
+  color: #7f8c8d;
+  font-size: 16px;
+  line-height: 1.5;
+  margin: 0;
+}
+
+.header-right {
+  margin-left: 20px;
+}
+
+.el-breadcrumb {
+  margin-bottom: 8px;
+}
+
+.el-breadcrumb :deep(.el-breadcrumb__item) {
+  font-size: 14px;
+}
+
+.el-breadcrumb :deep(.el-breadcrumb__inner) {
+  color: #7f8c8d;
+  font-weight: 400;
+}
+
+.el-breadcrumb :deep(.el-breadcrumb__inner:hover) {
+  color: #4facfe;
+}
+
+.el-breadcrumb :deep(.el-breadcrumb__inner.is-link) {
+  color: #4facfe;
+}
+</style>

+ 158 - 0
src/components/StatCard.vue

@@ -0,0 +1,158 @@
+<template>
+  <div class="stat-card" :class="{ 'stat-card--hover': hover }" @click="handleClick">
+    <div class="card-icon" :style="{ background: iconBackground }">
+      <el-icon>
+        <component :is="icon" />
+      </el-icon>
+    </div>
+    <div class="card-content">
+      <div class="card-number">{{ number }}</div>
+      <div class="card-label">{{ title || label }}</div>
+      <div class="card-trend" v-if="trend" :class="getTrendClass()">
+        <el-icon>
+          <ArrowUp v-if="trend.type === 'up'" />
+          <ArrowDown v-if="trend.type === 'down'" />
+          <Minus v-if="trend.type === 'stable'" />
+        </el-icon>
+        <span>{{ trend.value }}{{ trend.unit || '%' }}</span>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed } from 'vue'
+import { ArrowUp, ArrowDown, Minus } from '@element-plus/icons-vue'
+
+interface Trend {
+  value: number
+  type: 'up' | 'down' | 'stable'
+  unit?: string
+}
+
+const props = defineProps<{
+  title?: string
+  label?: string
+  number: string | number
+  icon: any
+  color?: string
+  trend?: Trend
+  hover?: boolean
+  clickable?: boolean
+}>()
+
+const emit = defineEmits<{
+  click: []
+}>()
+
+const iconBackground = computed(() => {
+  if (props.color) {
+    return props.color.includes('gradient') ? props.color : `linear-gradient(135deg, ${props.color}, ${props.color}dd)`
+  }
+  return 'linear-gradient(135deg, #4facfe, #00f2fe)'
+})
+
+const getTrendClass = () => {
+  if (!props.trend) return ''
+  return `trend-${props.trend.type}`
+}
+
+const handleClick = () => {
+  if (props.clickable) {
+    emit('click')
+  }
+}
+</script>
+
+<style scoped>
+.stat-card {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+  display: flex;
+  align-items: center;
+  gap: 16px;
+  transition: all 0.3s ease;
+  position: relative;
+  overflow: hidden;
+}
+
+.stat-card--hover {
+  cursor: pointer;
+}
+
+.stat-card--hover:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+  border-color: #4facfe;
+}
+
+.stat-card::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 4px;
+  background: linear-gradient(90deg, #4facfe, #00f2fe);
+  opacity: 0;
+  transition: opacity 0.3s ease;
+}
+
+.stat-card:hover::before {
+  opacity: 1;
+}
+
+.card-icon {
+  width: 56px;
+  height: 56px;
+  border-radius: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 24px;
+  color: white;
+  flex-shrink: 0;
+}
+
+.card-content {
+  flex: 1;
+}
+
+.card-number {
+  font-size: 32px;
+  font-weight: 700;
+  color: #2c3e50;
+  line-height: 1;
+  margin-bottom: 4px;
+}
+
+.card-label {
+  font-size: 16px;
+  color: #7f8c8d;
+  margin-bottom: 8px;
+  font-weight: 500;
+}
+
+.card-trend {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+  font-size: 14px;
+  font-weight: 500;
+}
+
+.trend-up {
+  color: #00b894;
+}
+
+.trend-down {
+  color: #e17055;
+}
+
+.trend-stable {
+  color: #7f8c8d;
+}
+</style>

+ 1 - 1
src/page/competition/award-mgmt/index.vue

@@ -576,7 +576,7 @@ onMounted(() => {
 
 .action-bar {
   margin-bottom: 16px;
-  
+
   .search-bar {
     display: flex;
     justify-content: flex-end;

+ 5 - 5
src/page/competition/index.vue

@@ -269,7 +269,7 @@ const handleQuickAction = (actionId: string) => {
   margin-bottom: 16px;
   display: flex;
   align-items: center;
-  
+
   &::before {
     content: '';
     width: 4px;
@@ -282,7 +282,7 @@ const handleQuickAction = (actionId: string) => {
 
 .quick-actions {
   margin-bottom: 32px;
-  
+
   .quick-action-btn {
     width: 100%;
     height: 48px;
@@ -292,7 +292,7 @@ const handleQuickAction = (actionId: string) => {
     border: 1px solid #e9ecef;
     color: #495057;
     transition: all 0.3s ease;
-    
+
     &:hover {
       background: #e9ecef;
       transform: translateY(-2px);
@@ -309,7 +309,7 @@ const handleQuickAction = (actionId: string) => {
     border: none;
     box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
   }
-  
+
   .activity-content {
     h4 {
       margin: 0 0 8px 0;
@@ -317,7 +317,7 @@ const handleQuickAction = (actionId: string) => {
       font-weight: 600;
       color: #333;
     }
-    
+
     p {
       margin: 0;
       font-size: 14px;

+ 24 - 24
src/page/competition/personal/index.vue

@@ -95,17 +95,17 @@
                   <el-table-column label="操作" width="200" fixed="right">
                     <template #default="{ row }">
                       <el-button size="small" @click="viewRecord(row)">查看</el-button>
-                      <el-button 
-                        size="small" 
-                        type="primary" 
+                      <el-button
+                        size="small"
+                        type="primary"
                         @click="editRecord(row)"
                         :disabled="row.status === 'approved'"
                       >
                         编辑
                       </el-button>
-                      <el-button 
-                        size="small" 
-                        type="danger" 
+                      <el-button
+                        size="small"
+                        type="danger"
                         @click="deleteRecord(row)"
                         :disabled="row.status === 'approved'"
                       >
@@ -190,7 +190,7 @@
                       </el-button>
                     </div>
                   </el-card>
-                  
+
                   <el-card class="management-card" style="margin-top: 20px;">
                     <template #header>
                       <span>材料补充</span>
@@ -455,19 +455,19 @@ const recordRules = {
 // 筛选后的记录
 const filteredRecords = computed(() => {
   let records = personalRecords.value
-  
+
   if (searchKeyword.value) {
-    records = records.filter(record => 
+    records = records.filter(record =>
       record.competitionName.includes(searchKeyword.value) ||
       getLevelText(record.level).includes(searchKeyword.value) ||
       getRankText(record.rank).includes(searchKeyword.value)
     )
   }
-  
+
   if (statusFilter.value) {
     records = records.filter(record => record.status === statusFilter.value)
   }
-  
+
   return records
 })
 
@@ -584,7 +584,7 @@ const saveRecord = () => {
     personalRecords.value.unshift(newRecord)
     ElMessage.success('新增成功')
   }
-  
+
   showAddDialog.value = false
   editingRecord.value = null
   Object.keys(recordForm).forEach(key => {
@@ -621,7 +621,7 @@ const beforeUpload = (file: File) => {
     ElMessage.error('文件大小不能超过 10MB!')
     return false
   }
-  
+
   ElMessage.success('文件上传成功')
   return false // 阻止自动上传
 }
@@ -659,18 +659,18 @@ onMounted(() => {
   display: flex;
   justify-content: space-between;
   align-items: center;
-  
+
   .avatar-section {
     display: flex;
     align-items: center;
     gap: 20px;
-    
+
     .user-info {
       h3 {
         margin: 0 0 8px 0;
         color: #333;
       }
-      
+
       p {
         margin: 4px 0;
         color: #666;
@@ -678,21 +678,21 @@ onMounted(() => {
       }
     }
   }
-  
+
   .stats-section {
     display: flex;
     gap: 40px;
-    
+
     .stat-item {
       text-align: center;
-      
+
       .stat-number {
         font-size: 32px;
         font-weight: bold;
         color: #409eff;
         margin-bottom: 8px;
       }
-      
+
       .stat-label {
         font-size: 14px;
         color: #666;
@@ -718,17 +718,17 @@ onMounted(() => {
 
 .timeline-card {
   margin-bottom: 16px;
-  
+
   h4 {
     margin: 0 0 8px 0;
     color: #333;
   }
-  
+
   p {
     margin: 0 0 12px 0;
     color: #666;
   }
-  
+
   .feedback {
     margin-top: 12px;
   }
@@ -742,7 +742,7 @@ onMounted(() => {
   display: flex;
   flex-direction: column;
   gap: 12px;
-  
+
   .el-button {
     justify-content: flex-start;
   }

+ 12 - 12
src/page/competition/query/index.vue

@@ -17,7 +17,7 @@
             <el-button type="text" @click="resetQuery">重置</el-button>
           </div>
         </template>
-        
+
         <el-form :model="queryForm" label-width="100px" :inline="false">
           <el-row :gutter="20">
             <el-col :span="8">
@@ -36,7 +36,7 @@
               </el-form-item>
             </el-col>
           </el-row>
-          
+
           <el-row :gutter="20">
             <el-col :span="8">
               <el-form-item label="竞赛类别">
@@ -72,7 +72,7 @@
               </el-form-item>
             </el-col>
           </el-row>
-          
+
           <el-row :gutter="20">
             <el-col :span="8">
               <el-form-item label="指导教师">
@@ -102,7 +102,7 @@
               </el-form-item>
             </el-col>
           </el-row>
-          
+
           <el-row>
             <el-col :span="24">
               <el-form-item>
@@ -128,7 +128,7 @@
             </div>
           </div>
         </template>
-        
+
         <el-table
           :data="paginatedResults"
           v-loading="loading"
@@ -176,7 +176,7 @@
             </template>
           </el-table-column>
         </el-table>
-        
+
         <!-- 分页 -->
         <div class="pagination-container">
           <el-pagination
@@ -419,11 +419,11 @@ const getStatusText = (status: string) => {
 // 事件处理
 const handleQuery = () => {
   loading.value = true
-  
+
   // 模拟查询延迟
   setTimeout(() => {
     let results = [...allAwards.value]
-    
+
     // 应用查询条件
     if (queryForm.studentName) {
       results = results.filter(item => item.studentName.includes(queryForm.studentName))
@@ -449,11 +449,11 @@ const handleQuery = () => {
     if (queryForm.status) {
       results = results.filter(item => item.status === queryForm.status)
     }
-    
+
     queryResults.value = results
     pagination.currentPage = 1
     loading.value = false
-    
+
     ElMessage.success(`查询完成,共找到 ${results.length} 条记录`)
   }, 1000)
 }
@@ -531,7 +531,7 @@ onMounted(() => {
   justify-content: space-between;
   align-items: center;
   font-weight: 600;
-  
+
   .header-actions {
     display: flex;
     gap: 8px;
@@ -549,7 +549,7 @@ onMounted(() => {
     background: #f8f9fa;
     border-radius: 8px;
     padding: 16px;
-    
+
     h4 {
       margin: 0 0 16px 0;
       text-align: center;

+ 646 - 0
src/page/lab-mgmt/equipment-borrow/index.vue

@@ -0,0 +1,646 @@
+<template>
+  <div class="equipment-borrow-container">
+    <!-- 页面头部 -->
+    <PageHeader
+      title="实验设备借用管理"
+      description="在线申请设备借用,智能审批流程,完整使用记录管理"
+      :icon="Box"
+      :breadcrumbs="breadcrumbs"
+    />
+
+    <!-- 功能选项卡 -->
+    <el-tabs v-model="activeTab" class="function-tabs">
+      <el-tab-pane label="设备申请" name="apply">
+        <div class="tab-content">
+          <!-- 设备申请表单 -->
+          <div class="apply-section">
+            <el-card class="apply-form-card">
+              <template #header>
+                <div class="card-header">
+                  <el-icon><DocumentAdd /></el-icon>
+                  <span>设备借用申请</span>
+                </div>
+              </template>
+
+              <el-form :model="applyForm" :rules="applyRules" ref="applyFormRef" label-width="120px">
+                <el-row :gutter="24">
+                  <el-col :span="12">
+                    <el-form-item label="申请人" prop="applicant">
+                      <el-input v-model="applyForm.applicant" placeholder="请输入申请人姓名" />
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="12">
+                    <el-form-item label="学号/工号" prop="studentId">
+                      <el-input v-model="applyForm.studentId" placeholder="请输入学号或工号" />
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+
+                <el-row :gutter="24">
+                  <el-col :span="12">
+                    <el-form-item label="联系电话" prop="phone">
+                      <el-input v-model="applyForm.phone" placeholder="请输入联系电话" />
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="12">
+                    <el-form-item label="所属院系" prop="department">
+                      <el-select v-model="applyForm.department" placeholder="请选择所属院系" style="width: 100%">
+                        <el-option label="计算机学院" value="computer" />
+                        <el-option label="电子工程学院" value="electronic" />
+                        <el-option label="机械工程学院" value="mechanical" />
+                        <el-option label="化学工程学院" value="chemical" />
+                      </el-select>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+
+                <el-form-item label="设备类型" prop="equipmentType">
+                  <el-select v-model="applyForm.equipmentType" placeholder="请选择设备类型" style="width: 100%" @change="onEquipmentTypeChange">
+                    <el-option label="显微镜" value="microscope" />
+                    <el-option label="投影仪" value="projector" />
+                    <el-option label="实验台" value="lab-table" />
+                    <el-option label="测量仪器" value="measurement" />
+                    <el-option label="计算机设备" value="computer" />
+                  </el-select>
+                </el-form-item>
+
+                <el-form-item label="具体设备" prop="specificEquipment">
+                  <el-select v-model="applyForm.specificEquipment" placeholder="请选择具体设备" style="width: 100%">
+                    <el-option
+                      v-for="equipment in availableEquipment"
+                      :key="equipment.id"
+                      :label="`${equipment.name} (${equipment.location}) - ${equipment.status}`"
+                      :value="equipment.id"
+                      :disabled="equipment.status !== '可用'"
+                    />
+                  </el-select>
+                </el-form-item>
+
+                <el-row :gutter="24">
+                  <el-col :span="12">
+                    <el-form-item label="借用开始时间" prop="startTime">
+                      <el-date-picker
+                        v-model="applyForm.startTime"
+                        type="datetime"
+                        placeholder="选择开始时间"
+                        style="width: 100%"
+                      />
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="12">
+                    <el-form-item label="借用结束时间" prop="endTime">
+                      <el-date-picker
+                        v-model="applyForm.endTime"
+                        type="datetime"
+                        placeholder="选择结束时间"
+                        style="width: 100%"
+                      />
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+
+                <el-form-item label="使用目的" prop="purpose">
+                  <el-input
+                    v-model="applyForm.purpose"
+                    type="textarea"
+                    :rows="3"
+                    placeholder="请详细说明设备使用目的和实验内容"
+                  />
+                </el-form-item>
+
+                <el-form-item label="指导教师" prop="supervisor">
+                  <el-input v-model="applyForm.supervisor" placeholder="请输入指导教师姓名" />
+                </el-form-item>
+
+                <el-form-item>
+                  <el-button type="primary" @click="submitApplication" :loading="submitting">
+                    <el-icon><Check /></el-icon>
+                    提交申请
+                  </el-button>
+                  <el-button @click="resetForm">
+                    <el-icon><Refresh /></el-icon>
+                    重置表单
+                  </el-button>
+                </el-form-item>
+              </el-form>
+            </el-card>
+          </div>
+        </div>
+      </el-tab-pane>
+
+      <el-tab-pane label="审批管理" name="approval">
+        <div class="tab-content">
+          <!-- 审批列表 -->
+          <div class="approval-section">
+            <div class="section-header">
+              <h3>待审批申请</h3>
+              <el-button type="primary" @click="batchApproval">
+                <el-icon><Select /></el-icon>
+                批量审批
+              </el-button>
+            </div>
+
+            <el-table :data="approvalList" style="width: 100%" @selection-change="handleSelectionChange">
+              <el-table-column type="selection" width="55" />
+              <el-table-column prop="id" label="申请编号" width="120" />
+              <el-table-column prop="applicant" label="申请人" width="100" />
+              <el-table-column prop="department" label="院系" width="120" />
+              <el-table-column prop="equipmentName" label="设备名称" width="150" />
+              <el-table-column prop="startTime" label="开始时间" width="180" />
+              <el-table-column prop="endTime" label="结束时间" width="180" />
+              <el-table-column prop="status" label="状态" width="100">
+                <template #default="scope">
+                  <el-tag :type="getStatusType(scope.row.status)">
+                    {{ scope.row.status }}
+                  </el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="200">
+                <template #default="scope">
+                  <el-button size="small" type="success" @click="approveApplication(scope.row)">
+                    <el-icon><Check /></el-icon>
+                    通过
+                  </el-button>
+                  <el-button size="small" type="danger" @click="rejectApplication(scope.row)">
+                    <el-icon><Close /></el-icon>
+                    拒绝
+                  </el-button>
+                  <el-button size="small" @click="viewDetails(scope.row)">
+                    <el-icon><View /></el-icon>
+                    详情
+                  </el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+
+            <el-pagination
+              v-model:current-page="approvalPagination.currentPage"
+              v-model:page-size="approvalPagination.pageSize"
+              :page-sizes="[10, 20, 50, 100]"
+              :total="approvalPagination.total"
+              layout="total, sizes, prev, pager, next, jumper"
+              class="pagination"
+            />
+          </div>
+        </div>
+      </el-tab-pane>
+
+      <el-tab-pane label="使用记录" name="records">
+        <div class="tab-content">
+          <!-- 使用记录查询 -->
+          <div class="records-section">
+            <div class="search-bar">
+              <el-form :model="searchForm" :inline="true">
+                <el-form-item label="申请人">
+                  <el-input v-model="searchForm.applicant" placeholder="请输入申请人" clearable />
+                </el-form-item>
+                <el-form-item label="设备名称">
+                  <el-input v-model="searchForm.equipmentName" placeholder="请输入设备名称" clearable />
+                </el-form-item>
+                <el-form-item label="时间范围">
+                  <el-date-picker
+                    v-model="searchForm.dateRange"
+                    type="daterange"
+                    range-separator="至"
+                    start-placeholder="开始日期"
+                    end-placeholder="结束日期"
+                  />
+                </el-form-item>
+                <el-form-item>
+                  <el-button type="primary" @click="searchRecords">
+                    <el-icon><Search /></el-icon>
+                    查询
+                  </el-button>
+                  <el-button @click="resetSearch">
+                    <el-icon><Refresh /></el-icon>
+                    重置
+                  </el-button>
+                  <el-button type="success" @click="exportRecords">
+                    <el-icon><Download /></el-icon>
+                    导出
+                  </el-button>
+                </el-form-item>
+              </el-form>
+            </div>
+
+            <el-table :data="recordsList" style="width: 100%">
+              <el-table-column prop="id" label="记录编号" width="120" />
+              <el-table-column prop="applicant" label="申请人" width="100" />
+              <el-table-column prop="studentId" label="学号/工号" width="120" />
+              <el-table-column prop="equipmentName" label="设备名称" width="150" />
+              <el-table-column prop="location" label="设备位置" width="120" />
+              <el-table-column prop="startTime" label="开始时间" width="180" />
+              <el-table-column prop="endTime" label="结束时间" width="180" />
+              <el-table-column prop="actualReturnTime" label="实际归还时间" width="180" />
+              <el-table-column prop="status" label="状态" width="100">
+                <template #default="scope">
+                  <el-tag :type="getRecordStatusType(scope.row.status)">
+                    {{ scope.row.status }}
+                  </el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="120">
+                <template #default="scope">
+                  <el-button size="small" @click="viewRecordDetails(scope.row)">
+                    <el-icon><View /></el-icon>
+                    详情
+                  </el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+
+            <el-pagination
+              v-model:current-page="recordsPagination.currentPage"
+              v-model:page-size="recordsPagination.pageSize"
+              :page-sizes="[10, 20, 50, 100]"
+              :total="recordsPagination.total"
+              layout="total, sizes, prev, pager, next, jumper"
+              class="pagination"
+            />
+          </div>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+
+    <!-- 申请详情对话框 -->
+    <el-dialog v-model="detailDialogVisible" title="申请详情" width="60%">
+      <div v-if="selectedApplication" class="detail-content">
+        <el-descriptions :column="2" border>
+          <el-descriptions-item label="申请编号">{{ selectedApplication.id }}</el-descriptions-item>
+          <el-descriptions-item label="申请人">{{ selectedApplication.applicant }}</el-descriptions-item>
+          <el-descriptions-item label="学号/工号">{{ selectedApplication.studentId }}</el-descriptions-item>
+          <el-descriptions-item label="联系电话">{{ selectedApplication.phone }}</el-descriptions-item>
+          <el-descriptions-item label="所属院系">{{ selectedApplication.department }}</el-descriptions-item>
+          <el-descriptions-item label="设备名称">{{ selectedApplication.equipmentName }}</el-descriptions-item>
+          <el-descriptions-item label="借用开始时间">{{ selectedApplication.startTime }}</el-descriptions-item>
+          <el-descriptions-item label="借用结束时间">{{ selectedApplication.endTime }}</el-descriptions-item>
+          <el-descriptions-item label="使用目的" :span="2">{{ selectedApplication.purpose }}</el-descriptions-item>
+          <el-descriptions-item label="指导教师">{{ selectedApplication.supervisor }}</el-descriptions-item>
+          <el-descriptions-item label="申请状态">
+            <el-tag :type="getStatusType(selectedApplication.status)">
+              {{ selectedApplication.status }}
+            </el-tag>
+          </el-descriptions-item>
+        </el-descriptions>
+      </div>
+      <template #footer>
+        <el-button @click="detailDialogVisible = false">关闭</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import {
+  Box,
+  DocumentAdd,
+  Check,
+  Close,
+  View,
+  Search,
+  Refresh,
+  Download,
+  Select
+} from '@element-plus/icons-vue'
+import PageHeader from '../../edu-industry/components/PageHeader.vue'
+
+// 面包屑导航
+const breadcrumbs = ref([
+  { label: '首页', path: '/' },
+  { label: '实验室管理', path: '/lab-mgmt' },
+  { label: '设备借用管理' }
+])
+
+// 当前选项卡
+const activeTab = ref('apply')
+
+// 申请表单
+const applyForm = reactive({
+  applicant: '',
+  studentId: '',
+  phone: '',
+  department: '',
+  equipmentType: '',
+  specificEquipment: '',
+  startTime: '',
+  endTime: '',
+  purpose: '',
+  supervisor: ''
+})
+
+// 表单验证规则
+const applyRules = {
+  applicant: [{ required: true, message: '请输入申请人姓名', trigger: 'blur' }],
+  studentId: [{ required: true, message: '请输入学号或工号', trigger: 'blur' }],
+  phone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
+  department: [{ required: true, message: '请选择所属院系', trigger: 'change' }],
+  equipmentType: [{ required: true, message: '请选择设备类型', trigger: 'change' }],
+  specificEquipment: [{ required: true, message: '请选择具体设备', trigger: 'change' }],
+  startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
+  endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
+  purpose: [{ required: true, message: '请输入使用目的', trigger: 'blur' }],
+  supervisor: [{ required: true, message: '请输入指导教师', trigger: 'blur' }]
+}
+
+const applyFormRef = ref()
+const submitting = ref(false)
+
+// 可用设备列表
+const availableEquipment = ref([])
+
+// 审批列表
+const approvalList = ref([
+  {
+    id: 'APP001',
+    applicant: '张三',
+    studentId: '2021001',
+    phone: '13800138001',
+    department: '计算机学院',
+    equipmentName: '光学显微镜-001',
+    startTime: '2024-01-16 09:00',
+    endTime: '2024-01-16 17:00',
+    purpose: '细胞结构观察实验',
+    supervisor: '李教授',
+    status: '待审批'
+  },
+  {
+    id: 'APP002',
+    applicant: '李四',
+    studentId: '2021002',
+    phone: '13800138002',
+    department: '电子工程学院',
+    equipmentName: '投影仪-003',
+    startTime: '2024-01-17 14:00',
+    endTime: '2024-01-17 16:00',
+    purpose: '课程演示',
+    supervisor: '王教授',
+    status: '待审批'
+  }
+])
+
+const approvalPagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 2
+})
+
+// 使用记录
+const recordsList = ref([
+  {
+    id: 'REC001',
+    applicant: '王五',
+    studentId: '2020001',
+    equipmentName: '光学显微镜-002',
+    location: '实验室A-101',
+    startTime: '2024-01-15 09:00',
+    endTime: '2024-01-15 17:00',
+    actualReturnTime: '2024-01-15 16:45',
+    status: '已归还'
+  },
+  {
+    id: 'REC002',
+    applicant: '赵六',
+    studentId: '2020002',
+    equipmentName: '投影仪-001',
+    location: '实验室B-203',
+    startTime: '2024-01-14 10:00',
+    endTime: '2024-01-14 12:00',
+    actualReturnTime: '2024-01-14 12:10',
+    status: '已归还'
+  }
+])
+
+const recordsPagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 2
+})
+
+// 搜索表单
+const searchForm = reactive({
+  applicant: '',
+  equipmentName: '',
+  dateRange: []
+})
+
+// 选中的申请
+const selectedApplications = ref([])
+const selectedApplication = ref(null)
+const detailDialogVisible = ref(false)
+
+// 设备类型变化
+const onEquipmentTypeChange = (type: string) => {
+  // 根据设备类型加载可用设备
+  const equipmentMap = {
+    microscope: [
+      { id: 'MIC001', name: '光学显微镜-001', location: '实验室A-101', status: '可用' },
+      { id: 'MIC002', name: '光学显微镜-002', location: '实验室A-102', status: '使用中' },
+      { id: 'MIC003', name: '电子显微镜-001', location: '实验室A-103', status: '可用' }
+    ],
+    projector: [
+      { id: 'PRO001', name: '投影仪-001', location: '实验室B-201', status: '可用' },
+      { id: 'PRO002', name: '投影仪-002', location: '实验室B-202', status: '维修中' },
+      { id: 'PRO003', name: '投影仪-003', location: '实验室B-203', status: '可用' }
+    ]
+  }
+
+  availableEquipment.value = equipmentMap[type] || []
+  applyForm.specificEquipment = ''
+}
+
+// 提交申请
+const submitApplication = async () => {
+  if (!applyFormRef.value) return
+
+  await applyFormRef.value.validate((valid) => {
+    if (valid) {
+      submitting.value = true
+
+      // 模拟提交
+      setTimeout(() => {
+        ElMessage.success('申请提交成功,等待审批')
+        resetForm()
+        submitting.value = false
+      }, 1000)
+    }
+  })
+}
+
+// 重置表单
+const resetForm = () => {
+  if (applyFormRef.value) {
+    applyFormRef.value.resetFields()
+  }
+  availableEquipment.value = []
+}
+
+// 审批操作
+const approveApplication = (application) => {
+  ElMessageBox.confirm('确认通过此申请?', '确认操作', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    application.status = '已通过'
+    ElMessage.success('审批通过')
+  })
+}
+
+const rejectApplication = (application) => {
+  ElMessageBox.prompt('请输入拒绝理由', '拒绝申请', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    inputPattern: /.+/,
+    inputErrorMessage: '请输入拒绝理由'
+  }).then(({ value }) => {
+    application.status = '已拒绝'
+    application.rejectReason = value
+    ElMessage.success('已拒绝申请')
+  })
+}
+
+// 查看详情
+const viewDetails = (application) => {
+  selectedApplication.value = application
+  detailDialogVisible.value = true
+}
+
+const viewRecordDetails = (record) => {
+  // 查看使用记录详情
+  console.log('查看记录详情:', record)
+}
+
+// 批量审批
+const batchApproval = () => {
+  if (selectedApplications.value.length === 0) {
+    ElMessage.warning('请选择要审批的申请')
+    return
+  }
+
+  ElMessageBox.confirm(`确认批量通过 ${selectedApplications.value.length} 个申请?`, '批量审批', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    selectedApplications.value.forEach(app => {
+      app.status = '已通过'
+    })
+    ElMessage.success('批量审批完成')
+    selectedApplications.value = []
+  })
+}
+
+const handleSelectionChange = (selection) => {
+  selectedApplications.value = selection
+}
+
+// 搜索记录
+const searchRecords = () => {
+  console.log('搜索记录:', searchForm)
+  // 实现搜索逻辑
+}
+
+const resetSearch = () => {
+  Object.assign(searchForm, {
+    applicant: '',
+    equipmentName: '',
+    dateRange: []
+  })
+}
+
+const exportRecords = () => {
+  ElMessage.success('导出功能开发中')
+}
+
+// 状态类型
+const getStatusType = (status: string) => {
+  const typeMap = {
+    '待审批': 'warning',
+    '已通过': 'success',
+    '已拒绝': 'danger',
+    '使用中': 'primary',
+    '已完成': 'info'
+  }
+  return typeMap[status] || 'info'
+}
+
+const getRecordStatusType = (status: string) => {
+  const typeMap = {
+    '使用中': 'primary',
+    '已归还': 'success',
+    '逾期': 'danger',
+    '损坏': 'warning'
+  }
+  return typeMap[status] || 'info'
+}
+
+onMounted(() => {
+  console.log('设备借用管理模块已加载')
+})
+</script>
+
+<style scoped lang="scss">
+.equipment-borrow-container {
+  padding: 16px;
+  background: #ffffff;
+  min-height: 100vh;
+}
+
+.function-tabs {
+  margin-top: 16px;
+
+  :deep(.el-tabs__header) {
+    margin-bottom: 20px;
+  }
+}
+
+.tab-content {
+  padding: 0;
+}
+
+.apply-form-card {
+  .card-header {
+    display: flex;
+    align-items: center;
+    font-size: 16px;
+    font-weight: 600;
+
+    .el-icon {
+      margin-right: 8px;
+      color: #4facfe;
+    }
+  }
+}
+
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+
+  h3 {
+    margin: 0;
+    font-size: 18px;
+    font-weight: 600;
+    color: #2c3e50;
+  }
+}
+
+.search-bar {
+  background: #f8f9fa;
+  padding: 16px;
+  border-radius: 8px;
+  margin-bottom: 16px;
+}
+
+.pagination {
+  margin-top: 16px;
+  text-align: right;
+}
+
+.detail-content {
+  padding: 16px 0;
+}
+</style>

+ 460 - 0
src/page/lab-mgmt/index.vue

@@ -0,0 +1,460 @@
+<template>
+  <div class="lab-mgmt-container">
+    <!-- 页面头部 -->
+    <PageHeader
+      title="实验室管理"
+      description="智能化实验室设备管理,提供设备借用、远程控制等全方位服务"
+      :icon="Monitor"
+      :breadcrumbs="breadcrumbs"
+    />
+
+    <!-- 数据概览 -->
+    <div class="overview-section">
+      <el-row :gutter="24">
+        <el-col :span="6">
+          <StatCard
+            title="设备总数"
+            :number="overviewData.totalEquipment"
+            icon="Monitor"
+            color="#4facfe"
+            :trend="{ value: 5, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="在用设备"
+            :number="overviewData.inUseEquipment"
+            icon="CircleCheck"
+            color="#43e97b"
+            :trend="{ value: 8, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="待审批"
+            :number="overviewData.pendingApproval"
+            icon="Clock"
+            color="#fa709a"
+            :trend="{ value: 2, type: 'down' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="故障设备"
+            :number="overviewData.faultyEquipment"
+            icon="Warning"
+            color="#ff9a9e"
+            :trend="{ value: 1, type: 'down' }"
+          />
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 核心功能模块 -->
+    <div class="core-functions">
+      <h2 class="section-title">核心功能</h2>
+      <el-row :gutter="24">
+        <el-col :span="12">
+          <div class="function-card" @click="navigateToEquipmentBorrow">
+            <div class="card-header">
+              <el-icon class="card-icon">
+                <Box />
+              </el-icon>
+              <h3>实验设备借用管理</h3>
+            </div>
+            <div class="card-content">
+              <p>在线申请替代纸质登记,完整的审批流程和使用记录管理</p>
+              <ul class="feature-list">
+                <li>线上申请系统</li>
+                <li>智能审批流程</li>
+                <li>设备使用记录</li>
+                <li>设备状态管理</li>
+              </ul>
+            </div>
+            <div class="card-footer">
+              <el-button type="primary" size="large">
+                <el-icon><ArrowRight /></el-icon>
+                进入管理
+              </el-button>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div class="function-card" @click="navigateToRemoteControl">
+            <div class="card-header">
+              <el-icon class="card-icon">
+                <Monitor />
+              </el-icon>
+              <h3>远程设备控制</h3>
+            </div>
+            <div class="card-content">
+              <p>远程设备电源管理,实时状态监控和智能提醒机制</p>
+              <ul class="feature-list">
+                <li>一键远程关机</li>
+                <li>设备状态监控</li>
+                <li>网络连接监控</li>
+                <li>异常提醒系统</li>
+              </ul>
+            </div>
+            <div class="card-footer">
+              <el-button type="primary" size="large">
+                <el-icon><ArrowRight /></el-icon>
+                进入控制
+              </el-button>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 快速操作 -->
+    <div class="quick-actions">
+      <h2 class="section-title">快速操作</h2>
+      <el-row :gutter="16">
+        <el-col :span="6">
+          <el-button class="quick-action-btn" @click="quickApplyEquipment">
+            <el-icon><Plus /></el-icon>
+            设备申请
+          </el-button>
+        </el-col>
+        <el-col :span="6">
+          <el-button class="quick-action-btn" @click="quickViewStatus">
+            <el-icon><View /></el-icon>
+            状态查看
+          </el-button>
+        </el-col>
+        <el-col :span="6">
+          <el-button class="quick-action-btn" @click="quickRemoteShutdown">
+            <el-icon><SwitchButton /></el-icon>
+            远程关机
+          </el-button>
+        </el-col>
+        <el-col :span="6">
+          <el-button class="quick-action-btn" @click="quickMaintenanceReport">
+            <el-icon><Tools /></el-icon>
+            故障报修
+          </el-button>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 最近活动 -->
+    <div class="recent-activities">
+      <h2 class="section-title">最近活动</h2>
+      <div class="activity-list">
+        <div class="activity-card" v-for="activity in recentActivities" :key="activity.id">
+          <div class="activity-icon">
+            <el-icon>
+              <component :is="activity.icon" />
+            </el-icon>
+          </div>
+          <div class="activity-content">
+            <h4>{{ activity.title }}</h4>
+            <p>{{ activity.description }}</p>
+            <span class="activity-time">{{ activity.time }}</span>
+          </div>
+          <div class="activity-status">
+            <el-tag :type="activity.status === '已完成' ? 'success' : activity.status === '进行中' ? 'warning' : 'info'">
+              {{ activity.status }}
+            </el-tag>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue'
+import { useRouter } from 'vue-router'
+import {
+  Monitor,
+  Box,
+  ArrowRight,
+  Plus,
+  View,
+  SwitchButton,
+  Tools,
+  CircleCheck,
+  Clock,
+  Warning
+} from '@element-plus/icons-vue'
+import PageHeader from '../edu-industry/components/PageHeader.vue'
+import StatCard from '../edu-industry/components/StatCard.vue'
+
+const router = useRouter()
+
+// 面包屑导航
+const breadcrumbs = ref([
+  { label: '首页', path: '/' },
+  { label: '实验室管理' }
+])
+
+// 概览数据
+const overviewData = ref({
+  totalEquipment: 156,
+  inUseEquipment: 89,
+  pendingApproval: 12,
+  faultyEquipment: 3
+})
+
+// 最近活动数据
+const recentActivities = ref([
+  {
+    id: 1,
+    title: '张三申请借用显微镜',
+    description: '申请时间:2024-01-15,预计使用3天',
+    time: '2024-01-15 09:30',
+    status: '待审批',
+    icon: 'Box'
+  },
+  {
+    id: 2,
+    title: '实验室A电脑远程关机成功',
+    description: '共关闭15台设备,节能模式已启动',
+    time: '2024-01-15 18:00',
+    status: '已完成',
+    icon: 'Monitor'
+  },
+  {
+    id: 3,
+    title: '李四归还投影仪设备',
+    description: '设备状态良好,已完成归还流程',
+    time: '2024-01-15 16:45',
+    status: '已完成',
+    icon: 'CircleCheck'
+  },
+  {
+    id: 4,
+    title: '实验室B网络异常提醒',
+    description: '检测到3台设备网络连接中断',
+    time: '2024-01-15 14:20',
+    status: '进行中',
+    icon: 'Warning'
+  }
+])
+
+// 导航方法
+const navigateToEquipmentBorrow = () => {
+  router.push('/lab-mgmt/equipment-borrow')
+}
+
+const navigateToRemoteControl = () => {
+  router.push('/lab-mgmt/remote-control')
+}
+
+// 快速操作方法
+const quickApplyEquipment = () => {
+  router.push('/lab-mgmt/equipment-borrow?action=apply')
+}
+
+const quickViewStatus = () => {
+  router.push('/lab-mgmt/remote-control?tab=status')
+}
+
+const quickRemoteShutdown = () => {
+  router.push('/lab-mgmt/remote-control?tab=control')
+}
+
+const quickMaintenanceReport = () => {
+  // 打开故障报修对话框或跳转到相关页面
+  console.log('打开故障报修')
+}
+
+onMounted(() => {
+  // 初始化数据
+  console.log('实验室管理模块已加载')
+})
+</script>
+
+<style scoped lang="scss">
+.lab-mgmt-container {
+  padding: 16px;
+  background: #ffffff;
+  min-height: 100vh;
+}
+
+.overview-section {
+  margin-bottom: 20px;
+}
+
+.core-functions {
+  margin-bottom: 20px;
+}
+
+.section-title {
+  font-size: 20px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin-bottom: 16px;
+  display: flex;
+  align-items: center;
+
+  &::before {
+    content: '';
+    width: 4px;
+    height: 20px;
+    background: #4facfe;
+    margin-right: 12px;
+    border-radius: 2px;
+  }
+}
+
+.function-card {
+  background: white;
+  border-radius: 16px;
+  padding: 24px;
+  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+  cursor: pointer;
+  transition: all 0.3s ease;
+  height: 100%;
+
+  &:hover {
+    transform: translateY(-4px);
+    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
+  }
+}
+
+.card-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 16px;
+
+  .card-icon {
+    font-size: 32px;
+    color: #4facfe;
+    margin-right: 12px;
+  }
+
+  h3 {
+    font-size: 18px;
+    font-weight: 600;
+    color: #2c3e50;
+    margin: 0;
+  }
+}
+
+.card-content {
+  margin-bottom: 20px;
+
+  p {
+    color: #7f8c8d;
+    margin-bottom: 12px;
+    line-height: 1.6;
+  }
+}
+
+.feature-list {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+
+  li {
+    padding: 4px 0;
+    color: #34495e;
+    font-size: 14px;
+    position: relative;
+    padding-left: 16px;
+
+    &::before {
+      content: '•';
+      color: #4facfe;
+      position: absolute;
+      left: 0;
+    }
+  }
+}
+
+.card-footer {
+  text-align: center;
+}
+
+.quick-actions {
+  margin-bottom: 32px;
+
+  .quick-action-btn {
+    width: 100%;
+    height: 48px;
+    font-size: 14px;
+    border-radius: 8px;
+    background: #f8f9fa;
+    border: 1px solid #e9ecef;
+    color: #495057;
+    transition: all 0.3s ease;
+
+    &:hover {
+      background: #e9ecef;
+      transform: translateY(-2px);
+      box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
+      color: #2c3e50;
+    }
+  }
+}
+
+.recent-activities {
+  .activity-list {
+    display: flex;
+    flex-direction: column;
+    gap: 12px;
+  }
+
+  .activity-card {
+    background: white;
+    border-radius: 12px;
+    padding: 16px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+    border: 1px solid #e4e7ed;
+    display: flex;
+    align-items: center;
+    transition: all 0.3s ease;
+
+    &:hover {
+      transform: translateX(4px);
+      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
+    }
+  }
+
+  .activity-icon {
+    width: 40px;
+    height: 40px;
+    border-radius: 50%;
+    background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-right: 16px;
+
+    .el-icon {
+      color: white;
+      font-size: 18px;
+    }
+  }
+
+  .activity-content {
+    flex: 1;
+
+    h4 {
+      margin: 0 0 4px 0;
+      font-size: 16px;
+      font-weight: 600;
+      color: #2c3e50;
+    }
+
+    p {
+      margin: 0 0 4px 0;
+      color: #7f8c8d;
+      font-size: 14px;
+    }
+
+    .activity-time {
+      font-size: 12px;
+      color: #bdc3c7;
+    }
+  }
+
+  .activity-status {
+    margin-left: 16px;
+  }
+}
+</style>

+ 1049 - 0
src/page/lab-mgmt/remote-control/index.vue

@@ -0,0 +1,1049 @@
+<template>
+  <div class="remote-control-container">
+    <!-- 页面头部 -->
+    <PageHeader
+      title="远程设备控制"
+      description="实时监控设备状态,远程电源管理,智能异常提醒"
+      :icon="Monitor"
+      :breadcrumbs="breadcrumbs"
+    />
+
+    <!-- 功能选项卡 -->
+    <el-tabs v-model="activeTab" class="function-tabs">
+      <el-tab-pane label="设备监控" name="monitor">
+        <div class="tab-content">
+          <!-- 实验室选择 -->
+          <div class="lab-selector">
+            <el-select v-model="selectedLab" placeholder="选择实验室" @change="onLabChange" style="width: 200px">
+              <el-option
+                v-for="lab in labList"
+                :key="lab.id"
+                :label="lab.name"
+                :value="lab.id"
+              />
+            </el-select>
+            <el-button type="primary" @click="refreshDevices" :loading="refreshing">
+              <el-icon><Refresh /></el-icon>
+              刷新状态
+            </el-button>
+          </div>
+
+          <!-- 设备状态概览 -->
+          <div class="status-overview">
+            <el-row :gutter="16">
+              <el-col :span="6">
+                <div class="status-card online">
+                  <div class="status-icon">
+                    <el-icon><CircleCheck /></el-icon>
+                  </div>
+                  <div class="status-info">
+                    <h3>{{ deviceStats.online }}</h3>
+                    <p>在线设备</p>
+                  </div>
+                </div>
+              </el-col>
+              <el-col :span="6">
+                <div class="status-card offline">
+                  <div class="status-icon">
+                    <el-icon><CircleClose /></el-icon>
+                  </div>
+                  <div class="status-info">
+                    <h3>{{ deviceStats.offline }}</h3>
+                    <p>离线设备</p>
+                  </div>
+                </div>
+              </el-col>
+              <el-col :span="6">
+                <div class="status-card warning">
+                  <div class="status-icon">
+                    <el-icon><Warning /></el-icon>
+                  </div>
+                  <div class="status-info">
+                    <h3>{{ deviceStats.warning }}</h3>
+                    <p>异常设备</p>
+                  </div>
+                </div>
+              </el-col>
+              <el-col :span="6">
+                <div class="status-card maintenance">
+                  <div class="status-icon">
+                    <el-icon><Tools /></el-icon>
+                  </div>
+                  <div class="status-info">
+                    <h3>{{ deviceStats.maintenance }}</h3>
+                    <p>维护中</p>
+                  </div>
+                </div>
+              </el-col>
+            </el-row>
+          </div>
+
+          <!-- 设备列表 -->
+          <div class="device-list">
+            <div class="list-header">
+              <h3>设备列表</h3>
+              <div class="header-actions">
+                <el-button type="success" @click="batchPowerOn" :disabled="selectedDevices.length === 0">
+                  <el-icon><VideoPlay /></el-icon>
+                  批量开机
+                </el-button>
+                <el-button type="danger" @click="batchPowerOff" :disabled="selectedDevices.length === 0">
+                  <el-icon><VideoPause /></el-icon>
+                  批量关机
+                </el-button>
+              </div>
+            </div>
+
+            <el-table
+              :data="deviceList"
+              style="width: 100%"
+              @selection-change="handleDeviceSelection"
+              :row-class-name="getRowClassName"
+            >
+              <el-table-column type="selection" width="55" />
+              <el-table-column prop="id" label="设备编号" width="120" />
+              <el-table-column prop="name" label="设备名称" width="150" />
+              <el-table-column prop="type" label="设备类型" width="120" />
+              <el-table-column prop="location" label="位置" width="150" />
+              <el-table-column prop="ip" label="IP地址" width="140" />
+              <el-table-column prop="status" label="状态" width="100">
+                <template #default="scope">
+                  <el-tag :type="getStatusTagType(scope.row.status)">
+                    {{ scope.row.status }}
+                  </el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column prop="lastHeartbeat" label="最后心跳" width="180" />
+              <el-table-column prop="networkStatus" label="网络状态" width="120">
+                <template #default="scope">
+                  <el-tag :type="scope.row.networkStatus === '正常' ? 'success' : 'danger'" size="small">
+                    {{ scope.row.networkStatus }}
+                  </el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="200">
+                <template #default="scope">
+                  <el-button
+                    size="small"
+                    type="success"
+                    @click="powerOn(scope.row)"
+                    :disabled="scope.row.status === '在线'"
+                  >
+                    <el-icon><VideoPlay /></el-icon>
+                    开机
+                  </el-button>
+                  <el-button
+                    size="small"
+                    type="danger"
+                    @click="powerOff(scope.row)"
+                    :disabled="scope.row.status === '离线'"
+                  >
+                    <el-icon><VideoPause /></el-icon>
+                    关机
+                  </el-button>
+                  <el-button size="small" @click="viewDeviceDetails(scope.row)">
+                    <el-icon><View /></el-icon>
+                    详情
+                  </el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </div>
+      </el-tab-pane>
+
+      <el-tab-pane label="远程控制" name="control">
+        <div class="tab-content">
+          <!-- 控制面板 -->
+          <div class="control-panel">
+            <el-row :gutter="24">
+              <el-col :span="12">
+                <el-card class="control-card">
+                  <template #header>
+                    <div class="card-header">
+                      <el-icon><SwitchButton /></el-icon>
+                      <span>电源控制</span>
+                    </div>
+                  </template>
+
+                  <div class="control-section">
+                    <h4>快速操作</h4>
+                    <el-row :gutter="16">
+                      <el-col :span="12">
+                        <el-button type="success" size="large" @click="powerOnAll" style="width: 100%">
+                          <el-icon><VideoPlay /></el-icon>
+                          全部开机
+                        </el-button>
+                      </el-col>
+                      <el-col :span="12">
+                        <el-button type="danger" size="large" @click="powerOffAll" style="width: 100%">
+                          <el-icon><VideoPause /></el-icon>
+                          全部关机
+                        </el-button>
+                      </el-col>
+                    </el-row>
+
+                    <h4 style="margin-top: 20px">定时控制</h4>
+                    <el-form :model="scheduleForm" label-width="100px">
+                      <el-form-item label="操作类型">
+                        <el-radio-group v-model="scheduleForm.action">
+                          <el-radio label="power_on">开机</el-radio>
+                          <el-radio label="power_off">关机</el-radio>
+                        </el-radio-group>
+                      </el-form-item>
+                      <el-form-item label="执行时间">
+                        <el-date-picker
+                          v-model="scheduleForm.time"
+                          type="datetime"
+                          placeholder="选择执行时间"
+                          style="width: 100%"
+                        />
+                      </el-form-item>
+                      <el-form-item label="目标设备">
+                        <el-select v-model="scheduleForm.devices" multiple placeholder="选择设备" style="width: 100%">
+                          <el-option
+                            v-for="device in deviceList"
+                            :key="device.id"
+                            :label="device.name"
+                            :value="device.id"
+                          />
+                        </el-select>
+                      </el-form-item>
+                      <el-form-item>
+                        <el-button type="primary" @click="scheduleTask">
+                          <el-icon><Timer /></el-icon>
+                          设置定时任务
+                        </el-button>
+                      </el-form-item>
+                    </el-form>
+                  </div>
+                </el-card>
+              </el-col>
+
+              <el-col :span="12">
+                <el-card class="control-card">
+                  <template #header>
+                    <div class="card-header">
+                      <el-icon><Bell /></el-icon>
+                      <span>监控设置</span>
+                    </div>
+                  </template>
+
+                  <div class="control-section">
+                    <h4>网络监控</h4>
+                    <el-form :model="monitorForm" label-width="120px">
+                      <el-form-item label="心跳检测间隔">
+                        <el-input-number v-model="monitorForm.heartbeatInterval" :min="10" :max="300" />
+                        <span style="margin-left: 8px">秒</span>
+                      </el-form-item>
+                      <el-form-item label="离线判定时间">
+                        <el-input-number v-model="monitorForm.offlineThreshold" :min="30" :max="600" />
+                        <span style="margin-left: 8px">秒</span>
+                      </el-form-item>
+                      <el-form-item label="异常提醒">
+                        <el-switch v-model="monitorForm.alertEnabled" />
+                      </el-form-item>
+                      <el-form-item label="提醒方式">
+                        <el-checkbox-group v-model="monitorForm.alertMethods">
+                          <el-checkbox label="email">邮件</el-checkbox>
+                          <el-checkbox label="sms">短信</el-checkbox>
+                          <el-checkbox label="system">系统通知</el-checkbox>
+                        </el-checkbox-group>
+                      </el-form-item>
+                      <el-form-item>
+                        <el-button type="primary" @click="saveMonitorSettings">
+                          <el-icon><Check /></el-icon>
+                          保存设置
+                        </el-button>
+                      </el-form-item>
+                    </el-form>
+                  </div>
+                </el-card>
+              </el-col>
+            </el-row>
+          </div>
+        </div>
+      </el-tab-pane>
+
+      <el-tab-pane label="异常提醒" name="alerts">
+        <div class="tab-content">
+          <!-- 提醒列表 -->
+          <div class="alerts-section">
+            <div class="section-header">
+              <h3>异常提醒记录</h3>
+              <el-button type="primary" @click="markAllAsRead">
+                <el-icon><Check /></el-icon>
+                全部标记已读
+              </el-button>
+            </div>
+
+            <div class="alert-filters">
+              <el-form :model="alertFilters" :inline="true">
+                <el-form-item label="提醒类型">
+                  <el-select v-model="alertFilters.type" placeholder="全部类型" clearable>
+                    <el-option label="设备离线" value="offline" />
+                    <el-option label="网络异常" value="network" />
+                    <el-option label="设备故障" value="fault" />
+                    <el-option label="温度异常" value="temperature" />
+                  </el-select>
+                </el-form-item>
+                <el-form-item label="状态">
+                  <el-select v-model="alertFilters.status" placeholder="全部状态" clearable>
+                    <el-option label="未读" value="unread" />
+                    <el-option label="已读" value="read" />
+                    <el-option label="已处理" value="resolved" />
+                  </el-select>
+                </el-form-item>
+                <el-form-item>
+                  <el-button type="primary" @click="filterAlerts">
+                    <el-icon><Search /></el-icon>
+                    筛选
+                  </el-button>
+                </el-form-item>
+              </el-form>
+            </div>
+
+            <div class="alert-list">
+              <div
+                v-for="alert in alertList"
+                :key="alert.id"
+                class="alert-item"
+                :class="{ 'unread': alert.status === 'unread' }"
+              >
+                <div class="alert-icon">
+                  <el-icon :class="getAlertIconClass(alert.type)">
+                    <component :is="getAlertIcon(alert.type)" />
+                  </el-icon>
+                </div>
+                <div class="alert-content">
+                  <h4>{{ alert.title }}</h4>
+                  <p>{{ alert.description }}</p>
+                  <div class="alert-meta">
+                    <span class="alert-time">{{ alert.time }}</span>
+                    <el-tag :type="getAlertTypeTag(alert.type)" size="small">{{ alert.typeLabel }}</el-tag>
+                  </div>
+                </div>
+                <div class="alert-actions">
+                  <el-button
+                    size="small"
+                    @click="markAsRead(alert)"
+                    v-if="alert.status === 'unread'"
+                  >
+                    标记已读
+                  </el-button>
+                  <el-button
+                    size="small"
+                    type="success"
+                    @click="resolveAlert(alert)"
+                    v-if="alert.status !== 'resolved'"
+                  >
+                    标记已处理
+                  </el-button>
+                  <el-button size="small" @click="viewAlertDetails(alert)">
+                    查看详情
+                  </el-button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+
+    <!-- 设备详情对话框 -->
+    <el-dialog v-model="deviceDetailVisible" title="设备详情" width="60%">
+      <div v-if="selectedDevice" class="device-detail">
+        <el-descriptions :column="2" border>
+          <el-descriptions-item label="设备编号">{{ selectedDevice.id }}</el-descriptions-item>
+          <el-descriptions-item label="设备名称">{{ selectedDevice.name }}</el-descriptions-item>
+          <el-descriptions-item label="设备类型">{{ selectedDevice.type }}</el-descriptions-item>
+          <el-descriptions-item label="位置">{{ selectedDevice.location }}</el-descriptions-item>
+          <el-descriptions-item label="IP地址">{{ selectedDevice.ip }}</el-descriptions-item>
+          <el-descriptions-item label="MAC地址">{{ selectedDevice.mac }}</el-descriptions-item>
+          <el-descriptions-item label="状态">
+            <el-tag :type="getStatusTagType(selectedDevice.status)">
+              {{ selectedDevice.status }}
+            </el-tag>
+          </el-descriptions-item>
+          <el-descriptions-item label="网络状态">
+            <el-tag :type="selectedDevice.networkStatus === '正常' ? 'success' : 'danger'" size="small">
+              {{ selectedDevice.networkStatus }}
+            </el-tag>
+          </el-descriptions-item>
+          <el-descriptions-item label="最后心跳">{{ selectedDevice.lastHeartbeat }}</el-descriptions-item>
+          <el-descriptions-item label="运行时间">{{ selectedDevice.uptime }}</el-descriptions-item>
+        </el-descriptions>
+      </div>
+      <template #footer>
+        <el-button @click="deviceDetailVisible = false">关闭</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, onMounted, onUnmounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import {
+  Monitor,
+  Refresh,
+  CircleCheck,
+  CircleClose,
+  Warning,
+  Tools,
+  VideoPlay,
+  VideoPause,
+  View,
+  SwitchButton,
+  Timer,
+  Bell,
+  Check,
+  Search
+} from '@element-plus/icons-vue'
+import PageHeader from '../../edu-industry/components/PageHeader.vue'
+
+// 面包屑导航
+const breadcrumbs = ref([
+  { label: '首页', path: '/' },
+  { label: '实验室管理', path: '/lab-mgmt' },
+  { label: '远程设备控制' }
+])
+
+// 当前选项卡
+const activeTab = ref('monitor')
+
+// 实验室列表
+const labList = ref([
+  { id: 'lab1', name: '实验室A-101' },
+  { id: 'lab2', name: '实验室B-203' },
+  { id: 'lab3', name: '实验室C-305' }
+])
+
+const selectedLab = ref('lab1')
+const refreshing = ref(false)
+
+// 设备统计
+const deviceStats = ref({
+  online: 15,
+  offline: 3,
+  warning: 2,
+  maintenance: 1
+})
+
+// 设备列表
+const deviceList = ref([
+  {
+    id: 'PC001',
+    name: '计算机-001',
+    type: '台式机',
+    location: '实验室A-101',
+    ip: '192.168.1.101',
+    mac: '00:1B:44:11:3A:B7',
+    status: '在线',
+    networkStatus: '正常',
+    lastHeartbeat: '2024-01-15 14:30:25',
+    uptime: '2天3小时'
+  },
+  {
+    id: 'PC002',
+    name: '计算机-002',
+    type: '台式机',
+    location: '实验室A-101',
+    ip: '192.168.1.102',
+    mac: '00:1B:44:11:3A:B8',
+    status: '离线',
+    networkStatus: '异常',
+    lastHeartbeat: '2024-01-15 12:15:10',
+    uptime: '0分钟'
+  },
+  {
+    id: 'PRJ001',
+    name: '投影仪-001',
+    type: '投影设备',
+    location: '实验室A-101',
+    ip: '192.168.1.201',
+    mac: '00:1B:44:11:3A:C1',
+    status: '在线',
+    networkStatus: '正常',
+    lastHeartbeat: '2024-01-15 14:29:45',
+    uptime: '1天12小时'
+  }
+])
+
+const selectedDevices = ref([])
+
+// 定时任务表单
+const scheduleForm = reactive({
+  action: 'power_off',
+  time: '',
+  devices: []
+})
+
+// 监控设置表单
+const monitorForm = reactive({
+  heartbeatInterval: 30,
+  offlineThreshold: 120,
+  alertEnabled: true,
+  alertMethods: ['email', 'system']
+})
+
+// 提醒筛选
+const alertFilters = reactive({
+  type: '',
+  status: ''
+})
+
+// 提醒列表
+const alertList = ref([
+  {
+    id: 'ALT001',
+    type: 'offline',
+    typeLabel: '设备离线',
+    title: '计算机-002 设备离线',
+    description: '设备已离线超过5分钟,请检查网络连接或设备状态',
+    time: '2024-01-15 14:25:30',
+    status: 'unread'
+  },
+  {
+    id: 'ALT002',
+    type: 'network',
+    typeLabel: '网络异常',
+    title: '实验室A-101 网络波动',
+    description: '检测到网络连接不稳定,可能影响设备正常使用',
+    time: '2024-01-15 13:45:15',
+    status: 'read'
+  },
+  {
+    id: 'ALT003',
+    type: 'temperature',
+    typeLabel: '温度异常',
+    title: '服务器机房温度过高',
+    description: '机房温度达到35°C,建议检查空调系统',
+    time: '2024-01-15 12:30:20',
+    status: 'resolved'
+  }
+])
+
+// 选中的设备详情
+const selectedDevice = ref(null)
+const deviceDetailVisible = ref(false)
+
+// 心跳检测定时器
+let heartbeatTimer: NodeJS.Timeout | null = null
+
+// 实验室切换
+const onLabChange = (labId: string) => {
+  console.log('切换实验室:', labId)
+  // 重新加载设备列表
+  loadDevices()
+}
+
+// 刷新设备状态
+const refreshDevices = () => {
+  refreshing.value = true
+  setTimeout(() => {
+    loadDevices()
+    refreshing.value = false
+    ElMessage.success('设备状态已刷新')
+  }, 1000)
+}
+
+// 加载设备列表
+const loadDevices = () => {
+  // 模拟加载设备数据
+  console.log('加载设备列表')
+}
+
+// 设备选择
+const handleDeviceSelection = (selection: any[]) => {
+  selectedDevices.value = selection
+}
+
+// 单个设备电源控制
+const powerOn = (device: any) => {
+  ElMessageBox.confirm(`确认开启设备 ${device.name}?`, '确认操作', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    device.status = '在线'
+    device.networkStatus = '正常'
+    device.lastHeartbeat = new Date().toLocaleString()
+    ElMessage.success('设备开启成功')
+  })
+}
+
+const powerOff = (device: any) => {
+  ElMessageBox.confirm(`确认关闭设备 ${device.name}?`, '确认操作', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    device.status = '离线'
+    device.networkStatus = '异常'
+    ElMessage.success('设备关闭成功')
+  })
+}
+
+// 批量电源控制
+const batchPowerOn = () => {
+  ElMessageBox.confirm(`确认开启选中的 ${selectedDevices.value.length} 台设备?`, '批量开机', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    selectedDevices.value.forEach((device: any) => {
+      device.status = '在线'
+      device.networkStatus = '正常'
+      device.lastHeartbeat = new Date().toLocaleString()
+    })
+    ElMessage.success('批量开机成功')
+    selectedDevices.value = []
+  })
+}
+
+const batchPowerOff = () => {
+  ElMessageBox.confirm(`确认关闭选中的 ${selectedDevices.value.length} 台设备?`, '批量关机', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    selectedDevices.value.forEach((device: any) => {
+      device.status = '离线'
+      device.networkStatus = '异常'
+    })
+    ElMessage.success('批量关机成功')
+    selectedDevices.value = []
+  })
+}
+
+// 全部设备电源控制
+const powerOnAll = () => {
+  ElMessageBox.confirm('确认开启所有设备?', '全部开机', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    deviceList.value.forEach(device => {
+      device.status = '在线'
+      device.networkStatus = '正常'
+      device.lastHeartbeat = new Date().toLocaleString()
+    })
+    ElMessage.success('全部设备开机成功')
+  })
+}
+
+const powerOffAll = () => {
+  ElMessageBox.confirm('确认关闭所有设备?', '全部关机', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    deviceList.value.forEach(device => {
+      device.status = '离线'
+      device.networkStatus = '异常'
+    })
+    ElMessage.success('全部设备关机成功')
+  })
+}
+
+// 定时任务
+const scheduleTask = () => {
+  if (!scheduleForm.time || scheduleForm.devices.length === 0) {
+    ElMessage.warning('请选择执行时间和目标设备')
+    return
+  }
+
+  ElMessage.success('定时任务设置成功')
+  // 重置表单
+  Object.assign(scheduleForm, {
+    action: 'power_off',
+    time: '',
+    devices: []
+  })
+}
+
+// 保存监控设置
+const saveMonitorSettings = () => {
+  ElMessage.success('监控设置保存成功')
+  // 重新启动心跳检测
+  startHeartbeatMonitor()
+}
+
+// 查看设备详情
+const viewDeviceDetails = (device: any) => {
+  selectedDevice.value = device
+  deviceDetailVisible.value = true
+}
+
+// 提醒相关方法
+const markAsRead = (alert: any) => {
+  alert.status = 'read'
+  ElMessage.success('已标记为已读')
+}
+
+const resolveAlert = (alert: any) => {
+  alert.status = 'resolved'
+  ElMessage.success('已标记为已处理')
+}
+
+const markAllAsRead = () => {
+  alertList.value.forEach(alert => {
+    if (alert.status === 'unread') {
+      alert.status = 'read'
+    }
+  })
+  ElMessage.success('全部标记为已读')
+}
+
+const filterAlerts = () => {
+  console.log('筛选提醒:', alertFilters)
+  // 实现筛选逻辑
+}
+
+const viewAlertDetails = (alert: any) => {
+  console.log('查看提醒详情:', alert)
+}
+
+// 样式相关方法
+const getRowClassName = ({ row }: { row: any }) => {
+  if (row.status === '离线') return 'offline-row'
+  if (row.status === '异常') return 'warning-row'
+  return ''
+}
+
+const getStatusTagType = (status: string) => {
+  const typeMap = {
+    '在线': 'success',
+    '离线': 'danger',
+    '异常': 'warning',
+    '维护中': 'info'
+  }
+  return typeMap[status] || 'info'
+}
+
+const getAlertIcon = (type: string) => {
+  const iconMap = {
+    'offline': 'CircleClose',
+    'network': 'Warning',
+    'fault': 'Tools',
+    'temperature': 'Warning'
+  }
+  return iconMap[type] || 'Warning'
+}
+
+const getAlertIconClass = (type: string) => {
+  const classMap = {
+    'offline': 'alert-icon-offline',
+    'network': 'alert-icon-network',
+    'fault': 'alert-icon-fault',
+    'temperature': 'alert-icon-temperature'
+  }
+  return classMap[type] || 'alert-icon-default'
+}
+
+const getAlertTypeTag = (type: string) => {
+  const typeMap = {
+    'offline': 'danger',
+    'network': 'warning',
+    'fault': 'danger',
+    'temperature': 'warning'
+  }
+  return typeMap[type] || 'info'
+}
+
+// 启动心跳监测
+const startHeartbeatMonitor = () => {
+  if (heartbeatTimer) {
+    clearInterval(heartbeatTimer)
+  }
+
+  heartbeatTimer = setInterval(() => {
+    // 模拟心跳检测
+    deviceList.value.forEach(device => {
+      if (device.status === '在线') {
+        device.lastHeartbeat = new Date().toLocaleString()
+      }
+    })
+  }, monitorForm.heartbeatInterval * 1000)
+}
+
+onMounted(() => {
+  console.log('远程设备控制模块已加载')
+  loadDevices()
+  startHeartbeatMonitor()
+})
+
+onUnmounted(() => {
+  if (heartbeatTimer) {
+    clearInterval(heartbeatTimer)
+  }
+})
+</script>
+
+<style scoped lang="scss">
+.remote-control-container {
+  padding: 16px;
+  background: #ffffff;
+  min-height: 100vh;
+}
+
+.function-tabs {
+  margin-top: 16px;
+
+  :deep(.el-tabs__header) {
+    margin-bottom: 20px;
+  }
+}
+
+.tab-content {
+  padding: 0;
+}
+
+.lab-selector {
+  display: flex;
+  align-items: center;
+  gap: 16px;
+  margin-bottom: 20px;
+}
+
+.status-overview {
+  margin-bottom: 24px;
+}
+
+.status-card {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+  display: flex;
+  align-items: center;
+
+  .status-icon {
+    width: 48px;
+    height: 48px;
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-right: 16px;
+
+    .el-icon {
+      font-size: 24px;
+      color: white;
+    }
+  }
+
+  .status-info {
+    h3 {
+      margin: 0 0 4px 0;
+      font-size: 24px;
+      font-weight: 600;
+      color: #2c3e50;
+    }
+
+    p {
+      margin: 0;
+      color: #7f8c8d;
+      font-size: 14px;
+    }
+  }
+
+  &.online .status-icon {
+    background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
+  }
+
+  &.offline .status-icon {
+    background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
+  }
+
+  &.warning .status-icon {
+    background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
+  }
+
+  &.maintenance .status-icon {
+    background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
+  }
+}
+
+.device-list {
+  .list-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 16px;
+
+    h3 {
+      margin: 0;
+      font-size: 18px;
+      font-weight: 600;
+      color: #2c3e50;
+    }
+
+    .header-actions {
+      display: flex;
+      gap: 12px;
+    }
+  }
+}
+
+:deep(.offline-row) {
+  background-color: #fef0f0;
+}
+
+:deep(.warning-row) {
+  background-color: #fdf6ec;
+}
+
+.control-panel {
+  .control-card {
+    height: 100%;
+
+    .card-header {
+      display: flex;
+      align-items: center;
+      font-size: 16px;
+      font-weight: 600;
+
+      .el-icon {
+        margin-right: 8px;
+        color: #4facfe;
+      }
+    }
+  }
+
+  .control-section {
+    h4 {
+      margin: 0 0 12px 0;
+      font-size: 14px;
+      font-weight: 600;
+      color: #2c3e50;
+    }
+  }
+}
+
+.alerts-section {
+  .section-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 16px;
+
+    h3 {
+      margin: 0;
+      font-size: 18px;
+      font-weight: 600;
+      color: #2c3e50;
+    }
+  }
+
+  .alert-filters {
+    background: #f8f9fa;
+    padding: 16px;
+    border-radius: 8px;
+    margin-bottom: 16px;
+  }
+
+  .alert-list {
+    display: flex;
+    flex-direction: column;
+    gap: 12px;
+  }
+
+  .alert-item {
+    background: white;
+    border-radius: 12px;
+    padding: 16px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+    border: 1px solid #e4e7ed;
+    display: flex;
+    align-items: center;
+    transition: all 0.3s ease;
+
+    &.unread {
+      border-left: 4px solid #4facfe;
+      background: #f8fbff;
+    }
+
+    &:hover {
+      transform: translateX(4px);
+      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
+    }
+  }
+
+  .alert-icon {
+    width: 40px;
+    height: 40px;
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-right: 16px;
+
+    .el-icon {
+      color: white;
+      font-size: 18px;
+    }
+
+    &.alert-icon-offline {
+      background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
+    }
+
+    &.alert-icon-network {
+      background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
+    }
+
+    &.alert-icon-fault {
+      background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
+    }
+
+    &.alert-icon-temperature {
+      background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
+    }
+
+    &.alert-icon-default {
+      background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
+    }
+  }
+
+  .alert-content {
+    flex: 1;
+
+    h4 {
+      margin: 0 0 4px 0;
+      font-size: 16px;
+      font-weight: 600;
+      color: #2c3e50;
+    }
+
+    p {
+      margin: 0 0 8px 0;
+      color: #7f8c8d;
+      font-size: 14px;
+      line-height: 1.5;
+    }
+
+    .alert-meta {
+      display: flex;
+      align-items: center;
+      gap: 12px;
+
+      .alert-time {
+        font-size: 12px;
+        color: #bdc3c7;
+      }
+    }
+  }
+
+  .alert-actions {
+    display: flex;
+    gap: 8px;
+    margin-left: 16px;
+  }
+}
+
+.device-detail {
+  padding: 16px 0;
+}
+</style>

+ 497 - 0
src/page/research/exchange-projects/index.vue

@@ -0,0 +1,497 @@
+<template>
+  <div class="exchange-projects-container">
+    <!-- 页面头部 -->
+    <PageHeader
+      title="短期交流项目"
+      description="完整的项目信息库、简化的申请流程、自动化初审机制、申请状态实时更新"
+      :icon="Briefcase"
+      :breadcrumbs="breadcrumbs"
+    />
+
+    <!-- 筛选与搜索 -->
+    <div class="filter-section">
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-select v-model="statusFilter" placeholder="项目状态" clearable>
+            <el-option label="全部" value="" />
+            <el-option label="招募中" value="recruiting" />
+            <el-option label="已截止" value="closed" />
+            <el-option label="进行中" value="ongoing" />
+            <el-option label="已完成" value="completed" />
+          </el-select>
+        </el-col>
+        <el-col :span="8">
+          <el-select v-model="typeFilter" placeholder="项目类型" clearable>
+            <el-option label="全部" value="" />
+            <el-option label="学术交流" value="academic" />
+            <el-option label="文化体验" value="cultural" />
+            <el-option label="实践实习" value="internship" />
+            <el-option label="竞赛参与" value="competition" />
+          </el-select>
+        </el-col>
+        <el-col :span="8">
+          <el-input
+            v-model="searchQuery"
+            placeholder="搜索项目名称或关键词"
+            prefix-icon="Search"
+            clearable
+          />
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 项目列表 -->
+    <div class="projects-section">
+      <div class="section-header">
+        <h2 class="section-title">项目信息库</h2>
+        <el-button type="primary" :icon="Plus" @click="handleCreateProject">
+          创建新项目
+        </el-button>
+      </div>
+      
+      <el-row :gutter="20">
+        <el-col :span="8" v-for="project in projects" :key="project.id">
+          <div class="project-card">
+            <div class="card-header">
+              <h3 class="project-title">{{ project.title }}</h3>
+              <el-tag :type="getProjectStatusType(project.status)">{{ getProjectStatusText(project.status) }}</el-tag>
+            </div>
+            
+            <div class="card-body">
+              <div class="project-info">
+                <div class="info-item">
+                  <el-icon class="info-icon"><Calendar /></el-icon>
+                  <span>{{ project.startDate }} - {{ project.endDate }}</span>
+                </div>
+                <div class="info-item">
+                  <el-icon class="info-icon"><Location /></el-icon>
+                  <span>{{ project.location }}</span>
+                </div>
+                <div class="info-item">
+                  <el-icon class="info-icon"><User /></el-icon>
+                  <span>{{ project.quota }}人</span>
+                </div>
+                <div class="info-item">
+                  <el-icon class="info-icon"><Document /></el-icon>
+                  <span>{{ project.funding }}</span>
+                </div>
+              </div>
+              
+              <p class="project-description">{{ project.description }}</p>
+            </div>
+            
+            <div class="card-footer">
+              <el-button type="primary" @click="handleApply(project.id)" v-if="project.status === 'recruiting'">
+                立即申请
+              </el-button>
+              <el-button type="default" @click="handleViewDetails(project.id)">
+                查看详情
+              </el-button>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 申请进度 -->
+    <div class="applications-section" v-if="userApplications.length > 0">
+      <h2 class="section-title">我的申请进度</h2>
+      <el-table :data="userApplications" style="width: 100%">
+        <el-table-column prop="projectName" label="项目名称" width="200" />
+        <el-table-column prop="applicationTime" label="申请时间" width="180" />
+        <el-table-column prop="status" label="申请状态">
+          <template #default="scope">
+            <el-tag :type="getApplicationStatusType(scope.row.status)">
+              {{ getApplicationStatusText(scope.row.status) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="progress" label="进度" width="180">
+          <template #default="scope">
+            <el-progress :percentage="scope.row.progress" />
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="150" fixed="right">
+          <template #default="scope">
+            <el-button type="text" @click="handleViewApplication(scope.row.id)">查看详情</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref } from 'vue'
+import { useRouter } from 'vue-router'
+import {
+  Briefcase,
+  Calendar,
+  Document,
+  Location,
+  Plus,
+  Search,
+  User
+} from '@element-plus/icons-vue'
+import PageHeader from '@/components/PageHeader.vue'
+
+const router = useRouter()
+
+// 面包屑导航
+const breadcrumbs = ref([
+  { label: '首页', path: '/' },
+  { label: '科研与国际化模块', path: '/research' },
+  { label: '短期交流项目', path: '/research/exchange-projects' }
+])
+
+// 筛选条件
+const statusFilter = ref('')
+const typeFilter = ref('')
+const searchQuery = ref('')
+
+// 项目数据
+const projects = reactive([
+  {
+    id: '1',
+    title: '2024年美国加州大学学术交流项目',
+    description: '与加州大学伯克利分校进行为期3个月的学术交流,涵盖计算机科学、人工智能等前沿领域的学习与研究。',
+    startDate: '2024-09-01',
+    endDate: '2024-11-30',
+    location: '美国,加利福尼亚州',
+    quota: 10,
+    funding: '全额资助',
+    status: 'recruiting',
+    type: 'academic'
+  },
+  {
+    id: '2',
+    title: '日本京都大学文化体验项目',
+    description: '前往日本京都大学进行为期2周的文化体验与学术交流活动,了解日本传统文化与现代科技发展。',
+    startDate: '2024-08-15',
+    endDate: '2024-08-29',
+    location: '日本,京都',
+    quota: 15,
+    funding: '部分资助',
+    status: 'recruiting',
+    type: 'cultural'
+  },
+  {
+    id: '3',
+    title: '德国慕尼黑工业大学实习项目',
+    description: '在德国慕尼黑工业大学的实验室进行为期6个月的实习,参与前沿科研项目的开发与研究。',
+    startDate: '2024-10-01',
+    endDate: '2025-03-31',
+    location: '德国,慕尼黑',
+    quota: 8,
+    funding: '提供津贴',
+    status: 'closed',
+    type: 'internship'
+  },
+  {
+    id: '4',
+    title: 'ACM国际大学生程序设计竞赛',
+    description: '组队参加ACM国际大学生程序设计竞赛亚洲区预选赛,与来自亚洲各国的优秀选手同台竞技。',
+    startDate: '2024-10-15',
+    endDate: '2024-10-20',
+    location: '中国,上海',
+    quota: 6,
+    funding: '全额资助',
+    status: 'ongoing',
+    type: 'competition'
+  },
+  {
+    id: '5',
+    title: '新加坡国立大学暑期学校',
+    description: '参加新加坡国立大学举办的暑期学校,学习数据科学与人工智能的前沿知识。',
+    startDate: '2024-07-01',
+    endDate: '2024-07-31',
+    location: '新加坡',
+    quota: 12,
+    funding: '部分资助',
+    status: 'completed',
+    type: 'academic'
+  },
+  {
+    id: '6',
+    title: '英国剑桥大学访问学者项目',
+    description: '作为访问学者前往英国剑桥大学进行为期1个月的学术交流与合作研究。',
+    startDate: '2024-11-01',
+    endDate: '2024-11-30',
+    location: '英国,剑桥',
+    quota: 5,
+    funding: '全额资助',
+    status: 'recruiting',
+    type: 'academic'
+  }
+])
+
+// 用户申请数据
+const userApplications = reactive([
+  {
+    id: '1',
+    projectId: '1',
+    projectName: '2024年美国加州大学学术交流项目',
+    applicationTime: '2024-06-15 14:30',
+    status: 'reviewing',
+    progress: 50
+  },
+  {
+    id: '2',
+    projectId: '4',
+    projectName: 'ACM国际大学生程序设计竞赛',
+    applicationTime: '2024-05-20 10:15',
+    status: 'approved',
+    progress: 80
+  }
+])
+
+// 获取项目状态标签类型
+const getProjectStatusType = (status: string) => {
+  switch (status) {
+    case 'recruiting':
+      return 'success'
+    case 'closed':
+      return 'info'
+    case 'ongoing':
+      return 'warning'
+    case 'completed':
+      return 'primary'
+    default:
+      return 'default'
+  }
+}
+
+// 获取项目状态文本
+const getProjectStatusText = (status: string) => {
+  switch (status) {
+    case 'recruiting':
+      return '招募中'
+    case 'closed':
+      return '已截止'
+    case 'ongoing':
+      return '进行中'
+    case 'completed':
+      return '已完成'
+    default:
+      return '未知'
+  }
+}
+
+// 获取申请状态标签类型
+const getApplicationStatusType = (status: string) => {
+  switch (status) {
+    case 'pending':
+      return 'info'
+    case 'reviewing':
+      return 'warning'
+    case 'approved':
+      return 'success'
+    case 'rejected':
+      return 'danger'
+    case 'canceled':
+      return 'default'
+    default:
+      return 'default'
+  }
+}
+
+// 获取申请状态文本
+const getApplicationStatusText = (status: string) => {
+  switch (status) {
+    case 'pending':
+      return '待提交'
+    case 'reviewing':
+      return '审核中'
+    case 'approved':
+      return '已通过'
+    case 'rejected':
+      return '未通过'
+    case 'canceled':
+      return '已取消'
+    default:
+      return '未知'
+  }
+}
+
+// 处理创建新项目
+const handleCreateProject = () => {
+  // 实际项目中应该导航到创建项目页面
+  console.log('创建新项目')
+}
+
+// 处理申请项目
+const handleApply = (projectId: string) => {
+  // 实际项目中应该导航到申请页面
+  console.log('申请项目', projectId)
+}
+
+// 查看项目详情
+const handleViewDetails = (projectId: string) => {
+  // 实际项目中应该导航到项目详情页面
+  console.log('查看项目详情', projectId)
+}
+
+// 查看申请详情
+const handleViewApplication = (applicationId: string) => {
+  // 实际项目中应该导航到申请详情页面
+  console.log('查看申请详情', applicationId)
+}
+</script>
+
+<style scoped lang="scss">
+.exchange-projects-container {
+  padding: 20px;
+  background: #f5f7fa;
+  min-height: 100vh;
+  box-sizing: border-box;
+}
+
+.filter-section {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  margin-bottom: 24px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+}
+
+.projects-section {
+  margin-bottom: 24px;
+}
+
+.applications-section {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+}
+
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+}
+
+.section-title {
+  font-size: 20px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin: 0 0 16px 0;
+  display: flex;
+  align-items: center;
+}
+
+.section-title::before {
+  content: '';
+  width: 4px;
+  height: 20px;
+  background: #4facfe;
+  margin-right: 8px;
+  border-radius: 2px;
+}
+
+.project-card {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+  transition: all 0.3s ease;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+
+.project-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+  border-color: #4facfe;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 16px;
+}
+
+.project-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin: 0;
+  flex: 1;
+  margin-right: 12px;
+  line-height: 1.3;
+}
+
+.card-body {
+  flex: 1;
+  margin-bottom: 16px;
+}
+
+.project-info {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+  margin-bottom: 12px;
+}
+
+.info-item {
+  display: flex;
+  align-items: center;
+  font-size: 14px;
+  color: #7f8c8d;
+}
+
+.info-icon {
+  margin-right: 8px;
+  font-size: 16px;
+  color: #4facfe;
+}
+
+.project-description {
+  font-size: 14px;
+  color: #2c3e50;
+  line-height: 1.5;
+  margin: 0;
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.card-footer {
+  display: flex;
+  justify-content: space-between;
+  gap: 12px;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .exchange-projects-container {
+    padding: 16px;
+  }
+  
+  .section-title {
+    font-size: 18px;
+  }
+  
+  .card-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 8px;
+  }
+  
+  .project-title {
+    font-size: 16px;
+  }
+  
+  .card-footer {
+    flex-direction: column;
+  }
+}
+</style>

+ 439 - 0
src/page/research/index.vue

@@ -0,0 +1,439 @@
+<template>
+  <div class="research-container">
+    <!-- 页面头部 -->
+    <PageHeader
+      title="科研与国际化模块"
+      description="短期交流项目、科研项目管理、国际合作平台"
+      :icon="Document"
+      :breadcrumbs="breadcrumbs"
+    />
+
+    <!-- 数据概览 -->
+    <div class="overview-section">
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <StatCard
+            title="交流项目"
+            :number="overviewData.exchangeProjects"
+            icon="Suitcase"
+            color="#4facfe"
+            :trend="{ value: 25, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="科研项目"
+            :number="overviewData.researchProjects"
+            icon="Document"
+            color="#06ffa5"
+            :trend="{ value: 18, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="合作机构"
+            :number="overviewData.cooperationInstitutions"
+            icon="OfficeBuilding"
+            color="#ff6b6b"
+            :trend="{ value: 12, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="已完成项目"
+            :number="`${overviewData.completedRate}%`"
+            icon="CheckCircle"
+            color="#f093fb"
+            :trend="{ value: 8, type: 'up' }"
+          />
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 核心功能区 -->
+    <div class="core-functions">
+      <h2 class="section-title">核心功能模块</h2>
+      <el-row :gutter="20">
+        <el-col :span="8" v-for="func in coreFunctions" :key="func.id">
+          <ActionCard
+            :title="func.title"
+            :description="func.description"
+            :icon="func.icon"
+            :clickable="true"
+            :stats="func.stats"
+            @click="navigateToFunction(func.path)"
+          >
+            <template #content>
+              <ul class="feature-list">
+                <li v-for="feature in func.features" :key="feature">{{ feature }}</li>
+              </ul>
+            </template>
+            <template #meta>
+              <el-tag :type="func.status === 'active' ? 'success' : 'warning'" size="small">
+                {{ func.statusText }}
+              </el-tag>
+            </template>
+          </ActionCard>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 快捷操作 -->
+    <div class="quick-actions">
+      <h2 class="section-title">快捷操作</h2>
+      <el-row :gutter="16">
+        <el-col :span="4" v-for="action in quickActions" :key="action.id">
+          <el-button
+            type="primary"
+            :icon="action.icon"
+            @click="handleQuickAction(action.id)"
+            class="quick-action-btn"
+          >
+            {{ action.label }}
+          </el-button>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 最近活动 -->
+    <div class="recent-activities">
+      <h2 class="section-title">最近活动</h2>
+      <div class="activity-list">
+        <div class="activity-card" v-for="activity in recentActivities" :key="activity.id">
+          <div class="activity-icon">
+            <el-icon>
+              <component :is="activity.icon" />
+            </el-icon>
+          </div>
+          <div class="activity-content">
+            <h4>{{ activity.title }}</h4>
+            <p>{{ activity.description }}</p>
+            <span class="activity-time">{{ activity.time }}</span>
+          </div>
+          <div class="activity-status">
+            <el-tag :type="activity.status === '已完成' ? 'success' : activity.status === '进行中' ? 'warning' : 'info'">
+              {{ activity.status }}
+            </el-tag>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref } from 'vue'
+import { useRouter } from 'vue-router'
+import {
+  Briefcase,
+  OfficeBuilding,
+  Calendar,
+  CheckCircle,
+  Document,
+  Plus,
+  Message,
+  Search,
+  Setting,
+  Star,
+  Trophy
+} from '@element-plus/icons-vue'
+import PageHeader from '@/components/PageHeader.vue'
+import StatCard from '@/components/StatCard.vue'
+import ActionCard from '@/components/ActionCard.vue'
+
+const router = useRouter()
+
+// 面包屑导航
+const breadcrumbs = ref([
+  { label: '首页', path: '/' },
+  { label: '科研与国际化模块', path: '/research' }
+])
+
+// 数据概览
+const overviewData = reactive({
+  exchangeProjects: 15,
+  researchProjects: 28,
+  cooperationInstitutions: 42,
+  completedRate: 76
+})
+
+// 核心功能
+const coreFunctions = reactive([
+  {
+    id: 'exchange-projects',
+    title: '短期交流项目',
+    description: '项目信息化、快速报名、资格审核、进度跟踪',
+    icon: Briefcase,
+    path: '/research/exchange-projects',
+    stats: [
+      { value: 15, label: '总项目' },
+      { value: 12, label: '活跃项目' }
+    ],
+    status: 'active',
+    statusText: '运行中',
+    features: ['项目信息库', '快速报名系统', '进度跟踪']
+  },
+  {
+    id: 'research-mgmt',
+    title: '科研项目管理',
+    description: '项目申报、过程监控、经费管理、成果管理',
+    icon: Document,
+    path: '/research/research-mgmt',
+    stats: [
+      { value: 28, label: '总项目' },
+      { value: 22, label: '进行中' }
+    ],
+    status: 'active',
+    statusText: '运行中',
+    features: ['项目申报', '过程管理', '成果管理']
+  },
+  {
+    id: 'international-coop',
+    title: '国际合作平台',
+    description: '合作机构管理、交流活动、成果展示',
+    icon: OfficeBuilding,
+    path: '/research/international-coop',
+    stats: [
+      { value: 42, label: '合作机构' },
+      { value: 18, label: '交流活动' }
+    ],
+    status: 'active',
+    statusText: '运行中',
+    features: ['合作机构管理', '交流活动', '成果展示']
+  }
+])
+
+// 快捷操作
+const quickActions = reactive([
+  {
+    id: 'create-project',
+    label: '创建项目',
+    icon: Plus
+  },
+  {
+    id: 'search-projects',
+    label: '搜索项目',
+    icon: Search
+  },
+  {
+    id: 'view-reports',
+    label: '查看报告',
+    icon: Message
+  },
+  {
+    id: 'system-settings',
+    label: '系统设置',
+    icon: Setting
+  }
+])
+
+// 最近活动
+const recentActivities = reactive([
+  {
+    id: 1,
+    title: '2024年国际学术交流项目启动',
+    description: '启动了新一轮的国际学术交流项目,面向全校开放申请',
+    time: '2024-06-15 10:30',
+    status: '进行中',
+    icon: Calendar
+  },
+  {
+    id: 2,
+    title: '重点科研项目验收完成',
+    description: '人工智能应用研究项目顺利通过验收,获得高度评价',
+    time: '2024-06-10 15:45',
+    status: '已完成',
+    icon: Trophy
+  },
+  {
+    id: 3,
+    title: '与美国加州大学签署合作备忘录',
+    description: '我校与美国加州大学签署学术交流合作备忘录',
+    time: '2024-06-05 09:00',
+    status: '已完成',
+    icon: Star
+  }
+])
+
+// 导航到功能模块
+const navigateToFunction = (path: string) => {
+  router.push(path)
+}
+
+// 处理快捷操作
+const handleQuickAction = (actionId: string) => {
+  switch (actionId) {
+    case 'create-project':
+      router.push('/research/exchange-projects/create')
+      break
+    case 'search-projects':
+      // 实现搜索功能
+      console.log('搜索项目')
+      break
+    case 'view-reports':
+      // 实现查看报告功能
+      console.log('查看报告')
+      break
+    case 'system-settings':
+      // 实现系统设置功能
+      console.log('系统设置')
+      break
+    default:
+      break
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.research-container {
+  padding: 20px;
+  background: #f5f7fa;
+  min-height: 100vh;
+  box-sizing: border-box;
+}
+
+.overview-section {
+  margin-bottom: 24px;
+}
+
+.core-functions {
+  margin-bottom: 24px;
+}
+
+.quick-actions {
+  margin-bottom: 24px;
+}
+
+.recent-activities {
+  margin-bottom: 24px;
+}
+
+.section-title {
+  font-size: 20px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin-bottom: 16px;
+  display: flex;
+  align-items: center;
+}
+
+.section-title::before {
+  content: '';
+  width: 4px;
+  height: 20px;
+  background: #4facfe;
+  margin-right: 8px;
+  border-radius: 2px;
+}
+
+.quick-action-btn {
+  width: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 12px 16px;
+  font-size: 14px;
+}
+
+.activity-list {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
+  gap: 16px;
+}
+
+.activity-card {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+  display: flex;
+  align-items: flex-start;
+  gap: 16px;
+  transition: all 0.3s ease;
+}
+
+.activity-card:hover {
+  transform: translateY(-2px);
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+  border-color: #4facfe;
+}
+
+.activity-icon {
+  width: 40px;
+  height: 40px;
+  border-radius: 8px;
+  background: linear-gradient(135deg, #4facfe, #00f2fe);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 20px;
+  color: white;
+  flex-shrink: 0;
+}
+
+.activity-content {
+  flex: 1;
+  min-width: 0;
+}
+
+.activity-content h4 {
+  margin: 0 0 8px 0;
+  font-size: 16px;
+  font-weight: 600;
+  color: #2c3e50;
+}
+
+.activity-content p {
+  margin: 0 0 8px 0;
+  font-size: 14px;
+  color: #7f8c8d;
+  line-height: 1.5;
+}
+
+.activity-time {
+  font-size: 12px;
+  color: #95a5a6;
+}
+
+.activity-status {
+  margin-left: 16px;
+  flex-shrink: 0;
+}
+
+.feature-list {
+  list-style: none;
+  padding: 0;
+  margin: 12px 0 0 0;
+}
+
+.feature-list li {
+  font-size: 14px;
+  color: #2c3e50;
+  margin-bottom: 8px;
+  display: flex;
+  align-items: center;
+}
+
+.feature-list li::before {
+  content: '•';
+  color: #4facfe;
+  font-weight: bold;
+  margin-right: 8px;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .research-container {
+    padding: 16px;
+  }
+  
+  .activity-list {
+    grid-template-columns: 1fr;
+  }
+  
+  .section-title {
+    font-size: 18px;
+  }
+}
+</style>

+ 673 - 0
src/page/research/international-coop/index.vue

@@ -0,0 +1,673 @@
+<template>
+  <div class="international-coop-container">
+    <!-- 页面头部 -->
+    <PageHeader
+      title="国际合作平台"
+      description="合作机构管理、交流活动、成果展示"
+      :icon="OfficeBuilding"
+      :breadcrumbs="breadcrumbs"
+    />
+
+    <!-- 数据概览 -->
+    <div class="overview-section">
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <StatCard
+            title="合作机构"
+            :number="overviewData.institutions"
+            icon="OfficeBuilding"
+            color="#4facfe"
+            :trend="{ value: 12, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="交流活动"
+            :number="overviewData.activities"
+            icon="Calendar"
+            color="#06ffa5"
+            :trend="{ value: 18, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="合作项目"
+            :number="overviewData.projects"
+            icon="Briefcase"
+            color="#ff6b6b"
+            :trend="{ value: 8, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="国际论文"
+            :number="overviewData.papers"
+            icon="FileText"
+            color="#f093fb"
+            :trend="{ value: 25, type: 'up' }"
+          />
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 合作机构管理 -->
+    <div class="institutions-section">
+      <div class="section-header">
+        <h2 class="section-title">合作机构管理</h2>
+        <el-button type="primary" :icon="Plus" @click="handleAddInstitution">
+          添加合作机构
+        </el-button>
+      </div>
+      
+      <div class="institutions-grid">
+        <div class="institution-card" v-for="institution in institutions" :key="institution.id">
+          <div class="institution-logo">
+            <el-icon><OfficeBuilding /></el-icon>
+          </div>
+          <div class="institution-info">
+            <h3 class="institution-name">{{ institution.name }}</h3>
+            <p class="institution-country">{{ institution.country }}</p>
+            <div class="institution-meta">
+              <span class="cooperation-years">合作 {{ institution.cooperationYears }} 年</span>
+              <el-tag :type="getCooperationLevelType(institution.level)">
+                {{ getCooperationLevelText(institution.level) }}
+              </el-tag>
+            </div>
+          </div>
+          <div class="institution-actions">
+            <el-button type="default" size="small" @click="handleViewInstitution(institution.id)">
+              查看详情
+            </el-button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 交流活动 -->
+    <div class="activities-section">
+      <div class="section-header">
+        <h2 class="section-title">近期交流活动</h2>
+        <el-button type="primary" :icon="Plus" @click="handleCreateActivity">
+          创建活动
+        </el-button>
+      </div>
+      
+      <el-timeline>
+        <el-timeline-item :timestamp="activity.date" v-for="activity in activities" :key="activity.id">
+          <el-card>
+            <h3 class="activity-title">{{ activity.title }}</h3>
+            <p class="activity-description">{{ activity.description }}</p>
+            <div class="activity-meta">
+              <span class="activity-location"><el-icon><Location /></el-icon> {{ activity.location }}</span>
+              <span class="activity-participants"><el-icon><User /></el-icon> {{ activity.participants }} 人参与</span>
+            </div>
+            <div class="activity-actions">
+              <el-button type="text" @click="handleViewActivity(activity.id)">查看详情</el-button>
+              <el-button type="text" @click="handleRegisterActivity(activity.id)" v-if="activity.status === 'upcoming'">报名参加</el-button>
+            </div>
+          </el-card>
+        </el-timeline-item>
+      </el-timeline>
+    </div>
+
+    <!-- 成果展示 -->
+    <div class="achievements-section">
+      <h2 class="section-title">国际合作成果展示</h2>
+      <el-tabs v-model="activeTab" type="border-card">
+        <el-tab-pane label="联合发表论文" name="papers">
+          <div class="papers-list">
+            <div class="paper-item" v-for="paper in papers" :key="paper.id">
+              <h3 class="paper-title">{{ paper.title }}</h3>
+              <p class="paper-authors">{{ paper.authors }}</p>
+              <div class="paper-meta">
+                <span class="paper-journal">{{ paper.journal }}</span>
+                <span class="paper-impact-factor">IF: {{ paper.impactFactor }}</span>
+                <span class="paper-date">{{ paper.date }}</span>
+              </div>
+              <el-button type="text" @click="handleViewPaper(paper.id)">查看详情</el-button>
+            </div>
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="联合科研项目" name="projects">
+          <div class="joint-projects-list">
+            <div class="joint-project-item" v-for="project in jointProjects" :key="project.id">
+              <h3 class="joint-project-title">{{ project.title }}</h3>
+              <p class="joint-project-description">{{ project.description }}</p>
+              <div class="joint-project-meta">
+                <span class="joint-project-institutions">{{ project.institutions }}</span>
+                <span class="joint-project-funding">{{ project.funding }}</span>
+                <span class="joint-project-period">{{ project.period }}</span>
+              </div>
+              <el-button type="text" @click="handleViewJointProject(project.id)">查看详情</el-button>
+            </div>
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="国际会议" name="conferences">
+          <div class="conferences-list">
+            <div class="conference-item" v-for="conference in conferences" :key="conference.id">
+              <h3 class="conference-title">{{ conference.title }}</h3>
+              <p class="conference-description">{{ conference.description }}</p>
+              <div class="conference-meta">
+                <span class="conference-location">{{ conference.location }}</span>
+                <span class="conference-date">{{ conference.date }}</span>
+                <span class="conference-participants">{{ conference.participants }} 人参会</span>
+              </div>
+              <el-button type="text" @click="handleViewConference(conference.id)">查看详情</el-button>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref } from 'vue'
+import { useRouter } from 'vue-router'
+import {
+  OfficeBuilding,
+  Calendar,
+  Briefcase,
+  FileText,
+  Plus,
+  Search,
+  Location,
+  User
+} from '@element-plus/icons-vue'
+import PageHeader from '@/components/PageHeader.vue'
+import StatCard from '@/components/StatCard.vue'
+
+const router = useRouter()
+
+// 面包屑导航
+const breadcrumbs = ref([
+  { label: '首页', path: '/' },
+  { label: '科研与国际化模块', path: '/research' },
+  { label: '国际合作平台', path: '/research/international-coop' }
+])
+
+// 数据概览
+const overviewData = reactive({
+  institutions: 42,
+  activities: 18,
+  projects: 25,
+  papers: 128
+})
+
+// 合作机构数据
+const institutions = reactive([
+  {
+    id: '1',
+    name: '美国加州大学伯克利分校',
+    country: '美国',
+    cooperationYears: 8,
+    level: 'strategic'
+  },
+  {
+    id: '2',
+    name: '英国剑桥大学',
+    country: '英国',
+    cooperationYears: 6,
+    level: 'strategic'
+  },
+  {
+    id: '3',
+    name: '日本东京大学',
+    country: '日本',
+    cooperationYears: 5,
+    level: 'important'
+  },
+  {
+    id: '4',
+    name: '德国慕尼黑工业大学',
+    country: '德国',
+    cooperationYears: 4,
+    level: 'important'
+  },
+  {
+    id: '5',
+    name: '新加坡国立大学',
+    country: '新加坡',
+    cooperationYears: 7,
+    level: 'strategic'
+  },
+  {
+    id: '6',
+    name: '澳大利亚悉尼大学',
+    country: '澳大利亚',
+    cooperationYears: 3,
+    level: 'general'
+  }
+])
+
+// 交流活动数据
+const activities = reactive([
+  {
+    id: '1',
+    title: '2024年国际人工智能学术研讨会',
+    description: '与美国加州大学伯克利分校联合举办的人工智能领域前沿学术研讨会',
+    date: '2024-09-15',
+    location: '线上线下同步',
+    participants: 150,
+    status: 'upcoming'
+  },
+  {
+    id: '2',
+    title: '中英高等教育合作论坛',
+    description: '与英国剑桥大学共同组织的高等教育合作论坛',
+    date: '2024-08-20',
+    location: '中国,上海',
+    participants: 80,
+    status: 'upcoming'
+  },
+  {
+    id: '3',
+    title: '中日科技创新合作交流会',
+    description: '与日本东京大学合作举办的科技创新领域交流活动',
+    date: '2024-07-10',
+    location: '日本,东京',
+    participants: 60,
+    status: 'completed'
+  },
+  {
+    id: '4',
+    title: '中德智能制造论坛',
+    description: '与德国慕尼黑工业大学联合举办的智能制造领域论坛',
+    date: '2024-06-05',
+    location: '德国,慕尼黑',
+    participants: 90,
+    status: 'completed'
+  }
+])
+
+// 论文数据
+const papers = reactive([
+  {
+    id: '1',
+    title: 'Deep Learning for Medical Image Analysis: A Review',
+    authors: 'Zhang M, Smith J, Wang L, et al.',
+    journal: 'Nature Medicine',
+    impactFactor: '87.241',
+    date: '2024-05'
+  },
+  {
+    id: '2',
+    title: 'A Novel Approach to Quantum Computing Algorithms',
+    authors: 'Li H, Johnson R, Chen W, et al.',
+    journal: 'Science',
+    impactFactor: '63.714',
+    date: '2024-03'
+  },
+  {
+    id: '3',
+    title: 'Sustainable Energy Solutions for Smart Cities',
+    authors: 'Wang Q, Brown T, Liu Z, et al.',
+    journal: 'Energy & Environmental Science',
+    impactFactor: '38.532',
+    date: '2024-01'
+  }
+])
+
+// 联合科研项目数据
+const jointProjects = reactive([
+  {
+    id: '1',
+    title: '人工智能辅助医疗诊断系统研究',
+    description: '与美国加州大学伯克利分校联合开展的人工智能在医疗领域应用研究',
+    institutions: '本校 & 美国加州大学伯克利分校',
+    funding: '200万元',
+    period: '2024-2026'
+  },
+  {
+    id: '2',
+    title: '新能源材料研发与应用',
+    description: '与英国剑桥大学合作开展的新能源材料研究项目',
+    institutions: '本校 & 英国剑桥大学',
+    funding: '150万元',
+    period: '2023-2025'
+  }
+])
+
+// 国际会议数据
+const conferences = reactive([
+  {
+    id: '1',
+    title: '2024 IEEE国际计算机视觉大会',
+    description: '派团参加在法国巴黎举办的IEEE国际计算机视觉大会',
+    location: '法国,巴黎',
+    date: '2024-10-01 至 2024-10-07',
+    participants: 15
+  },
+  {
+    id: '2',
+    title: 'ACM国际人工智能会议',
+    description: '派团参加在美国纽约举办的ACM国际人工智能会议',
+    location: '美国,纽约',
+    date: '2024-07-15 至 2024-07-20',
+    participants: 12
+  }
+])
+
+// 当前激活的标签页
+const activeTab = ref('papers')
+
+// 获取合作级别标签类型
+const getCooperationLevelType = (level: string) => {
+  switch (level) {
+    case 'strategic':
+      return 'primary'
+    case 'important':
+      return 'success'
+    case 'general':
+      return 'info'
+    default:
+      return 'default'
+  }
+}
+
+// 获取合作级别文本
+const getCooperationLevelText = (level: string) => {
+  switch (level) {
+    case 'strategic':
+      return '战略合作'
+    case 'important':
+      return '重要合作'
+    case 'general':
+      return '一般合作'
+    default:
+      return '未知'
+  }
+}
+
+// 处理添加合作机构
+const handleAddInstitution = () => {
+  console.log('添加合作机构')
+}
+
+// 查看合作机构详情
+const handleViewInstitution = (institutionId: string) => {
+  console.log('查看合作机构详情', institutionId)
+}
+
+// 处理创建活动
+const handleCreateActivity = () => {
+  console.log('创建活动')
+}
+
+// 查看活动详情
+const handleViewActivity = (activityId: string) => {
+  console.log('查看活动详情', activityId)
+}
+
+// 报名参加活动
+const handleRegisterActivity = (activityId: string) => {
+  console.log('报名参加活动', activityId)
+}
+
+// 查看论文详情
+const handleViewPaper = (paperId: string) => {
+  console.log('查看论文详情', paperId)
+}
+
+// 查看联合项目详情
+const handleViewJointProject = (projectId: string) => {
+  console.log('查看联合项目详情', projectId)
+}
+
+// 查看会议详情
+const handleViewConference = (conferenceId: string) => {
+  console.log('查看会议详情', conferenceId)
+}
+</script>
+
+<style scoped lang="scss">
+.international-coop-container {
+  padding: 20px;
+  background: #f5f7fa;
+  min-height: 100vh;
+  box-sizing: border-box;
+}
+
+.overview-section {
+  margin-bottom: 24px;
+}
+
+.institutions-section {
+  margin-bottom: 24px;
+}
+
+.activities-section {
+  margin-bottom: 24px;
+}
+
+.achievements-section {
+  margin-bottom: 24px;
+}
+
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+}
+
+.section-title {
+  font-size: 20px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin: 0 0 16px 0;
+  display: flex;
+  align-items: center;
+}
+
+.section-title::before {
+  content: '';
+  width: 4px;
+  height: 20px;
+  background: #4facfe;
+  margin-right: 8px;
+  border-radius: 2px;
+}
+
+/* 合作机构样式 */
+.institutions-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
+  gap: 20px;
+}
+
+.institution-card {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+  transition: all 0.3s ease;
+  display: flex;
+  align-items: center;
+  gap: 16px;
+}
+
+.institution-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+  border-color: #4facfe;
+}
+
+.institution-logo {
+  width: 60px;
+  height: 60px;
+  border-radius: 12px;
+  background: linear-gradient(135deg, #4facfe, #00f2fe);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 24px;
+  color: white;
+  flex-shrink: 0;
+}
+
+.institution-info {
+  flex: 1;
+  min-width: 0;
+}
+
+.institution-name {
+  font-size: 18px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin: 0 0 4px 0;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.institution-country {
+  font-size: 14px;
+  color: #7f8c8d;
+  margin: 0 0 8px 0;
+}
+
+.institution-meta {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  font-size: 12px;
+  color: #95a5a6;
+}
+
+.institution-actions {
+  flex-shrink: 0;
+}
+
+/* 活动样式 */
+.activity-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin: 0 0 8px 0;
+}
+
+.activity-description {
+  font-size: 14px;
+  color: #7f8c8d;
+  margin: 0 0 12px 0;
+  line-height: 1.5;
+}
+
+.activity-meta {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 12px;
+  font-size: 14px;
+  color: #95a5a6;
+}
+
+.activity-actions {
+  display: flex;
+  gap: 12px;
+}
+
+/* 成果展示样式 */
+.papers-list,
+.joint-projects-list,
+.conferences-list {
+  display: flex;
+  flex-direction: column;
+  gap: 16px;
+}
+
+.paper-item,
+.joint-project-item,
+.conference-item {
+  background: white;
+  border-radius: 8px;
+  padding: 16px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+  border: 1px solid #e4e7ed;
+  transition: all 0.3s ease;
+}
+
+.paper-item:hover,
+.joint-project-item:hover,
+.conference-item:hover {
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
+  border-color: #4facfe;
+}
+
+.paper-title,
+.joint-project-title,
+.conference-title {
+  font-size: 16px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin: 0 0 8px 0;
+}
+
+.paper-authors,
+.joint-project-description,
+.conference-description {
+  font-size: 14px;
+  color: #7f8c8d;
+  margin: 0 0 12px 0;
+  line-height: 1.5;
+}
+
+.paper-meta,
+.joint-project-meta,
+.conference-meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px;
+  margin-bottom: 12px;
+  font-size: 14px;
+  color: #95a5a6;
+}
+
+.paper-impact-factor {
+  color: #4facfe;
+  font-weight: 600;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .international-coop-container {
+    padding: 16px;
+  }
+  
+  .section-title {
+    font-size: 18px;
+  }
+  
+  .section-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 12px;
+  }
+  
+  .institutions-grid {
+    grid-template-columns: 1fr;
+  }
+  
+  .institution-card {
+    flex-direction: column;
+    text-align: center;
+  }
+  
+  .institution-meta {
+    justify-content: center;
+  }
+  
+  .activity-meta {
+    flex-direction: column;
+    gap: 8px;
+  }
+  
+  .paper-meta,
+  .joint-project-meta,
+  .conference-meta {
+    flex-direction: column;
+    gap: 8px;
+  }
+}
+</style>

+ 555 - 0
src/page/research/research-mgmt/index.vue

@@ -0,0 +1,555 @@
+<template>
+  <div class="research-mgmt-container">
+    <!-- 页面头部 -->
+    <PageHeader
+      title="科研项目管理"
+      description="项目申报、过程监控、经费管理、成果管理"
+      :icon="Document"
+      :breadcrumbs="breadcrumbs"
+    />
+
+    <!-- 数据概览 -->
+    <div class="overview-section">
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <StatCard
+            title="在研项目"
+            :number="overviewData.ongoingProjects"
+            icon="Clock"
+            color="#4facfe"
+            :trend="{ value: 12, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="已完成项目"
+            :number="overviewData.completedProjects"
+            icon="CheckCircle"
+            color="#06ffa5"
+            :trend="{ value: 8, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="申报项目"
+            :number="overviewData.appliedProjects"
+            icon="FileAdd"
+            color="#ff6b6b"
+            :trend="{ value: 15, type: 'up' }"
+          />
+        </el-col>
+        <el-col :span="6">
+          <StatCard
+            title="项目经费"
+            :number="`${overviewData.totalFunding}万元`"
+            icon="DollarSign"
+            color="#f093fb"
+            :trend="{ value: 20, type: 'up' }"
+          />
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 筛选与搜索 -->
+    <div class="filter-section">
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <el-select v-model="typeFilter" placeholder="项目类型" clearable>
+            <el-option label="全部" value="" />
+            <el-option label="国家级" value="national" />
+            <el-option label="省部级" value="provincial" />
+            <el-option label="校级" value="university" />
+            <el-option label="横向项目" value="horizontal" />
+          </el-select>
+        </el-col>
+        <el-col :span="6">
+          <el-select v-model="statusFilter" placeholder="项目状态" clearable>
+            <el-option label="全部" value="" />
+            <el-option label="申报中" value="applying" />
+            <el-option label="立项" value="approved" />
+            <el-option label="在研" value="ongoing" />
+            <el-option label="结题" value="completed" />
+            <el-option label="中止" value="terminated" />
+          </el-select>
+        </el-col>
+        <el-col :span="6">
+          <el-date-picker
+            v-model="dateRange"
+            type="daterange"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            placeholder="选择时间范围"
+          />
+        </el-col>
+        <el-col :span="6">
+          <el-input
+            v-model="searchQuery"
+            placeholder="搜索项目名称或负责人"
+            prefix-icon="Search"
+            clearable
+          />
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 项目列表 -->
+    <div class="projects-section">
+      <div class="section-header">
+        <h2 class="section-title">项目列表</h2>
+        <el-button type="primary" :icon="Plus" @click="handleCreateProject">
+          申报新项目
+        </el-button>
+      </div>
+      
+      <el-table :data="projects" style="width: 100%">
+        <el-table-column prop="id" label="项目编号" width="150" />
+        <el-table-column prop="title" label="项目名称" min-width="250">
+          <template #default="scope">
+            <span class="project-title-link" @click="handleViewDetails(scope.row.id)">{{ scope.row.title }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="type" label="项目类型" width="120">
+          <template #default="scope">
+            <el-tag :type="getProjectTypeTag(scope.row.type)">{{ getProjectTypeText(scope.row.type) }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="funding" label="经费(万元)" width="120" />
+        <el-table-column prop="principal" label="负责人" width="120" />
+        <el-table-column prop="startDate" label="开始日期" width="120" />
+        <el-table-column prop="endDate" label="结束日期" width="120" />
+        <el-table-column prop="status" label="项目状态" width="100">
+          <template #default="scope">
+            <el-tag :type="getProjectStatusType(scope.row.status)">{{ getProjectStatusText(scope.row.status) }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="180" fixed="right">
+          <template #default="scope">
+            <el-button type="text" @click="handleViewDetails(scope.row.id)">查看详情</el-button>
+            <el-button type="text" @click="handleEditProject(scope.row.id)" v-if="scope.row.status !== 'completed' && scope.row.status !== 'terminated'">编辑</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- 项目成果统计 -->
+    <div class="achievements-section">
+      <h2 class="section-title">项目成果统计</h2>
+      <div class="achievements-grid">
+        <div class="achievement-card">
+          <h3>论文发表</h3>
+          <div class="achievement-stats">
+            <div class="stat-item">
+              <span class="stat-number">42</span>
+              <span class="stat-label">SCI论文</span>
+            </div>
+            <div class="stat-item">
+              <span class="stat-number">28</span>
+              <span class="stat-label">EI论文</span>
+            </div>
+            <div class="stat-item">
+              <span class="stat-number">65</span>
+              <span class="stat-label">核心期刊</span>
+            </div>
+          </div>
+        </div>
+        <div class="achievement-card">
+          <h3>专利申请</h3>
+          <div class="achievement-stats">
+            <div class="stat-item">
+              <span class="stat-number">18</span>
+              <span class="stat-label">发明专利</span>
+            </div>
+            <div class="stat-item">
+              <span class="stat-number">32</span>
+              <span class="stat-label">实用新型</span>
+            </div>
+            <div class="stat-item">
+              <span class="stat-number">15</span>
+              <span class="stat-label">软件著作权</span>
+            </div>
+          </div>
+        </div>
+        <div class="achievement-card">
+          <h3>成果转化</h3>
+          <div class="achievement-stats">
+            <div class="stat-item">
+              <span class="stat-number">8</span>
+              <span class="stat-label">技术转让</span>
+            </div>
+            <div class="stat-item">
+              <span class="stat-number">12</span>
+              <span class="stat-label">产学研合作</span>
+            </div>
+            <div class="stat-item">
+              <span class="stat-number">250</span>
+              <span class="stat-label">转化金额(万)</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref } from 'vue'
+import { useRouter } from 'vue-router'
+import {
+  CheckCircle,
+  Clock,
+  DateRange,
+  DollarSign,
+  Document,
+  FileAdd,
+  Plus,
+  Search,
+  Star
+} from '@element-plus/icons-vue'
+import PageHeader from '@/components/PageHeader.vue'
+import StatCard from '@/components/StatCard.vue'
+
+const router = useRouter()
+
+// 面包屑导航
+const breadcrumbs = ref([
+  { label: '首页', path: '/' },
+  { label: '科研与国际化模块', path: '/research' },
+  { label: '科研项目管理', path: '/research/research-mgmt' }
+])
+
+// 数据概览
+const overviewData = reactive({
+  ongoingProjects: 32,
+  completedProjects: 45,
+  appliedProjects: 18,
+  totalFunding: 1256
+})
+
+// 筛选条件
+const typeFilter = ref('')
+const statusFilter = ref('')
+const dateRange = ref<Date[] | null>(null)
+const searchQuery = ref('')
+
+// 项目数据
+const projects = reactive([
+  {
+    id: 'KY2024001',
+    title: '人工智能辅助医疗诊断系统研究',
+    type: 'national',
+    funding: 120,
+    principal: '张明',
+    startDate: '2024-01-01',
+    endDate: '2026-12-31',
+    status: 'ongoing'
+  },
+  {
+    id: 'KY2024002',
+    title: '新能源汽车电池管理技术研发',
+    type: 'provincial',
+    funding: 80,
+    principal: '李华',
+    startDate: '2024-03-01',
+    endDate: '2025-12-31',
+    status: 'ongoing'
+  },
+  {
+    id: 'KY2024003',
+    title: '大数据分析在智慧城市中的应用',
+    type: 'university',
+    funding: 30,
+    principal: '王强',
+    startDate: '2024-02-01',
+    endDate: '2024-12-31',
+    status: 'ongoing'
+  },
+  {
+    id: 'KY2024004',
+    title: '工业互联网安全防护系统开发',
+    type: 'horizontal',
+    funding: 200,
+    principal: '赵静',
+    startDate: '2024-01-15',
+    endDate: '2024-09-15',
+    status: 'ongoing'
+  },
+  {
+    id: 'KY2023015',
+    title: '区块链技术在供应链管理中的应用研究',
+    type: 'provincial',
+    funding: 50,
+    principal: '陈明',
+    startDate: '2023-01-01',
+    endDate: '2023-12-31',
+    status: 'completed'
+  },
+  {
+    id: 'KY2024006',
+    title: '量子计算算法研究与应用',
+    type: 'national',
+    funding: 200,
+    principal: '刘伟',
+    startDate: '2024-04-01',
+    endDate: '2027-03-31',
+    status: 'approved'
+  },
+  {
+    id: 'KY2024007',
+    title: '智能机器人控制系统设计',
+    type: 'university',
+    funding: 25,
+    principal: '周杰',
+    startDate: '2024-03-15',
+    endDate: '2025-03-15',
+    status: 'applying'
+  },
+  {
+    id: 'KY2022032',
+    title: '新型材料在航空航天领域的应用',
+    type: 'national',
+    funding: 150,
+    principal: '孙伟',
+    startDate: '2022-01-01',
+    endDate: '2023-12-31',
+    status: 'terminated'
+  }
+])
+
+// 获取项目类型标签
+const getProjectTypeTag = (type: string) => {
+  switch (type) {
+    case 'national':
+      return 'primary'
+    case 'provincial':
+      return 'success'
+    case 'university':
+      return 'warning'
+    case 'horizontal':
+      return 'info'
+    default:
+      return 'default'
+  }
+}
+
+// 获取项目类型文本
+const getProjectTypeText = (type: string) => {
+  switch (type) {
+    case 'national':
+      return '国家级'
+    case 'provincial':
+      return '省部级'
+    case 'university':
+      return '校级'
+    case 'horizontal':
+      return '横向项目'
+    default:
+      return '未知'
+  }
+}
+
+// 获取项目状态标签类型
+const getProjectStatusType = (status: string) => {
+  switch (status) {
+    case 'applying':
+      return 'info'
+    case 'approved':
+      return 'success'
+    case 'ongoing':
+      return 'warning'
+    case 'completed':
+      return 'primary'
+    case 'terminated':
+      return 'danger'
+    default:
+      return 'default'
+  }
+}
+
+// 获取项目状态文本
+const getProjectStatusText = (status: string) => {
+  switch (status) {
+    case 'applying':
+      return '申报中'
+    case 'approved':
+      return '立项'
+    case 'ongoing':
+      return '在研'
+    case 'completed':
+      return '结题'
+    case 'terminated':
+      return '中止'
+    default:
+      return '未知'
+  }
+}
+
+// 处理创建新项目
+const handleCreateProject = () => {
+  // 实际项目中应该导航到创建项目页面
+  console.log('申报新项目')
+}
+
+// 查看项目详情
+const handleViewDetails = (projectId: string) => {
+  // 实际项目中应该导航到项目详情页面
+  console.log('查看项目详情', projectId)
+}
+
+// 编辑项目
+const handleEditProject = (projectId: string) => {
+  // 实际项目中应该导航到编辑项目页面
+  console.log('编辑项目', projectId)
+}
+</script>
+
+<style scoped lang="scss">
+.research-mgmt-container {
+  padding: 20px;
+  background: #f5f7fa;
+  min-height: 100vh;
+  box-sizing: border-box;
+}
+
+.overview-section {
+  margin-bottom: 24px;
+}
+
+.filter-section {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  margin-bottom: 24px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+}
+
+.projects-section {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  margin-bottom: 24px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+}
+
+.achievements-section {
+  margin-bottom: 24px;
+}
+
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+}
+
+.section-title {
+  font-size: 20px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin: 0 0 16px 0;
+  display: flex;
+  align-items: center;
+}
+
+.section-title::before {
+  content: '';
+  width: 4px;
+  height: 20px;
+  background: #4facfe;
+  margin-right: 8px;
+  border-radius: 2px;
+}
+
+.project-title-link {
+  color: #4facfe;
+  cursor: pointer;
+  text-decoration: underline;
+}
+
+.project-title-link:hover {
+  color: #0095ff;
+}
+
+.achievements-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+  gap: 20px;
+}
+
+.achievement-card {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+  border: 1px solid #e4e7ed;
+  transition: all 0.3s ease;
+}
+
+.achievement-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+  border-color: #4facfe;
+}
+
+.achievement-card h3 {
+  font-size: 18px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin: 0 0 16px 0;
+  text-align: center;
+}
+
+.achievement-stats {
+  display: flex;
+  justify-content: space-around;
+  text-align: center;
+}
+
+.stat-item {
+  flex: 1;
+}
+
+.stat-number {
+  display: block;
+  font-size: 24px;
+  font-weight: 700;
+  color: #4facfe;
+  margin-bottom: 4px;
+}
+
+.stat-label {
+  font-size: 14px;
+  color: #7f8c8d;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .research-mgmt-container {
+    padding: 16px;
+  }
+  
+  .section-title {
+    font-size: 18px;
+  }
+  
+  .section-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 12px;
+  }
+  
+  .filter-section .el-row {
+    flex-direction: column;
+  }
+  
+  .filter-section .el-col {
+    margin-bottom: 12px;
+  }
+  
+  .achievements-grid {
+    grid-template-columns: 1fr;
+  }
+}
+</style>

+ 1018 - 0
src/page/studio-mgmt/competition-selection/index.vue

@@ -0,0 +1,1018 @@
+<template>
+  <div class="competition-selection-container">
+    <!-- 页面头部 -->
+    <PageHeader
+      title="比赛与项目遴选"
+      description="智能化比赛项目发布、学生报名与筛选匹配系统"
+      :icon="Trophy"
+      :breadcrumbs="breadcrumbs"
+    />
+
+    <!-- 功能导航 -->
+    <div class="function-nav">
+      <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+        <el-tab-pane label="项目发布" name="publish">
+          <div class="tab-content">
+            <!-- 发布项目区域 -->
+            <div class="publish-section">
+              <div class="section-header">
+                <h3>项目发布管理</h3>
+                <el-button type="primary" :icon="Plus" @click="showPublishDialog = true">
+                  发布新项目
+                </el-button>
+              </div>
+
+              <!-- 项目列表 -->
+              <div class="project-list">
+                <div class="project-card" v-for="project in publishedProjects" :key="project.id">
+                  <div class="project-header">
+                    <div class="project-info">
+                      <h4>{{ project.title }}</h4>
+                      <el-tag :type="getProjectType(project.type)" size="small">{{ project.type }}</el-tag>
+                    </div>
+                    <div class="project-status">
+                      <el-tag :type="getStatusType(project.status)">{{ project.status }}</el-tag>
+                    </div>
+                  </div>
+                  
+                  <div class="project-content">
+                    <p class="project-description">{{ project.description }}</p>
+                    
+                    <div class="project-requirements">
+                      <span class="label">技能要求:</span>
+                      <el-tag v-for="skill in project.requiredSkills" :key="skill" size="small" class="skill-tag">
+                        {{ skill }}
+                      </el-tag>
+                    </div>
+                    
+                    <div class="project-details">
+                      <div class="detail-item">
+                        <el-icon><Calendar /></el-icon>
+                        <span>报名截止: {{ project.deadline }}</span>
+                      </div>
+                      <div class="detail-item">
+                        <el-icon><UserFilled /></el-icon>
+                        <span>团队规模: {{ project.teamSize }}</span>
+                      </div>
+                      <div class="detail-item">
+                        <el-icon><Trophy /></el-icon>
+                        <span>奖励: {{ project.reward }}</span>
+                      </div>
+                    </div>
+                  </div>
+                  
+                  <div class="project-stats">
+                    <div class="stat-item">
+                      <span class="stat-number">{{ project.applicants }}</span>
+                      <span class="stat-label">报名人数</span>
+                    </div>
+                    <div class="stat-item">
+                      <span class="stat-number">{{ project.matched }}</span>
+                      <span class="stat-label">已匹配</span>
+                    </div>
+                    <div class="stat-item">
+                      <span class="stat-number">{{ project.teams }}</span>
+                      <span class="stat-label">组建团队</span>
+                    </div>
+                  </div>
+                  
+                  <div class="project-actions">
+                    <el-button size="small" @click="viewProjectDetail(project)">详情</el-button>
+                    <el-button size="small" type="primary" @click="manageApplicants(project)">管理报名</el-button>
+                    <el-button size="small" type="warning" @click="editProject(project)">编辑</el-button>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-tab-pane>
+
+        <el-tab-pane label="学生报名" name="registration">
+          <div class="tab-content">
+            <!-- 报名统计 -->
+            <div class="registration-stats">
+              <el-row :gutter="20">
+                <el-col :span="6" v-for="stat in registrationStats" :key="stat.label">
+                  <div class="stat-card">
+                    <div class="stat-icon" :style="{ background: stat.color }">
+                      <el-icon>
+                        <component :is="stat.icon" />
+                      </el-icon>
+                    </div>
+                    <div class="stat-content">
+                      <div class="stat-number">{{ stat.value }}</div>
+                      <div class="stat-label">{{ stat.label }}</div>
+                    </div>
+                  </div>
+                </el-col>
+              </el-row>
+            </div>
+
+            <!-- 报名列表 -->
+            <div class="registration-list">
+              <div class="section-header">
+                <h3>报名管理</h3>
+                <div class="header-filters">
+                  <el-select v-model="filterProject" placeholder="筛选项目" style="width: 200px; margin-right: 12px;">
+                    <el-option label="全部项目" value="" />
+                    <el-option v-for="project in publishedProjects" :key="project.id" :label="project.title" :value="project.id" />
+                  </el-select>
+                  <el-select v-model="filterStatus" placeholder="筛选状态" style="width: 120px;">
+                    <el-option label="全部状态" value="" />
+                    <el-option label="待审核" value="pending" />
+                    <el-option label="已通过" value="approved" />
+                    <el-option label="已拒绝" value="rejected" />
+                  </el-select>
+                </div>
+              </div>
+
+              <el-table :data="filteredRegistrations" style="width: 100%">
+                <el-table-column prop="studentName" label="学生姓名" width="120" />
+                <el-table-column prop="studentId" label="学号" width="120" />
+                <el-table-column prop="projectTitle" label="报名项目" width="200" />
+                <el-table-column prop="skills" label="技能标签" width="250">
+                  <template #default="scope">
+                    <el-tag v-for="skill in scope.row.skills" :key="skill" size="small" class="skill-tag">
+                      {{ skill }}
+                    </el-tag>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="experience" label="相关经验" width="100">
+                  <template #default="scope">
+                    <el-rate v-model="scope.row.experience" disabled show-score />
+                  </template>
+                </el-table-column>
+                <el-table-column prop="motivation" label="申请理由" width="200" show-overflow-tooltip />
+                <el-table-column prop="status" label="状态" width="100">
+                  <template #default="scope">
+                    <el-tag :type="getRegistrationStatusType(scope.row.status)">
+                      {{ getRegistrationStatusText(scope.row.status) }}
+                    </el-tag>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="applyTime" label="报名时间" width="120" />
+                <el-table-column label="操作" width="200">
+                  <template #default="scope">
+                    <el-button size="small" @click="viewStudentProfile(scope.row)">档案</el-button>
+                    <el-button size="small" type="success" @click="approveRegistration(scope.row)" v-if="scope.row.status === 'pending'">
+                      通过
+                    </el-button>
+                    <el-button size="small" type="danger" @click="rejectRegistration(scope.row)" v-if="scope.row.status === 'pending'">
+                      拒绝
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+          </div>
+        </el-tab-pane>
+
+        <el-tab-pane label="智能匹配" name="matching">
+          <div class="tab-content">
+            <!-- 匹配配置 -->
+            <div class="matching-config">
+              <div class="section-header">
+                <h3>智能匹配配置</h3>
+                <el-button type="primary" :icon="Magic" @click="performMatching">
+                  执行智能匹配
+                </el-button>
+              </div>
+              
+              <el-form :model="matchingForm" label-width="120px" class="matching-form">
+                <el-row :gutter="20">
+                  <el-col :span="8">
+                    <el-form-item label="目标项目">
+                      <el-select v-model="matchingForm.projectId" placeholder="请选择项目">
+                        <el-option v-for="project in publishedProjects" :key="project.id" :label="project.title" :value="project.id" />
+                      </el-select>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="8">
+                    <el-form-item label="匹配算法">
+                      <el-select v-model="matchingForm.algorithm" placeholder="请选择算法">
+                        <el-option label="技能匹配优先" value="skill-first" />
+                        <el-option label="经验权重优先" value="experience-first" />
+                        <el-option label="综合评估" value="comprehensive" />
+                      </el-select>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="8">
+                    <el-form-item label="团队规模">
+                      <el-input-number v-model="matchingForm.teamSize" :min="2" :max="8" />
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+                
+                <el-form-item label="权重配置">
+                  <el-row :gutter="20">
+                    <el-col :span="6">
+                      <div class="weight-item">
+                        <span>技能匹配</span>
+                        <el-slider v-model="matchingForm.weights.skill" :max="100" />
+                      </div>
+                    </el-col>
+                    <el-col :span="6">
+                      <div class="weight-item">
+                        <span>经验水平</span>
+                        <el-slider v-model="matchingForm.weights.experience" :max="100" />
+                      </div>
+                    </el-col>
+                    <el-col :span="6">
+                      <div class="weight-item">
+                        <span>学习能力</span>
+                        <el-slider v-model="matchingForm.weights.learning" :max="100" />
+                      </div>
+                    </el-col>
+                    <el-col :span="6">
+                      <div class="weight-item">
+                        <span>团队协作</span>
+                        <el-slider v-model="matchingForm.weights.teamwork" :max="100" />
+                      </div>
+                    </el-col>
+                  </el-row>
+                </el-form-item>
+              </el-form>
+            </div>
+
+            <!-- 匹配结果 -->
+            <div class="matching-results">
+              <h3>匹配结果</h3>
+              <div class="result-list">
+                <div class="result-card" v-for="result in matchingResults" :key="result.id">
+                  <div class="result-header">
+                    <h4>{{ result.projectTitle }} - 团队 {{ result.teamId }}</h4>
+                    <div class="result-score">
+                      <el-progress type="circle" :percentage="result.matchScore" :width="60" />
+                      <span class="score-label">匹配度</span>
+                    </div>
+                  </div>
+                  
+                  <div class="result-content">
+                    <div class="team-members">
+                      <h5>团队成员</h5>
+                      <div class="member-list">
+                        <div class="member-item" v-for="member in result.members" :key="member.id">
+                          <div class="member-avatar">
+                            <el-icon><UserFilled /></el-icon>
+                          </div>
+                          <div class="member-info">
+                            <div class="member-name">{{ member.name }}</div>
+                            <div class="member-skills">
+                              <el-tag v-for="skill in member.skills.slice(0, 3)" :key="skill" size="small">
+                                {{ skill }}
+                              </el-tag>
+                            </div>
+                          </div>
+                          <div class="member-score">
+                            <el-rate v-model="member.score" disabled show-score />
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                    
+                    <div class="match-analysis">
+                      <h5>匹配分析</h5>
+                      <div class="analysis-item">
+                        <span class="analysis-label">技能覆盖率:</span>
+                        <el-progress :percentage="result.analysis.skillCoverage" />
+                      </div>
+                      <div class="analysis-item">
+                        <span class="analysis-label">经验互补性:</span>
+                        <el-progress :percentage="result.analysis.experienceBalance" />
+                      </div>
+                      <div class="analysis-item">
+                        <span class="analysis-label">团队协作度:</span>
+                        <el-progress :percentage="result.analysis.teamworkScore" />
+                      </div>
+                    </div>
+                  </div>
+                  
+                  <div class="result-actions">
+                    <el-button size="small" @click="viewDetailedAnalysis(result)">详细分析</el-button>
+                    <el-button size="small" type="primary" @click="confirmTeamFormation(result)">确认组队</el-button>
+                    <el-button size="small" type="warning" @click="adjustTeam(result)">调整团队</el-button>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+
+    <!-- 发布项目对话框 -->
+    <el-dialog v-model="showPublishDialog" title="发布新项目" width="700px">
+      <el-form :model="publishForm" label-width="120px">
+        <el-form-item label="项目标题">
+          <el-input v-model="publishForm.title" placeholder="请输入项目标题" />
+        </el-form-item>
+        <el-form-item label="项目类型">
+          <el-select v-model="publishForm.type" placeholder="请选择项目类型">
+            <el-option label="学科竞赛" value="学科竞赛" />
+            <el-option label="创新项目" value="创新项目" />
+            <el-option label="实践项目" value="实践项目" />
+            <el-option label="研究项目" value="研究项目" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="技能要求">
+          <el-select v-model="publishForm.requiredSkills" placeholder="请选择技能要求" multiple>
+            <el-option v-for="skill in availableSkills" :key="skill" :label="skill" :value="skill" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="团队规模">
+          <el-input-number v-model="publishForm.teamSize" :min="2" :max="8" />
+        </el-form-item>
+        <el-form-item label="报名截止">
+          <el-date-picker v-model="publishForm.deadline" type="date" placeholder="请选择截止时间" />
+        </el-form-item>
+        <el-form-item label="项目奖励">
+          <el-input v-model="publishForm.reward" placeholder="请输入项目奖励" />
+        </el-form-item>
+        <el-form-item label="项目描述">
+          <el-input v-model="publishForm.description" type="textarea" rows="4" placeholder="请输入项目描述" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="showPublishDialog = false">取消</el-button>
+        <el-button type="primary" @click="publishProject">发布</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, computed } from 'vue'
+import { useRouter } from 'vue-router'
+import { ElMessage } from 'element-plus'
+import { 
+  Trophy, Plus, Calendar, UserFilled, Magic,
+  TrendCharts, CheckCircle, Clock, Warning 
+} from '@element-plus/icons-vue'
+import PageHeader from '@/components/PageHeader.vue'
+import StatCard from '@/components/StatCard.vue'
+import ActionCard from '@/components/ActionCard.vue'
+
+const router = useRouter()
+
+// 面包屑导航
+const breadcrumbs = [
+  { label: '首页', path: '/' },
+  { label: '工作室建设与管理', path: '/studio-mgmt' },
+  { label: '比赛与项目遴选', path: '/studio-mgmt/competition-selection' }
+]
+
+// 当前激活的标签页
+const activeTab = ref('publish')
+
+// 已发布项目数据
+const publishedProjects = ref([
+  {
+    id: 1,
+    title: '全国大学生数学建模竞赛',
+    type: '学科竞赛',
+    description: '运用数学方法解决实际问题,培养学生的创新思维和实践能力',
+    requiredSkills: ['数学建模', 'MATLAB', 'Python', '数据分析'],
+    teamSize: '3人',
+    deadline: '2024-03-15',
+    reward: '国家级证书 + 奖金',
+    status: '报名中',
+    applicants: 45,
+    matched: 36,
+    teams: 12
+  },
+  {
+    id: 2,
+    title: '智能家居控制系统开发',
+    type: '创新项目',
+    description: '基于物联网技术的智能家居控制系统设计与实现',
+    requiredSkills: ['物联网', 'Java', 'React', '硬件开发'],
+    teamSize: '4-5人',
+    deadline: '2024-02-28',
+    reward: '项目资助 + 专利申请',
+    status: '进行中',
+    applicants: 32,
+    matched: 28,
+    teams: 7
+  },
+  {
+    id: 3,
+    title: '机器学习算法优化研究',
+    type: '研究项目',
+    description: '针对特定领域的机器学习算法优化与性能提升研究',
+    requiredSkills: ['机器学习', 'Python', 'TensorFlow', '算法优化'],
+    teamSize: '2-3人',
+    deadline: '2024-04-10',
+    reward: '学术论文发表机会',
+    status: '即将开始',
+    applicants: 28,
+    matched: 18,
+    teams: 6
+  }
+])
+
+// 报名统计数据
+const registrationStats = ref([
+  { label: '总报名数', value: 105, icon: 'UserFilled', color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' },
+  { label: '待审核', value: 23, icon: 'Clock', color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)' },
+  { label: '已通过', value: 68, icon: 'CheckCircle', color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)' },
+  { label: '已匹配', value: 82, icon: 'TrendCharts', color: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)' }
+])
+
+// 报名列表数据
+const registrationList = ref([
+  {
+    id: 1,
+    studentName: '张三',
+    studentId: '2021001',
+    projectTitle: '全国大学生数学建模竞赛',
+    projectId: 1,
+    skills: ['数学建模', 'MATLAB', 'Python'],
+    experience: 4,
+    motivation: '对数学建模有浓厚兴趣,希望通过比赛提升实践能力',
+    status: 'pending',
+    applyTime: '2024-01-15'
+  },
+  {
+    id: 2,
+    studentName: '李四',
+    studentId: '2021002',
+    projectTitle: '智能家居控制系统开发',
+    projectId: 2,
+    skills: ['Java', 'React', '物联网'],
+    experience: 3,
+    motivation: '有相关项目经验,希望深入学习物联网技术',
+    status: 'approved',
+    applyTime: '2024-01-12'
+  },
+  {
+    id: 3,
+    studentName: '王五',
+    studentId: '2021003',
+    projectTitle: '机器学习算法优化研究',
+    projectId: 3,
+    skills: ['Python', 'TensorFlow', '机器学习'],
+    experience: 5,
+    motivation: '对算法优化研究感兴趣,希望参与学术研究',
+    status: 'approved',
+    applyTime: '2024-01-10'
+  }
+])
+
+// 匹配表单
+const matchingForm = reactive({
+  projectId: '',
+  algorithm: '',
+  teamSize: 3,
+  weights: {
+    skill: 40,
+    experience: 30,
+    learning: 20,
+    teamwork: 10
+  }
+})
+
+// 匹配结果
+const matchingResults = ref([
+  {
+    id: 1,
+    projectTitle: '全国大学生数学建模竞赛',
+    teamId: 'A',
+    matchScore: 92,
+    members: [
+      { id: 1, name: '张三', skills: ['数学建模', 'MATLAB', 'Python'], score: 4.5 },
+      { id: 2, name: '李四', skills: ['数据分析', 'R语言', '统计学'], score: 4.2 },
+      { id: 3, name: '王五', skills: ['算法设计', 'C++', '优化理论'], score: 4.8 }
+    ],
+    analysis: {
+      skillCoverage: 95,
+      experienceBalance: 88,
+      teamworkScore: 90
+    }
+  },
+  {
+    id: 2,
+    projectTitle: '智能家居控制系统开发',
+    teamId: 'B',
+    matchScore: 87,
+    members: [
+      { id: 4, name: '赵六', skills: ['Java', 'Spring', '后端开发'], score: 4.3 },
+      { id: 5, name: '钱七', skills: ['React', 'Vue.js', '前端开发'], score: 4.1 },
+      { id: 6, name: '孙八', skills: ['物联网', '硬件开发', '嵌入式'], score: 4.6 },
+      { id: 7, name: '周九', skills: ['UI设计', '用户体验', 'Figma'], score: 4.0 }
+    ],
+    analysis: {
+      skillCoverage: 90,
+      experienceBalance: 85,
+      teamworkScore: 86
+    }
+  }
+])
+
+// 筛选条件
+const filterProject = ref('')
+const filterStatus = ref('')
+
+// 对话框显示状态
+const showPublishDialog = ref(false)
+
+// 发布表单
+const publishForm = reactive({
+  title: '',
+  type: '',
+  requiredSkills: [],
+  teamSize: 3,
+  deadline: '',
+  reward: '',
+  description: ''
+})
+
+// 可用技能列表
+const availableSkills = ref([
+  '数学建模', 'MATLAB', 'Python', '数据分析', 'Java', 'React', 'Vue.js',
+  '物联网', '机器学习', 'TensorFlow', '算法优化', 'C++', 'JavaScript',
+  'UI设计', '用户体验', '硬件开发', '嵌入式', '后端开发', '前端开发'
+])
+
+// 过滤后的报名列表
+const filteredRegistrations = computed(() => {
+  let filtered = registrationList.value
+  
+  if (filterProject.value) {
+    filtered = filtered.filter(reg => reg.projectId === filterProject.value)
+  }
+  
+  if (filterStatus.value) {
+    filtered = filtered.filter(reg => reg.status === filterStatus.value)
+  }
+  
+  return filtered
+})
+
+// 处理标签页切换
+const handleTabChange = (tabName: string) => {
+  console.log('切换到标签页:', tabName)
+}
+
+// 获取项目类型样式
+const getProjectType = (type: string) => {
+  switch (type) {
+    case '学科竞赛': return 'danger'
+    case '创新项目': return 'primary'
+    case '实践项目': return 'success'
+    case '研究项目': return 'warning'
+    default: return 'info'
+  }
+}
+
+// 获取状态类型
+const getStatusType = (status: string) => {
+  switch (status) {
+    case '报名中': return 'success'
+    case '进行中': return 'primary'
+    case '即将开始': return 'warning'
+    case '已结束': return 'info'
+    default: return 'info'
+  }
+}
+
+// 获取报名状态类型
+const getRegistrationStatusType = (status: string) => {
+  switch (status) {
+    case 'approved': return 'success'
+    case 'pending': return 'warning'
+    case 'rejected': return 'danger'
+    default: return 'info'
+  }
+}
+
+// 获取报名状态文本
+const getRegistrationStatusText = (status: string) => {
+  switch (status) {
+    case 'approved': return '已通过'
+    case 'pending': return '待审核'
+    case 'rejected': return '已拒绝'
+    default: return '未知'
+  }
+}
+
+// 发布项目
+const publishProject = () => {
+  if (!publishForm.title || !publishForm.type || !publishForm.deadline) {
+    ElMessage.warning('请填写完整信息')
+    return
+  }
+  
+  // 这里应该调用API发布项目
+  showPublishDialog.value = false
+  Object.assign(publishForm, { 
+    title: '', type: '', requiredSkills: [], teamSize: 3, 
+    deadline: '', reward: '', description: '' 
+  })
+  ElMessage.success('项目发布成功')
+}
+
+// 查看项目详情
+const viewProjectDetail = (project: any) => {
+  ElMessage.info('查看项目详情功能开发中...')
+}
+
+// 管理报名
+const manageApplicants = (project: any) => {
+  ElMessage.info('管理报名功能开发中...')
+}
+
+// 编辑项目
+const editProject = (project: any) => {
+  ElMessage.info('编辑项目功能开发中...')
+}
+
+// 查看学生档案
+const viewStudentProfile = (registration: any) => {
+  ElMessage.info('查看学生档案功能开发中...')
+}
+
+// 通过报名
+const approveRegistration = (registration: any) => {
+  registration.status = 'approved'
+  ElMessage.success('报名已通过')
+}
+
+// 拒绝报名
+const rejectRegistration = (registration: any) => {
+  registration.status = 'rejected'
+  ElMessage.success('报名已拒绝')
+}
+
+// 执行智能匹配
+const performMatching = () => {
+  if (!matchingForm.projectId || !matchingForm.algorithm) {
+    ElMessage.warning('请选择项目和匹配算法')
+    return
+  }
+  ElMessage.success('智能匹配执行成功')
+}
+
+// 查看详细分析
+const viewDetailedAnalysis = (result: any) => {
+  ElMessage.info('查看详细分析功能开发中...')
+}
+
+// 确认组队
+const confirmTeamFormation = (result: any) => {
+  ElMessage.success('团队组建确认成功')
+}
+
+// 调整团队
+const adjustTeam = (result: any) => {
+  ElMessage.info('调整团队功能开发中...')
+}
+</script>
+
+<style scoped lang="scss">
+.competition-selection-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+
+  .function-nav {
+    background: white;
+    border-radius: 12px;
+    padding: 20px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+    margin-top: 20px;
+
+    .tab-content {
+      margin-top: 20px;
+    }
+  }
+
+  .section-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+
+    h3 {
+      margin: 0;
+      font-size: 18px;
+      font-weight: 600;
+      color: #2c3e50;
+    }
+
+    .header-filters {
+      display: flex;
+      align-items: center;
+    }
+  }
+
+  .publish-section {
+    .project-list {
+      .project-card {
+        background: white;
+        border-radius: 12px;
+        padding: 20px;
+        margin-bottom: 16px;
+        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+        transition: transform 0.3s ease;
+
+        &:hover {
+          transform: translateY(-2px);
+        }
+
+        .project-header {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          margin-bottom: 12px;
+
+          .project-info {
+            display: flex;
+            align-items: center;
+            gap: 12px;
+
+            h4 {
+              margin: 0;
+              font-size: 18px;
+              font-weight: 600;
+              color: #2c3e50;
+            }
+          }
+        }
+
+        .project-content {
+          margin-bottom: 16px;
+
+          .project-description {
+            color: #666;
+            line-height: 1.6;
+            margin-bottom: 12px;
+          }
+
+          .project-requirements {
+            margin-bottom: 12px;
+
+            .label {
+              font-weight: 600;
+              margin-right: 8px;
+              color: #666;
+            }
+
+            .skill-tag {
+              margin-right: 4px;
+            }
+          }
+
+          .project-details {
+            display: flex;
+            gap: 24px;
+
+            .detail-item {
+              display: flex;
+              align-items: center;
+              gap: 4px;
+              font-size: 14px;
+              color: #666;
+
+              .el-icon {
+                color: #409eff;
+              }
+            }
+          }
+        }
+
+        .project-stats {
+          display: flex;
+          gap: 24px;
+          margin-bottom: 16px;
+          padding: 12px;
+          background: #f8f9fa;
+          border-radius: 8px;
+
+          .stat-item {
+            text-align: center;
+
+            .stat-number {
+              display: block;
+              font-size: 20px;
+              font-weight: 600;
+              color: #2c3e50;
+            }
+
+            .stat-label {
+              font-size: 12px;
+              color: #666;
+            }
+          }
+        }
+
+        .project-actions {
+          text-align: right;
+
+          .el-button {
+            margin-left: 8px;
+          }
+        }
+      }
+    }
+  }
+
+  .registration-stats {
+    margin-bottom: 30px;
+
+    .stat-card {
+      background: white;
+      border-radius: 12px;
+      padding: 20px;
+      display: flex;
+      align-items: center;
+      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+      .stat-icon {
+        width: 48px;
+        height: 48px;
+        border-radius: 50%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin-right: 16px;
+
+        .el-icon {
+          color: white;
+          font-size: 20px;
+        }
+      }
+
+      .stat-content {
+        .stat-number {
+          font-size: 24px;
+          font-weight: 600;
+          color: #2c3e50;
+          margin-bottom: 4px;
+        }
+
+        .stat-label {
+          font-size: 14px;
+          color: #666;
+        }
+      }
+    }
+  }
+
+  .registration-list {
+    .skill-tag {
+      margin-right: 4px;
+    }
+  }
+
+  .matching-config {
+    margin-bottom: 30px;
+    padding: 20px;
+    background: #f8f9fa;
+    border-radius: 12px;
+
+    .matching-form {
+      .weight-item {
+        text-align: center;
+
+        span {
+          display: block;
+          margin-bottom: 8px;
+          font-size: 14px;
+          color: #666;
+        }
+      }
+    }
+  }
+
+  .matching-results {
+    .result-list {
+      .result-card {
+        background: white;
+        border-radius: 12px;
+        padding: 20px;
+        margin-bottom: 16px;
+        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+        .result-header {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          margin-bottom: 16px;
+
+          h4 {
+            margin: 0;
+            font-size: 16px;
+            font-weight: 600;
+            color: #2c3e50;
+          }
+
+          .result-score {
+            text-align: center;
+
+            .score-label {
+              display: block;
+              margin-top: 8px;
+              font-size: 12px;
+              color: #666;
+            }
+          }
+        }
+
+        .result-content {
+          margin-bottom: 16px;
+
+          .team-members {
+            margin-bottom: 20px;
+
+            h5 {
+              margin: 0 0 12px 0;
+              font-size: 14px;
+              font-weight: 600;
+              color: #2c3e50;
+            }
+
+            .member-list {
+              .member-item {
+                display: flex;
+                align-items: center;
+                padding: 12px;
+                background: #f8f9fa;
+                border-radius: 8px;
+                margin-bottom: 8px;
+
+                .member-avatar {
+                  width: 40px;
+                  height: 40px;
+                  border-radius: 50%;
+                  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+                  display: flex;
+                  align-items: center;
+                  justify-content: center;
+                  margin-right: 12px;
+
+                  .el-icon {
+                    color: white;
+                  }
+                }
+
+                .member-info {
+                  flex: 1;
+
+                  .member-name {
+                    font-weight: 600;
+                    color: #2c3e50;
+                    margin-bottom: 4px;
+                  }
+
+                  .member-skills {
+                    .el-tag {
+                      margin-right: 4px;
+                    }
+                  }
+                }
+
+                .member-score {
+                  margin-left: 12px;
+                }
+              }
+            }
+          }
+
+          .match-analysis {
+            h5 {
+              margin: 0 0 12px 0;
+              font-size: 14px;
+              font-weight: 600;
+              color: #2c3e50;
+            }
+
+            .analysis-item {
+              display: flex;
+              align-items: center;
+              margin-bottom: 8px;
+
+              .analysis-label {
+                width: 100px;
+                font-size: 14px;
+                color: #666;
+              }
+
+              .el-progress {
+                flex: 1;
+              }
+            }
+          }
+        }
+
+        .result-actions {
+          text-align: right;
+
+          .el-button {
+            margin-left: 8px;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 337 - 78
src/page/studio-mgmt/index.vue

@@ -3,48 +3,48 @@
     <!-- 页面头部 -->
     <PageHeader
       title="工作室建设与管理"
-      description="创新工作室全方位管理,空间规划、设备配置、团队协作一站式服务"
+      description="学生能力信息化管理,项目可视化跟踪,智能化比赛项目遴选"
       :icon="OfficeBuilding"
       :breadcrumbs="breadcrumbs"
     />
 
     <!-- 数据概览 -->
     <div class="overview-section">
-      <el-row :gutter="24">
+      <el-row :gutter="20">
         <el-col :span="6">
           <StatCard
-            title="工作室总数"
-            :number="overviewData.totalStudios"
-            icon="OfficeBuilding"
-            color="#ff6b6b"
-            :trend="{ value: 12, type: 'up' }"
+            title="注册学生"
+            :number="overviewData.totalStudents"
+            icon="UserFilled"
+            color="#4facfe"
+            :trend="{ value: 15, type: 'up' }"
           />
         </el-col>
         <el-col :span="6">
           <StatCard
-            title="活跃团队"
-            :number="overviewData.activeTeams"
-            icon="UserFilled"
-            color="#4facfe"
+            title="活跃项目"
+            :number="overviewData.activeProjects"
+            icon="Briefcase"
+            color="#06ffa5"
             :trend="{ value: 8, type: 'up' }"
           />
         </el-col>
         <el-col :span="6">
           <StatCard
-            title="设备总数"
-            :number="overviewData.totalEquipment"
-            icon="Monitor"
-            color="#06ffa5"
-            :trend="{ value: 5, type: 'up' }"
+            title="技能标签"
+            :number="overviewData.skillTags"
+            icon="Collection"
+            color="#ff6b6b"
+            :trend="{ value: 12, type: 'up' }"
           />
         </el-col>
         <el-col :span="6">
           <StatCard
-            title="使用率"
-            :number="`${overviewData.utilizationRate}%`"
+            title="匹配成功率"
+            :number="`${overviewData.matchSuccessRate}%`"
             icon="TrendCharts"
             color="#f093fb"
-            :trend="{ value: 3, type: 'up' }"
+            :trend="{ value: 5, type: 'up' }"
           />
         </el-col>
       </el-row>
@@ -52,8 +52,8 @@
 
     <!-- 核心功能区 -->
     <div class="core-functions">
-      <h2 class="section-title">核心功能</h2>
-      <el-row :gutter="24">
+      <h2 class="section-title">核心功能模块</h2>
+      <el-row :gutter="20">
         <el-col :span="8" v-for="func in coreFunctions" :key="func.id">
           <ActionCard
             :title="func.title"
@@ -63,6 +63,11 @@
             :stats="func.stats"
             @click="navigateToFunction(func.path)"
           >
+            <template #content>
+              <ul class="feature-list">
+                <li v-for="feature in func.features" :key="feature">{{ feature }}</li>
+              </ul>
+            </template>
             <template #meta>
               <el-tag :type="func.status === 'active' ? 'success' : 'warning'" size="small">
                 {{ func.statusText }}
@@ -89,6 +94,30 @@
         </el-col>
       </el-row>
     </div>
+
+    <!-- 最近活动 -->
+    <div class="recent-activities">
+      <h2 class="section-title">最近活动</h2>
+      <div class="activity-list">
+        <div class="activity-card" v-for="activity in recentActivities" :key="activity.id">
+          <div class="activity-icon">
+            <el-icon>
+              <component :is="activity.icon" />
+            </el-icon>
+          </div>
+          <div class="activity-content">
+            <h4>{{ activity.title }}</h4>
+            <p>{{ activity.description }}</p>
+            <span class="activity-time">{{ activity.time }}</span>
+          </div>
+          <div class="activity-status">
+            <el-tag :type="activity.status === '已完成' ? 'success' : activity.status === '进行中' ? 'warning' : 'info'">
+              {{ activity.status }}
+            </el-tag>
+          </div>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -105,11 +134,12 @@ import {
   Search,
   Document,
   Tools,
-  Calendar
+  Calendar,
+  Trophy
 } from '@element-plus/icons-vue'
-import PageHeader from '../edu-industry/components/PageHeader.vue'
-import StatCard from '../edu-industry/components/StatCard.vue'
-import ActionCard from '../edu-industry/components/ActionCard.vue'
+import PageHeader from '@/components/PageHeader.vue'
+import StatCard from '@/components/StatCard.vue'
+import ActionCard from '@/components/ActionCard.vue'
 
 const router = useRouter()
 
@@ -121,56 +151,112 @@ const breadcrumbs = ref([
 
 // 数据概览
 const overviewData = reactive({
-  totalStudios: 42,
-  activeTeams: 38,
-  totalEquipment: 156,
-  utilizationRate: 87
+  totalStudents: 156,
+  activeProjects: 89,
+  skillTags: 234,
+  matchSuccessRate: 87
 })
 
 // 核心功能
 const coreFunctions = reactive([
   {
-    id: 'space-mgmt',
-    title: '空间管理',
-    description: '工作室空间规划、布局设计、使用情况监控',
-    icon: OfficeBuilding,
-    path: '/studio-mgmt/space',
-    stats: { total: 42, active: 38 },
+    id: 'student-ability',
+    title: '学生能力信息化',
+    description: '技能标签库管理、任务状态跟踪、智能匹配推荐',
+    icon: UserFilled,
+    path: '/studio-mgmt/student-ability',
+    stats: [
+      { value: 156, label: '总人数' },
+      { value: 142, label: '活跃人数' }
+    ],
     status: 'active',
-    statusText: '运行中'
+    statusText: '运行中',
+    features: ['技能标签管理', '能力评估', '任务跟踪']
   },
   {
-    id: 'equipment-mgmt',
-    title: '设备配置',
-    description: '设备采购、维护、使用记录、故障处理',
-    icon: Monitor,
-    path: '/studio-mgmt/equipment',
-    stats: { total: 156, active: 142 },
+    id: 'project-visualization',
+    title: '项目可视化',
+    description: '项目仪表板、进度管理、质量控制可视化展示',
+    icon: TrendCharts,
+    path: '/studio-mgmt/project-visualization',
+    stats: [
+      { value: 89, label: '总项目' },
+      { value: 76, label: '活跃项目' }
+    ],
     status: 'active',
-    statusText: '运行中'
+    statusText: '运行中',
+    features: ['项目仪表板', '进度跟踪', '质量控制']
   },
   {
-    id: 'team-collaboration',
-    title: '团队协作',
-    description: '团队组建、项目协作、成果展示、交流分享',
-    icon: UserFilled,
-    path: '/studio-mgmt/team',
-    stats: { total: 38, active: 35 },
+    id: 'competition-selection',
+    title: '比赛与项目遴选',
+    description: '智能化比赛项目发布、学生报名与筛选匹配系统',
+    icon: Trophy,
+    path: '/studio-mgmt/competition-selection',
+    stats: [
+      { value: 45, label: '总项目' },
+      { value: 38, label: '活跃项目' }
+    ],
     status: 'active',
-    statusText: '运行中'
+    statusText: '运行中',
+    features: ['项目发布管理', '学生报名审核', '智能团队匹配']
   }
 ])
 
 // 快捷操作
 const quickActions = reactive([
-  { id: 'new-studio', label: '新建工作室', icon: Plus },
-  { id: 'search-equipment', label: '设备查询', icon: Search },
-  { id: 'maintenance', label: '设备维护', icon: Tools },
-  { id: 'booking', label: '空间预约', icon: Calendar },
-  { id: 'reports', label: '使用报告', icon: Document },
+  { id: 'new-project', label: '新建项目', icon: Plus },
+  { id: 'student-search', label: '学生查询', icon: Search },
+  { id: 'skill-manage', label: '技能管理', icon: Tools },
+  { id: 'project-match', label: '项目匹配', icon: Calendar },
+  { id: 'progress-report', label: '进度报告', icon: Document },
   { id: 'settings', label: '系统设置', icon: Setting }
 ])
 
+// 最近活动
+const recentActivities = reactive([
+  {
+    id: 1,
+    title: '新增技能标签',
+    description: '添加了"Vue.js"、"机器学习"等5个新技能标签',
+    time: '2小时前',
+    status: '已完成',
+    icon: Plus
+  },
+  {
+    id: 2,
+    title: '项目进度更新',
+    description: '智能推荐系统项目进度更新至75%',
+    time: '4小时前',
+    status: '进行中',
+    icon: TrendCharts
+  },
+  {
+    id: 3,
+    title: '学生能力评估',
+    description: '完成了20名学生的技能能力评估',
+    time: '6小时前',
+    status: '已完成',
+    icon: UserFilled
+  },
+  {
+    id: 4,
+    title: '比赛项目匹配',
+    description: '为"创新创业大赛"匹配了8个优质项目',
+    time: '1天前',
+    status: '已完成',
+    icon: Trophy
+  },
+  {
+    id: 5,
+    title: '系统维护',
+    description: '完成了数据库优化和性能提升',
+    time: '2天前',
+    status: '已完成',
+    icon: Setting
+  }
+])
+
 // 导航到功能页面
 const navigateToFunction = (path: string) => {
   router.push(path)
@@ -186,51 +272,224 @@ const handleQuickAction = (actionId: string) => {
 <style scoped lang="scss">
 .studio-mgmt-container {
   padding: 24px;
-  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  background: #ffffff;
   min-height: 100vh;
+  color: #000000;
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
 }
 
 .overview-section {
   margin-bottom: 32px;
+  animation: fadeIn 0.6s ease-in-out;
 }
 
 .core-functions {
   margin-bottom: 32px;
+  animation: fadeIn 0.6s ease-in-out 0.2s both;
+}
+
+.quick-actions {
+  margin-bottom: 32px;
+  animation: fadeIn 0.6s ease-in-out 0.4s both;
+}
+
+.recent-activities {
+  animation: fadeIn 0.6s ease-in-out 0.6s both;
 }
 
 .section-title {
-  font-size: 20px;
-  font-weight: 600;
-  color: #fff;
-  margin-bottom: 16px;
+  font-size: 22px;
+  font-weight: 700;
+  color: #000000;
+  margin-bottom: 24px;
   display: flex;
   align-items: center;
-  
-  &::before {
-    content: '';
-    width: 4px;
-    height: 20px;
-    background: #ff6b6b;
-    margin-right: 12px;
-    border-radius: 2px;
-  }
+  position: relative;
+  padding-left: 20px;
+  letter-spacing: 0.5px;
+}
+
+.section-title::before {
+  content: '';
+  position: absolute;
+  left: 0;
+  top: 50%;
+  transform: translateY(-50%);
+  width: 4px;
+  height: 24px;
+  background: linear-gradient(180deg, #4cc9f0 0%, #4895ef 100%);
+  border-radius: 2px;
+  box-shadow: 0 4px 12px rgba(76, 201, 240, 0.4);
 }
 
 .quick-actions {
   .quick-action-btn {
     width: 100%;
-    height: 48px;
+    height: 52px;
     font-size: 14px;
-    border-radius: 8px;
-    background: rgba(255, 255, 255, 0.1);
-    border: 1px solid rgba(255, 255, 255, 0.2);
-    color: #fff;
-    transition: all 0.3s ease;
-    
+    font-weight: 500;
+    border-radius: 12px;
+    background: #f0f0f0;
+    border: 1px solid #ddd;
+    color: #000000;
+    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+    position: relative;
+    overflow: hidden;
+    z-index: 1;
+
+    &::before {
+      content: '';
+      position: absolute;
+      top: 0;
+      left: -100%;
+      width: 100%;
+      height: 100%;
+      background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.05), transparent);
+      transition: all 0.6s;
+      z-index: -1;
+    }
+
     &:hover {
-      background: rgba(255, 255, 255, 0.2);
+      background: #e6e6e6;
       transform: translateY(-2px);
-      box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
+      box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
+      border-color: #ccc;
+
+      &::before {
+        left: 100%;
+      }
+    }
+
+    &:active {
+      transform: translateY(0);
+    }
+  }
+}
+
+// 最近活动样式
+.recent-activities {
+  .activity-list {
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
+  }
+
+  .activity-card {
+    display: flex;
+    align-items: flex-start;
+    gap: 16px;
+    padding: 20px;
+    background: #f9f9f9;
+    border-radius: 12px;
+    border: 1px solid #e0e0e0;
+    transition: all 0.3s ease;
+    position: relative;
+    overflow: hidden;
+
+    &::before {
+      content: '';
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 4px;
+      height: 100%;
+      background: linear-gradient(180deg, #4cc9f0, #4361ee);
+    }
+
+    &:hover {
+      background: #f5f5f5;
+      transform: translateX(8px);
+      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
+      border-color: #d0d0d0;
+    }
+  }
+
+  .activity-icon {
+    flex-shrink: 0;
+    width: 40px;
+    height: 40px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background: #f0f0f0;
+    border-radius: 10px;
+    font-size: 18px;
+    color: #4361ee;
+  }
+
+  .activity-content {
+    flex: 1;
+    min-width: 0;
+  }
+
+  .activity-content h4 {
+    font-size: 16px;
+    font-weight: 600;
+    color: #000000;
+    margin: 0 0 8px 0;
+  }
+
+  .activity-content p {
+    font-size: 14px;
+    color: #333333;
+    margin: 0 0 8px 0;
+    line-height: 1.5;
+  }
+
+  .activity-time {
+    font-size: 12px;
+    color: #666666;
+  }
+
+  .activity-status {
+    flex-shrink: 0;
+    margin-left: auto;
+  }
+}
+
+// 动画效果
+@keyframes fadeIn {
+  from {
+    opacity: 0;
+    transform: translateY(20px);
+  }
+  to {
+    opacity: 1;
+    transform: translateY(0);
+  }
+}
+
+// 响应式设计
+@media (max-width: 1200px) {
+  .studio-mgmt-container {
+    padding: 20px;
+  }
+}
+
+@media (max-width: 768px) {
+  .studio-mgmt-container {
+    padding: 16px;
+  }
+
+  .section-title {
+    font-size: 20px;
+    margin-bottom: 16px;
+  }
+
+  .activity-card {
+    flex-direction: column;
+    gap: 12px;
+    padding: 16px;
+  }
+
+  .activity-status {
+    align-self: flex-start;
+    margin-left: 52px;
+  }
+
+  .core-functions {
+    .el-col {
+      margin-bottom: 16px;
     }
   }
 }

+ 851 - 0
src/page/studio-mgmt/project-visualization/index.vue

@@ -0,0 +1,851 @@
+<template>
+  <div class="project-visualization-container">
+    <!-- 页面头部 -->
+    <PageHeader
+      title="项目可视化"
+      description="项目全生命周期可视化管理,实时监控项目进度与质量"
+      :icon="DataAnalysis"
+      :breadcrumbs="breadcrumbs"
+    />
+
+    <!-- 项目概览仪表盘 -->
+    <div class="dashboard-section">
+      <h2 class="section-title">项目概览仪表盘</h2>
+      
+      <!-- 统计卡片 -->
+      <el-row :gutter="20" class="stats-row">
+        <el-col :span="6" v-for="stat in projectStats" :key="stat.label">
+          <div class="stat-card">
+            <div class="stat-icon" :style="{ background: stat.color }">
+              <el-icon>
+                <component :is="stat.icon" />
+              </el-icon>
+            </div>
+            <div class="stat-content">
+              <div class="stat-number">{{ stat.value }}</div>
+              <div class="stat-label">{{ stat.label }}</div>
+              <div class="stat-trend" :class="stat.trend.type">
+                <el-icon>
+                  <ArrowUp v-if="stat.trend.type === 'up'" />
+                  <ArrowDown v-else />
+                </el-icon>
+                {{ stat.trend.value }}%
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+
+      <!-- 图表区域 -->
+      <el-row :gutter="20" class="charts-row">
+        <el-col :span="12">
+          <div class="chart-card">
+            <h3>项目进度分布</h3>
+            <div class="chart-placeholder">
+              <div class="progress-chart">
+                <div class="progress-item" v-for="item in progressData" :key="item.stage">
+                  <div class="progress-label">{{ item.stage }}</div>
+                  <div class="progress-bar">
+                    <div class="progress-fill" :style="{ width: item.percentage + '%', background: item.color }"></div>
+                  </div>
+                  <div class="progress-value">{{ item.count }}个项目</div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div class="chart-card">
+            <h3>项目质量评分</h3>
+            <div class="chart-placeholder">
+              <div class="quality-chart">
+                <div class="quality-item" v-for="item in qualityData" :key="item.level">
+                  <div class="quality-circle" :style="{ background: item.color }">
+                    {{ item.count }}
+                  </div>
+                  <div class="quality-label">{{ item.level }}</div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 项目列表与管理 -->
+    <div class="project-management">
+      <div class="section-header">
+        <h2 class="section-title">项目管理</h2>
+        <div class="header-actions">
+          <el-select v-model="filterStatus" placeholder="筛选状态" style="width: 120px; margin-right: 12px;">
+            <el-option label="全部" value="" />
+            <el-option label="进行中" value="进行中" />
+            <el-option label="已完成" value="已完成" />
+            <el-option label="暂停" value="暂停" />
+          </el-select>
+          <el-button type="primary" :icon="Plus" @click="showCreateProjectDialog = true">
+            创建项目
+          </el-button>
+        </div>
+      </div>
+
+      <!-- 项目表格 -->
+      <el-table :data="filteredProjects" style="width: 100%">
+        <el-table-column prop="name" label="项目名称" width="200">
+          <template #default="scope">
+            <div class="project-name">
+              <el-icon class="project-icon">
+                <Briefcase />
+              </el-icon>
+              {{ scope.row.name }}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="leader" label="项目负责人" width="120" />
+        <el-table-column prop="team" label="团队成员" width="200">
+          <template #default="scope">
+            <el-tag v-for="member in scope.row.team" :key="member" size="small" class="team-tag">
+              {{ member }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="progress" label="进度" width="150">
+          <template #default="scope">
+            <div class="progress-cell">
+              <el-progress :percentage="scope.row.progress" :stroke-width="8" />
+              <span class="progress-text">{{ scope.row.progress }}%</span>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="status" label="状态" width="100">
+          <template #default="scope">
+            <el-tag :type="getStatusType(scope.row.status)">
+              {{ scope.row.status }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="quality" label="质量评分" width="120">
+          <template #default="scope">
+            <div class="quality-score" :class="getQualityClass(scope.row.quality)">
+              {{ scope.row.quality }}分
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="deadline" label="截止时间" width="120" />
+        <el-table-column label="操作" width="200">
+          <template #default="scope">
+            <el-button size="small" @click="viewProjectDetail(scope.row)">详情</el-button>
+            <el-button size="small" type="primary" @click="editProject(scope.row)">编辑</el-button>
+            <el-button size="small" type="warning" @click="viewTimeline(scope.row)">时间线</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- 质量管控面板 -->
+    <div class="quality-control">
+      <h2 class="section-title">质量管控</h2>
+      
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <div class="control-card">
+            <h3>代码质量检查</h3>
+            <div class="control-content">
+              <div class="metric-item">
+                <span class="metric-label">代码覆盖率</span>
+                <div class="metric-value">
+                  <el-progress :percentage="85" color="#67c23a" />
+                  <span>85%</span>
+                </div>
+              </div>
+              <div class="metric-item">
+                <span class="metric-label">代码重复率</span>
+                <div class="metric-value">
+                  <el-progress :percentage="12" color="#f56c6c" />
+                  <span>12%</span>
+                </div>
+              </div>
+              <div class="metric-item">
+                <span class="metric-label">技术债务</span>
+                <div class="metric-value">
+                  <el-progress :percentage="25" color="#e6a23c" />
+                  <span>25%</span>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-col>
+        
+        <el-col :span="8">
+          <div class="control-card">
+            <h3>项目风险评估</h3>
+            <div class="control-content">
+              <div class="risk-item" v-for="risk in riskAssessment" :key="risk.type">
+                <div class="risk-header">
+                  <span class="risk-type">{{ risk.type }}</span>
+                  <el-tag :type="getRiskType(risk.level)" size="small">{{ risk.level }}</el-tag>
+                </div>
+                <div class="risk-description">{{ risk.description }}</div>
+              </div>
+            </div>
+          </div>
+        </el-col>
+        
+        <el-col :span="8">
+          <div class="control-card">
+            <h3>性能指标</h3>
+            <div class="control-content">
+              <div class="performance-grid">
+                <div class="performance-item" v-for="perf in performanceMetrics" :key="perf.name">
+                  <div class="perf-icon" :style="{ background: perf.color }">
+                    <el-icon>
+                      <component :is="perf.icon" />
+                    </el-icon>
+                  </div>
+                  <div class="perf-content">
+                    <div class="perf-value">{{ perf.value }}</div>
+                    <div class="perf-label">{{ perf.name }}</div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 创建项目对话框 -->
+    <el-dialog v-model="showCreateProjectDialog" title="创建新项目" width="600px">
+      <el-form :model="projectForm" label-width="100px">
+        <el-form-item label="项目名称">
+          <el-input v-model="projectForm.name" placeholder="请输入项目名称" />
+        </el-form-item>
+        <el-form-item label="项目负责人">
+          <el-select v-model="projectForm.leader" placeholder="请选择负责人">
+            <el-option v-for="user in userList" :key="user.id" :label="user.name" :value="user.name" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="团队成员">
+          <el-select v-model="projectForm.team" placeholder="请选择团队成员" multiple>
+            <el-option v-for="user in userList" :key="user.id" :label="user.name" :value="user.name" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="项目类型">
+          <el-select v-model="projectForm.type" placeholder="请选择项目类型">
+            <el-option label="Web开发" value="web" />
+            <el-option label="移动应用" value="mobile" />
+            <el-option label="数据分析" value="data" />
+            <el-option label="人工智能" value="ai" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="截止时间">
+          <el-date-picker v-model="projectForm.deadline" type="date" placeholder="请选择截止时间" />
+        </el-form-item>
+        <el-form-item label="项目描述">
+          <el-input v-model="projectForm.description" type="textarea" rows="3" placeholder="请输入项目描述" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="showCreateProjectDialog = false">取消</el-button>
+        <el-button type="primary" @click="createProject">创建</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, computed } from 'vue'
+import { useRouter } from 'vue-router'
+import { ElMessage } from 'element-plus'
+import { 
+  DataAnalysis, Briefcase, Plus, ArrowUp, ArrowDown, 
+  TrendCharts, CheckCircle, Clock, Warning, Monitor 
+} from '@element-plus/icons-vue'
+import PageHeader from '@/components/PageHeader.vue'
+import StatCard from '@/components/StatCard.vue'
+import ActionCard from '@/components/ActionCard.vue'
+
+const router = useRouter()
+
+// 面包屑导航
+const breadcrumbs = [
+  { label: '首页', path: '/' },
+  { label: '工作室建设与管理', path: '/studio-mgmt' },
+  { label: '项目可视化', path: '/studio-mgmt/project-visualization' }
+]
+
+// 项目统计数据
+const projectStats = ref([
+  {
+    label: '总项目数',
+    value: 42,
+    icon: 'Briefcase',
+    color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
+    trend: { type: 'up', value: 12 }
+  },
+  {
+    label: '进行中',
+    value: 28,
+    icon: 'Clock',
+    color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
+    trend: { type: 'up', value: 8 }
+  },
+  {
+    label: '已完成',
+    value: 14,
+    icon: 'CheckCircle',
+    color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
+    trend: { type: 'up', value: 15 }
+  },
+  {
+    label: '平均质量分',
+    value: 87,
+    icon: 'TrendCharts',
+    color: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)',
+    trend: { type: 'up', value: 5 }
+  }
+])
+
+// 进度分布数据
+const progressData = ref([
+  { stage: '需求分析', count: 8, percentage: 80, color: '#409eff' },
+  { stage: '设计阶段', count: 12, percentage: 60, color: '#67c23a' },
+  { stage: '开发阶段', count: 15, percentage: 75, color: '#e6a23c' },
+  { stage: '测试阶段', count: 5, percentage: 50, color: '#f56c6c' },
+  { stage: '部署上线', count: 2, percentage: 20, color: '#909399' }
+])
+
+// 质量分布数据
+const qualityData = ref([
+  { level: '优秀(90+)', count: 12, color: '#67c23a' },
+  { level: '良好(80-89)', count: 18, color: '#409eff' },
+  { level: '一般(70-79)', count: 8, color: '#e6a23c' },
+  { level: '待改进(<70)', count: 4, color: '#f56c6c' }
+])
+
+// 项目列表数据
+const projectList = ref([
+  {
+    id: 1,
+    name: '智能学习平台',
+    leader: '张三',
+    team: ['李四', '王五', '赵六'],
+    progress: 75,
+    status: '进行中',
+    quality: 88,
+    deadline: '2024-03-15',
+    type: 'web'
+  },
+  {
+    id: 2,
+    name: '移动端APP开发',
+    leader: '李四',
+    team: ['张三', '钱七'],
+    progress: 90,
+    status: '即将完成',
+    quality: 92,
+    deadline: '2024-02-28',
+    type: 'mobile'
+  },
+  {
+    id: 3,
+    name: '数据分析系统',
+    leader: '王五',
+    team: ['赵六', '孙八'],
+    progress: 45,
+    status: '进行中',
+    quality: 85,
+    deadline: '2024-04-10',
+    type: 'data'
+  },
+  {
+    id: 4,
+    name: '人工智能助手',
+    leader: '赵六',
+    team: ['张三', '李四', '王五'],
+    progress: 100,
+    status: '已完成',
+    quality: 95,
+    deadline: '2024-01-30',
+    type: 'ai'
+  }
+])
+
+// 风险评估数据
+const riskAssessment = ref([
+  {
+    type: '技术风险',
+    level: '中等',
+    description: '新技术栈学习成本较高,可能影响开发进度'
+  },
+  {
+    type: '进度风险',
+    level: '低',
+    description: '当前项目进度正常,按计划推进'
+  },
+  {
+    type: '资源风险',
+    level: '高',
+    description: '部分关键人员可能存在时间冲突'
+  }
+])
+
+// 性能指标数据
+const performanceMetrics = ref([
+  { name: '响应时间', value: '120ms', icon: 'Clock', color: '#409eff' },
+  { name: '错误率', value: '0.2%', icon: 'Warning', color: '#f56c6c' },
+  { name: '可用性', value: '99.9%', icon: 'CheckCircle', color: '#67c23a' },
+  { name: 'CPU使用率', value: '45%', icon: 'Monitor', color: '#e6a23c' }
+])
+
+// 筛选状态
+const filterStatus = ref('')
+
+// 用户列表
+const userList = ref([
+  { id: 1, name: '张三' },
+  { id: 2, name: '李四' },
+  { id: 3, name: '王五' },
+  { id: 4, name: '赵六' },
+  { id: 5, name: '钱七' },
+  { id: 6, name: '孙八' }
+])
+
+// 对话框显示状态
+const showCreateProjectDialog = ref(false)
+
+// 项目表单
+const projectForm = reactive({
+  name: '',
+  leader: '',
+  team: [],
+  type: '',
+  deadline: '',
+  description: ''
+})
+
+// 过滤后的项目列表
+const filteredProjects = computed(() => {
+  if (!filterStatus.value) return projectList.value
+  return projectList.value.filter(project => project.status === filterStatus.value)
+})
+
+// 获取状态类型
+const getStatusType = (status: string) => {
+  switch (status) {
+    case '已完成': return 'success'
+    case '进行中': return 'primary'
+    case '即将完成': return 'warning'
+    case '暂停': return 'danger'
+    default: return 'info'
+  }
+}
+
+// 获取质量等级样式
+const getQualityClass = (score: number) => {
+  if (score >= 90) return 'excellent'
+  if (score >= 80) return 'good'
+  if (score >= 70) return 'average'
+  return 'poor'
+}
+
+// 获取风险等级类型
+const getRiskType = (level: string) => {
+  switch (level) {
+    case '高': return 'danger'
+    case '中等': return 'warning'
+    case '低': return 'success'
+    default: return 'info'
+  }
+}
+
+// 查看项目详情
+const viewProjectDetail = (project: any) => {
+  ElMessage.info('查看项目详情功能开发中...')
+}
+
+// 编辑项目
+const editProject = (project: any) => {
+  ElMessage.info('编辑项目功能开发中...')
+}
+
+// 查看时间线
+const viewTimeline = (project: any) => {
+  ElMessage.info('查看项目时间线功能开发中...')
+}
+
+// 创建项目
+const createProject = () => {
+  if (!projectForm.name || !projectForm.leader || !projectForm.deadline) {
+    ElMessage.warning('请填写完整信息')
+    return
+  }
+  
+  // 这里应该调用API创建项目
+  showCreateProjectDialog.value = false
+  Object.assign(projectForm, { name: '', leader: '', team: [], type: '', deadline: '', description: '' })
+  ElMessage.success('项目创建成功')
+}
+</script>
+
+<style scoped lang="scss">
+.project-visualization-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+
+  .section-title {
+    font-size: 20px;
+    font-weight: 600;
+    color: #2c3e50;
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+
+    &::before {
+      content: '';
+      width: 4px;
+      height: 20px;
+      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+      margin-right: 12px;
+      border-radius: 2px;
+    }
+  }
+
+  .dashboard-section {
+    margin-bottom: 30px;
+
+    .stats-row {
+      margin-bottom: 20px;
+
+      .stat-card {
+        background: white;
+        border-radius: 12px;
+        padding: 20px;
+        display: flex;
+        align-items: center;
+        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+        transition: transform 0.3s ease;
+
+        &:hover {
+          transform: translateY(-2px);
+        }
+
+        .stat-icon {
+          width: 60px;
+          height: 60px;
+          border-radius: 50%;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          margin-right: 16px;
+
+          .el-icon {
+            color: white;
+            font-size: 24px;
+          }
+        }
+
+        .stat-content {
+          flex: 1;
+
+          .stat-number {
+            font-size: 28px;
+            font-weight: 600;
+            color: #2c3e50;
+            margin-bottom: 4px;
+          }
+
+          .stat-label {
+            font-size: 14px;
+            color: #666;
+            margin-bottom: 4px;
+          }
+
+          .stat-trend {
+            font-size: 12px;
+            display: flex;
+            align-items: center;
+
+            &.up {
+              color: #67c23a;
+            }
+
+            &.down {
+              color: #f56c6c;
+            }
+
+            .el-icon {
+              margin-right: 2px;
+            }
+          }
+        }
+      }
+    }
+
+    .charts-row {
+      .chart-card {
+        background: white;
+        border-radius: 12px;
+        padding: 20px;
+        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+
+        h3 {
+          margin: 0 0 16px 0;
+          font-size: 16px;
+          font-weight: 600;
+          color: #2c3e50;
+        }
+
+        .chart-placeholder {
+          height: 200px;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+
+          .progress-chart {
+            width: 100%;
+
+            .progress-item {
+              display: flex;
+              align-items: center;
+              margin-bottom: 12px;
+
+              .progress-label {
+                width: 80px;
+                font-size: 14px;
+                color: #666;
+              }
+
+              .progress-bar {
+                flex: 1;
+                height: 8px;
+                background: #f0f0f0;
+                border-radius: 4px;
+                margin: 0 12px;
+                overflow: hidden;
+
+                .progress-fill {
+                  height: 100%;
+                  border-radius: 4px;
+                  transition: width 0.3s ease;
+                }
+              }
+
+              .progress-value {
+                width: 60px;
+                font-size: 12px;
+                color: #666;
+                text-align: right;
+              }
+            }
+          }
+
+          .quality-chart {
+            display: flex;
+            justify-content: space-around;
+            align-items: center;
+            width: 100%;
+
+            .quality-item {
+              text-align: center;
+
+              .quality-circle {
+                width: 60px;
+                height: 60px;
+                border-radius: 50%;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                color: white;
+                font-size: 18px;
+                font-weight: 600;
+                margin-bottom: 8px;
+              }
+
+              .quality-label {
+                font-size: 12px;
+                color: #666;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .project-management {
+    margin-bottom: 30px;
+    background: white;
+    border-radius: 12px;
+    padding: 20px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+
+    .section-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 20px;
+
+      .header-actions {
+        display: flex;
+        align-items: center;
+      }
+    }
+
+    .project-name {
+      display: flex;
+      align-items: center;
+
+      .project-icon {
+        margin-right: 8px;
+        color: #409eff;
+      }
+    }
+
+    .team-tag {
+      margin-right: 4px;
+      margin-bottom: 4px;
+    }
+
+    .progress-cell {
+      display: flex;
+      align-items: center;
+
+      .progress-text {
+        margin-left: 8px;
+        font-size: 12px;
+        color: #666;
+      }
+    }
+
+    .quality-score {
+      font-weight: 600;
+
+      &.excellent {
+        color: #67c23a;
+      }
+
+      &.good {
+        color: #409eff;
+      }
+
+      &.average {
+        color: #e6a23c;
+      }
+
+      &.poor {
+        color: #f56c6c;
+      }
+    }
+  }
+
+  .quality-control {
+    .control-card {
+      background: white;
+      border-radius: 12px;
+      padding: 20px;
+      box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+      height: 300px;
+
+      h3 {
+        margin: 0 0 16px 0;
+        font-size: 16px;
+        font-weight: 600;
+        color: #2c3e50;
+      }
+
+      .control-content {
+        .metric-item {
+          margin-bottom: 16px;
+
+          .metric-label {
+            display: block;
+            font-size: 14px;
+            color: #666;
+            margin-bottom: 8px;
+          }
+
+          .metric-value {
+            display: flex;
+            align-items: center;
+
+            span {
+              margin-left: 8px;
+              font-size: 12px;
+              color: #666;
+            }
+          }
+        }
+
+        .risk-item {
+          margin-bottom: 16px;
+          padding: 12px;
+          background: #f8f9fa;
+          border-radius: 6px;
+
+          .risk-header {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            margin-bottom: 8px;
+
+            .risk-type {
+              font-weight: 600;
+              color: #2c3e50;
+            }
+          }
+
+          .risk-description {
+            font-size: 12px;
+            color: #666;
+            line-height: 1.4;
+          }
+        }
+
+        .performance-grid {
+          display: grid;
+          grid-template-columns: 1fr 1fr;
+          gap: 12px;
+
+          .performance-item {
+            display: flex;
+            align-items: center;
+            padding: 12px;
+            background: #f8f9fa;
+            border-radius: 6px;
+
+            .perf-icon {
+              width: 32px;
+              height: 32px;
+              border-radius: 50%;
+              display: flex;
+              align-items: center;
+              justify-content: center;
+              margin-right: 8px;
+
+              .el-icon {
+                color: white;
+                font-size: 14px;
+              }
+            }
+
+            .perf-content {
+              .perf-value {
+                font-size: 16px;
+                font-weight: 600;
+                color: #2c3e50;
+              }
+
+              .perf-label {
+                font-size: 12px;
+                color: #666;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 672 - 0
src/page/studio-mgmt/student-ability/index.vue

@@ -0,0 +1,672 @@
+<template>
+  <div class="student-ability-container">
+    <!-- 页面头部 -->
+    <PageHeader
+      title="学生能力信息化"
+      description="构建学生能力标签库,实现智能化能力评估与匹配"
+      :icon="UserFilled"
+      :breadcrumbs="breadcrumbs"
+    />
+
+    <!-- 功能导航 -->
+    <div class="function-nav">
+      <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+        <el-tab-pane label="能力标签库" name="tags">
+          <div class="tab-content">
+            <!-- 标签管理区域 -->
+            <div class="tags-management">
+              <div class="section-header">
+                <h3>技能标签管理</h3>
+                <el-button type="primary" :icon="Plus" @click="showAddTagDialog = true">
+                  添加标签
+                </el-button>
+              </div>
+              
+              <!-- 标签分类 -->
+              <div class="tag-categories">
+                <div class="category-item" v-for="category in tagCategories" :key="category.id">
+                  <div class="category-header">
+                    <h4>{{ category.name }}</h4>
+                    <el-tag :type="category.type" size="small">{{ category.count }}个标签</el-tag>
+                  </div>
+                  <div class="category-tags">
+                    <el-tag
+                      v-for="tag in category.tags"
+                      :key="tag.id"
+                      :type="tag.level === 'expert' ? 'danger' : tag.level === 'advanced' ? 'warning' : 'info'"
+                      closable
+                      @close="removeTag(tag.id)"
+                      class="tag-item"
+                    >
+                      {{ tag.name }}
+                    </el-tag>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-tab-pane>
+
+        <el-tab-pane label="任务状态管理" name="tasks">
+          <div class="tab-content">
+            <!-- 任务状态概览 -->
+            <div class="task-overview">
+              <el-row :gutter="20">
+                <el-col :span="6" v-for="stat in taskStats" :key="stat.label">
+                  <div class="stat-card">
+                    <div class="stat-icon">
+                      <el-icon>
+                        <component :is="stat.icon" />
+                      </el-icon>
+                    </div>
+                    <div class="stat-content">
+                      <div class="stat-number">{{ stat.value }}</div>
+                      <div class="stat-label">{{ stat.label }}</div>
+                    </div>
+                  </div>
+                </el-col>
+              </el-row>
+            </div>
+
+            <!-- 任务列表 -->
+            <div class="task-list">
+              <div class="section-header">
+                <h3>学生任务状态</h3>
+                <el-button type="primary" :icon="Plus" @click="showAddTaskDialog = true">
+                  分配任务
+                </el-button>
+              </div>
+              
+              <el-table :data="taskList" style="width: 100%">
+                <el-table-column prop="studentName" label="学生姓名" width="120" />
+                <el-table-column prop="taskName" label="任务名称" width="200" />
+                <el-table-column prop="skillTags" label="相关技能" width="250">
+                  <template #default="scope">
+                    <el-tag
+                      v-for="tag in scope.row.skillTags"
+                      :key="tag"
+                      size="small"
+                      class="skill-tag"
+                    >
+                      {{ tag }}
+                    </el-tag>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="progress" label="完成进度" width="120">
+                  <template #default="scope">
+                    <el-progress :percentage="scope.row.progress" :stroke-width="8" />
+                  </template>
+                </el-table-column>
+                <el-table-column prop="status" label="状态" width="100">
+                  <template #default="scope">
+                    <el-tag :type="getStatusType(scope.row.status)">
+                      {{ scope.row.status }}
+                    </el-tag>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="deadline" label="截止时间" width="120" />
+                <el-table-column label="操作" width="150">
+                  <template #default="scope">
+                    <el-button size="small" @click="viewTaskDetail(scope.row)">详情</el-button>
+                    <el-button size="small" type="primary" @click="updateTaskProgress(scope.row)">更新</el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+          </div>
+        </el-tab-pane>
+
+        <el-tab-pane label="智能匹配" name="matching">
+          <div class="tab-content">
+            <!-- 匹配配置 -->
+            <div class="matching-config">
+              <div class="section-header">
+                <h3>智能匹配配置</h3>
+                <el-button type="primary" :icon="Search" @click="performMatching">
+                  执行匹配
+                </el-button>
+              </div>
+              
+              <el-form :model="matchingForm" label-width="120px">
+                <el-row :gutter="20">
+                  <el-col :span="12">
+                    <el-form-item label="匹配类型">
+                      <el-select v-model="matchingForm.type" placeholder="请选择匹配类型">
+                        <el-option label="项目团队匹配" value="team" />
+                        <el-option label="导师学生匹配" value="mentor" />
+                        <el-option label="技能互补匹配" value="skill" />
+                      </el-select>
+                    </el-form-item>
+                  </el-col>
+                  <el-col :span="12">
+                    <el-form-item label="匹配算法">
+                      <el-select v-model="matchingForm.algorithm" placeholder="请选择算法">
+                        <el-option label="技能相似度" value="similarity" />
+                        <el-option label="互补性分析" value="complementary" />
+                        <el-option label="综合评估" value="comprehensive" />
+                      </el-select>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+              </el-form>
+            </div>
+
+            <!-- 匹配结果 -->
+            <div class="matching-results">
+              <h3>匹配结果</h3>
+              <div class="result-list">
+                <div class="result-item" v-for="result in matchingResults" :key="result.id">
+                  <div class="result-header">
+                    <h4>{{ result.title }}</h4>
+                    <el-tag :type="result.score >= 90 ? 'success' : result.score >= 70 ? 'warning' : 'info'">
+                      匹配度: {{ result.score }}%
+                    </el-tag>
+                  </div>
+                  <div class="result-content">
+                    <div class="participants">
+                      <span class="label">参与者:</span>
+                      <el-tag v-for="participant in result.participants" :key="participant" size="small">
+                        {{ participant }}
+                      </el-tag>
+                    </div>
+                    <div class="skills">
+                      <span class="label">匹配技能:</span>
+                      <el-tag v-for="skill in result.matchedSkills" :key="skill" type="success" size="small">
+                        {{ skill }}
+                      </el-tag>
+                    </div>
+                  </div>
+                  <div class="result-actions">
+                    <el-button size="small" @click="viewMatchDetail(result)">查看详情</el-button>
+                    <el-button size="small" type="primary" @click="confirmMatch(result)">确认匹配</el-button>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+
+    <!-- 添加标签对话框 -->
+    <el-dialog v-model="showAddTagDialog" title="添加技能标签" width="500px">
+      <el-form :model="tagForm" label-width="100px">
+        <el-form-item label="标签名称">
+          <el-input v-model="tagForm.name" placeholder="请输入标签名称" />
+        </el-form-item>
+        <el-form-item label="所属分类">
+          <el-select v-model="tagForm.category" placeholder="请选择分类">
+            <el-option v-for="cat in tagCategories" :key="cat.id" :label="cat.name" :value="cat.id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="技能等级">
+          <el-select v-model="tagForm.level" placeholder="请选择等级">
+            <el-option label="初级" value="beginner" />
+            <el-option label="中级" value="intermediate" />
+            <el-option label="高级" value="advanced" />
+            <el-option label="专家" value="expert" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="标签描述">
+          <el-input v-model="tagForm.description" type="textarea" rows="3" placeholder="请输入标签描述" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="showAddTagDialog = false">取消</el-button>
+        <el-button type="primary" @click="addTag">确定</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 分配任务对话框 -->
+    <el-dialog v-model="showAddTaskDialog" title="分配任务" width="600px">
+      <el-form :model="taskForm" label-width="100px">
+        <el-form-item label="学生选择">
+          <el-select v-model="taskForm.studentId" placeholder="请选择学生" multiple>
+            <el-option v-for="student in studentList" :key="student.id" :label="student.name" :value="student.id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="任务名称">
+          <el-input v-model="taskForm.name" placeholder="请输入任务名称" />
+        </el-form-item>
+        <el-form-item label="相关技能">
+          <el-select v-model="taskForm.skillTags" placeholder="请选择相关技能" multiple>
+            <el-option v-for="tag in allTags" :key="tag.id" :label="tag.name" :value="tag.name" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="截止时间">
+          <el-date-picker v-model="taskForm.deadline" type="date" placeholder="请选择截止时间" />
+        </el-form-item>
+        <el-form-item label="任务描述">
+          <el-input v-model="taskForm.description" type="textarea" rows="3" placeholder="请输入任务描述" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="showAddTaskDialog = false">取消</el-button>
+        <el-button type="primary" @click="addTask">确定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, computed } from 'vue'
+import { useRouter } from 'vue-router'
+import { ElMessage } from 'element-plus'
+import { UserFilled, Plus, Search, TrendCharts, CheckCircle, Clock, Warning } from '@element-plus/icons-vue'
+import PageHeader from '@/components/PageHeader.vue'
+import StatCard from '@/components/StatCard.vue'
+import ActionCard from '@/components/ActionCard.vue'
+
+const router = useRouter()
+
+// 面包屑导航
+const breadcrumbs = [
+  { label: '首页', path: '/' },
+  { label: '工作室建设与管理', path: '/studio-mgmt' },
+  { label: '学生能力信息化', path: '/studio-mgmt/student-ability' }
+]
+
+// 当前激活的标签页
+const activeTab = ref('tags')
+
+// 标签分类数据
+const tagCategories = ref([
+  {
+    id: 1,
+    name: '编程语言',
+    type: 'primary',
+    count: 12,
+    tags: [
+      { id: 1, name: 'Python', level: 'advanced' },
+      { id: 2, name: 'JavaScript', level: 'intermediate' },
+      { id: 3, name: 'Java', level: 'expert' },
+      { id: 4, name: 'C++', level: 'intermediate' }
+    ]
+  },
+  {
+    id: 2,
+    name: '前端技术',
+    type: 'success',
+    count: 8,
+    tags: [
+      { id: 5, name: 'Vue.js', level: 'advanced' },
+      { id: 6, name: 'React', level: 'intermediate' },
+      { id: 7, name: 'CSS3', level: 'advanced' },
+      { id: 8, name: 'TypeScript', level: 'intermediate' }
+    ]
+  },
+  {
+    id: 3,
+    name: '数据科学',
+    type: 'warning',
+    count: 6,
+    tags: [
+      { id: 9, name: '机器学习', level: 'expert' },
+      { id: 10, name: '数据分析', level: 'advanced' },
+      { id: 11, name: '深度学习', level: 'intermediate' },
+      { id: 12, name: 'TensorFlow', level: 'intermediate' }
+    ]
+  }
+])
+
+// 任务统计数据
+const taskStats = ref([
+  { label: '总任务数', value: 156, icon: 'TrendCharts' },
+  { label: '进行中', value: 42, icon: 'Clock' },
+  { label: '已完成', value: 98, icon: 'CheckCircle' },
+  { label: '逾期任务', value: 16, icon: 'Warning' }
+])
+
+// 任务列表数据
+const taskList = ref([
+  {
+    id: 1,
+    studentName: '张三',
+    taskName: 'Vue.js项目开发',
+    skillTags: ['Vue.js', 'JavaScript', 'CSS3'],
+    progress: 75,
+    status: '进行中',
+    deadline: '2024-02-15'
+  },
+  {
+    id: 2,
+    studentName: '李四',
+    taskName: '机器学习算法实现',
+    skillTags: ['Python', '机器学习', '数据分析'],
+    progress: 90,
+    status: '即将完成',
+    deadline: '2024-02-10'
+  },
+  {
+    id: 3,
+    studentName: '王五',
+    taskName: 'React组件开发',
+    skillTags: ['React', 'TypeScript', 'CSS3'],
+    progress: 45,
+    status: '进行中',
+    deadline: '2024-02-20'
+  }
+])
+
+// 匹配表单
+const matchingForm = reactive({
+  type: '',
+  algorithm: ''
+})
+
+// 匹配结果
+const matchingResults = ref([
+  {
+    id: 1,
+    title: '前端开发团队匹配',
+    score: 92,
+    participants: ['张三', '李四', '王五'],
+    matchedSkills: ['Vue.js', 'JavaScript', 'CSS3']
+  },
+  {
+    id: 2,
+    title: '数据科学项目匹配',
+    score: 85,
+    participants: ['赵六', '钱七'],
+    matchedSkills: ['Python', '机器学习', '数据分析']
+  }
+])
+
+// 对话框显示状态
+const showAddTagDialog = ref(false)
+const showAddTaskDialog = ref(false)
+
+// 表单数据
+const tagForm = reactive({
+  name: '',
+  category: '',
+  level: '',
+  description: ''
+})
+
+const taskForm = reactive({
+  studentId: [],
+  name: '',
+  skillTags: [],
+  deadline: '',
+  description: ''
+})
+
+// 学生列表
+const studentList = ref([
+  { id: 1, name: '张三' },
+  { id: 2, name: '李四' },
+  { id: 3, name: '王五' },
+  { id: 4, name: '赵六' },
+  { id: 5, name: '钱七' }
+])
+
+// 所有标签
+const allTags = computed(() => {
+  return tagCategories.value.flatMap(category => category.tags)
+})
+
+// 处理标签页切换
+const handleTabChange = (tabName: string) => {
+  console.log('切换到标签页:', tabName)
+}
+
+// 移除标签
+const removeTag = (tagId: number) => {
+  tagCategories.value.forEach(category => {
+    category.tags = category.tags.filter(tag => tag.id !== tagId)
+    category.count = category.tags.length
+  })
+  ElMessage.success('标签删除成功')
+}
+
+// 添加标签
+const addTag = () => {
+  if (!tagForm.name || !tagForm.category || !tagForm.level) {
+    ElMessage.warning('请填写完整信息')
+    return
+  }
+  
+  const category = tagCategories.value.find(cat => cat.id === tagForm.category)
+  if (category) {
+    const newTag = {
+      id: Date.now(),
+      name: tagForm.name,
+      level: tagForm.level
+    }
+    category.tags.push(newTag)
+    category.count = category.tags.length
+  }
+  
+  showAddTagDialog.value = false
+  Object.assign(tagForm, { name: '', category: '', level: '', description: '' })
+  ElMessage.success('标签添加成功')
+}
+
+// 添加任务
+const addTask = () => {
+  if (!taskForm.studentId.length || !taskForm.name || !taskForm.deadline) {
+    ElMessage.warning('请填写完整信息')
+    return
+  }
+  
+  // 这里应该调用API添加任务
+  showAddTaskDialog.value = false
+  Object.assign(taskForm, { studentId: [], name: '', skillTags: [], deadline: '', description: '' })
+  ElMessage.success('任务分配成功')
+}
+
+// 获取状态类型
+const getStatusType = (status: string) => {
+  switch (status) {
+    case '已完成': return 'success'
+    case '进行中': return 'primary'
+    case '即将完成': return 'warning'
+    case '逾期': return 'danger'
+    default: return 'info'
+  }
+}
+
+// 查看任务详情
+const viewTaskDetail = (task: any) => {
+  ElMessage.info('查看任务详情功能开发中...')
+}
+
+// 更新任务进度
+const updateTaskProgress = (task: any) => {
+  ElMessage.info('更新任务进度功能开发中...')
+}
+
+// 执行匹配
+const performMatching = () => {
+  if (!matchingForm.type || !matchingForm.algorithm) {
+    ElMessage.warning('请选择匹配类型和算法')
+    return
+  }
+  ElMessage.success('匹配执行成功')
+}
+
+// 查看匹配详情
+const viewMatchDetail = (result: any) => {
+  ElMessage.info('查看匹配详情功能开发中...')
+}
+
+// 确认匹配
+const confirmMatch = (result: any) => {
+  ElMessage.success('匹配确认成功')
+}
+</script>
+
+<style scoped lang="scss">
+.student-ability-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+
+  .function-nav {
+    background: white;
+    border-radius: 12px;
+    padding: 20px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+    margin-top: 20px;
+
+    .tab-content {
+      margin-top: 20px;
+    }
+  }
+
+  .section-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+
+    h3 {
+      margin: 0;
+      font-size: 18px;
+      font-weight: 600;
+      color: #2c3e50;
+    }
+  }
+
+  .tags-management {
+    .tag-categories {
+      .category-item {
+        margin-bottom: 24px;
+        padding: 16px;
+        background: #f8f9fa;
+        border-radius: 8px;
+
+        .category-header {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          margin-bottom: 12px;
+
+          h4 {
+            margin: 0;
+            font-size: 16px;
+            font-weight: 600;
+            color: #2c3e50;
+          }
+        }
+
+        .category-tags {
+          .tag-item {
+            margin-right: 8px;
+            margin-bottom: 8px;
+          }
+        }
+      }
+    }
+  }
+
+  .task-overview {
+    margin-bottom: 30px;
+
+    .stat-card {
+      background: white;
+      border-radius: 8px;
+      padding: 20px;
+      display: flex;
+      align-items: center;
+      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+      .stat-icon {
+        width: 48px;
+        height: 48px;
+        border-radius: 50%;
+        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin-right: 16px;
+
+        .el-icon {
+          color: white;
+          font-size: 24px;
+        }
+      }
+
+      .stat-content {
+        .stat-number {
+          font-size: 24px;
+          font-weight: 600;
+          color: #2c3e50;
+          margin-bottom: 4px;
+        }
+
+        .stat-label {
+          font-size: 14px;
+          color: #666;
+        }
+      }
+    }
+  }
+
+  .task-list {
+    .skill-tag {
+      margin-right: 4px;
+    }
+  }
+
+  .matching-config {
+    margin-bottom: 30px;
+    padding: 20px;
+    background: #f8f9fa;
+    border-radius: 8px;
+  }
+
+  .matching-results {
+    .result-list {
+      .result-item {
+        background: white;
+        border-radius: 8px;
+        padding: 20px;
+        margin-bottom: 16px;
+        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+        .result-header {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          margin-bottom: 12px;
+
+          h4 {
+            margin: 0;
+            font-size: 16px;
+            font-weight: 600;
+            color: #2c3e50;
+          }
+        }
+
+        .result-content {
+          margin-bottom: 16px;
+
+          .participants, .skills {
+            margin-bottom: 8px;
+
+            .label {
+              font-weight: 600;
+              margin-right: 8px;
+              color: #666;
+            }
+
+            .el-tag {
+              margin-right: 4px;
+            }
+          }
+        }
+
+        .result-actions {
+          text-align: right;
+
+          .el-button {
+            margin-left: 8px;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 81 - 25
src/router/index.ts

@@ -51,6 +51,30 @@ const router = createRouter({
         title: '工作室建设与管理'
       }
     },
+    {
+      path: '/studio-mgmt/student-ability',
+      name: 'StudioMgmtStudentAbility',
+      component: () => import('../page/studio-mgmt/student-ability/index.vue'),
+      meta: {
+        title: '学生能力信息化'
+      }
+    },
+    {
+      path: '/studio-mgmt/project-visualization',
+      name: 'StudioMgmtProjectVisualization',
+      component: () => import('../page/studio-mgmt/project-visualization/index.vue'),
+      meta: {
+        title: '项目可视化'
+      }
+    },
+    {
+      path: '/studio-mgmt/competition-selection',
+      name: 'StudioMgmtCompetitionSelection',
+      component: () => import('../page/studio-mgmt/competition-selection/index.vue'),
+      meta: {
+        title: '比赛与项目遴选'
+      }
+    },
     {
       path: '/competition',
       name: 'Competition',
@@ -82,32 +106,64 @@ const router = createRouter({
       meta: {
         title: '个人空间'
       }
+    },
+    {
+      path: '/lab-mgmt',
+      name: 'LabMgmt',
+      component: () => import('../page/lab-mgmt/index.vue'),
+      meta: {
+        title: '实验室管理'
+      }
+    },
+    {
+      path: '/lab-mgmt/equipment-borrow',
+      name: 'LabMgmtEquipmentBorrow',
+      component: () => import('../page/lab-mgmt/equipment-borrow/index.vue'),
+      meta: {
+        title: '设备借用管理'
+      }
+    },
+    {
+      path: '/lab-mgmt/remote-control',
+      name: 'LabMgmtRemoteControl',
+      component: () => import('../page/lab-mgmt/remote-control/index.vue'),
+      meta: {
+        title: '远程设备控制'
+      }
+    },
+    // 科研与国际化模块
+    {
+      path: '/research',
+      name: 'Research',
+      component: () => import('@/page/research/index.vue'),
+      meta: {
+        title: '科研与国际化模块'
+      }
+    },
+    {
+      path: '/research/exchange-projects',
+      name: 'ResearchExchangeProjects',
+      component: () => import('@/page/research/exchange-projects/index.vue'),
+      meta: {
+        title: '短期交流项目'
+      }
+    },
+    {
+      path: '/research/research-mgmt',
+      name: 'ResearchMgmt',
+      component: () => import('@/page/research/research-mgmt/index.vue'),
+      meta: {
+        title: '科研项目管理'
+      }
+    },
+    {
+      path: '/research/international-coop',
+      name: 'ResearchInternationalCoop',
+      component: () => import('@/page/research/international-coop/index.vue'),
+      meta: {
+        title: '国际合作平台'
+      }
     }
-    // 其他模块路由暂时注释,等待模块创建后再启用
-    // {
-    //   path: '/lab-mgmt',
-    //   name: 'LabMgmt',
-    //   component: () => import('../page/lab-mgmt/index.vue'),
-    //   meta: {
-    //     title: '实验室管理'
-    //   }
-    // },
-    // {
-    //   path: '/research',
-    //   name: 'Research',
-    //   component: () => import('../page/research/index.vue'),
-    //   meta: {
-    //     title: '科研项目管理'
-    //   }
-    // },
-    // {
-    //   path: '/studio-mgmt',
-    //   name: 'StudioMgmt',
-    //   component: () => import('../page/studio-mgmt/index.vue'),
-    //   meta: {
-    //     title: '工作室管理'
-    //   }
-    // }
   ],
 })