wwj 3 months ago
parent
commit
832d2788e9
25 changed files with 1175 additions and 528 deletions
  1. 2 2
      src/layout/components/ToolHeader.vue
  2. 31 16
      src/views/Home/Index.vue
  3. 424 401
      src/views/system/Home/Index.vue
  4. 4 4
      src/views/system/graduateStudent/UserForm.vue
  5. 6 6
      src/views/system/graduateStudent/index.vue
  6. 1 1
      src/views/system/selfAchievement/index.vue
  7. 2 2
      src/views/system/studentAttendanceManage/studentAttendance/index.vue
  8. 2 2
      src/views/system/studentAttendanceManage/studentAttendanceError/index.vue
  9. 2 2
      src/views/system/studentAttendanceManage/studentAttendanceExcused/index.vue
  10. 9 8
      src/views/system/studentAttendanceManage/studentFaceManage/index.vue
  11. 214 0
      src/views/system/studentSelf/SForm.vue
  12. 298 0
      src/views/system/studentSelf/index.vue
  13. 1 1
      src/views/system/workroomCollege/dept/index.vue
  14. 11 4
      src/views/system/workroomCollege/deptInfo/index.vue
  15. 5 0
      src/views/system/workroomCollege/deptInfo/student.vue
  16. 2 0
      src/views/system/workroomCollege/deptInfo/teacher.vue
  17. 4 4
      src/views/system/workroomCollege/user/UserForm.vue
  18. 58 29
      src/views/system/workroomCollege/user/student.vue
  19. 2 2
      src/views/system/workroomCollege/user/teacher.vue
  20. 30 20
      src/views/system/workroomTeacher/TeacherSelf/index.vue
  21. 20 7
      src/views/system/workroomTeacher/dept/index.vue
  22. 8 4
      src/views/system/workroomTeacher/dept/student.vue
  23. 2 0
      src/views/system/workroomTeacher/dept/teacher.vue
  24. 4 4
      src/views/system/workroomTeacher/user/UserForm.vue
  25. 33 9
      src/views/system/workroomTeacher/user/student.vue

+ 2 - 2
src/layout/components/ToolHeader.vue

@@ -1,6 +1,6 @@
 <script lang="tsx">
 import { defineComponent, computed } from 'vue'
-import { Message } from '@/layout/components//Message'
+// import { Message } from '@/layout/components//Message'
 import { Collapse } from '@/layout/components/Collapse'
 import { UserInfo } from '@/layout/components/UserInfo'
 import { Screenfull } from '@/layout/components/Screenfull'
@@ -76,7 +76,7 @@ export default defineComponent({
             ></LocaleDropdown>
           ) : undefined}
           {message.value ? (
-            <Message class="custom-hover" color="var(--top-header-text-color)"></Message>
+            {/* <Message class="custom-hover" color="var(--top-header-text-color)"></Message> */}
           ) : undefined}
           <UserInfo></UserInfo>
         </div>

+ 31 - 16
src/views/Home/Index.vue

@@ -53,8 +53,8 @@
     <el-row :gutter="8">
       <!-- 第一部分 -->
       <el-col :xs="24" :sm="24" :md="24" :lg="14" :xl="10">
-        <el-card>
-          <el-card shadow="never" class="h-100%  ">
+        <el-card class="h-940px mb-10px">
+          <el-card shadow="never" class="h-100%">
 
             <template #header>
               <div class="h-7 flex justify-between fw-800 text-20px">
@@ -117,26 +117,26 @@
         </el-card>
       </el-col>
       <!-- 第二部分 -->
-      <el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="7">
+      <el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="7" class="h-480px">
         <!-- 第一个el-row -->
         <el-row :gutter="15">
           <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-            <el-card shadow="never" class=" mb-10px h-480px ">
+            <el-card shadow="never" class=" mb-10px h-465px ">
               <template #header>
                 <div class="h-7 flex justify-between fw-800 text-20px">
                   <span>周出勤情况</span>
                 </div>
               </template>
-              <el-card shadow="hover" class="mt-1px h-380px ">
-                <el-skeleton :loading="loading" animated>
-                  <Echart :options="barOptionsData" :height="350" />
+              <el-card shadow="hover" class=" h-365px ">
+                <el-skeleton :loading="loading" animated >
+                  <Echart :options="barOptionsData" :height="350" style="margin-top: -30px;"/>
                 </el-skeleton>
               </el-card>
             </el-card>
           </el-col>
 
           <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-            <el-card shadow="never" class="mb-10px ">
+            <el-card shadow="never" class="mb-10px h-465px ">
               <template #header>
                 <div class="h-7 flex justify-between fw-800 text-20px">
                   <span>实时打卡状态</span>
@@ -186,11 +186,14 @@
                       </el-col>
                     </el-row>
                   </div>
-                  <div v-if="list.length == 0"
+                  <!-- <div v-if="list.length == 0"
                     style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
                     暂无预测记录
-                  </div>
+                  </div> -->
                 </vue3ScrollSeamless>
+                <div v-if="list2.length == 0" style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; margin-top: -230px;">
+                  <el-empty description="暂无数据"/>
+                </div>
               </div>
             </el-card>
 
@@ -201,7 +204,7 @@
       <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="7">
         <el-row :gutter="15" align="center">
           <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="24">
-            <el-card shadow="never" class=" h-480px mb-10px "> <!-- 移除 el-card 的边框 -->
+            <el-card shadow="never" class=" h-465px mb-10px "> <!-- 移除 el-card 的边框 -->
               <template #header>
                 <div class="h-7 flex justify-between fw-800 text-20px">
                   <span>缺勤预警</span>
@@ -251,23 +254,37 @@
                       </el-col>
                     </el-row>
                   </div>
-                  <div v-if="list2.length == 0"
+                  <!-- <div v-if="list2.length == 0"
                     style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
                     暂无预测记录
-                  </div>
+                  </div> -->
                 </vue3ScrollSeamless>
+                <div v-if="list2.length == 0" style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; margin-top: -230px;">
+                  <el-empty description="暂无数据"/>
+                </div>
               </div>
             </el-card>
 
           </el-col>
           <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="24">
-            <el-card shadow="never" class=" mt-1px h-480px ">
+            <el-card shadow="never" class=" mt-1px h-465px ">
               <template #header>
                 <div class="h-7 flex justify-between fw-800 text-20px">
                   <span>学生毕业条件达成率</span>
                 </div>
               </template>
+        
               <div class="demoss">
+                <div class="header">
+                <el-row class="shouye h-25px" style="border: none;">
+                  <el-col :span="12" class="center text-18px" style="border: none;padding: 8px;margin-left: 5px; margin-top: -5px;">
+                    <div>工作间</div>
+                  </el-col>
+                  <el-col :span="12" class="center text-18px" style="border: none;padding: 8px;margin-left: -35px; margin-top: -5px;">
+                    <div>达成率</div>
+                  </el-col>
+                </el-row>
+              </div>
                 <vue3ScrollSeamless class="scroll-wrapss  text-color" :classOptions="list1Options" :dataList="list1">
                   <div v-if="list1.length > 0">
                     <el-row v-for="(item, i) of list1" :key="i" class="shouye" :style="{ marginBottom: '10px' }">
@@ -285,9 +302,7 @@
                     暂无预测记录
                   </div>
                 </vue3ScrollSeamless>
-
               </div>
-
             </el-card>
           </el-col>
         </el-row>

+ 424 - 401
src/views/system/Home/Index.vue

@@ -1,264 +1,279 @@
 <template>
   <el-skeleton :loading="loading" animated>
-    <el-row :gutter="8">
-      <!-- 第一部分 -->
-      <el-col :xs="24" :sm="24" :md="24" :lg="14" :xl="10">
-        <el-card>
-          <el-card shadow="never" class="h-100%  ">
-
-            <template #header>
-              <div class="h-7 flex justify-between fw-800 text-20px">
-                <span>基本信息</span>
-              </div>
-            </template>
-
-            <el-row style="flex-wrap: wrap; ">
-              <el-col v-for="(item, index) in projects" :key="`card-${index}`" :xs="24" :sm="24" :md="24" :lg="8" :xl="8">
-                <el-card shadow="hover" class="mr-5px mt-5px " style="background-color:#2585a6 ">
-                  <div class="flex items-center h-75px ">
-                    <!-- <Icon :icon="item.icon" :size="25" class="mr-8px" /> -->
-                    <Icon :icon="item.icon" :size="38" class="mr-8px " />
-
-                    <span class="text-17px c-white">{{ item.name }}</span>
-                  </div>
-                  <div class="mb-18px text-32px c-white ml-20px text-center">{{ t(item.message) }}</div>
-                  <!-- <div class="mt-12px flex justify-between text-12px text-gray-400">                                                                  </div> -->
-                </el-card>
-              </el-col>
-            </el-row>
-          </el-card>
-
-          <el-card shadow="never" class=" h-100% mt-10px ">
-            <template #header>
-              <div class="h-5 flex justify-between fw-800 text-20px">
-                <span>实时出勤统计</span>
-              </div>
-            </template>
-            <el-card shadow="never" class="ml-2px  pr-10px  mt-10px" style="background-color:#33a3dc ;opacity: 0.8; ">
-              <div class="h-70px flex items-center justify-center flex-wrap mt-10px c-white">
-                <div class="px-25px text-center" style="margin: auto;">
-                  <div class="mb-16px text-18px text-white ">打卡人数</div>
-                  <CountTo class="text-28px" :start-val="0" :end-val="totalSate.normalNum" :duration="2600" />
-                </div>
-                <el-divider direction="vertical" border-style="dashed" />
-                <div class="px-8px text-center" style="margin: auto;">
-                  <div class="mb-16px text-18px text-white ">未打卡人数</div>
-                  <CountTo class="text-28px" :start-val="0" :end-val="totalSate.errorNum" :duration="2600" />
-                </div>
-                <el-divider direction="vertical" border-style="dashed" />
-                <div class="px-8px text-center" style="margin: auto;">
-                  <div class="mb-16px text-18px text-white ">请假人数</div>
-                  <CountTo class="text-28px" :start-val="0" :end-val="totalSate.excuseNum" :duration="2600" />
-                </div>
-              </div>
-            </el-card>
-          </el-card>
-
-          <el-card shadow="hover" class=" mt-10px">
-            <template #header>
-              <div class="h-5 flex justify-between fw-800 text-20px">
-                <span>毕业条件达成统计</span>
-              </div>
-            </template>
-            <el-skeleton :loading="loading" animated>
-              <Echart :options="pieOptionsData" :height="250" />
-            </el-skeleton>
-          </el-card>
-        </el-card>
-      </el-col>
-      <!-- 第二部分 -->
-      <el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="7">
-        <!-- 第一个el-row -->
-        <el-row :gutter="15">
-          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-            <el-card shadow="never" class=" mb-10px h-480px ">
-              <template #header>
-                <div class="h-7 flex justify-between fw-800 text-20px">
-                  <span>周出勤情况</span>
-                </div>
-              </template>
-              <el-card shadow="hover" class="mt-1px h-380px ">
-                <el-skeleton :loading="loading" animated>
-                  <Echart :options="barOptionsData" :height="350" />
-                </el-skeleton>
-              </el-card>
-            </el-card>
-          </el-col>
-
-          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-            <el-card shadow="never" class="mb-10px ">
-              <template #header>
-                <div class="h-7 flex justify-between fw-800 text-20px">
-                  <span>实时打卡状态</span>
-                </div>
-              </template>
-              <div class="demo">
-                <div class="table-header">
-                          <div class="header">
-                            <el-row class="shouye" style="border: none;">
-                              <el-col :span="6" class="center text-18px" style="border: none;">
-                                <div>姓名</div>
-                              </el-col>
-                              <el-col :span="6" class="center text-18px" style="border: none;">
-                                <div>学号</div>
-                              </el-col>
-                              <el-col :span="6" class="center text-18px" style="border: none;">
-                                <div>工作间</div>
-                              </el-col>
-                              <el-col :span="6" class="center text-18px" style="border: none;">
-                                <div>打卡时间</div>
-                              </el-col>
-                              <!-- <el-col :span="10" class="center text-18px" style="border: none;">
-                                <div>缺勤时间段</div>
-                              </el-col> -->
-                            </el-row>
-                          </div>
-                        </div>
-                <vue3ScrollSeamless class="scroll-wrap text-color" :classOptions="classOptions" :dataList="list">
-                  <div v-if="list.length > 0">
-                    <el-row v-for="(item, i) of list" :key="i" class="shouye"
-                      style="margin-bottom: 10px; display: flex; justify-content: center;">
-                      <el-col :span="6" class="center"
-                        style="display: flex; justify-content: center; align-items: center; padding: 6px;">
-                        <div>{{ item.studentName }}</div>
-                      </el-col>
-                      <el-col :span="6" class="center"
-                        style="display: flex; justify-content: center; align-items: center; padding: 6px;">
-                        <div>{{ item.userNumber }}</div>
-                      </el-col>
-                      <el-col :span="6" class="center"
-                        style="display: flex; justify-content: center; align-items: center; padding: 6px;">
-                        <div>{{ item.daptName }}</div>
-                      </el-col>
-                      <el-col :span="6" class="center"
-                        style="display: flex; justify-content: center; align-items: center; padding: 6px;">
-                        <div>{{ formatDate(item.clockInTime) }}</div>
-                      </el-col>
-                    </el-row>
-                  </div>
-                  <div v-if="list.length == 0"
-                    style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
-                    暂无预测记录
-                  </div>
-                </vue3ScrollSeamless>
-              </div>
-            </el-card>
-
-          </el-col>
-        </el-row>
-      </el-col>
-              <!-- 第二个el-row -->
-      <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="7">
-        <el-row :gutter="15" align="center">
-          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="24">
-            <el-card shadow="never" class=" h-480px mb-10px "> <!-- 移除 el-card 的边框 -->
-              <template #header>
-                <div class="h-7 flex justify-between fw-800 text-20px">
-                  <span>缺勤预警</span>
-                </div>
-              </template>
-
-              <div class="demos">
-                <div class="table-header">
-                          <div class="header">
-                            <el-row class="shouye" style="border: none;">
-                              <el-col :span="6" class="center text-18px" style="border: none;">
-                                <div>姓名</div>
-                              </el-col>
-                              <el-col :span="6" class="center text-18px" style="border: none;">
-                                <div>学号</div>
-                              </el-col>
-                              <el-col :span="6" class="center text-18px" style="border: none;">
-                                <div>工作间</div>
-                              </el-col>
-                              <el-col :span="6" class="center text-18px" style="border: none;">
-                                <div>导师</div>
-                              </el-col>
-                              <!-- <el-col :span="10" class="center text-18px" style="border: none;">
-                                <div>缺勤时间段</div>
-                              </el-col> -->
-                            </el-row>
-                          </div>
-                        </div>
-
-                <vue3ScrollSeamless class="scroll-wraps text-color" :classOptions="class2Options" :dataList="list2">
-                  <div v-if="list2.length > 0">
-                    <el-row v-for="(item, i) of list2" :key="i" class="shouye">
-                      <!-- <el-col :span="6" class="center" style="padding: 10px; border: none;">
-                        <div>{{ item.ID }}</div>
-                      </el-col> -->
-                      <el-col :span="6" class="center" style="padding: 10px; border: none;">
-                        <div>{{ item.studentName }}</div>
-                      </el-col>
-                      <el-col :span="6" class="center" style="padding: 10px; border: none;">
-                        <div>{{ item.userNumber }}</div>
-                      </el-col>
-                      <el-col :span="6" class="center" style="padding: 10px; border: none;">
-                        <div>{{ item.deptName }}</div>
-                      </el-col>
-                      <el-col :span="6" class="center" style="padding: 10px; border: none;">
-                        <div>{{ item.supervisor }}</div>
-                      </el-col>
-                    </el-row>
-                  </div>
-                  <div v-if="list2.length == 0"
-                    style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
-                    暂无预测记录
-                  </div>
-                </vue3ScrollSeamless>
-              </div>
-            </el-card>
-
-          </el-col>
-          <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="24">
-            <el-card shadow="never" class=" mt-1px h-480px ">
-              <template #header>
-                <div class="h-7 flex justify-between fw-800 text-20px">
-                  <span>学生毕业条件达成率</span>
-                </div>
-              </template>
-              <div class="demoss">
-                <vue3ScrollSeamless class="scroll-wrapss  text-color" :classOptions="list1Options" :dataList="list1">
-                  <div v-if="list1.length > 0">
-                    <el-row v-for="(item, i) of list1" :key="i" class="shouye" :style="{ marginBottom: '10px' }">
-                      <!-- 增加行与行之间的间距 -->
-                      <el-col :span="12" class="center" style="padding: 8px;"> <!-- 增加内边距 -->
-                        <div>{{ item.name }}</div>
-                      </el-col>
-                      <el-col :span="12" class="center" style="padding: 8px;">
-                        <div>{{ item.graduationRate }}%</div>
-                      </el-col>
-                    </el-row>
-                  </div>
-                  <div v-if="list1.length == 0"
-                    style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
-                    暂无预测记录
-                  </div>
-                </vue3ScrollSeamless>
-
-              </div>
-
-            </el-card>
-          </el-col>
-        </el-row>
-      </el-col>
-    </el-row>
+                                                      <el-row :gutter="8">
+                                                        <!-- 第一部分 -->
+                                                        <el-col :xs="24" :sm="24" :md="24" :lg="14" :xl="10">
+                                                          <el-card class="h-940px mb-10px">
+                                                            <el-card shadow="never" class="h-100%">
+                                                  
+                                                              <template #header>
+                                                                <div class="h-7 flex justify-between fw-800 text-20px">
+                                                                  <span>基本信息</span>
+                                                                </div>
+                                                              </template>
+                                                  
+                                                              <el-row style="flex-wrap: wrap; ">
+                                                                <el-col v-for="(item, index) in projects" :key="`card-${index}`" :xs="24" :sm="24" :md="24" :lg="8" :xl="8">
+                                                                  <el-card shadow="hover" class="mr-5px mt-5px " style="background-color:#2585a6 ">
+                                                                    <div class="flex items-center h-75px ">
+                                                                      <!-- <Icon :icon="item.icon" :size="25" class="mr-8px" /> -->
+                                                                      <Icon :icon="item.icon" :size="38" class="mr-8px " />
+                                                  
+                                                                      <span class="text-17px c-white">{{ item.name }}</span>
+                                                                    </div>
+                                                                    <div class="mb-18px text-32px c-white ml-20px text-center">{{ t(item.message) }}</div>
+                                                                    <!-- <div class="mt-12px flex justify-between text-12px text-gray-400">                                                                  </div> -->
+                                                                  </el-card>
+                                                                </el-col>
+                                                              </el-row>
+                                                            </el-card>
+                                                  
+                                                            <el-card shadow="never" class=" h-100% mt-10px ">
+                                                              <template #header>
+                                                                <div class="h-5 flex justify-between fw-800 text-20px">
+                                                                  <span>实时出勤统计</span>
+                                                                </div>
+                                                              </template>
+                                                              <el-card shadow="never" class="ml-2px  pr-10px  mt-10px" style="background-color:#33a3dc ;opacity: 0.8; ">
+                                                                <div class="h-70px flex items-center justify-center flex-wrap mt-10px c-white">
+                                                                  <div class="px-25px text-center" style="margin: auto;">
+                                                                    <div class="mb-16px text-18px text-white ">打卡人数</div>
+                                                                    <CountTo class="text-28px" :start-val="0" :end-val="totalSate.normalNum" :duration="2600" />
+                                                                  </div>
+                                                                  <el-divider direction="vertical" border-style="dashed" />
+                                                                  <div class="px-8px text-center" style="margin: auto;">
+                                                                    <div class="mb-16px text-18px text-white ">未打卡人数</div>
+                                                                    <CountTo class="text-28px" :start-val="0" :end-val="totalSate.errorNum" :duration="2600" />
+                                                                  </div>
+                                                                  <el-divider direction="vertical" border-style="dashed" />
+                                                                  <div class="px-8px text-center" style="margin: auto;">
+                                                                    <div class="mb-16px text-18px text-white ">请假人数</div>
+                                                                    <CountTo class="text-28px" :start-val="0" :end-val="totalSate.excuseNum" :duration="2600" />
+                                                                  </div>
+                                                                </div>
+                                                              </el-card>
+                                                            </el-card>
+                                                  
+                                                            <el-card shadow="hover" class=" mt-10px">
+                                                              <template #header>
+                                                                <div class="h-5 flex justify-between fw-800 text-20px">
+                                                                  <span>毕业条件达成统计</span>
+                                                                </div>
+                                                              </template>
+                                                              <el-skeleton :loading="loading" animated>
+                                                                <Echart :options="pieOptionsData" :height="250" />
+                                                              </el-skeleton>
+                                                            </el-card>
+                                                          </el-card>
+                                                        </el-col>
+                                                        <!-- 第二部分 -->
+                                                        <el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="7" class="h-480px">
+                                                          <!-- 第一个el-row -->
+                                                          <el-row :gutter="15">
+                                                            <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                                                              <el-card shadow="never" class=" mb-10px h-465px ">
+                                                                <template #header>
+                                                                  <div class="h-7 flex justify-between fw-800 text-20px">
+                                                                    <span>周出勤情况</span>
+                                                                  </div>
+                                                                </template>
+                                                                <el-card shadow="hover" class=" h-365px ">
+                                                                  <el-skeleton :loading="loading" animated >
+                                                                    <Echart :options="barOptionsData" :height="350" style="margin-top: -30px;"/>
+                                                                  </el-skeleton>
+                                                                </el-card>
+                                                              </el-card>
+                                                            </el-col>
+                                                  
+                                                            <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+                                                              <el-card shadow="never" class="mb-10px h-465px ">
+                                                                <template #header>
+                                                                  <div class="h-7 flex justify-between fw-800 text-20px">
+                                                                    <span>实时打卡状态</span>
+                                                                  </div>
+                                                                </template>
+                                                                <div class="demo">
+                                                                  <div class="table-header">
+                                                                            <div class="header">
+                                                                              <el-row class="shouye" style="border: none;">
+                                                                                <el-col :span="6" class="center text-18px" style="border: none;">
+                                                                                  <div>姓名</div>
+                                                                                </el-col>
+                                                                                <el-col :span="6" class="center text-18px" style="border: none;">
+                                                                                  <div>学号</div>
+                                                                                </el-col>
+                                                                                <el-col :span="6" class="center text-18px" style="border: none;">
+                                                                                  <div>工作间</div>
+                                                                                </el-col>
+                                                                                <el-col :span="6" class="center text-18px" style="border: none;">
+                                                                                  <div>打卡时间</div>
+                                                                                </el-col>
+                                                                                <!-- <el-col :span="10" class="center text-18px" style="border: none;">
+                                                                                  <div>缺勤时间段</div>
+                                                                                </el-col> -->
+                                                                              </el-row>
+                                                                            </div>
+                                                                          </div>
+                                                                  <vue3ScrollSeamless class="scroll-wrap text-color" :classOptions="classOptions" :dataList="list">
+                                                                    <div v-if="list.length > 0">
+                                                                      <el-row v-for="(item, i) of list" :key="i" class="shouye"
+                                                                        style="margin-bottom: 10px; display: flex; justify-content: center;">
+                                                                        <el-col :span="6" class="center"
+                                                                          style="display: flex; justify-content: center; align-items: center; padding: 6px;">
+                                                                          <div>{{ item.studentName }}</div>
+                                                                        </el-col>
+                                                                        <el-col :span="6" class="center"
+                                                                          style="display: flex; justify-content: center; align-items: center; padding: 6px;">
+                                                                          <div>{{ item.userNumber }}</div>
+                                                                        </el-col>
+                                                                        <el-col :span="6" class="center"
+                                                                          style="display: flex; justify-content: center; align-items: center; padding: 6px;">
+                                                                          <div>{{ item.daptName }}</div>
+                                                                        </el-col>
+                                                                        <el-col :span="6" class="center"
+                                                                          style="display: flex; justify-content: center; align-items: center; padding: 6px;">
+                                                                          <div>{{ formatDate(item.clockInTime) }}</div>
+                                                                        </el-col>
+                                                                      </el-row>
+                                                                    </div>
+                                                                    <!-- <div v-if="list.length == 0"
+                                                                      style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
+                                                                      暂无预测记录
+                                                                    </div> -->
+                                                                  </vue3ScrollSeamless>
+                                                                  <div v-if="list2.length == 0" style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; margin-top: -230px;">
+                                                                    <el-empty description="暂无数据"/>
+                                                                  </div>
+                                                                </div>
+                                                              </el-card>
+                                                  
+                                                            </el-col>
+                                                          </el-row>
+                                                        </el-col>
+                                                                <!-- 第二个el-row -->
+                                                        <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="7">
+                                                          <el-row :gutter="15" align="center">
+                                                            <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="24">
+                                                              <el-card shadow="never" class=" h-465px mb-10px "> <!-- 移除 el-card 的边框 -->
+                                                                <template #header>
+                                                                  <div class="h-7 flex justify-between fw-800 text-20px">
+                                                                    <span>缺勤预警</span>
+                                                                  </div>
+                                                                </template>
+                                                  
+                                                                <div class="demos">
+                                                                  <div class="table-header">
+                                                                            <div class="header">
+                                                                              <el-row class="shouye" style="border: none;">
+                                                                                <el-col :span="6" class="center text-18px" style="border: none;">
+                                                                                  <div>姓名</div>
+                                                                                </el-col>
+                                                                                <el-col :span="6" class="center text-18px" style="border: none;">
+                                                                                  <div>学号</div>
+                                                                                </el-col>
+                                                                                <el-col :span="6" class="center text-18px" style="border: none;">
+                                                                                  <div>工作间</div>
+                                                                                </el-col>
+                                                                                <el-col :span="6" class="center text-18px" style="border: none;">
+                                                                                  <div>导师</div>
+                                                                                </el-col>
+                                                                                <!-- <el-col :span="10" class="center text-18px" style="border: none;">
+                                                                                  <div>缺勤时间段</div>
+                                                                                </el-col> -->
+                                                                              </el-row>
+                                                                            </div>
+                                                                          </div>
+                                                  
+                                                                  <vue3ScrollSeamless class="scroll-wraps text-color" :classOptions="class2Options" :dataList="list2">
+                                                                    <div v-if="list2.length > 0">
+                                                                      <el-row v-for="(item, i) of list2" :key="i" class="shouye">
+                                                                        <!-- <el-col :span="6" class="center" style="padding: 10px; border: none;">
+                                                                          <div>{{ item.ID }}</div>
+                                                                        </el-col> -->
+                                                                        <el-col :span="6" class="center" style="padding: 10px; border: none;">
+                                                                          <div>{{ item.studentName }}</div>
+                                                                        </el-col>
+                                                                        <el-col :span="6" class="center" style="padding: 10px; border: none;">
+                                                                          <div>{{ item.userNumber }}</div>
+                                                                        </el-col>
+                                                                        <el-col :span="6" class="center" style="padding: 10px; border: none;">
+                                                                          <div>{{ item.deptName }}</div>
+                                                                        </el-col>
+                                                                        <el-col :span="6" class="center" style="padding: 10px; border: none;">
+                                                                          <div>{{ item.supervisor }}</div>
+                                                                        </el-col>
+                                                                      </el-row>
+                                                                    </div>
+                                                                    <!-- <div v-if="list2.length == 0"
+                                                                      style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
+                                                                      暂无预测记录
+                                                                    </div> -->
+                                                                  </vue3ScrollSeamless>
+                                                                  <div v-if="list2.length == 0" style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; margin-top: -230px;">
+                                                                    <el-empty description="暂无数据"/>
+                                                                  </div>
+                                                                </div>
+                                                              </el-card>
+                                                  
+                                                            </el-col>
+                                                            <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="24">
+                                                              <el-card shadow="never" class=" mt-1px h-465px ">
+                                                                <template #header>
+                                                                  <div class="h-7 flex justify-between fw-800 text-20px">
+                                                                    <span>学生毕业条件达成率</span>
+                                                                  </div>
+                                                                </template>
+                                                          
+                                                                <div class="demoss">
+                                                                  <div class="header">
+                                                                  <el-row class="shouye h-25px" style="border: none;">
+                                                                    <el-col :span="12" class="center text-18px" style="border: none;padding: 8px;margin-left: 5px; margin-top: -5px;">
+                                                                      <div>工作间</div>
+                                                                    </el-col>
+                                                                    <el-col :span="12" class="center text-18px" style="border: none;padding: 8px;margin-left: -35px; margin-top: -5px;">
+                                                                      <div>达成率</div>
+                                                                    </el-col>
+                                                                  </el-row>
+                                                                </div>
+                                                                  <vue3ScrollSeamless class="scroll-wrapss  text-color" :classOptions="list1Options" :dataList="list1">
+                                                                    <div v-if="list1.length > 0">
+                                                                      <el-row v-for="(item, i) of list1" :key="i" class="shouye" :style="{ marginBottom: '10px' }">
+                                                                        <!-- 增加行与行之间的间距 -->
+                                                                        <el-col :span="12" class="center" style="padding: 8px;"> <!-- 增加内边距 -->
+                                                                          <div>{{ item.name }}</div>
+                                                                        </el-col>
+                                                                        <el-col :span="12" class="center" style="padding: 8px;">
+                                                                          <div>{{ item.graduationRate }}%</div>
+                                                                        </el-col>
+                                                                      </el-row>
+                                                                    </div>
+                                                                    <div v-if="list1.length == 0"
+                                                                      style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
+                                                                      暂无预测记录
+                                                                    </div>
+                                                                  </vue3ScrollSeamless>
+                                                                </div>
+                                                              </el-card>
+                                                            </el-col>
+                                                          </el-row>
+                                                        </el-col>
+                                                      </el-row>
   </el-skeleton>
 </template>
 
 <script lang="ts" setup>
 import { EChartsOption, List } from 'echarts'
-import { formatTime } from '@/utils'
-import {formatDate} from "@/utils/formatTime";
-import { useUserStore } from '@/store/modules/user'
-import { useWatermark } from '@/hooks/web/useWatermark'
-import type { WorkplaceTotal, Project, Notice, Shortcut } from './types'
-import { pieOptions, barOptions } from './echarts-data'
-import { reactive, onMounted, watchEffect } from "vue";
-import { vue3ScrollSeamless } from "vue3-scroll-seamless";
-import * as UserApi from '@/api/system/user'
-import * as  DeptApi from '@/api/system/dept'
-import  { StudentAttendanceApi } from '@/api/system/studentAttendance'
+                                                  import { formatTime } from '@/utils'
+                                                  import {formatDate} from "@/utils/formatTime";
+                                                  import { useUserStore } from '@/store/modules/user'
+                                                  import { useWatermark } from '@/hooks/web/useWatermark'
+                                                  import type { WorkplaceTotal, Project, Notice, Shortcut } from './types'
+                                                  import { pieOptions, barOptions } from './echarts-data'
+                                                  import { reactive, onMounted, watchEffect } from "vue";
+                                                  import { vue3ScrollSeamless } from "vue3-scroll-seamless";
+                                                  import * as UserApi from '@/api/system/user'
+                                                  import * as  DeptApi from '@/api/system/dept'
+                                                  import  { StudentAttendanceApi } from '@/api/system/studentAttendance'
 
 defineOptions({ name: 'Home' })
 
@@ -273,202 +288,209 @@ const username = userStore.getUser.nickname
 
 /*基本信息*/
 const detail = reactive({
-  deptNum: undefined,
-  teacherNum: undefined,
-  studentNum: undefined
+                                                    deptNum: undefined,
+                                                    teacherNum: undefined,
+                                                    studentNum: undefined
 })
 const getDetail = async () => {
-  const data = await UserApi.getDetail()
-  console.log("基本信息", data);
-  detail.deptNum = data.deptNum
-  detail.teacherNum = data.teacherNum
-  detail.studentNum = data.studentNum
+                                                    const data = await UserApi.getDetail()
+                                                    console.log("基本信息", data);
+                                                    detail.deptNum = data.deptNum
+                                                    detail.teacherNum = data.teacherNum
+                                                    detail.studentNum = data.studentNum
 }
 // 获取项目数
 let projects = reactive<Project[]>([])
 const getProject = async () => {
-  const data = [
-    {
-      name: '学院工作间数量',
-      icon: 'svg-icon:gzs',
-      message: String(detail.deptNum) + '个',
-      time: new Date()
-    },
-    {
-      name: '导师数量',
-      icon: 'svg-icon:ds',
-      message: String(detail.teacherNum) + '人',
-      time: new Date()
-    },
-    {
-      name: '在校生数量',
-      icon: 'svg-icon:zxs',
-      message: String(detail.studentNum) + '人',
-      time: new Date()
-    }
-
-  ]
-  projects = Object.assign(projects, data)
+                                                    const data = [
+                                                      {
+                                                        name: '学院工作间数量',
+                                                        icon: 'svg-icon:gzs',
+                                                        message: String(detail.deptNum) + '个',
+                                                        time: new Date()
+                                                      },
+                                                      {
+                                                        name: '导师数量',
+                                                        icon: 'svg-icon:ds',
+                                                        message: String(detail.teacherNum) + '人',
+                                                        time: new Date()
+                                                      },
+                                                      {
+                                                        name: '在校生数量',
+                                                        icon: 'svg-icon:zxs',
+                                                        message: String(detail.studentNum) + '人',
+                                                        time: new Date()
+                                                      }
+                                                  
+                                                    ]
+                                                    projects = Object.assign(projects, data)
 }
 
 
 /**实时出勤统计 */
 // 获取统计数
 let totalSate = reactive<WorkplaceTotal>({
-  normalNum: 0,
-  errorNum: 0,
-  excuseNum: 0,
+                                                    normalNum: 0,
+                                                    errorNum: 0,
+                                                    excuseNum: 0,
 })
 const getCount = async () => {
-  const data = await StudentAttendanceApi.getDayAttendance()
-  console.log("实时出勤统计", data);
-  totalSate = Object.assign(totalSate, data)
+                                                    const data = await StudentAttendanceApi.getDayAttendance()
+                                                    console.log("实时出勤统计", data);
+                                                    totalSate = Object.assign(totalSate, data)
 }
 
 // /**毕业达成统计 */
 let pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
 const getGraduateCount = async () => {
-  const data = await UserApi.getGraduateCount()
-  console.log("毕业达成统计", data);
-  const studentNum = data.studentNum;
-  const graduateNum = data.graduateNum;
-  const options = {
-    title: {
-      text: null,
-      left: 'center',
-      top: '20px'
-    },
-    tooltip: {
-      trigger: 'item',
-    },
-    legend: {
-      top: '10%',  // 顶部位置
-      left: 'left', // 左侧位置
-    },
-    series: [
-      {
-        type: 'pie',
-        radius: ['120px', '70px'], // 设定内圈和外圈半径
-        center: ['50%', '85%'], // 中心位置
-        startAngle: 180,
-        endAngle: 360,
-        data: [
-          {
-            value: graduateNum, // 畢業生数量
-            name: '已达成', // 国际化名称或直接用字符串 '毕业生'
-            label: {
-              show: true,
-              position: 'outside',  // 拉出标注
-              formatter: '{b}: {c}', // 显示名称和数值
-              emphasis: {
-                show: true,
-              },
-            },
-            labelLine: {
-              show: true,
-              length: 75,
-              length2: 10,
-              smooth: true,
-              lineDash: [5, 5],
-            },
-          },
-          {
-            value: studentNum, // 在校生数量(总在校生减去毕业生)
-            name: '未达成', // 国际化名称或直接用字符串 '在校生'
-            label: {
-              show: true,
-              position: 'outside',
-              formatter: '{b}: {c}',
-              emphasis: {
-                show: true,
-              },
-            },
-            labelLine: {
-              show: true,
-              length: 75,
-              length2: 10,
-              smooth: true,
-              lineDash: [5, 5],
-            },
-          },
-        ],
-        itemStyle: {
-          // 设置饼图的颜色
-          color: function (params) {
-            const colorList = ['#2585a6','#5cb5e3' ]; // 定义颜色数组
-            return colorList[params.dataIndex]; // 根据数据索引返回对应的颜色
-          }
-        }
-      },
-    ],
-  };
-  pieOptionsData = Object.assign(pieOptionsData, options);
+                                                    const data = await UserApi.getGraduateCount()
+                                                    console.log("毕业达成统计", data);
+                                                    const studentNum = data.studentNum;
+                                                    const graduateNum = data.graduateNum;
+                                                    const options = {
+                                                      title: {
+                                                        text: null,
+                                                        left: 'center',
+                                                        top: '20px'
+                                                      },
+                                                      tooltip: {
+                                                        trigger: 'item',
+                                                      },
+                                                      legend: {
+                                                        top: '10%',  // 顶部位置
+                                                        left: 'left', // 左侧位置
+                                                      },
+                                                      series: [
+                                                        {
+                                                          type: 'pie',
+                                                          radius: ['120px', '70px'], // 设定内圈和外圈半径
+                                                          center: ['50%', '85%'], // 中心位置
+                                                          startAngle: 180,
+                                                          endAngle: 360,
+                                                          data: [
+                                                            {
+                                                              value: graduateNum, // 畢業生数量
+                                                              name: '已达成', // 国际化名称或直接用字符串 '毕业生'
+                                                              label: {
+                                                                show: true,
+                                                                position: 'outside',  // 拉出标注
+                                                                formatter: '{b}: {c}', // 显示名称和数值
+                                                                emphasis: {
+                                                                  show: true,
+                                                                },
+                                                              },
+                                                              labelLine: {
+                                                                show: true,
+                                                                length: 75,
+                                                                length2: 10,
+                                                                smooth: true,
+                                                                lineDash: [5, 5],
+                                                              },
+                                                            },
+                                                            {
+                                                              value: studentNum, // 在校生数量(总在校生减去毕业生)
+                                                              name: '未达成', // 国际化名称或直接用字符串 '在校生'
+                                                              label: {
+                                                                show: true,
+                                                                position: 'outside',
+                                                                formatter: '{b}: {c}',
+                                                                emphasis: {
+                                                                  show: true,
+                                                                },
+                                                              },
+                                                              labelLine: {
+                                                                show: true,
+                                                                length: 75,
+                                                                length2: 10,
+                                                                smooth: true,
+                                                                lineDash: [5, 5],
+                                                              },
+                                                            },
+                                                          ],
+                                                          itemStyle: {
+                                                            // 设置饼图的颜色
+                                                            color: function (params) {
+                                                              const colorList = ['#2585a6','#5cb5e3' ]; // 定义颜色数组
+                                                              return colorList[params.dataIndex]; // 根据数据索引返回对应的颜色
+                                                            }
+                                                          }
+                                                        },
+                                                      ],
+                                                    };
+                                                  
+                                                  //   // set(
+                                                  //   //   pieOptionsData,
+                                                  //   //   'legend.data',
+                                                  //   //   data.map((v) => t(v.name))
+                                                  //   // );
+                                                  
+                                                    pieOptionsData = Object.assign(pieOptionsData, options);
 };
 
 /**周出勤情况 */
 let barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption
 const getWeekend = async () => {
-    const data = await StudentAttendanceApi.getWeekendAttendance();
-    console.log("周出勤情况", data);
-    const normalData = data.dailyNormalList
-    const errorData = data.dailyErrorList;
-    const excuseData = data.dailyExcuseList;
-    barOptionsData.series[0].data = normalData;
-    barOptionsData.series[1].data = errorData; 
-    barOptionsData.series[2].data = excuseData;
+                                                      const data = await StudentAttendanceApi.getWeekendAttendance();
+                                                      console.log("周出勤情况", data);
+                                                      const normalData = data.dailyNormalList
+                                                      const errorData = data.dailyErrorList;
+                                                      const excuseData = data.dailyExcuseList;
+                                                      barOptionsData.series[0].data = normalData;
+                                                      barOptionsData.series[1].data = errorData;
+                                                      barOptionsData.series[2].data = excuseData;
 };
 
 /**缺勤预警 */
 let list2 = reactive([]);
 const getStudentAttendanceError = async () => {
-  const data = await StudentAttendanceApi.getDayStudentErrorAttendance()
-  console.log("缺勤列表", data);
-  list2.splice(0, list2.length, ...data);
+                                                    const data = await StudentAttendanceApi.getDayStudentErrorAttendance()
+                                                    console.log("缺勤列表", data);
+                                                    list2.splice(0, list2.length, ...data);
 }
 const class2Options = reactive({
-  step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
-  limitMoveNum: list2.length,//无缝滚动列表元素的长度,一般设置为列表的长度
-  direction: 1,//方向: 0 往下 1 往上 2 向左 3 向右。
+                                                    step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
+                                                    limitMoveNum: list2.length,//无缝滚动列表元素的长度,一般设置为列表的长度
+                                                    direction: 1,//方向: 0 往下 1 往上 2 向左 3 向右。
 });
 
 /**实时打卡状态 */
 //打卡滚动列表
 const list = reactive([]);
 const getStudentAttendance = async () => {
-  const data = await StudentAttendanceApi.getDayStudentAttendance()
-  console.log("打卡列表", data);
-  list.splice(0, list.length, ...data);
+                                                    const data = await StudentAttendanceApi.getDayStudentAttendance()
+                                                    console.log("打卡列表", data);
+                                                    list.splice(0, list.length, ...data);
 }
 const classOptions = reactive({
-  step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
-  limitMoveNum: list.length,//无缝滚动列表元素的长度,一般设置为列表的长度
-  direction: 1,//方向: 0 往下 1 往上 2 向左 3 向右。
-
+                                                    step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
+                                                    limitMoveNum: list.length,//无缝滚动列表元素的长度,一般设置为列表的长度
+                                                    direction: 1,//方向: 0 往下 1 往上 2 向左 3 向右。
+                                                  
 });
 
 /** 学生毕业条件达成率 */
 //在线情况滚动列表
 const list1 = reactive([]);
 const getGraduationSource = async () => {
-  const data = await DeptApi.getGraduationSource()
-  console.log("毕业条件达成率", data);
-  list1.splice(0, list1.length,  ...data);
+                                                    const data = await DeptApi.getGraduationSource()
+                                                    console.log("毕业条件达成率", data);
+                                                    list1.splice(0, list1.length,  ...data);
 }
 const list1Options = reactive({
-  step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
-  limitMoveNum: list1.length,//无缝滚动列表元素的长度,一般设置为列表的长度
-  direction: 1,//方向: 0 往下 1 往上 2 向左 3 向右。
+                                                    step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
+                                                    limitMoveNum: list1.length,//无缝滚动列表元素的长度,一般设置为列表的长度
+                                                    direction: 1,//方向: 0 往下 1 往上 2 向左 3 向右。
 });
 
 onMounted(() => {
-  getDetail()
-  getWeekend()
-  getProject()
-  getCount()
-  getStudentAttendanceError()
-  getStudentAttendance()
-  getGraduationSource()
-  getGraduateCount()
+                                                    getDetail()
+                                                    getWeekend()
+                                                    getProject()
+                                                    getCount()
+                                                    getStudentAttendanceError()
+                                                    getStudentAttendance()
+                                                    getGraduationSource()
+                                                    getGraduateCount()
 })
 
 const getAllApi = async () => {
@@ -495,7 +517,7 @@ getAllApi()
 
 <style scoped>
 .center {
-  text-align: center;
+                                                    text-align: center;
 }
 
 /* 滚动列表 */
@@ -607,3 +629,4 @@ getAllApi()
   border-left: 1px solid white;
 }
 </style>
+                                                  

+ 4 - 4
src/views/system/graduateStudent/UserForm.vue

@@ -272,14 +272,14 @@ const gradeOptions = computed(() => {
 // 获取所有专业
 const majorOptions = [
   { value: '测绘工程' },
-  { value: '地理信息系统' },
-  { value: '遥感科学' },
+  { value: '测绘科学与技术' },
+  { value: '资源与环境' },
 ]
 
 // 获取所有学位类型
 const masterTypeOptions = [
-  { value: '硕' },
-  { value: '博士' },
+  { value: '硕' },
+  { value: '专硕' },
 ]
 
 //获取所有导师

+ 6 - 6
src/views/system/graduateStudent/index.vue

@@ -184,7 +184,7 @@
               @click="openForm('create')"
               v-hasPermi="['system:user:create']"
             >
-              <Icon icon="ep:plus" /> 新增
+              <Icon icon="ep:plus" /> 创建毕业生
             </el-button>
             
             <el-button
@@ -193,7 +193,7 @@
               @click="handleImport"
               v-hasPermi="['system:user:importGraduateStudent']"
             >
-              <Icon icon="ep:upload" /> 导入
+              <Icon icon="ep:upload" /> 批量导入
             </el-button>
             <el-button
               type="success"
@@ -432,14 +432,14 @@ const handleSupervisorChange = (value: number) => {
 // 获取所有专业
 const majorOptions = [
   { value: '测绘工程' },
-  { value: '地理信息系统' },
-  { value: '遥感科学' },
+  { value: '测绘科学与技术' },
+  { value: '资源与环境' },
 ]
 
 // 获取所有学位类型
 const masterTypeOptions = [
-  { value: '硕' },
-  { value: '博士' },
+  { value: '硕' },
+  { value: '专硕' },
 ]
 
 // const NewList = (inputList) => {

+ 1 - 1
src/views/system/selfAchievement/index.vue

@@ -76,7 +76,7 @@
           @click="openForm('create')"
           v-hasPermi="['system:user-achievement:selfCreate']"
         >
-          <Icon icon="ep:plus" class="mr-5px" /> 新增
+          <Icon icon="ep:plus" class="mr-5px" /> 创建成果
         </el-button>
         <el-button
           type="success"

+ 2 - 2
src/views/system/studentAttendanceManage/studentAttendance/index.vue

@@ -2,13 +2,13 @@
   <ContentWrap v-if="userInfo.userType !== '1'">
     <!-- 数据展示 -->
     <div class="flex">
-      <div class="data-item" style="color: black;">
+      <div class="data-item" style="color: #67c23a;">
         正常打卡人数: <span>{{ totalSate.normalNum }}</span>
       </div>
       <div class="data-item" style="color: #f56c6c;">
         异常打卡人数: <span>{{ totalSate.errorNum }}</span>
       </div>
-      <div class="data-item" style="color: gray;">
+      <div class="data-item" style="color: #e6a23c;">
         请假人数: <span>{{ totalSate.excuseNum }}</span>
       </div>
     </div>

+ 2 - 2
src/views/system/studentAttendanceManage/studentAttendanceError/index.vue

@@ -2,13 +2,13 @@
 <ContentWrap v-if="userInfo.userType !== '1'">
     <!-- 数据展示 -->
     <div class="flex">
-      <div class="data-item" style="color: black;">
+      <div class="data-item" style="color: #67c23a;">
         正常打卡人数: <span>{{ totalSate.normalNum }}</span>
       </div>
       <div class="data-item" style="color: #f56c6c;">
         异常打卡人数: <span>{{ totalSate.errorNum }}</span>
       </div>
-      <div class="data-item" style="color: gray;">
+      <div class="data-item" style="color: #e6a23c;">
         请假人数: <span>{{ totalSate.excuseNum }}</span>
       </div>
     </div>

+ 2 - 2
src/views/system/studentAttendanceManage/studentAttendanceExcused/index.vue

@@ -2,13 +2,13 @@
   <ContentWrap v-if="userInfo.userType !== '1'">
     <!-- 数据展示 -->
     <div class="flex">
-      <div class="data-item" style="color: black;">
+      <div class="data-item" style="color: #67c23a;">
         正常打卡人数: <span>{{ totalSate.normalNum }}</span>
       </div>
       <div class="data-item" style="color: #f56c6c;">
         异常打卡人数: <span>{{ totalSate.errorNum }}</span>
       </div>
-      <div class="data-item" style="color: gray;">
+      <div class="data-item" style="color: #e6a23c;">
         请假人数: <span>{{ totalSate.excuseNum }}</span>
       </div>
     </div>

+ 9 - 8
src/views/system/studentAttendanceManage/studentFaceManage/index.vue

@@ -85,6 +85,14 @@
         >
           <Icon icon="ep:plus" class="mr-5px" /> 新增
         </el-button> -->
+        <el-button
+          type="primary"
+          plain
+          @click="handleImportzip"
+          v-hasPermi="['md:acs:users-info-with-image:import']"
+        >
+          <Icon icon="ep:upload" class="mr-5px" /> 批量导入
+        </el-button>
         <el-button
           type="success"
           plain
@@ -94,14 +102,7 @@
         >
           <Icon icon="ep:download" class="mr-5px" /> 导出
         </el-button>
-        <el-button
-          type="primary"
-          plain
-          @click="handleImportzip"
-          v-hasPermi="['md:acs:users-info-with-image:import']"
-        >
-          <Icon icon="ep:upload" class="mr-5px" /> 批量导入
-        </el-button>
+        
       </el-form-item>
     </el-form>
   </ContentWrap>

+ 214 - 0
src/views/system/studentSelf/SForm.vue

@@ -0,0 +1,214 @@
+<template>
+  <Dialog v-model="dialogVisible" :title="dialogTitle">
+    <el-form
+      ref="formRef"
+      v-loading="formLoading"
+      :model="formData"
+      :rules="formRules"
+      label-width="85px"
+    >
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="姓名" prop="nickname">
+            <el-input  disabled v-model="formData.nickname" placeholder="请输入姓名" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="工作间" prop="dept">
+            <el-input disabled v-model="formData.dept"/>
+            <!-- <el-tree-select
+              v-model="formData.deptId"
+              :data="deptList"
+              :props="defaultProps"
+              check-strictly
+              node-key="id"
+              placeholder="请选择归属工作间"
+            /> -->
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="手机号码" prop="mobile">
+            <el-input v-model="formData.mobile" maxlength="11" placeholder="请输入手机号码" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="邮箱" prop="email">
+            <el-input v-model="formData.email" maxlength="50" placeholder="请输入邮箱" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="用户类型" prop="userType">
+            <el-select v-model="formData.userType" placeholder="请选择用户类型" disabled="true">
+             <el-option
+                v-for="option in userTypes"
+                :key="option.value"
+                :label="option.label"
+                :value="option.value"
+                />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="学号" prop="userNumber">
+            <el-input disabled v-model="formData.userNumber" placeholder="请输入工号" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="简介" prop="remark">
+            <Editor v-model="formData.remark" ref="editorRef"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template #footer>
+      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script lang="ts" setup>
+import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
+import { CommonStatusEnum } from '@/utils/constants'
+import { defaultProps, handleTree } from '@/utils/tree'
+import * as DeptApi from '@/api/system/dept'
+import * as PostApi from '@/api/system/post'
+import { FormRules } from 'element-plus'
+import {
+  getUserProfile,
+  updateUserProfile,
+  UserProfileUpdateReqVO
+} from '@/api/system/user/profile'
+
+defineOptions({ name: 'SystemUserForm' })
+
+const props = defineProps({
+  form: Object,
+});
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+const userTypeSt = ref('1')
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formData = ref({
+  mobile: '',
+  email: '',
+  nickname: '',
+  password: '',
+  sex: undefined,
+  // remark: '',
+  userType: undefined,
+  userNumber: '',
+  dept: undefined,
+  deptId: undefined,
+})
+const formRules = reactive<FormRules>({
+  username: [{ required: true, message: '账号不能为空', trigger: 'blur' }],
+  nickname: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
+  email: [
+    { required: true, message: '邮箱不能为空', trigger: 'blur' }, // 确保这是必填
+    {
+      type: 'email',
+      message: '请输入正确的邮箱地址',
+      trigger: ['blur', 'change']
+    }
+  ],
+  mobile: [
+    { required: true, message: '手机号码不能为空', trigger: 'blur' },
+    {
+      pattern: /^(?:(?:\+|00)86)?1(?:3[\d]|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8[\d]|9[189])\d{8}$/,
+      message: '请输入正确的手机号码',
+      trigger: 'blur'
+    }
+  ],
+  userNumber: [{ required: true, message: '学号不能为空', trigger: 'blur' }],
+  userType: [{ required: true, message: '用户类型不能为空', trigger: 'blur' }],
+})
+
+const formRef = ref() // 表单 Ref
+const deptList = ref<Tree[]>([]) // 树形结构
+const postList = ref([] as PostApi.PostVO[]) // 岗位列表
+
+//用户类型
+const userTypes = [
+  { value: '1', label: '学生' },
+]
+
+/** 打开弹窗 */
+const open = async (id?: number) => {
+  dialogVisible.value = true
+  resetForm()
+  // 修改时,设置数据
+  if (id) {
+    formLoading.value = true
+    try {
+      const data = await getUserProfile()
+      console.log(data,'打开弹窗数据');
+      formData.value = {
+        ...data,
+        deptId: data.dept.id, 
+        dept: data.dept.name
+      }
+    } 
+    catch (error) {
+      console.error('获取用户资料失败:', error); // 添加错误日志
+    }finally {
+      formLoading.value = false
+    }
+  }
+  formData.value = {
+      ...props.form,
+      deptId: props.form.dept ? props.form.dept.id : undefined,
+      dept: props.form.dept ? props.form.dept.name : ''
+    }; 
+}
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  console.log(formData.value,'提交的表单');
+  if (!formRef) return
+  const valid = await formRef.value.validate()
+  if (!valid) return
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value as unknown as UserProfileUpdateReqVO
+      await updateUserProfile(data)
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    mobile: '',
+    email: '',
+    nickname: '',
+    password: '',
+    sex: undefined,
+    // remark: '',
+    userType: undefined,
+    userNumber: '',
+    dept: undefined,
+    deptId: undefined,
+    }
+    formRef.value?.resetFields()
+}
+
+</script>

+ 298 - 0
src/views/system/studentSelf/index.vue

@@ -0,0 +1,298 @@
+<template>
+  <div class="flex" v-loading="loading">
+    <el-card class="workspace-info w-full" shadow="always" style="padding-bottom: 40px;">
+        <template #header>
+          <div class="card-header" style="display: flex; align-items: center; justify-content: space-between;">
+            <span style="flex-grow: 1; text-align: center;font-weight: bold;">个人信息</span>
+            <div class="pull-right">
+              <el-button type="primary" @click="openDialog">修改</el-button>
+            </div>
+          </div>
+        </template>
+        <ul class="user-info">
+          <div class="info-row">
+            <li class="info-item">
+              <Icon class="mr-5px" icon="ep:user" />
+              <span class="info-label">姓名:</span>
+              <span class="pull-right">{{ userInfo.nickname }}</span>
+            </li>
+            <li class="info-item">
+              <Icon class="mr-5px" icon="ep:location" />
+              <span class="info-label">工作间:</span>
+              <span class="pull-right">{{ userInfo.dept ? userInfo.dept.name : '未知部门' }}</span>
+            </li>
+          </div>
+
+          <div class="info-row">
+            <li class="info-item">
+              <Icon class="mr-5px" icon="ep:phone" />
+              <span class="info-label">手机号码:</span>
+              <span class="pull-right">{{ userInfo.mobile }}</span>
+            </li>
+            <li class="info-item">
+              <Icon class="mr-5px" icon="fontisto:email" />
+              <span class="info-label">邮箱:</span>
+              <span class="pull-right">{{ userInfo.email }}</span>
+            </li>
+          </div>
+
+          <div class="info-row">
+            <li class="info-item">
+              <Icon class="mr-5px" icon="ep:user" />
+              <span class="info-label">用户类型:</span>
+              <span class="pull-right"> {{ userTypeMapping[userInfo.userType] || '未知用户类型' }}</span>
+            </li>
+            <li class="info-item">
+              <Icon class="mr-5px" icon="ep:bell" />
+              <span class="info-label">学号:</span>
+              <span class="pull-right">{{ userInfo.userNumber }}</span>
+            </li>
+          </div>
+
+        </ul>
+        <div class="info-description">
+          <div style="display: flex; align-items: center;">
+            <Icon icon="ep:picture" />
+            <div class="div-label" style="margin-left: 8px;">简介:</div>
+          </div>
+          <div class="description-content">{{ cleanedDescription }}</div>
+          <div class="image-container">
+            <div v-for="(url, index) in extractedImageUrls" :key="index" class="image-item">
+              <img :src="url" />
+            </div>
+          </div>
+        </div>
+        
+      </el-card>
+      <SForm
+        ref="formRef"
+        :visible="dialogVisible"
+        :form="userInfo"
+        @update:visible="dialogVisible = $event"
+        @success="handleSuccess"
+      />
+  </div>
+ 
+</template>
+
+<script lang="ts">
+import { defineComponent, reactive, ref, onMounted } from 'vue';
+import { useI18n } from 'vue-i18n';
+import { useMessage } from '@/hooks/web/useMessage';
+import SForm from './SForm.vue';
+import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
+
+
+export default defineComponent({
+  components: {
+    SForm,
+  },
+  setup() {
+    const { t } = useI18n();
+    const message = useMessage();
+    const dialogVisible = ref(false);
+    const loading = ref(true) // 列表的加载中
+    const formRef = ref();
+
+    // 将 userInfo 定义放入 setup 中
+const userInfo = ref({} as ProfileVO)
+const getUserInfo = async () => {
+  try {
+    loading.value = true; 
+    const users = await getUserProfile();
+    console.log(users, 'users');
+    userInfo.value = users;
+  } catch (error) {
+    console.error('获取用户信息失败:', error);
+  } finally {
+    loading.value = false; // 隐藏加载中
+  }
+}
+
+const userTypeMapping = {
+  '1': '学生',
+};
+
+const openDialog = () => {
+  loading.value = true; // 显示加载中
+  dialogVisible.value = true;
+  formRef.value.open(); // 打开弹窗
+};
+
+const extractedImageUrls = ref<string[]>([]);
+const handleSuccess = (urls) => {
+  extractedImageUrls.value = urls;
+  console.log('提取到的图片URL:', extractedImageUrls);
+  dialogVisible.value = false;
+};
+const fetchImageUrls = async () => {
+  try {
+    loading.value = true; // 开始加载
+    const res = await getUserProfile();
+    const urls = res.description.match(/<img.*?src="(.*?)"/g);
+    if (urls) {
+      extractedImageUrls.value = urls.map(url => {
+        const match = url.match(/src="(.*?)"/);
+        return match ? match[1] : '';
+      });
+    } else {
+      extractedImageUrls.value = [];
+    }
+  } catch (error) {
+    console.error('获取图片 URL 失败:', error);
+  } finally {
+    loading.value = false; // 完成加载
+  }
+};
+// 创建一个 computed 属性来处理并去掉 <p> 标签
+  const cleanedDescription = computed(() => {
+  return userInfo.value.description ? userInfo.value.description.replace(/<\/?[^>]+(>|$)/g, '') : '';
+});
+
+
+    // 表单提交
+    // const submit = async () => {
+    //   try {
+    //     await formRef.value?.validate();
+    //     console.log('提交的数据:', form);
+    //     await updateDept(form).then((res) => {
+    //       console.log('更新成功:', res);
+    //     });
+    //     message.success('成功');
+    //   } catch (error) {
+    //     console.error('提交错误:', error);
+    //     message.error('错误');
+    //   }
+    // };
+
+
+    // 表单重置
+    // const init = async () => {
+    //   const res = await getUserProfile();
+    //   console.log('获取的数据:', res);
+    //   form.id = res.id;
+    //   form.address = res.address;
+    //   form.supervisor = res.user.nickname;
+    //   form.phone = res.phone;
+    //   form.email = res.email;
+    //   form.name = res.name;
+    //   form.leaderUserId = res.user.id;
+    //   form.description = res.description;
+    //   userInfo.value = res.user; 
+    // };
+
+    onMounted(async () => {
+      // await init();
+      await getUserInfo();
+      await fetchImageUrls(); // 这里 add 一個方法来加载图片
+    });
+
+    return {
+      t,
+      // form,
+      userInfo,   
+      // init,
+      loading,
+      getUserInfo,
+      fetchImageUrls,
+      formRef,
+      dialogVisible,
+      openDialog,
+      handleSuccess,
+      extractedImageUrls,
+      cleanedDescription,
+      userTypeMapping,
+    };
+  }
+});
+
+
+</script>
+
+<style scoped>
+.user-info {
+  margin-top: 10px;
+  margin-left: 5%;
+  margin-right: 5%;
+  padding-right: 0;
+  padding-left: 0;
+  border-right: 0;
+  border-left: 0;
+  border-radius: 0;
+  list-style: none;
+}
+
+.info-row {
+  display: flex;
+  justify-content: space-between; /* 保持并排显示 */
+  align-items: center; /* 垂直居中对齐 */
+  margin-bottom: 20px; /* 增加行之间的间距 */
+}
+
+.info-item {
+  flex: 1; /* 每个信息项占据相同的空间 */
+  padding: 11px 0; /* 内部上下填充 */
+  margin-right: 50px; /* 每个信息项之间的右边距 */
+}
+
+/* 仅为每个信息项添加底部边框 */
+.info-item:first-child {
+  border-bottom: 1px solid #e7eaec;
+}
+
+.info-item:last-child {
+  border-bottom: 1px solid #e7eaec; 
+}
+
+.info-description {
+  margin-top: 30px; /* 与上面的信息分隔 */
+  margin-left: 5%; /* 左侧与上面列表保持一致 */
+  margin-right: 5%; /* 右侧与上面列表保持一致 */
+  /* display: flex;  */
+  align-items: center; /* 确保标题与描述对齐 */
+  align-items: flex-start;
+}
+
+.info-label {
+  font-weight: bold; /* 加粗标题 */
+  margin-right: 10px; /* 标题与内容之间的间距 */
+}
+
+.div-label {
+  font-weight: bold; /* 加粗标题 */
+  display: block;
+  
+}
+
+.description-content {
+  white-space: pre-wrap; /* 保持换行 */
+  overflow-wrap: break-word; /* 自动断行 */
+  margin-right: 5%;
+  font-size: 13px; /* 根据需要设置字体大小 */
+  margin-top: 20px; /* 内容与标题之间不需要额外间距 */
+  letter-spacing: 3px;
+  text-indent: 2em; 
+  line-height: 2;
+}
+
+.pull-right {
+  float: right !important;
+}
+
+.info-label {
+  font-weight: bold;
+}
+
+.image-container {
+  display: flex; /* 使图片横向排列 */
+  flex-wrap: wrap; /* 如果空间不足则换行 */
+  gap: 10px; /* 图片之间的间距 */
+  margin-left: 20px; /* 左边距,根据需要设置 */
+}
+
+.image-item img {
+  width: 150px; /* 设置更大的宽度 */
+  height: auto; /* 保持高度自动 */
+}
+
+</style>

+ 1 - 1
src/views/system/workroomCollege/dept/index.vue

@@ -102,7 +102,7 @@
           @click="openForm('create')"
           v-hasPermi="['system:dept:create']"
         >
-          <Icon icon="ep:plus" /> 新增
+          <Icon icon="ep:plus" /> 创建工作间
         </el-button>
         <!-- <el-button type="danger" plain @click="toggleExpandAll">
           <Icon icon="ep:sort" class="mr-5px" /> 展开/折叠

+ 11 - 4
src/views/system/workroomCollege/deptInfo/index.vue

@@ -7,7 +7,7 @@
     </div>
   </el-card> -->
   <div>
-    <div class="flex mb-3">
+    <div class="flex mb-3" v-loading="loading">
       <el-card class="workspace-info w-full" style="padding-bottom: 40px;">
         <template #header>
           <div class="card-header">
@@ -146,6 +146,7 @@ export default defineComponent({
   setup() {
     const { t } = useI18n();
     // const message = useMessage();
+    const loading = ref(true) // 列表的加载中
     const formRef = ref();
 
     const route = useRoute()
@@ -199,10 +200,15 @@ export default defineComponent({
     // 将 userInfo 定义放入 setup 中
     const userInfo = ref({} as DeptVO);  
     const fetchUserInfo = async (id) => {
-      const users = await getDept(id);
-      console.log(users,'userInfo');
-      userInfo.value = users;
+      try {
+        loading.value = true; // 开始加载
+        const users = await getDept(id);
+        console.log(users,'userInfo');
+        userInfo.value = users;
         // name: users.user[0].nickname // 提取 nickname
+      }finally {
+        loading.value = false; // 结束加载
+      }
     };
 
     //获取工作间下的导师
@@ -295,6 +301,7 @@ export default defineComponent({
       t,
       // form,
       userInfo,
+      loading,  
       // isEditMode,
       // toggleEditMode,
       // submit,

+ 5 - 0
src/views/system/workroomCollege/deptInfo/student.vue

@@ -15,6 +15,10 @@
             prop="nickname"
             :show-overflow-tooltip="true"
           />
+          <el-table-column label="年级" align="center" prop="grade" />
+          <el-table-column label="学号" align="center" prop="userNumber" />
+          <el-table-column label="专业" align="center" prop="major" />
+          <el-table-column label="导师姓名" align="center" prop="supervisor"/>
           <el-table-column
             label="工作间"
             align="center"
@@ -23,6 +27,7 @@
             :show-overflow-tooltip="true"
           />
           <el-table-column label="手机号码" align="center" prop="mobile" />
+          <el-table-column label="邮箱" align="center" prop="email" />
           <el-table-column label="是否达成毕业条件" align="center" prop="isGraduate">
             <template #default="scope">
               <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_GRADUATE_STATUS" :value="scope.row.isGraduate" />  

+ 2 - 0
src/views/system/workroomCollege/deptInfo/teacher.vue

@@ -15,6 +15,7 @@
             prop="nickname"
             :show-overflow-tooltip="true"
           />
+          <el-table-column label="工号" align="center" prop="userNumber" />
           <el-table-column
             label="工作间"
             align="center"
@@ -23,6 +24,7 @@
             :show-overflow-tooltip="true"
           />
           <el-table-column label="手机号码" align="center" prop="mobile" />
+          <el-table-column label="邮箱" align="center" prop="email" />
           <el-table-column
             label="创建时间"
             align="center"

+ 4 - 4
src/views/system/workroomCollege/user/UserForm.vue

@@ -314,14 +314,14 @@ const userTypes = computed(() => {
 // 获取所有专业
 const majorOptions = [
   { value: '测绘工程' },
-  { value: '地理信息系统' },
-  { value: '遥感科学' },
+  { value: '测绘科学与技术' },
+  { value: '资源与环境' },
 ]
 
 // 获取所有学位类型
 const masterTypeOptions = [
-  { value: '硕' },
-  { value: '博士' },
+  { value: '硕' },
+  { value: '专硕' },
 ]
 
 

+ 58 - 29
src/views/system/workroomCollege/user/student.vue

@@ -35,6 +35,28 @@
               class="!w-240px"
             />
           </el-form-item>
+          <el-form-item label="年级" prop="grade">
+            <el-input
+              v-model="queryParams.grade"
+              placeholder="请输入年级"
+              clearable
+              @keyup.enter="handleQuery"
+              class="!w-240px"
+            />
+              <!-- <el-select
+                v-model="queryParams.grade"
+                placeholder="请选择年级"
+                clearable
+                class="!w-240px"
+              >
+                <el-option
+                  v-for="year in grades"
+                  :key="year"
+                  :label="year.toString()"
+                  :value="year"
+                />
+              </el-select> -->
+        </el-form-item>
           <el-form-item label="学号" prop="userNumber">
             <el-input
               v-model="queryParams.userNumber"
@@ -61,7 +83,7 @@
               />
             </el-select>
           </el-form-item>
-          <el-form-item label="专硕" prop="masterType"> 
+          <!-- <el-form-item label="专硕" prop="masterType"> 
             <el-select 
               v-model="queryParams.masterType" 
               placeholder="请选择学位类型"
@@ -77,7 +99,24 @@
                 :value="option.value"
               />
             </el-select>
-          </el-form-item> 
+          </el-form-item>  -->
+          <el-form-item label="导师姓名" prop="supervisor">
+          <el-select
+              v-model="queryParams.supervisor"
+              @change="handleSupervisorChange"
+              placeholder="请选择导师"
+              clearable
+              filterable
+              class="!w-240px"
+            >
+              <el-option
+                v-for="user in users"
+                :key="user.id"
+                :label="user.nickname"
+                :value="user.id"
+              />
+            </el-select>
+          </el-form-item>
           <el-form-item label="手机号码" prop="mobile">
             <el-input
               v-model="queryParams.mobile"
@@ -96,23 +135,7 @@
               class="!w-240px"
             />
           </el-form-item>
-          <el-form-item label="导师姓名" prop="supervisor">
-          <el-select
-              v-model="queryParams.supervisor"
-              @change="handleSupervisorChange"
-              placeholder="请选择导师"
-              clearable
-              filterable
-              class="!w-240px"
-            >
-              <el-option
-                v-for="user in users"
-                :key="user.id"
-                :label="user.nickname"
-                :value="user.id"
-              />
-            </el-select>
-      </el-form-item>
+          
           <el-form-item label="毕业条件" prop='isGraduate'>
             <el-select 
               v-model="queryParams.isGraduate" 
@@ -160,7 +183,7 @@
               @click="openForm('create-S')"
               v-hasPermi="['system:user:create']"
             >
-              <Icon icon="ep:plus" /> 新增
+              <Icon icon="ep:plus" /> 创建学生
             </el-button>
             <el-button
               type="warning"
@@ -168,7 +191,7 @@
               @click="handleImport"
               v-hasPermi="['system:user:importSchoolStudent']"
             >
-              <Icon icon="ep:upload" /> 导入
+              <Icon icon="ep:upload" /> 批量导入
             </el-button>
             <el-button
               type="success"
@@ -199,6 +222,7 @@
             align="center"
             prop="username"
             :show-overflow-tooltip="true"
+            width="200"
           />
           <el-table-column
             label="姓名"
@@ -206,26 +230,30 @@
             prop="nickname"
             :show-overflow-tooltip="true"
           />
+          <el-table-column label="年级" align="center" prop="grade" width="120" />
           <el-table-column
             label="学号"
             align="center"
             prop="userNumber"
             :show-overflow-tooltip="true"
+            width="200"
           />
           <el-table-column label="专业" align="center" prop="major" width="120" />
-          <el-table-column label="专硕" align="center" prop="masterType" width="120" />
+          <!-- <el-table-column label="专硕" align="center" prop="masterType" width="120" /> -->
+          <el-table-column label="导师姓名" align="center" prop="supervisor" width="120" />
           <el-table-column
             label="工作间"
             align="center"
             key="deptName"
             prop="deptName"
             :show-overflow-tooltip="true"
+            width="150"
           />
           <el-table-column label="手机号码" align="center" prop="mobile" width="120" />
 
           <el-table-column label="邮箱" align="center" prop="email" width="120" />
 
-          <el-table-column label="导师姓名" align="center" prop="supervisor" width="120" />
+          
           <!-- <el-table-column label="状态" key="status">
             <template #default="scope">
               <el-switch
@@ -258,13 +286,13 @@
                 />
             </template>
           </el-table-column> 
-          <el-table-column
+          <!-- <el-table-column
             label="创建时间"
             align="center"
             prop="createTime"
             :formatter="dateFormatter"
             width="180"
-          />
+          /> -->
           <el-table-column label="操作" align="center" width="190">
             <template #default="scope">
               <div class="flex items-center justify-center">
@@ -389,6 +417,7 @@ const queryParams = reactive({
   supervisorId: undefined,
   major: undefined,
   masterType: undefined,
+  grade: undefined,
 })
 const queryFormRef = ref() // 搜索的表单
 
@@ -433,14 +462,14 @@ const handleSupervisorChange = (value: number) => {
 // 获取所有专业
 const majorOptions = [
   { value: '测绘工程' },
-  { value: '地理信息系统' },
-  { value: '遥感科学' },
+  { value: '测绘科学与技术' },
+  { value: '资源与环境' },
 ]
 
 // 获取所有学位类型
 const masterTypeOptions = [
-  { value: '硕' },
-  { value: '博士' },
+  { value: '硕' },
+  { value: '专硕' },
 ]
 
 /** 搜索按钮操作 */

+ 2 - 2
src/views/system/workroomCollege/user/teacher.vue

@@ -106,7 +106,7 @@
               @click="openForm('create-T')"
               v-hasPermi="['system:user:create']"
             >
-              <Icon icon="ep:plus" /> 新增
+              <Icon icon="ep:plus" /> 创建教师
             </el-button>
             <el-button
               type="warning"
@@ -114,7 +114,7 @@
               @click="handleImport"
               v-hasPermi="['system:user:importTeacher']"
             >
-              <Icon icon="ep:upload" /> 导入
+              <Icon icon="ep:upload" /> 批量导入
             </el-button>
             <el-button
               type="success"

+ 30 - 20
src/views/system/workroomTeacher/TeacherSelf/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="flex">
+  <div class="flex" v-loading="loading">
     <el-card class="workspace-info w-full" shadow="always" style="padding-bottom: 40px;">
         <template #header>
           <div class="card-header" style="display: flex; align-items: center; justify-content: space-between;">
@@ -50,16 +50,18 @@
           </div>
 
         </ul>
-        <!-- <div class="info-description">
-          <Icon class="mr-5px" icon="ep:location" /> -->
-          <!-- <div class="div-label" style="margin-left: 20px;">简介:</div>
+        <div class="info-description">
+          <div style="display: flex; align-items: center;">
+            <Icon icon="ep:picture" />
+            <div class="div-label" style="margin-left: 8px;">简介:</div>
+          </div>
           <div class="description-content">{{ cleanedDescription }}</div>
           <div class="image-container">
             <div v-for="(url, index) in extractedImageUrls" :key="index" class="image-item">
               <img :src="url" />
             </div>
           </div>
-        </div> -->
+        </div>
         
       </el-card>
       <TForm
@@ -89,17 +91,21 @@ export default defineComponent({
     const { t } = useI18n();
     const message = useMessage();
     const dialogVisible = ref(false);
+    const loading = ref(true) // 列表的加载中
     const formRef = ref();
 
     // 将 userInfo 定义放入 setup 中
-    const userInfo = ref({} as ProfileVO)
-    const getUserInfo = async () => {
+const userInfo = ref({} as ProfileVO)
+const getUserInfo = async () => {
   try {
+    loading.value = true; 
     const users = await getUserProfile();
     console.log(users, 'users');
     userInfo.value = users;
   } catch (error) {
     console.error('获取用户信息失败:', error);
+  } finally {
+    loading.value = false; // 隐藏加载中
   }
 }
 
@@ -108,6 +114,7 @@ const userTypeMapping = {
 };
 
 const openDialog = () => {
+  loading.value = true; // 显示加载中
   dialogVisible.value = true;
   formRef.value.open(); // 打开弹窗
 };
@@ -119,26 +126,28 @@ const handleSuccess = (urls) => {
   dialogVisible.value = false;
 };
 const fetchImageUrls = async () => {
-  // 你的获取图片 URL 的 API 调用
-  const res = await getUserProfile();
-  const urls = res.description.match(/<img.*?src="(.*?)"/g); // 使用更合理的正则表达式
-    // 如果找到的 URL 数组不为空,则进行处理
+  try {
+    loading.value = true; // 开始加载
+    const res = await getUserProfile();
+    const urls = res.description.match(/<img.*?src="(.*?)"/g);
     if (urls) {
-      // 从匹配的字符串中提取出 URL
       extractedImageUrls.value = urls.map(url => {
-        // 取出匹配到的 src 属性部分
         const match = url.match(/src="(.*?)"/);
         return match ? match[1] : '';
       });
     } else {
-      extractedImageUrls.value = []; // 没有找到图片则设为空数组
-    }  // 将获取到的 URL 赋值
+      extractedImageUrls.value = [];
+    }
+  } catch (error) {
+    console.error('获取图片 URL 失败:', error);
+  } finally {
+    loading.value = false; // 完成加载
+  }
 };
-
 // 创建一个 computed 属性来处理并去掉 <p> 标签
-//   const cleanedDescription = computed(() => {
-//   return userInfo.value.description ? userInfo.value.description.replace(/<\/?[^>]+(>|$)/g, '') : '';
-// });
+  const cleanedDescription = computed(() => {
+  return userInfo.value.description ? userInfo.value.description.replace(/<\/?[^>]+(>|$)/g, '') : '';
+});
 
 
     // 表单提交
@@ -182,6 +191,7 @@ const fetchImageUrls = async () => {
       t,
       // form,
       userInfo,   
+      loading,
       // init,
       getUserInfo,
       fetchImageUrls,
@@ -190,7 +200,7 @@ const fetchImageUrls = async () => {
       openDialog,
       handleSuccess,
       extractedImageUrls,
-      // cleanedDescription
+      cleanedDescription,
       userTypeMapping,
     };
   }

+ 20 - 7
src/views/system/workroomTeacher/dept/index.vue

@@ -6,7 +6,7 @@
       </div>
     </div>
   </el-card> -->
-  <div class="flex">
+  <div class="flex" v-loading="loading">
     <el-card class="workspace-info w-full" shadow="always" style="padding-bottom: 40px;">
         <template #header>
           <div class="card-header" style="display: flex; align-items: center; justify-content: space-between;">
@@ -120,6 +120,7 @@ export default defineComponent({
   setup() {
     const { t } = useI18n();
     const message = useMessage();
+    const loading = ref(true) // 列表的加载中
     const dialogVisible = ref(false);
     const formRef = ref();
 
@@ -170,11 +171,16 @@ export default defineComponent({
     // 将 userInfo 定义放入 setup 中
     const userInfo = ref({} as DeptVO);  
     const fetchUserInfo = async () => {
-      const users = await getUserDept();
-      console.log(users,'userDeptInfo');
-      userInfo.value = {...users,
-        // name: users.user[0].nickname // 提取 nickname
-      };
+      try{
+        loading.value = true; // 开始加载状态
+        const users = await getUserDept();
+        console.log(users,'userDeptInfo');
+        userInfo.value = {...users,
+          // name: users.user[0].nickname // 提取 nickname
+        };
+      }finally{
+          loading.value = false; // 关闭加载状态
+      }
     };
 
 //   //获取所有导师
@@ -205,6 +211,7 @@ export default defineComponent({
 // };
 
 const openDialog = () => {
+  loading.value = true; 
   dialogVisible.value = true;
   formRef.value.open(); // 打开弹窗
 };
@@ -216,7 +223,9 @@ const handleSuccess = (urls) => {
   dialogVisible.value = false;
 };
 const fetchImageUrls = async () => {
-  // 你的获取图片 URL 的 API 调用
+  try {
+    loading.value = true; // 开始加载状态
+    // 你的获取图片 URL 的 API 调用
   const res = await getUserDept();
   const urls = res.description.match(/<img.*?src="(.*?)"/g); // 使用更合理的正则表达式
     // 如果找到的 URL 数组不为空,则进行处理
@@ -230,6 +239,9 @@ const fetchImageUrls = async () => {
     } else {
       extractedImageUrls.value = []; // 没有找到图片则设为空数组
     }  // 将获取到的 URL 赋值
+  }finally{
+    loading.value = false; // 关闭加载状态
+  }
 };
 
 // 创建一个 computed 属性来处理并去掉 <p> 标签
@@ -280,6 +292,7 @@ const fetchImageUrls = async () => {
       t,
       form,
       userInfo,
+      loading,
       // isEditMode,
       // toggleEditMode,
       submit,

+ 8 - 4
src/views/system/workroomTeacher/dept/student.vue

@@ -18,14 +18,18 @@
             prop="nickname"
             :show-overflow-tooltip="true"
           />
-          <el-table-column
+          <el-table-column label="年级" align="center" prop="grade" width="120" />
+          <el-table-column label="学号" align="center" prop="studentId" width="120" />
+          <el-table-column label="专业" align="center" prop="major" width="120" />
+          <!-- <el-table-column
             label="工作间"
             align="center"
             key="deptName"
             prop="deptName"
             :show-overflow-tooltip="true"
-          />
+          /> -->
           <el-table-column label="手机号码" align="center" prop="mobile" width="120" />
+          <el-table-column label="邮箱" align="center" prop="email"/>
           <el-table-column label="是否达成毕业条件" align="center" prop="isGraduate">
             <template #default="scope">
               <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_GRADUATE_STATUS" :value="scope.row.isGraduate" />  
@@ -48,13 +52,13 @@
               />
             </template>
           </el-table-column>
-          <el-table-column
+          <!-- <el-table-column
             label="创建时间"
             align="center"
             prop="createTime"
             :formatter="dateFormatter"
             width="180"
-          />
+          /> -->
           <el-table-column label="操作" align="center" width="190">
             <template #default="scope">
               <div class="flex items-center justify-center">

+ 2 - 0
src/views/system/workroomTeacher/dept/teacher.vue

@@ -25,6 +25,8 @@
             :show-overflow-tooltip="true"
           />
           <el-table-column label="手机号码" align="center" prop="mobile"/>
+          <el-table-column label="邮箱" align="center" prop="email"/>
+          <el-table-column label="工号" align="center" prop="userNumber"/>
           <el-table-column
             label="创建时间"
             align="center"

+ 4 - 4
src/views/system/workroomTeacher/user/UserForm.vue

@@ -297,14 +297,14 @@ const userTypes = computed(() => {
 // 获取所有专业
 const majorOptions = [
   { value: '测绘工程' },
-  { value: '地理信息系统' },
-  { value: '遥感科学' },
+  { value: '测绘科学与技术' },
+  { value: '资源与环境' },
 ]
 
 // 获取所有学位类型
 const masterTypeOptions = [
-  { value: '硕' },
-  { value: '博士' },
+  { value: '硕' },
+  { value: '专硕' },
 ]
 
 

+ 33 - 9
src/views/system/workroomTeacher/user/student.vue

@@ -30,6 +30,28 @@
               class="!w-240px"
             />
           </el-form-item>
+          <el-form-item label="年级" prop="grade">
+            <el-input
+              v-model="queryParams.grade"
+              placeholder="请输入年级"
+              clearable
+              @keyup.enter="handleQuery"
+              class="!w-240px"
+            />
+              <!-- <el-select
+                v-model="queryParams.grade"
+                placeholder="请选择年级"
+                clearable
+                class="!w-240px"
+              >
+                <el-option
+                  v-for="year in grades"
+                  :key="year"
+                  :label="year.toString()"
+                  :value="year"
+                />
+              </el-select> -->
+        </el-form-item>
           <el-form-item label="学号" prop="userNumber">
             <el-input
               v-model="queryParams.userNumber"
@@ -54,7 +76,7 @@
               />
             </el-select>
           </el-form-item>
-          <el-form-item label="专硕" prop="masterType"> 
+          <!-- <el-form-item label="专硕" prop="masterType"> 
             <el-select 
               v-model="queryParams.masterType" 
               placeholder="请选择学位类型"
@@ -68,7 +90,7 @@
                 :value="option.value"
               />
             </el-select>
-          </el-form-item>
+          </el-form-item> -->
           <!-- <el-form-item label="工作间" prop="deptName">
             <el-input v-model="queryParams.deptName" placeholder="请输入工作间" clearable @keyup.enter="handleQuery" class="!w-240px" />
           </el-form-item> -->
@@ -174,6 +196,7 @@
             prop="nickname"
             :show-overflow-tooltip="true"
           />
+          <el-table-column label="年级" align="center" prop="grade" width="120" />
           <el-table-column
             label="学号"
             align="center"
@@ -181,7 +204,7 @@
             :show-overflow-tooltip="true"
           />
           <el-table-column label="专业" align="center" prop="major" width="120" />
-          <el-table-column label="专硕" align="center" prop="masterType" width="120" />
+          <!-- <el-table-column label="专硕" align="center" prop="masterType" width="120" /> -->
           <!-- <el-table-column
             label="工作间"
             align="center"
@@ -223,13 +246,13 @@
               />
             </template>
           </el-table-column>
-          <el-table-column
+          <!-- <el-table-column
             label="创建时间"
             align="center"
             prop="createTime"
             :formatter="dateFormatter"
             width="180"
-          />
+          /> -->
           <el-table-column label="操作" align="center" width="190">
             <template #default="scope">
               <div class="flex items-center justify-center">
@@ -342,6 +365,7 @@ const queryParams = reactive({
   isGraduate: undefined,
   major: undefined,
   masterType: undefined,
+  grade: undefined,
 })
 const queryFormRef = ref() // 搜索的表单
 
@@ -366,14 +390,14 @@ const openUserAchievement = (id) => {
 // 获取所有专业
 const majorOptions = [
   { value: '测绘工程' },
-  { value: '地理信息系统' },
-  { value: '遥感科学' },
+  { value: '测绘科学与技术' },
+  { value: '资源与环境' },
 ]
 
 // 获取所有学位类型
 const masterTypeOptions = [
-  { value: '硕' },
-  { value: '博士' },
+  { value: '硕' },
+  { value: '专硕' },
 ]
 
 /** 搜索按钮操作 */