1
0
mirror of https://github.com/FatttSnake/Pinnacle-OA.git synced 2026-04-04 22:41:24 +08:00

commit 2023/05/06

This commit is contained in:
gzw
2023-05-06 00:41:06 +08:00
parent c72b6dc4dc
commit 2fa80301e2
15 changed files with 995 additions and 9 deletions

View File

@@ -1,18 +1,112 @@
package com.cfive.pinnacle.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cfive.pinnacle.entity.Attendance;
import com.cfive.pinnacle.entity.common.ResponseCode;
import com.cfive.pinnacle.entity.common.ResponseResult;
import com.cfive.pinnacle.service.IAttendanceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 考勤 前端控制器
* </p>
*
* @author FatttSnake
* @author gzw
* @since 2023-04-30
*/
@CrossOrigin
@RestController
@RequestMapping("/attendance")
public class AttendanceController {
@Autowired
private IAttendanceService attendanceService;
//查询所有考勤信息和用户名
@GetMapping("findAllAttendance")
public ResponseResult findAllAttendanceAndUser() {
List<Attendance> attendances = attendanceService.getAllAttendanceAndUser();
return ResponseResult.build(ResponseCode.DATABASE_SELECT_OK, "success", attendances);
}
//模糊时间查询
@GetMapping("/findAttendanceByTime")
public ResponseResult findAttendanceAndUser(String startTime,String endTime) {
List<Attendance> attendances = attendanceService.selectByTime(startTime, endTime);
return ResponseResult.build(ResponseCode.DATABASE_SELECT_OK, "success", attendances);
}
//用户个人模糊时间查询
@GetMapping("/findOneAttendanceByTime")
public ResponseResult findOneAttendanceAndUser(String startTime,String endTime,Long userId) {
List<Attendance> attendances = attendanceService.selectOneByTime(startTime, endTime,userId);
return ResponseResult.build(ResponseCode.DATABASE_SELECT_OK, "success", attendances);
}
//添加或更新考勤信息
@PostMapping("/saveAttendance")
public ResponseResult saveAttendance(@RequestBody Attendance attendance) {
attendance.setModifyId(1652714496280469506L);
return attendanceService.saveOrUpdate(attendance) ? ResponseResult.build(ResponseCode.DATABASE_SAVE_OK, "success", attendance) :
ResponseResult.build(ResponseCode.DATABASE_SAVE_ERROR, "error", null);
}
//个人签到
@PostMapping("/saveOneAttendance")
public ResponseResult saveOneAttendance(@RequestBody Attendance attendance) {
attendance.setModifyId(1652714496280469506L);
if (attendance.getAttTime().getHour() > 1 && attendance.getAttTime().getHour() < 10) {
// 迟到
attendance.setStatus(3);
return attendanceService.save(attendance) ? ResponseResult.build(ResponseCode.DATABASE_SAVE_OK, "success", attendance) :
ResponseResult.build(ResponseCode.DATABASE_SAVE_ERROR, "error", null);
} else if (attendance.getAttTime().getHour() >= 10&& attendance.getAttTime().getHour() < 15) {
// 签退
attendance.setStatus(2);
return attendanceService.save(attendance) ? ResponseResult.build(ResponseCode.DATABASE_SAVE_OK, "success", attendance) :
ResponseResult.build(ResponseCode.DATABASE_SAVE_ERROR, "error", null);
} else if (attendance.getAttTime().getHour() <= 1) {
// 签到
attendance.setStatus(1);
return attendanceService.save(attendance) ? ResponseResult.build(ResponseCode.DATABASE_SAVE_OK, "success", attendance) :
ResponseResult.build(ResponseCode.DATABASE_SAVE_ERROR, "error", null);
} else {
// 考勤异常
attendance.setStatus(0);
return attendanceService.save(attendance) ? ResponseResult.build(ResponseCode.DATABASE_SAVE_OK, "success", attendance) :
ResponseResult.build(ResponseCode.DATABASE_SAVE_ERROR, "error", null);
}
}
//查询个人考勤
@GetMapping("/selectAttendance/{userId}")
public ResponseResult findAttendanceAndUser(@PathVariable Long userId) {
List<Attendance> attendances = attendanceService.getAttendanceAndUserByid(userId);
return ResponseResult.build(ResponseCode.DATABASE_SELECT_OK, "success", attendances);
}
//删除考勤信息
@DeleteMapping("/delAttendance/{id}")
public ResponseResult delAttendance(@PathVariable Long id) {
return attendanceService.removeById(id) ? ResponseResult.build(ResponseCode.DATABASE_DELETE_OK, "success", null) :
ResponseResult.build(ResponseCode.DATABASE_DELETE_ERROR, "error", null);
}
//批量删除考勤信息
@PostMapping("/delBatchAttendance")
public ResponseResult delBatchAttendance(@RequestBody List<Long> ids) {
return attendanceService.removeByIds(ids) ? ResponseResult.build(ResponseCode.DATABASE_DELETE_OK, "success", null) :
ResponseResult.build(ResponseCode.DATABASE_DELETE_ERROR, "error", null);
}
}

View File

@@ -10,6 +10,9 @@ import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -18,7 +21,7 @@ import lombok.experimental.Accessors;
* 考勤
* </p>
*
* @author FatttSnake
* @author gzw
* @since 2023-04-30
*/
@Data
@@ -30,18 +33,21 @@ public class Attendance implements Serializable {
private static final long serialVersionUID = 1L;
@TableId("id")
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 用户
*/
@TableField("user_id")
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/**
* 考勤时间
*/
@TableField("att_time")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",timezone = "UTC")
private LocalDateTime attTime;
/**
@@ -54,6 +60,7 @@ public class Attendance implements Serializable {
* 修改人
*/
@TableField("modify_id")
@JsonSerialize(using = ToStringSerializer.class)
private Long modifyId;
/**
@@ -63,10 +70,13 @@ public class Attendance implements Serializable {
private LocalDateTime modifyTime;
@TableField("deleted")
@TableLogic
@TableLogic(value = "0",delval = "1")
private Integer deleted;
@TableField("version")
@Version
private Integer version;
@TableField(exist = false)
private User user;
}

View File

@@ -1,18 +1,26 @@
package com.cfive.pinnacle.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cfive.pinnacle.entity.Attendance;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* <p>
* 考勤 Mapper 接口
* </p>
*
* @author FatttSnake
* @author gzw
* @since 2023-04-30
*/
@Mapper
public interface AttendanceMapper extends BaseMapper<Attendance> {
List<Attendance> getAllAttendanceAndUser();
List<Attendance> getAttendanceAndUserByid(Long userId);
}

View File

@@ -1,16 +1,26 @@
package com.cfive.pinnacle.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cfive.pinnacle.entity.Attendance;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 考勤 服务类
* </p>
*
* @author FatttSnake
* @author gzw
* @since 2023-04-30
*/
public interface IAttendanceService extends IService<Attendance> {
List<Attendance> getAllAttendanceAndUser();
List<Attendance> getAttendanceAndUserByid(Long userId);
List<Attendance> selectByTime(String startTime,String endTime);
List<Attendance> selectOneByTime(String startTime,String endTime,Long userId);
}

View File

@@ -1,20 +1,79 @@
package com.cfive.pinnacle.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cfive.pinnacle.entity.Attendance;
import com.cfive.pinnacle.mapper.AttendanceMapper;
import com.cfive.pinnacle.mapper.UserMapper;
import com.cfive.pinnacle.service.IAttendanceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* <p>
* 考勤 服务实现类
* </p>
*
* @author FatttSnake
* @author gzw
* @since 2023-04-30
*/
@Service
public class AttendanceServiceImpl extends ServiceImpl<AttendanceMapper, Attendance> implements IAttendanceService {
@Autowired
private AttendanceMapper attendanceMapper;
@Autowired
private UserMapper userMapper;
@Override
public List<Attendance> getAllAttendanceAndUser() {
return attendanceMapper.getAllAttendanceAndUser();
}
@Override
public List<Attendance> getAttendanceAndUserByid(Long userId) {
return attendanceMapper.getAttendanceAndUserByid(userId);
}
@Override
public List<Attendance> selectByTime(String startTime, String endTime) {
LocalDateTime start = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime end = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(start);
System.out.println(end);
LambdaQueryWrapper<Attendance> lqw = new LambdaQueryWrapper<>();
lqw.ge(null != start, Attendance::getAttTime, start).le(null != end, Attendance::getAttTime, end);
List<Attendance> attendancesByTime = attendanceMapper.selectList(lqw);
for (Attendance attendance:
attendancesByTime) {
attendance.setUser(userMapper.selectById(attendance.getUserId()));
}
return attendancesByTime;
}
@Override
public List<Attendance> selectOneByTime(String startTime, String endTime,Long userId) {
LocalDateTime start = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime end = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(start);
System.out.println(end);
LambdaQueryWrapper<Attendance> lqw = new LambdaQueryWrapper<>();
lqw.ge(null != start, Attendance::getAttTime, start).le(null != end, Attendance::getAttTime, end);
List<Attendance> oneAttendancesByTime = attendanceMapper.selectList(lqw);
for (Attendance attendance:
oneAttendancesByTime) {
attendance.setUser(userMapper.selectById(userId));
}
return oneAttendancesByTime;
}
}

View File

@@ -2,4 +2,72 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cfive.pinnacle.mapper.AttendanceMapper">
</mapper>
<select id="getAllAttendanceAndUser" resultMap="AllAttendAndUserResult">
select att.id attId,
att.user_id,
att.att_time,
att.status,
att.modify_id,
att.modify_time,
att.deleted attDel,
att.version attVer,
u.id uId,
u.username,
u.passwd,
u.department_id,
u.deleted uDel,
u.version uVer
from t_attendance att,
t_user u
where att.user_id = u.id
and att.deleted = 0
order by att_time DESC
</select>
<resultMap id="AllAttendAndUserResult" type="attendance" autoMapping="true">
<id property="id" column="attId"/>
<result property="deleted" column="attDel"/>
<result property="version" column="attVer"/>
<association property="user" javaType="user" autoMapping="true">
<id property="id" column="uId"/>
<result property="deleted" column="uDel"/>
<result property="version" column="uVer"/>
</association>
</resultMap>
<select id="getAttendanceAndUserByid" resultMap="AttendAndUserResult">
select att.id attId,
att.user_id,
att.att_time,
att.status,
att.modify_id,
att.modify_time,
att.deleted attDel,
att.version attVer,
u.id uId,
u.username,
u.passwd,
u.department_id,
u.deleted uDel,
u.version uVer
from t_attendance att,
t_user u
where att.user_id = u.id
and att.deleted = 0 and att.user_id=#{userid}
order by att_time DESC
</select>
<resultMap id="AttendAndUserResult" type="attendance" autoMapping="true">
<id property="id" column="attId"/>
<result property="deleted" column="attDel"/>
<result property="version" column="attVer"/>
<association property="user" javaType="user" autoMapping="true">
<id property="id" column="uId"/>
<result property="deleted" column="uDel"/>
<result property="version" column="uVer"/>
</association>
</resultMap>
</mapper>

View File

@@ -0,0 +1,22 @@
package com.cfive.pinnacle.attendance;
import com.cfive.pinnacle.controller.AttendanceController;
import com.cfive.pinnacle.entity.Attendance;
import com.cfive.pinnacle.service.IAttendanceService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class AttendanceTest {
@Autowired
IAttendanceService attendanceService;
@Test
void addTest() {
Attendance attendance = new Attendance();
attendance.setUserId(1L);
attendance.setModifyId(1L);
attendanceService.save(attendance);
}
}

View File

@@ -0,0 +1,13 @@
*{
padding:0;
margin: 0;
}
#attendanceMain1{
margin-bottom:10px ;
}
/*
#attendanceMain{
width: 100vw;
height: 100vh;
}*/

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1682929177020" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5566" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M775.779 418.172l-2.051 0c-15.159 0-27.6 4.355-39.583 11.771-10.486-30.584-37.159-52.615-71.513-52.615-15.16 0-29.638 4.354-41.62 11.77-10.487-30.583-37.172-52.615-71.527-52.615-13.399 0-25.85 3.357-36.873 9.255l0-78.691c0-42.861-32.418-77.606-75.59-77.606-43.173 0-78.17 34.745-78.17 77.606l0 301.282-47.49-47.295c-30.528-30.306-84.558-25.992-110.55 0s-43.038 78.308-5.818 115.528l218.306 216.875c4.504 4.471 9.455 8.2 14.663 11.353 39.803 32.47 85.412 51.692 181.857 51.692 220.324 0 240.728-118.865 240.728-265.492L850.548 495.777C850.547 452.917 818.952 418.172 775.779 418.172zM809.403 650.988c0 124.069-0.593 224.647-199.585 224.647-84.298 0-134.907-18.796-173.246-56.858L229.904 613.455c-18.285-18.285-13.687-41.664 1.282-56.633 14.968-14.968 42.441-15.486 56.902-1.131 0 0 36.259 36.045 67.498 67.1 23.641 23.502 44.408 44.145 44.408 44.145l0-391.72c0-20.302 16.578-36.76 37.028-36.76 20.449 0 34.448 16.459 34.448 36.76l0 249.154 0.415 0c-0.27 1.32-0.415 2.685-0.415 4.085 0 11.278 9.21 20.423 20.571 20.423 11.36 0 20.57-9.144 20.57-20.423 0-1.4-0.144-2.765-0.415-4.085l0.415 0L512.611 422.257c0-20.302 14.795-36.761 35.245-36.761 0 0 36.232-0.49 36.232 36.761l0 134.787 0.415 0c-0.27 1.321-0.415 2.686-0.415 4.085 0 11.279 9.21 20.423 20.57 20.423 11.361 0 20.571-9.143 20.571-20.423 0-1.399-0.144-2.764-0.415-4.085l0.415 0 0-93.942c0-20.303 14.559-36.762 35.01-36.762 0 0 36.983 2.303 36.983 36.762l0 118.449 0.415 0c-0.269 1.32-0.415 2.686-0.415 4.085 0 11.279 9.21 20.423 20.571 20.423s20.055-9.143 20.055-20.423c0-1.399-0.136-2.765-0.392-4.085l0.392 0 0-80.872c0-20.302 15.255-36.761 35.704-36.761 0 0 35.851-1.45 35.851 36.761C809.403 500.679 809.403 617.954 809.403 650.988zM328.307 382.755l0-68.631c-6.531-14.641-10.24-30.817-10.24-47.884 0-65.037 52.723-117.76 117.76-117.76s117.76 52.723 117.76 117.76c0 8.884-1.05 17.509-2.935 25.82 14.812 0.578 28.176 6.726 37.904 16.597 3.771-13.518 5.99-27.685 5.99-42.417 0-87.658-71.062-158.72-158.72-158.72s-158.72 71.062-158.72 158.72C277.107 312.36 296.898 353.755 328.307 382.755z" p-id="5567"></path></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1682930466914" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7958" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M585.7 129.7C543.4 87.3 487.1 64 427.2 64c-59.9 0-116.2 23.3-158.6 65.7-42.4 42.3-65.7 98.7-65.7 158.5 0 59.9 23.3 116.2 65.7 158.5 15.6 15.6 33.1 28.6 51.9 38.8 1.5 0.8 3 1.6 4.5 2.3l-3.9 1.2c-11.9 3.6-23.7 7.9-35.2 12.8-43.2 18.3-82.1 44.5-115.4 77.8-33.5 33.4-59.7 72.2-78 115.5C73.6 739.9 64 787.4 64 836.4c0 16.4 13.3 29.8 29.8 29.8s29.8-13.3 29.8-29.8c0-143 99.4-263.3 232.8-295.3 22.7-5.5 46.4-8.3 70.8-8.3 28.2 0 56.1 4 83 11.6 19.8-12.6 33.9-30.1 39-50.1-6.6-2.3-13.2-4.5-19.8-6.4 7.5-3.9 14.8-8.2 21.9-12.9 12.3-8.2 23.8-17.6 34.5-28.3 42.4-42.3 65.7-98.7 65.7-158.5-0.1-59.9-23.4-116.2-65.8-158.5z m-61.5 291.5c-27.2 19.9-60.8 31.7-97 31.7-31.9 0-61.7-9.1-86.9-24.8-46.7-29.1-77.8-80.9-77.8-139.8 0-90.8 73.9-164.7 164.7-164.7 90.8 0 164.7 73.9 164.7 164.7 0 54.5-26.7 102.9-67.7 132.9z" p-id="7959"></path><path d="M880.4 500.7c-34.3-28.3-73.6-50.1-115.5-64.2 35.7-36.8 53.2-85.8 53.2-148.3 0-102.1-68.9-191.3-167.6-217-15.9-4.1-32.2 5.4-36.3 21.3-4.1 15.9 5.4 32.2 21.3 36.3 72.5 18.9 123.1 84.4 123.1 159.4 0 62.2-20.2 102.2-65.6 129.8-10.6 6.5-15.8 18.5-13.9 30.1-2.5 16 8.2 31.1 24.2 33.9 51 9.1 99.2 31.4 139.3 64.6 5.5 4.6 12.3 6.8 18.9 6.8 8.6 0 17.1-3.7 23-10.8 10.4-12.7 8.6-31.4-4.1-41.9z" p-id="7960"></path><path d="M795 729l165-196.5-193.7 162.3L601 498l-69 68.9L725.4 729 532 891.1l69 68.9 165.3-196.8L960 925.5z" p-id="7961"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1682929078680" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4539"
xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<path d="M931.07 384.75a368 368 0 0 0-704 95.25H64l192 192 192-192H288.91C312 333.51 439.12 221.13 592 221.13c169.21 0 306.87 137.66 306.87 306.87S761.21 834.87 592 834.87a307.37 307.37 0 0 1-194.56-69.55 30.57 30.57 0 0 0-38.79 47.25 368.1 368.1 0 0 0 572.42-427.82z"
p-id="4540"></path>
</svg>

After

Width:  |  Height:  |  Size: 648 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1682927770403" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2697" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M469.333333 768c-166.4 0-298.666667-132.266667-298.666666-298.666667s132.266667-298.666667 298.666666-298.666666 298.666667 132.266667 298.666667 298.666666-132.266667 298.666667-298.666667 298.666667z m0-85.333333c119.466667 0 213.333333-93.866667 213.333334-213.333334s-93.866667-213.333333-213.333334-213.333333-213.333333 93.866667-213.333333 213.333333 93.866667 213.333333 213.333333 213.333334z m251.733334 0l119.466666 119.466666-59.733333 59.733334-119.466667-119.466667 59.733334-59.733333z" p-id="2698"></path></svg>

After

Width:  |  Height:  |  Size: 860 B

View File

@@ -0,0 +1,398 @@
<template>
<div id="attendanceMain">
<div id="attendanceMain1">
<el-date-picker
v-model="attTime"
type="datetimerange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD HH:mm:ss"
>
</el-date-picker>
<el-button type="primary" style="margin-left: 15px" @click="getAttendancesByTime()">
<el-icon :size="SIZE_ICON_SM()" style="vertical-align: center">
<icon-pinnacle-search />
</el-icon>
<span style="vertical-align: center">查询</span>
</el-button>
<el-button type="warning" style="margin-left: 15px" @click="resetParam()">
<el-icon :size="SIZE_ICON_SM()" style="vertical-align: center">
<icon-pinnacle-reset />
</el-icon>
<span style="vertical-align: center">重置</span>
</el-button>
<el-button type="success" style="margin-left: 15px" @click="handleAdd()">
<el-icon :size="SIZE_ICON_SM()" style="vertical-align: center">
<icon-pinnacle-click />
</el-icon>
<span style="vertical-align: center">增加</span>
</el-button>
<el-popconfirm
title="你确定要批量删除这些数据吗?"
confirm-button-text="确定"
cancel-button-text="再想想"
icon-color="red"
@cancel="cancel"
@confirm="delBatch"
>
<template #reference>
<el-button type="danger" style="margin-left: 15px">
<el-icon :size="SIZE_ICON_SM()" style="vertical-align: center">
<icon-pinnacle-deleteAll />
</el-icon>
<span style="vertical-align: center">批量删除</span>
</el-button>
</template>
</el-popconfirm>
</div>
<div id="attendanceMain2">
<el-table
:data="tableData"
border
style="width: 80%"
:header-cell-style="{ background: 'aliceblue' }"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="考勤编号" width="200"></el-table-column>
<el-table-column prop="user.username" label="用户名" width="180"></el-table-column>
<el-table-column prop="attTime" label="考勤时间">
<template #default="scope">
{{ formatDate(scope.row.attTime) }}
</template>
</el-table-column>
<el-table-column prop="status" label="考勤状态">
<template v-slot="scope">
<el-tag
:type="
scope.row.status === 1
? 'success'
: scope.row.status === 2
? 'primary'
: scope.row.status === 3
? 'warning'
: 'danger'
"
disable-transitions
>{{
scope.row.status === 1
? '签到'
: scope.row.status === 2
? '签退'
: scope.row.status === 3
? '迟到'
: '异常'
}}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="operations" label="操作">
<template #default="scope">
<el-button type="success" size="small" @click="viewUpdate(scope.row)"
>更改
</el-button>
<el-popconfirm
title="您确定要删除吗?"
confirm-button-text="确定"
cancel-button-text="再想想"
icon-color="red"
@cancel="cancel"
@confirm="handleDelete(scope.row.id)"
>
<template #reference>
<el-button type="danger" size="small">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
<div>
<el-dialog v-model="dialogFormVisible" title="考勤信息" width="25%">
<el-form ref="ruleForm" :rules="rules" :model="form" :label-width="formLabelWidth">
<el-form-item label="用户编号" prop="userId">
<el-input v-model="form.userId" autocomplete="off" style="width: 200px" />
</el-form-item>
<el-form-item label="考勤状态" prop="status">
<el-select
v-model="form.status"
placeholder="请选择考勤状态"
style="width: 200px"
>
<el-option label="签到" value="1" />
<el-option label="签退" value="2" />
<el-option label="迟到" value="3" />
</el-select>
</el-form-item>
<el-form-item label="考勤时间" v-model="form.attTime" prop="attTime">
<div class="block">
<el-date-picker
v-model="form.attTime"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择考勤时间"
style="width: 200px"
/>
</div>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="submitForm">确认</el-button>
<el-button @click="cancel">取消</el-button>
</span>
</template>
</el-dialog>
</div>
</div>
</template>
<script lang="ts">
import axios from 'axios'
import { SIZE_ICON_SM, SIZE_ICON_XL } from '@/constants/Common.constants.js'
import { ElMessage } from 'element-plus'
import 'element-plus/theme-chalk/el-message.css'
import _ from 'lodash'
export default {
name: 'AttendanceHome',
data() {
return {
attendance: '',
id: '',
username: '',
attTime: [],
status: '',
pageNum: 1,
pageSize: 10,
total: 0,
multipleSelection: [],
formLabelWidth: '80px',
value1: '',
form: {
userId: '',
userName: '',
status: '',
attTime: ''
},
tableData: [],
dialogFormVisible: false,
rules: {
userId: [{ required: true, message: '请输入用户编号', trigger: 'change' }],
status: [{ required: true, message: '请选择考勤状态', trigger: 'change' }],
attTime: [{ required: true, message: '请选择考勤时间', trigger: 'change' }]
},
options: [
{
value: 1,
label: '签到'
},
{
value: 2,
label: '签退'
},
{
value: 3,
label: '迟到'
}
]
}
},
methods: {
SIZE_ICON_SM() {
return SIZE_ICON_SM
},
SIZE_ICON_XL() {
return SIZE_ICON_XL
},
formatDate(time) {
return new Date(time).toLocaleString()
},
// 获取所有考勤信息
getAttendances() {
axios
.get('http://localhost:8621/attendance/findAllAttendance')
.then((response) => {
console.log(response.data.data)
this.tableData = response.data.data
})
.catch((reportError) => {
console.log(reportError)
})
},
getAttendancesByTime() {
console.log(typeof this.attTime[0])
const start = this.handleDateFormatUTC(this.attTime[0])
const end = this.handleDateFormatUTC(this.attTime[1])
console.log(start + '\t' + end)
axios
.get('http://localhost:8621/attendance/findAttendanceByTime', {
params: {
startTime: start,
endTime: end
}
})
.then((response) => {
console.log(response.data.data)
this.tableData = response.data.data
ElMessage({
message: '查询成功',
type: 'success'
})
})
.catch((reportError) => {
console.log(reportError)
ElMessage({
message: '查询失败',
type: 'error'
})
})
},
handleDateFormatUTC(date) {
let newFormat = ''
const dateParse = new Date(Date.parse(date))
const yy = dateParse.getUTCFullYear()
const mm = _.padStart((dateParse.getUTCMonth() + 1).toString(), 2, '0')
const dd = _.padStart(dateParse.getUTCDate().toString(), 2, '0')
const hh = _.padStart(dateParse.getUTCHours().toString(), 2, '0')
const mf = _.padStart(dateParse.getUTCMinutes().toString(), 2, '0')
const ss = _.padStart(dateParse.getUTCSeconds().toString(), 2, '0')
newFormat = yy + '-' + mm + '-' + dd + ' ' + hh + ':' + mf + ':' + ss
return newFormat
},
// 重置参数
resetParam() {
this.attTime = []
this.status = ''
this.getAttendances()
ElMessage({
message: '重置成功',
type: 'success'
})
},
// 表单重置
resetForm() {
this.$nextTick(() => {
this.$refs.ruleForm.resetFields()
})
},
// 打开添加弹窗
handleAdd() {
this.dialogFormVisible = true
this.resetForm()
},
// 处理保存
doSave() {
axios
.post('http://localhost:8621/attendance/saveAttendance', this.form)
.then((response) => {
this.dialogFormVisible = false
this.getAttendances()
console.log(response.data.data)
})
.catch((reportError) => {
console.log(reportError)
})
},
// 获取更改数据
viewUpdate(row) {
this.dialogFormVisible = true
this.$nextTick(() => {
this.form = row
this.form.status = row.status + ''
})
},
// 点击取消
cancel() {
this.dialogFormVisible = false
ElMessage({
message: '取消操作',
type: 'warning'
})
this.getAttendances()
},
// 提交表单
submitForm() {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
this.doSave()
ElMessage({
message: '操作成功',
type: 'success'
})
} else {
ElMessage.error('操作失败')
return false
}
})
},
// 操作删除
handleDelete(id) {
console.log(id)
axios
.delete('http://localhost:8621/attendance/delAttendance/' + id)
.then((response) => {
if (response) {
ElMessage({
message: '删除成功',
type: 'success'
})
this.getAttendances()
} else {
ElMessage({
message: '删除失败',
type: 'error'
})
}
})
.catch((reportError) => {
console.log(reportError)
})
},
// 批量删除
handleSelectionChange(val) {
console.log(val)
this.multipleSelection = val
},
// 批量删除
delBatch() {
const map = this.multipleSelection.map((v) => v.id)
axios
.post('http://localhost:8621/attendance/delBatchAttendance', map)
.then((response) => {
if (response) {
ElMessage({
message: '批量删除成功',
type: 'success'
})
this.getAttendances()
} else {
ElMessage({
message: '批量删除失败',
type: 'error'
})
}
})
.catch((reportError) => {
console.log(reportError)
})
}
},
created() {
this.getAttendances()
}
}
</script>
<style scoped></style>

View File

@@ -0,0 +1,293 @@
<template>
<div id="attendanceMain">
<div id="attendanceMain1">
<el-date-picker
v-model="attTimeB"
type="datetimerange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD HH:mm:ss"
>
</el-date-picker>
<el-button type="primary" style="margin-left: 15px" @click="getOneAttendancesByTime()">
<el-icon :size="SIZE_ICON_SM()" style="vertical-align: center">
<icon-pinnacle-search />
</el-icon>
<span style="vertical-align: center">查询</span>
</el-button>
<el-button type="warning" style="margin-left: 15px" @click="resetParam()">
<el-icon :size="SIZE_ICON_SM()" style="vertical-align: center">
<icon-pinnacle-reset />
</el-icon>
<span style="vertical-align: center">重置</span>
</el-button>
<el-button type="success" @click="handleAdd()" style="margin-left: 15px">
<el-icon :size="SIZE_ICON_SM()" style="vertical-align: center">
<icon-pinnacle-click />
</el-icon>
<span style="vertical-align: center">打卡</span>
</el-button>
</div>
<div id="attendanceMain2">
<el-table
:data="tableData"
border
style="width: 80%"
:header-cell-style="{ background: 'aliceblue' }"
>
<el-table-column prop="id" label="考勤编号" width="400"></el-table-column>
<el-table-column prop="user.username" label="用户名" width="180"></el-table-column>
<el-table-column prop="attTime" label="考勤时间">
<template #default="scope">
{{ formatDate(scope.row.attTime) }}
</template>
</el-table-column>
<el-table-column prop="status" label="考勤状态">
<template v-slot="scope">
<el-tag
:type="
scope.row.status === 1
? 'success'
: scope.row.status === 2
? 'primary'
: scope.row.status === 3
? 'warning'
: 'danger'
"
disable-transitions
>{{
scope.row.status === 1
? '签到'
: scope.row.status === 2
? '签退'
: scope.row.status === 3
? '迟到'
: '异常'
}}
</el-tag>
</template>
</el-table-column>
</el-table>
</div>
<div class="demo-pagination-block">
<el-pagination
small
:current-page="pageNum"
:page-size="pageSize"
:page-sizes="[5, 10, 20, 30]"
background
layout="total,sizes,prev, pager, next,jumper"
:total="total"
/>
</div>
<div>
<el-dialog v-model="dialogFormVisible" title="考勤信息" width="25%">
<el-form ref="ruleForm" :rules="rules" :model="form" :label-width="formLabelWidth">
<el-form-item label="用户编号" prop="userId">
<el-input
v-model="form.userId"
autocomplete="off"
style="width: 200px"
disabled
/>
</el-form-item>
<el-form-item label="考勤时间" v-model="attTime" prop="attTime">
<div class="block">
<el-date-picker
v-model="nowTime"
type="datetime"
disabled
style="width: 200px"
/>
</div>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="submitForm()">确认</el-button>
<el-button @click="cancel">取消</el-button>
</span>
</template>
</el-dialog>
</div>
</div>
</template>
<script lang="ts">
import axios from 'axios'
import { SIZE_ICON_SM, SIZE_ICON_XL } from '@/constants/Common.constants.js'
import { ElMessage } from 'element-plus'
import 'element-plus/theme-chalk/el-message.css'
import _ from 'lodash'
export default {
name: 'UserAttendance',
data() {
return {
attendance: '',
id: '',
userId: 1,
username: '',
attTime: '',
attTimeB: [],
status: '',
pageNum: 1,
pageSize: 10,
total: 0,
nowTime: new Date(),
formLabelWidth: '80px',
value1: '',
form: {
userId: '',
userName: '',
status: '',
attTime: new Date()
},
tableData: [],
dialogFormVisible: false,
rules: {
userId: [{ required: true, message: '请输入用户编号', trigger: 'change' }],
attTime: [{ required: true, message: '请选择考勤时间', trigger: 'change' }]
}
}
},
methods: {
SIZE_ICON_SM() {
return SIZE_ICON_SM
},
SIZE_ICON_XL() {
return SIZE_ICON_XL
},
formatDate(time) {
return new Date(time).toLocaleString()
},
handleDateFormatUTC(date) {
let newFormat = ''
const dateParse = new Date(Date.parse(date))
const yy = dateParse.getUTCFullYear()
const mm = _.padStart((dateParse.getUTCMonth() + 1).toString(), 2, '0')
const dd = _.padStart(dateParse.getUTCDate().toString(), 2, '0')
const hh = _.padStart(dateParse.getUTCHours().toString(), 2, '0')
const mf = _.padStart(dateParse.getUTCMinutes().toString(), 2, '0')
const ss = _.padStart(dateParse.getUTCSeconds().toString(), 2, '0')
newFormat = yy + '-' + mm + '-' + dd + ' ' + hh + ':' + mf + ':' + ss
return newFormat
},
// 重置参数
resetParam() {
this.attTimeB = []
this.status = ''
this.getAttendancesByUserId()
ElMessage({
message: '重置成功',
type: 'success'
})
},
getOneAttendancesByTime() {
console.log(typeof this.attTimeB[0])
const start = this.handleDateFormatUTC(this.attTimeB[0])
const end = this.handleDateFormatUTC(this.attTimeB[1])
console.log(start + '\t' + end)
axios
.get('http://localhost:8621/attendance/findOneAttendanceByTime', {
params: {
startTime: start,
endTime: end,
userId: this.userId
}
})
.then((response) => {
console.log(response.data.data)
this.tableData = response.data.data
ElMessage({
message: '查询成功',
type: 'success'
})
})
.catch((reportError) => {
console.log(reportError)
ElMessage({
message: '查询失败',
type: 'error'
})
this.getAttendancesByUserId()
})
},
getAttendancesByUserId() {
axios
.get('http://localhost:8621/attendance/selectAttendance/' + this.userId)
.then((response) => {
console.log(response.data.data)
this.tableData = response.data.data
})
.catch((reportError) => {
console.log(reportError)
})
},
resetForm() {
this.$refs.form.resetFields()
},
handleAdd() {
this.dialogFormVisible = true
// this.getNowDate()
this.nowTime = new Date()
this.form.attTime = this.nowTime
this.$nextTick(() => {
this.form.userId = this.userId + ''
})
},
doSave() {
axios
.post('http://localhost:8621/attendance/saveOneAttendance', this.form)
.then((response) => {
this.dialogFormVisible = false
this.getAttendancesByUserId()
console.log(response.data.data)
})
.catch((reportError) => {
console.log(reportError)
})
},
submitForm() {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
console.log(this.form.attTime)
this.doSave()
ElMessage({
message: '操作成功',
type: 'success'
})
} else {
ElMessage.error('操作失败')
return false
}
})
},
// 点击取消
cancel() {
this.dialogFormVisible = false
ElMessage({
message: '取消操作',
type: 'warning'
})
this.getAttendancesByUserId()
}
},
created() {
this.getAttendancesByUserId()
}
}
</script>
<style scoped></style>