update wuzhen
This commit is contained in:
1 parent
96caabab43
commit
b28889161c
6 files changed
+100
-61
No files matched your search
+5
-9
@@ -69,25 +69,25 @@ public class ZsjyInternshipDaily extends BaseEntity {
|
||||
* 签到地点 (对应数据库check_in_location字段)
|
||||
*/
|
||||
@TableField("check_in_location")
|
||||
private String checkOutLocation;
|
||||
private String checkInLocation;
|
||||
|
||||
/**
|
||||
* 签到经度 (对应数据库longitude字段)
|
||||
*/
|
||||
@TableField("longitude")
|
||||
private BigDecimal checkOutLongitude;
|
||||
private BigDecimal longitude;
|
||||
|
||||
/**
|
||||
* 签到纬度 (对应数据库latitude字段)
|
||||
*/
|
||||
@TableField("latitude")
|
||||
private BigDecimal checkOutLatitude;
|
||||
private BigDecimal latitude;
|
||||
|
||||
/**
|
||||
* 工作内容/日总结
|
||||
*/
|
||||
@TableField("daily_summary")
|
||||
private String workContent;
|
||||
private String dailySummary;
|
||||
|
||||
/**
|
||||
* 图片附件(JSON格式)
|
||||
@@ -157,11 +157,7 @@ public class ZsjyInternshipDaily extends BaseEntity {
|
||||
@TableField(exist = false)
|
||||
private String position;
|
||||
|
||||
/**
|
||||
* 签到地点 (业务扩展字段,当前只有签退地点)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String checkInLocation;
|
||||
|
||||
|
||||
/**
|
||||
* 签到经度 (业务扩展字段,当前只有签退经度)
|
||||
|
||||
+21
-2
@@ -7,7 +7,7 @@ import lombok.Data;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Time;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@@ -53,7 +53,14 @@ public class ZsjyInternshipDailyVo implements Serializable {
|
||||
*/
|
||||
@Schema(description = "签到时间")
|
||||
@JsonFormat(pattern = "HH:mm:ss")
|
||||
private Time checkInTime;
|
||||
private LocalTime checkInTime;
|
||||
|
||||
/**
|
||||
* 签退时间
|
||||
*/
|
||||
@Schema(description = "签退时间")
|
||||
@JsonFormat(pattern = "HH:mm:ss")
|
||||
private LocalTime checkOutTime;
|
||||
|
||||
/**
|
||||
* 签到位置
|
||||
@@ -155,6 +162,18 @@ public class ZsjyInternshipDailyVo implements Serializable {
|
||||
@Schema(description = "学号")
|
||||
private String studentNo;
|
||||
|
||||
/**
|
||||
* 学号(前端兼容字段)
|
||||
*/
|
||||
@Schema(description = "学号")
|
||||
private String studentNumber;
|
||||
|
||||
/**
|
||||
* 工作时长(小时)
|
||||
*/
|
||||
@Schema(description = "工作时长")
|
||||
private BigDecimal workDuration;
|
||||
|
||||
/**
|
||||
* 公司名称
|
||||
*/
|
||||
|
||||
+8
-9
@@ -97,10 +97,10 @@ public class ZsjyInternshipDailyServiceImpl implements IZsjyInternshipDailyServi
|
||||
entity.setStudentId(addBo.getStudentId());
|
||||
entity.setCheckDate(addBo.getCheckDate());
|
||||
entity.setCheckInTime(addBo.getCheckInTime());
|
||||
entity.setCheckOutLocation(addBo.getCheckOutLocation()); // 对应数据库check_in_location字段
|
||||
entity.setCheckOutLatitude(addBo.getCheckOutLatitude()); // 对应数据库latitude字段
|
||||
entity.setCheckOutLongitude(addBo.getCheckOutLongitude()); // 对应数据库longitude字段
|
||||
entity.setWorkContent(addBo.getWorkContent()); // 对应数据库daily_summary字段
|
||||
entity.setCheckInLocation(addBo.getCheckOutLocation()); // 对应数据库check_in_location字段
|
||||
entity.setLatitude(addBo.getCheckOutLatitude()); // 对应数据库latitude字段
|
||||
entity.setLongitude(addBo.getCheckOutLongitude()); // 对应数据库longitude字段
|
||||
entity.setDailySummary(addBo.getWorkContent()); // 对应数据库daily_summary字段
|
||||
entity.setImages(addBo.getImages());
|
||||
entity.setIsException(addBo.getIsException());
|
||||
entity.setExceptionReason(addBo.getExceptionReason());
|
||||
@@ -188,11 +188,10 @@ public class ZsjyInternshipDailyServiceImpl implements IZsjyInternshipDailyServi
|
||||
// 2. 补充统计信息
|
||||
if (ObjectUtil.isNull(statistics)) {
|
||||
statistics = new HashMap<>();
|
||||
statistics.put("totalDays", 0);
|
||||
statistics.put("attendanceDays", 0);
|
||||
statistics.put("exceptionDays", 0);
|
||||
statistics.put("pendingExceptions", 0);
|
||||
statistics.put("attendanceRate", 0.0);
|
||||
statistics.put("totalStudents", 0);
|
||||
statistics.put("todayCheckedIn", 0);
|
||||
statistics.put("todayLate", 0);
|
||||
statistics.put("attendanceRate", "0%");
|
||||
}
|
||||
|
||||
return R.ok(statistics);
|
||||
|
||||
+47
-28
@@ -9,6 +9,7 @@
|
||||
<result property="studentId" column="student_id" />
|
||||
<result property="checkDate" column="check_date" />
|
||||
<result property="checkInTime" column="check_in_time" />
|
||||
<result property="checkOutTime" column="check_out_time" />
|
||||
<result property="checkInLocation" column="check_in_location" />
|
||||
<result property="latitude" column="latitude" />
|
||||
<result property="longitude" column="longitude" />
|
||||
@@ -26,7 +27,9 @@
|
||||
<!-- 扩展字段 -->
|
||||
<result property="studentName" column="student_name" />
|
||||
<result property="studentNo" column="student_no" />
|
||||
<result property="studentNumber" column="student_no" />
|
||||
<result property="companyName" column="company_name" />
|
||||
<result property="workDuration" column="work_duration" />
|
||||
</resultMap>
|
||||
|
||||
<!-- 基础SQL片段 -->
|
||||
@@ -37,6 +40,7 @@
|
||||
d.student_id,
|
||||
d.check_date,
|
||||
d.check_in_time,
|
||||
d.check_out_time,
|
||||
d.check_in_location,
|
||||
d.latitude,
|
||||
d.longitude,
|
||||
@@ -54,7 +58,13 @@
|
||||
-- 关联查询扩展字段
|
||||
i.student_name,
|
||||
i.student_no,
|
||||
i.company_name
|
||||
i.company_name,
|
||||
-- 计算工作时长(小时)
|
||||
CASE
|
||||
WHEN d.check_in_time IS NOT NULL AND d.check_out_time IS NOT NULL THEN
|
||||
ROUND(TIMESTAMPDIFF(MINUTE, d.check_in_time, d.check_out_time) / 60.0, 2)
|
||||
ELSE NULL
|
||||
END as work_duration
|
||||
FROM zsjy_internship_daily d
|
||||
LEFT JOIN zsjy_internship_info i ON d.internship_id = i.internship_id
|
||||
</sql>
|
||||
@@ -126,34 +136,43 @@
|
||||
<!-- 获取考勤统计数据 -->
|
||||
<select id="selectStatistics" resultType="java.util.Map">
|
||||
SELECT
|
||||
COUNT(*) as totalDays,
|
||||
SUM(CASE WHEN check_in_time IS NOT NULL THEN 1 ELSE 0 END) as attendanceDays,
|
||||
SUM(CASE WHEN is_exception = '1' THEN 1 ELSE 0 END) as exceptionDays,
|
||||
SUM(CASE WHEN is_exception = '1' AND exception_status = '0' THEN 1 ELSE 0 END) as pendingExceptions,
|
||||
ROUND(
|
||||
SUM(CASE WHEN check_in_time IS NOT NULL THEN 1 ELSE 0 END) * 100.0 /
|
||||
NULLIF(COUNT(*), 0), 2
|
||||
-- 实习学生总数
|
||||
(SELECT COUNT(DISTINCT student_id)
|
||||
FROM zsjy_internship_daily
|
||||
WHERE deleted = 0) as totalStudents,
|
||||
|
||||
-- 今日已签到
|
||||
(SELECT COUNT(DISTINCT student_id)
|
||||
FROM zsjy_internship_daily
|
||||
WHERE deleted = 0
|
||||
AND check_date = CURDATE()
|
||||
AND check_in_time IS NOT NULL) as todayCheckedIn,
|
||||
|
||||
-- 今日迟到(假设9:00之后签到为迟到)
|
||||
(SELECT COUNT(DISTINCT student_id)
|
||||
FROM zsjy_internship_daily
|
||||
WHERE deleted = 0
|
||||
AND check_date = CURDATE()
|
||||
AND check_in_time > '09:00:00') as todayLate,
|
||||
|
||||
-- 本月出勤率
|
||||
CONCAT(
|
||||
ROUND(
|
||||
(SELECT COUNT(*)
|
||||
FROM zsjy_internship_daily
|
||||
WHERE deleted = 0
|
||||
AND YEAR(check_date) = YEAR(CURDATE())
|
||||
AND MONTH(check_date) = MONTH(CURDATE())
|
||||
AND check_in_time IS NOT NULL) * 100.0 /
|
||||
NULLIF(
|
||||
(SELECT COUNT(*)
|
||||
FROM zsjy_internship_daily
|
||||
WHERE deleted = 0
|
||||
AND YEAR(check_date) = YEAR(CURDATE())
|
||||
AND MONTH(check_date) = MONTH(CURDATE())), 0
|
||||
), 1
|
||||
), '%'
|
||||
) as attendanceRate
|
||||
FROM zsjy_internship_daily d
|
||||
LEFT JOIN zsjy_internship_info i ON d.internship_id = i.internship_id
|
||||
<where>
|
||||
d.deleted = 0
|
||||
<if test="queryBo.studentId != null">
|
||||
AND d.student_id = #{queryBo.studentId}
|
||||
</if>
|
||||
<if test="queryBo.internshipId != null">
|
||||
AND d.internship_id = #{queryBo.internshipId}
|
||||
</if>
|
||||
<if test="queryBo.checkDateStart != null">
|
||||
AND d.check_date >= #{queryBo.checkDateStart}
|
||||
</if>
|
||||
<if test="queryBo.checkDateEnd != null">
|
||||
AND d.check_date <= #{queryBo.checkDateEnd}
|
||||
</if>
|
||||
<if test="queryBo.companyName != null and queryBo.companyName != ''">
|
||||
AND i.company_name LIKE CONCAT('%', #{queryBo.companyName}, '%')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 检查学生当日是否已签到 -->
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<el-icon class="status-icon success"><SuccessFilled /></el-icon>
|
||||
<div class="status-text">
|
||||
<h4>已签到</h4>
|
||||
<p>{{ parseTime(todayRecord.checkInTime, '{h}:{i}') }}</p>
|
||||
<p>{{ todayRecord.checkInTime }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="not-checked-in">
|
||||
@@ -184,12 +184,12 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="签到时间" width="100">
|
||||
<template #default="scope">
|
||||
{{ scope.row.checkInTime ? parseTime(scope.row.checkInTime, '{h}:{i}') : '-' }}
|
||||
{{ scope.row.checkInTime || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="签退时间" width="100">
|
||||
<template #default="scope">
|
||||
{{ scope.row.checkOutTime ? parseTime(scope.row.checkOutTime, '{h}:{i}') : '-' }}
|
||||
{{ scope.row.checkOutTime || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工作时长" width="100">
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
<div class="student-info">
|
||||
<div class="student-name">{{ scope.row.studentName }}</div>
|
||||
<div class="student-number">学号:{{ scope.row.studentNumber }}</div>
|
||||
<div class="student-class">班级:{{ scope.row.className }}</div>
|
||||
<!-- <div class="student-class">班级:{{ scope.row.className }}</div> -->
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -161,8 +161,8 @@
|
||||
<el-table-column label="签到时间" min-width="120" align="center">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.checkInTime">
|
||||
<div>{{ parseTime(scope.row.checkInTime, '{y}-{m}-{d}') }}</div>
|
||||
<div class="time-detail">{{ parseTime(scope.row.checkInTime, '{h}:{i}') }}</div>
|
||||
<div>{{ parseTime(scope.row.checkDate, '{y}-{m}-{d}') }}</div>
|
||||
<div class="time-detail">{{ scope.row.checkInTime }}</div>
|
||||
</div>
|
||||
<span v-else class="text-danger">未签到</span>
|
||||
</template>
|
||||
@@ -171,8 +171,8 @@
|
||||
<el-table-column label="签退时间" min-width="120" align="center">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.checkOutTime">
|
||||
<div>{{ parseTime(scope.row.checkOutTime, '{y}-{m}-{d}') }}</div>
|
||||
<div class="time-detail">{{ parseTime(scope.row.checkOutTime, '{h}:{i}') }}</div>
|
||||
<div>{{ parseTime(scope.row.checkDate, '{y}-{m}-{d}') }}</div>
|
||||
<div class="time-detail">{{ scope.row.checkOutTime }}</div>
|
||||
</div>
|
||||
<span v-else class="text-muted">未签退</span>
|
||||
</template>
|
||||
@@ -231,10 +231,10 @@
|
||||
<el-descriptions-item label="班级">{{ currentRecord.className }}</el-descriptions-item>
|
||||
<el-descriptions-item label="实习单位">{{ currentRecord.companyName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="签到时间">
|
||||
{{ currentRecord.checkInTime ? parseTime(currentRecord.checkInTime) : '未签到' }}
|
||||
{{ currentRecord.checkInTime || '未签到' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="签退时间">
|
||||
{{ currentRecord.checkOutTime ? parseTime(currentRecord.checkOutTime) : '未签退' }}
|
||||
{{ currentRecord.checkOutTime || '未签退' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="工作时长">
|
||||
{{ currentRecord.workDuration ? currentRecord.workDuration + '小时' : '-' }}
|
||||
@@ -406,9 +406,10 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="InternshipDaily">
|
||||
import { listInternshipDaily, getCalendar, getStatistics, addInternshipDaily } from "@/api/zsjy/internshipDaily";
|
||||
import { parseTime } from "@/utils/ruoyi";
|
||||
<script setup name="InternshipDaily" lang="ts">
|
||||
import { listInternshipDaily, getCalendar, getStatistics, addInternshipDaily } from '@/api/zsjy/internshipDaily';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
import { User, Check, Warning, TrendCharts } from '@element-plus/icons-vue';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@@ -508,8 +509,13 @@ const getList = () => {
|
||||
|
||||
// 获取统计数据
|
||||
const getStatisticsData = () => {
|
||||
console.log('正在获取统计数据...');
|
||||
getStatistics().then(response => {
|
||||
console.log('统计数据响应:', response);
|
||||
statistics.value = response.data || {};
|
||||
console.log('设置的统计数据:', statistics.value);
|
||||
}).catch(error => {
|
||||
console.error('获取统计数据失败:', error);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user