Browse Source

Merge branch 'master' of http://gogs.gisvg.com/YDM/graduate-ui

47 3 months ago
parent
commit
ac9df00e58

+ 9 - 0
src/api/system/dept/index.ts

@@ -38,6 +38,10 @@ export const getDept = async (id: number) => {
   return await request.get({ url: '/system/dept/get?id=' + id })
 }
 
+// 获取部门分页
+export const getDeptList = async (params: PageParam) => {
+  return await request.get({ url: '/system/dept/page', params })
+}
 
 // 查询登录导师的工作间详情
 export const getUserDept = async () => {
@@ -60,3 +64,8 @@ export const updateDept = async (params: DeptVO) => {
 export const deleteDept = async (id: number) => {
   return await request.delete({ url: '/system/dept/delete?id=' + id })
 }
+
+// 获取毕业达成率
+export const getGraduationSource = async () => {
+  return await request.get({ url: '/system/dept/getGraduationSource' })
+}

+ 1 - 1
src/api/system/studentAttendance/index.ts

@@ -25,7 +25,7 @@ export const StudentAttendanceApi = {
     return await request.get({ url: `/system/student-attendance/excusedPage`, params })
   },
 
-  // 查询学生勤记录分页
+  // 查询学生勤记录分页
   getStudentAttendanceErrorPage: async (params: any) => {
     return await request.get({ url: `/system/student-attendance/errorPage`, params })
   },

+ 5 - 0
src/api/system/user/index.ts

@@ -193,3 +193,8 @@ export const deletestudentFace = (userNumber: number) => {
 export const getDetail = () => {
   return request.get({ url: '/system/user/getDetail' })
 }
+
+// 获取毕业生人数统计
+export const getGraduateCount = () => {
+  return request.get({ url: '/system/user/getGraduateCount' })
+}

+ 138 - 158
src/views/Home/Index.vue

@@ -98,7 +98,7 @@
                 <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.ExcuNum" :duration="2600" />
+                  <CountTo class="text-28px" :start-val="0" :end-val="totalSate.excuseNum" :duration="2600" />
                 </div>
               </div>
             </el-card>
@@ -123,7 +123,7 @@
           <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-5 flex justify-between fw-800 text-20px">
+                <div class="h-7 flex justify-between fw-800 text-20px">
                   <span>周出勤情况</span>
                 </div>
               </template>
@@ -138,30 +138,51 @@
           <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
             <el-card shadow="never" class="mb-10px ">
               <template #header>
-                <div class="h-5 flex justify-between fw-800 text-20px">
+                <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="7" class="center"
+                      <el-col :span="6" class="center"
                         style="display: flex; justify-content: center; align-items: center; padding: 6px;">
-                        <div>{{ item.trainNumber }}</div>
+                        <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.destination }}</div>
+                        <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.departureTime }}</div>
+                        <div>{{ item.daptName }}</div>
                       </el-col>
-                      <el-col :span="5" class="center"
+                      <el-col :span="6" class="center"
                         style="display: flex; justify-content: center; align-items: center; padding: 6px;">
-                        <div>{{ item.status }}</div>
+                        <div>{{ item.clockInTime }}</div>
                       </el-col>
                     </el-row>
                   </div>
@@ -188,39 +209,45 @@
               </template>
 
               <div class="demos">
-                <!-- <div class="table-header">
+                <div class="table-header">
                           <div class="header">
                             <el-row class="shouye" style="border: none;">
-                              <el-col :span="8" class="center text-18px" style="border: none;">
-                                <div>学生学号</div>
+                              <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;">
+                              <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;">
+                              <!-- <el-col :span="10" class="center text-18px" style="border: none;">
                                 <div>缺勤时间段</div>
-                              </el-col>
+                              </el-col> -->
                             </el-row>
                           </div>
-                        </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;">
+                      <!-- <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.destination }}</div>
+                        <div>{{ item.userNumber }}</div>
                       </el-col>
                       <el-col :span="6" class="center" style="padding: 10px; border: none;">
-                        <div>{{ item.trainNumber }}</div>
+                        <div>{{ item.deptName }}</div>
                       </el-col>
                       <el-col :span="6" class="center" style="padding: 10px; border: none;">
-                        <div>{{ item.departureTime }}</div>
+                        <div>{{ item.supervisor }}</div>
                       </el-col>
                     </el-row>
                   </div>
@@ -241,28 +268,15 @@
                 </div>
               </template>
               <div class="demoss">
-                <!-- <div class="table-header">
-                          <div class="header">
-                            <el-row class="shouye">
-                              <el-col :span="12" class="center text-18px">
-                                <div>工作间</div>
-                              </el-col>
-                              <el-col :span="15" class="center  text-18px ">
-                                <div>学生毕业条件达成率</div>
-                              </el-col>
-                            </el-row>
-                          </div>
-                        </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.destination }}</div>
+                        <div>{{ item.name }}</div>
                       </el-col>
                       <el-col :span="12" class="center" style="padding: 8px;">
-                        <div>{{ item.departureNumber }}</div>
+                        <div>{{ item.graduationRate }}%</div>
                       </el-col>
                     </el-row>
                   </div>
@@ -283,7 +297,6 @@
 </template>
 
 <script lang="ts" setup>
-import { set } from 'lodash-es'
 import { EChartsOption, List } from 'echarts'
 import { formatTime } from '@/utils'
 import { useUserStore } from '@/store/modules/user'
@@ -293,6 +306,7 @@ 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' })
@@ -352,7 +366,7 @@ const getProject = async () => {
 let totalSate = reactive<WorkplaceTotal>({
   normalNum: 0,
   errorNum: 0,
-  ExcuNum: 0,
+  excuseNum: 0,
 })
 const getCount = async () => {
   const data = await StudentAttendanceApi.getDayAttendance()
@@ -360,14 +374,13 @@ const getCount = async () => {
   totalSate = Object.assign(totalSate, data)
 }
 
-/**毕业达成统计 */
+// /**毕业达成统计 */
 let pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
-const getUserAccessSource = async () => {
-  const data = [
-    { value: 1048, name: '达成人数' },
-    { value: 735, name: '未达成人数' },
-  ];
-
+const getGraduateCount = async () => {
+  const data = await UserApi.getGraduateCount()
+  console.log("毕业达成统计", data);
+  const studentNum = data[0].studentNum; 
+  const graduateNum = data[1].graduateNum; 
   const options = {
     title: {
       text: null,
@@ -388,31 +401,50 @@ const getUserAccessSource = async () => {
         center: ['50%', '85%'], // 中心位置
         startAngle: 180,
         endAngle: 360,
-        data: data.map(v => ({
-          value: v.value,
-          name: t(v.name),
-          label: {
-            show: true,
-            position: 'outside',  // 拉出标注
-            formatter: '{b}: {c}', // 显示名称和数值
-            // 可以自定义引线的样式
-            emphasis: {
+        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],
             },
           },
-          // 自定义引线样式
-          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 = ['#94d6da', '#00a6ac']; // 定义颜色数组
+            const colorList = ['#2585a6','#5cb5e3' ]; // 定义颜色数组
             return colorList[params.dataIndex]; // 根据数据索引返回对应的颜色
           }
         }
@@ -420,61 +452,39 @@ const getUserAccessSource = async () => {
     ],
   };
 
-  set(
-    pieOptionsData,
-    'legend.data',
-    data.map((v) => t(v.name))
-  );
+//   // 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 () => {
-  try {
-    const res = await StudentAttendanceApi.getWeekendAttendance();
-    console.log("周出勤情况", res);
-     // 更新图表数据
-     barOptionsData.series = [
-      {
-        name: '正常出勤',
-        type: 'bar',
-        data: [res.normalNum], // 将正常出勤人数放入数据中
-      },
-      {
-        name: '缺勤',
-        type: 'bar',
-        data: [res.errorNum], // 将缺勤人数放入数据中
-      }
-    ];
-  } catch (error) {
-    console.error("获取周出勤情况失败:", error);
-  }
+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 params = reactive({
+  list: [] 
+})
 /**缺勤预警 */
-const list2 = reactive([
-  { trainNumber: '张一', destination: '101', departureTime: '09:00', ID: '10' },
-  { trainNumber: '张二', destination: '102', departureTime: '09:15', ID: '15' },
-  { trainNumber: '张三', destination: '103', departureTime: '09:30', ID: '13' },
-  { trainNumber: '张四', destination: '104', departureTime: '09:45', ID: '18' },
-  { trainNumber: '张五', destination: '105', departureTime: '10:00', ID: '19' },
-  { trainNumber: '李一', destination: '201', departureTime: '10:15', ID: '12' },
-  { trainNumber: '李二', destination: '202', departureTime: '10:30', ID: '02' },
-  { trainNumber: '李三', destination: '203', departureTime: '10:45', ID: '09' },
-  { trainNumber: '李四', destination: '204', departureTime: '11:00', ID: '16' },
-  { trainNumber: '李五', destination: '205', departureTime: '11:15', ID: '20' },
-  { trainNumber: '王一', destination: '301', departureTime: '11:30', ID: '28' },
-  { trainNumber: '王二', destination: '302', departureTime: '11:45', ID: '36' },
-  { trainNumber: '王三', destination: '303', departureTime: '12:00', ID: '07' },
-  { trainNumber: '王四', destination: '304', departureTime: '12:15', ID: '41' },
-  { trainNumber: '王五', destination: '305', departureTime: '12:30', ID: '15' },
-  { trainNumber: '王六', destination: '306', departureTime: '12:45', ID: '22' },
-  { trainNumber: '王七', destination: '307', departureTime: '13:00', ID: '27' }
-
-]);
+let list2 = reactive([]);
+const getStudentAttendanceError = async () => {
+  const data = await StudentAttendanceApi.getStudentAttendanceErrorPage(params)
+  console.log("缺勤列表", data);
+  list2.splice(0, list2.length, ...data.list);
+}
 const class2Options = reactive({
   step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
   limitMoveNum: list2.length,//无缝滚动列表元素的长度,一般设置为列表的长度
@@ -483,26 +493,12 @@ const class2Options = reactive({
 
 /**实时打卡状态 */
 //打卡滚动列表
-const list = reactive([
-  { trainNumber: '张一', destination: '101', departureTime: '09:00', status: '准点' },
-  { trainNumber: '张二', destination: '102', departureTime: '09:15', status: '准点' },
-  { trainNumber: '张三', destination: '103', departureTime: '09:30', status: '晚点' },
-  { trainNumber: '张四', destination: '104', departureTime: '09:45', status: '准点' },
-  { trainNumber: '张五', destination: '105', departureTime: '10:00', status: '准点' },
-  { trainNumber: '李一', destination: '201', departureTime: '10:15', status: '准点' },
-  { trainNumber: '李二', destination: '202', departureTime: '10:30', status: '晚点' },
-  { trainNumber: '李三', destination: '203', departureTime: '10:45', status: '准点' },
-  { trainNumber: '李四', destination: '204', departureTime: '11:00', status: '晚点' },
-  { trainNumber: '李五', destination: '205', departureTime: '11:15', status: '准点' },
-  { trainNumber: '王一', destination: '301', departureTime: '11:30', status: '准点' },
-  { trainNumber: '王二', destination: '302', departureTime: '11:45', status: '准点' },
-  { trainNumber: '王三', destination: '303', departureTime: '12:00', status: '晚点' },
-  { trainNumber: '王四', destination: '304', departureTime: '12:15', status: '准点' },
-  { trainNumber: '王五', destination: '305', departureTime: '12:30', status: '准点' },
-  { trainNumber: '王六', destination: '306', departureTime: '12:45', status: '准点' },
-  { trainNumber: '王七', destination: '307', departureTime: '13:00', status: '晚点' }
-
-]);
+const list = reactive([]);
+const getStudentAttendance = async () => {
+  const data = await StudentAttendanceApi.getStudentAttendancePage(params)
+  console.log("打卡列表", data);
+  list.splice(0, list.length, ...data.list);
+}
 const classOptions = reactive({
   step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
   limitMoveNum: list.length,//无缝滚动列表元素的长度,一般设置为列表的长度
@@ -512,31 +508,16 @@ const classOptions = reactive({
 
 /** 学生毕业条件达成率 */
 //在线情况滚动列表
-const list1 = reactive([
-  { destination: '101', departureNumber: '98%' },
-  { destination: '102', departureNumber: '94%' },
-  { destination: '103', departureNumber: '96%' },
-  { destination: '104', departureNumber: '98%' },
-  { destination: '105', departureNumber: '93%' },
-  { destination: '201', departureNumber: '97%' },
-  { destination: '202', departureNumber: '95%' },
-  { destination: '203', departureNumber: '98%' },
-  { destination: '204', departureNumber: '96%' },
-  { destination: '205', departureNumber: '94%' },
-  { destination: '301', departureNumber: '97%' },
-  { destination: '302', departureNumber: '96%' },
-  { destination: '303', departureNumber: '95%' },
-  { destination: '304', departureNumber: '97%' },
-  { destination: '305', departureNumber: '98%' },
-  { destination: '306', departureNumber: '99%' },
-  { destination: '307', departureNumber: '96%' }
-
-]);
+const list1 = reactive([]);
+const getGraduationSource = async () => {
+  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 向右。
-
 });
 
 onMounted(() => {
@@ -544,7 +525,10 @@ onMounted(() => {
   getWeekend()
   getProject()
   getCount()
-  // getNotice()
+  getStudentAttendanceError()
+  getStudentAttendance()
+  getGraduationSource()
+  getGraduateCount()
 })
 
 
@@ -780,6 +764,11 @@ const getAllApi = async () => {
     await getDetail(),
     getCount(),
     getProject(),
+    getWeekend(),
+    getStudentAttendanceError(),
+    getStudentAttendance(),
+    getGraduationSource(),
+    getGraduateCount(),
     // getNotice(),
     // getBasic(),
     // getShortcut(),
@@ -789,15 +778,6 @@ const getAllApi = async () => {
   loading.value = false
 }
 
-watchEffect(detail => {
-  console.log('detail', detail)
-  // getBasic()
-})
-
-// onMounted(() => {
-
-// })
-
 getAllApi()
 </script>
 

+ 22 - 3
src/views/Home/echarts-data.ts

@@ -146,9 +146,28 @@ export const barOptions: EChartsOption = {
   },
   series: [
     {
-      name: t('analysis.activeQuantity'),
-      data: [13253, 34235, 26321, 12340, 24643, 1322, 1324],
-      type: 'bar'
+      name: '正常',
+      data: [],
+      type: 'bar',
+      itemStyle: {
+        color: '#5cb5e3'
+      }
+    },
+    {
+      name: '异常',
+      data: [],
+      type: 'bar',
+      itemStyle: {
+        color: '#CD5C5C'
+      }
+    },
+    {
+      name: '请假',
+      data: [],
+      type: 'bar',
+      itemStyle: {
+        color: '#FFF68F'
+      }
     }
   ]
 }

+ 1 - 1
src/views/Home/types.ts

@@ -1,7 +1,7 @@
 export type WorkplaceTotal = {
   normalNum: number
   errorNum: number
-  ExcuNum: number
+  excuseNum: number
 }
 
 export type Project = {

+ 4 - 3
src/views/system/workroomCollege/dept/index.vue

@@ -181,7 +181,6 @@
       </el-table-column>
     </el-table>
     <Pagination
-      @current-change="handleCurrentChange"
       :total="total"
       v-model:page="queryParams.pageNo"
       v-model:limit="queryParams.pageSize"
@@ -227,9 +226,11 @@ const userList = ref<UserApi.UserVO[]>([]) // 用户列表
 const getList = async () => {
   loading.value = true
   try {
-    const data = await DeptApi.getDeptPage(queryParams)
+    const data = await DeptApi.getDeptList(queryParams)
     console.log(data,'111');
-    list.value = handleTree(data)
+    // list.value = handleTree(data)
+    list.value = data.list
+    total.value = data.total
   } finally {
     loading.value = false
   }