Merge branch 'dev' into frx
This commit is contained in:
commit
644fc15bc1
@ -62,7 +62,9 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
||||
"work_log_use",
|
||||
"work_log_statistics",
|
||||
"work_log_instance_ext",
|
||||
"bpm_oa_work_task"
|
||||
"bpm_oa_work_task",
|
||||
"zc_dept_assets",
|
||||
"zc_dept_assets_in_out_stock"
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -9,6 +9,8 @@ import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.annotation.security.PermitAll;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - 文件")
|
||||
public interface ConfigApi {
|
||||
@ -18,6 +20,7 @@ public interface ConfigApi {
|
||||
@GetMapping(value = "/get-value-by-key")
|
||||
@Operation(summary = "根据参数键名查询参数值", description = "不可见的配置,不允许返回给前端")
|
||||
@Parameter(name = "key", description = "参数键", required = true, example = "yunai.biz.username")
|
||||
@PermitAll
|
||||
CommonResult<String> getConfigKey(@RequestParam("key") String key);
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - 微信小程序订阅消息发送")
|
||||
public interface SubscribeMessageSendApi {
|
||||
@ -30,4 +32,8 @@ public interface SubscribeMessageSendApi {
|
||||
@PostMapping(PREFIX + "/send-worklog-comment")
|
||||
@Operation(summary = "发送日志评论、回复通知")
|
||||
CommonResult<Long> sendWorkLogComment(@RequestBody SubscribeMessageReqDTO reqDTO);
|
||||
|
||||
@PostMapping(PREFIX + "/send-punch-reminder")
|
||||
@Operation(summary = "发送打卡提醒通知")
|
||||
CommonResult<Long> sendPunchReminder(@RequestBody SubscribeMessageReqDTO reqDTO);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.system.api.subscribe.dto.MsgData;
|
||||
import cn.iocoder.yudao.module.system.api.subscribe.dto.SubscribeMessageReqDTO;
|
||||
import cn.iocoder.yudao.module.system.service.social.SocialClientService;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@ -22,6 +23,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
*/
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class SubscribeMessageSendApiImpl implements SubscribeMessageSendApi {
|
||||
|
||||
@Resource
|
||||
@ -55,6 +57,16 @@ public class SubscribeMessageSendApiImpl implements SubscribeMessageSendApi {
|
||||
return success(1L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Long> sendPunchReminder(SubscribeMessageReqDTO reqDTO) {
|
||||
try {
|
||||
socialClientService.getWxMaService().getMsgService().sendSubscribeMsg(initWxMaSubscribeMessage(reqDTO));
|
||||
} catch (Exception e) {
|
||||
log.error("当前用户没有订阅考勤消息:{}", reqDTO.getToUser());
|
||||
}
|
||||
return success(1L);
|
||||
}
|
||||
|
||||
private WxMaSubscribeMessage initWxMaSubscribeMessage(SubscribeMessageReqDTO reqDTO) {
|
||||
WxMaSubscribeMessage message = WxMaSubscribeMessage.builder()
|
||||
.toUser(reqDTO.getToUser())
|
||||
|
@ -73,7 +73,6 @@ public class AssetsController {
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得资产分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:assets:query')")
|
||||
public CommonResult<PageResult<AssetsRespVO>> getAssetsPage(@Valid AssetsPageReqVO pageReqVO) {
|
||||
PageResult<AssetsDO> pageResult = assetsService.getAssetsPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, AssetsRespVO.class));
|
||||
|
@ -81,7 +81,6 @@ public class AssetsSecondmentController {
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得资产借调分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:assets-secondment:query')")
|
||||
public CommonResult<PageResult<AssetsSecondmentRespVO>> getAssetsSecondmentPage(@Valid AssetsSecondmentPageReqVO pageReqVO) {
|
||||
PageResult<AssetsSecondmentRespVO> pageResult = assetsSecondmentService.getAssetsSecondmentPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, AssetsSecondmentRespVO.class));
|
||||
|
@ -24,6 +24,10 @@ public class AssetsSecondmentRecordRespVO {
|
||||
@ExcelProperty("资产名称")
|
||||
private String assetsName;
|
||||
|
||||
@Schema(description = "资产编号", example = "13886")
|
||||
@ExcelProperty("资产编号")
|
||||
private String assetsNo;
|
||||
|
||||
@Schema(description = "使用人id", example = "12905")
|
||||
@ExcelProperty("使用人id")
|
||||
private Long useUserId;
|
||||
|
@ -0,0 +1,16 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.attendance.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AttendanceWorkDTO {
|
||||
|
||||
@Schema(description = "上下班")
|
||||
private String workTypeStr;
|
||||
|
||||
@Schema(description = "内容")
|
||||
private String data;
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.attendance.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AttendanceExportExcelByCycleVO {
|
||||
@Schema(description = "用户名称")
|
||||
private String name;
|
||||
@Schema(description = "考勤组名称")
|
||||
private String groupName;
|
||||
@Schema(description = "部门名称")
|
||||
private String deptName;
|
||||
@Schema(description = "职位名称")
|
||||
private String postName;
|
||||
@Schema(description = "出勤天数")
|
||||
private String attendanceDays;
|
||||
@Schema(description = "休息天数")
|
||||
private String restDays;
|
||||
@Schema(description = "工作时长")
|
||||
private String lengthOfWork;
|
||||
@Schema(description = "迟到次数")
|
||||
private String lateNum;
|
||||
@Schema(description = "迟到时长")
|
||||
private String lateTime;
|
||||
@Schema(description = "早退次数")
|
||||
private String leaveEarlyNum;
|
||||
@Schema(description = "早退时长")
|
||||
private String leaveEarlyTime;
|
||||
@Schema(description = "上班缺卡次数")
|
||||
private String upMissingCardsNum;
|
||||
@Schema(description = "下班缺卡次数")
|
||||
private String downMissingCardsNum;
|
||||
@Schema(description = "旷工天数")
|
||||
private String absenteeismNum;
|
||||
// @Schema(description = "出差时长")
|
||||
// private String onBusinessTripTime;
|
||||
// @Schema(description = "加班-审批单统计")
|
||||
// private String overtimeApprovalOrderStatistics;
|
||||
|
||||
|
||||
@Data
|
||||
public class OvertimeVO {
|
||||
@Schema(description = "工作日加班")
|
||||
private String workingOvertimeOnWorkingDays;
|
||||
@Schema(description = "休息日加班")
|
||||
private String workOvertimeOnRestDays;
|
||||
@Schema(description = "节假日加班")
|
||||
private String workOvertimeOnHolidays;
|
||||
}
|
||||
}
|
@ -13,6 +13,8 @@ import java.util.List;
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AttendancePunchPageVO {
|
||||
@Schema(description = "考勤组id")
|
||||
private Long attendanceGroupId;
|
||||
@Schema(description = "是否在考勤组 0否 1是")
|
||||
private Integer inGroup = 1;
|
||||
@Schema(description = "当天是否需要考勤 0否 1是")
|
||||
|
@ -13,4 +13,6 @@ public class RoleSimpleRespVO {
|
||||
@Schema(description = "角色名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "角色编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "admin")
|
||||
private String code;
|
||||
}
|
||||
|
@ -78,6 +78,9 @@ public class AttendancePunchRecordSaveReqVO {
|
||||
@Schema(description = "早退时长时间戳")
|
||||
private Long leaveEarlyTime;
|
||||
|
||||
@Schema(description = "加班时长时间戳")
|
||||
private Long workOvertimeTime;
|
||||
|
||||
|
||||
/**
|
||||
* 打卡类型(0上班卡 1下班卡 2迟到卡 3早退卡 4未到打卡时间) 转 打卡状态 0正常 1迟到 2早退 3缺卡 4未打卡(还没到打卡时间) 5补卡
|
||||
|
@ -3,7 +3,9 @@ package cn.iocoder.yudao.module.system.controller.admin.user;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSimpleRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
|
||||
@ -73,6 +75,18 @@ public class UserProfileController {
|
||||
return success(UserConvert.INSTANCE.convert(user, userRoles, dept, posts, socialUsers));
|
||||
}
|
||||
|
||||
@GetMapping("/getRoles")
|
||||
@Operation(summary = "获得登录用户角色信息")
|
||||
@DataPermission(enable = false) // 关闭数据权限,避免只查看自己时,查询不到部门。
|
||||
public CommonResult<List<RoleSimpleRespVO>> getRoles() {
|
||||
// 获得用户基本信息
|
||||
AdminUserDO user = userService.getUser(getLoginUserId());
|
||||
// 获得用户角色
|
||||
List<RoleDO> userRoles = roleService.getRoleListFromCache(permissionService.getUserRoleIdListByUserId(user.getId()));
|
||||
List<RoleSimpleRespVO> bean = BeanUtils.toBean(userRoles, RoleSimpleRespVO.class);
|
||||
return success(bean);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改用户个人信息")
|
||||
public CommonResult<Boolean> updateUserProfile(@Valid @RequestBody UserProfileUpdateReqVO reqVO) {
|
||||
|
@ -124,4 +124,14 @@ public class AttendancePunchRecordDO extends BaseDO {
|
||||
* 早退时长时间戳
|
||||
*/
|
||||
private Long leaveEarlyTime;
|
||||
|
||||
/**
|
||||
* 加班时长时间戳
|
||||
*/
|
||||
private Long workOvertimeTime;
|
||||
|
||||
/**
|
||||
* 是否已提醒 0否 1是
|
||||
*/
|
||||
private Integer remindFlag;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.system.framework.datapermission.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.assets.DeptAssetsDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.worklog.LogInstanceDO;
|
||||
@ -24,13 +25,13 @@ public class DataPermissionConfiguration {
|
||||
rule.addDeptColumn(LogUseDO.class, "use_user_dept");
|
||||
rule.addDeptColumn(LogStatisticsDO.class, "dept_id");
|
||||
rule.addDeptColumn(LogInstanceDO.class, "dept_id");
|
||||
rule.addDeptColumn(DeptAssetsDO.class, "dept_id");
|
||||
|
||||
// user
|
||||
rule.addUserColumn(AdminUserDO.class, "id");
|
||||
rule.addUserColumn(LogUseDO.class, "use_user_id");
|
||||
rule.addUserColumn(LogStatisticsDO.class, "user_id");
|
||||
rule.addUserColumn(LogInstanceDO.class, "start_user_id");
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,131 @@
|
||||
package cn.iocoder.yudao.module.system.job.attendance;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.BetweenFormatter;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.Constants;
|
||||
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
|
||||
import cn.iocoder.yudao.module.system.api.subscribe.SubscribeMessageSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.subscribe.dto.MsgData;
|
||||
import cn.iocoder.yudao.module.system.api.subscribe.dto.SubscribeMessageReqDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.attendance.dto.AttendanceWorkDTO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.attendance.punchrecord.AttendancePunchRecordDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.service.attendance.punchrecord.AttendancePunchRecordService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RemindJob {
|
||||
@Resource
|
||||
private AttendancePunchRecordService attendancePunchRecordService;
|
||||
@Resource
|
||||
private SubscribeMessageSendApi subscribeMessageSendApi;
|
||||
@Resource
|
||||
private AdminUserService adminUserService;
|
||||
|
||||
// TODO: 2024/4/22 - 考勤提醒 每10分钟执行一次
|
||||
@XxlJob("remindJob")
|
||||
@TenantJob // --- ⚠️ 这个注解 会将租户列表拉出来 完了后逐个租户执行 定时任务需要注意
|
||||
public ReturnT<String> execute() throws Exception {
|
||||
// -- 获取当天以及明天的未打卡并且未提醒记录
|
||||
//未提醒列表
|
||||
LocalDateTime localDateTime = LocalDateTime.now();
|
||||
LocalDateTime futureTime = localDateTime.plusMinutes(15);
|
||||
|
||||
List<AttendancePunchRecordDO> attendancePunchRecordDOS = attendancePunchRecordService.getNotReminded(localDateTime);
|
||||
if (attendancePunchRecordDOS.isEmpty()) {
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
//还有10分钟就要上班了,别忘记打卡哦~
|
||||
//幸苦一天了,研发部全体人员提醒您,记得打卡哦~
|
||||
|
||||
Map<Long, AttendanceWorkDTO> map = new HashMap<>();
|
||||
//打卡时间 - 15分钟之后是否是 大于打卡时间 - 是的话 - 把用户id拿出来 组装好消息发送
|
||||
List<AttendancePunchRecordDO> editList = new ArrayList<>();
|
||||
for (AttendancePunchRecordDO attendancePunchRecordDO : attendancePunchRecordDOS) {
|
||||
if (attendancePunchRecordDO.getWorkType().equals(Constants.ZERO) && futureTime.isAfter(attendancePunchRecordDO.getShouldPunchTime())) {
|
||||
AttendanceWorkDTO dto = new AttendanceWorkDTO();
|
||||
dto.setWorkTypeStr("上班打卡");
|
||||
dto.setData(String.format("还有%s钟就要上班了,别忘记打卡哦~",
|
||||
DateUtil.formatBetween(LocalDateTimeUtil.between(localDateTime, attendancePunchRecordDO.getShouldPunchTime()).toMillis(), BetweenFormatter.Level.MINUTE)));
|
||||
map.put(attendancePunchRecordDO.getUserId(), dto);
|
||||
attendancePunchRecordDO.setRemindFlag(Constants.TRUE);
|
||||
editList.add(attendancePunchRecordDO);
|
||||
} else if (attendancePunchRecordDO.getWorkType().equals(Constants.ONE) && localDateTime.isAfter(attendancePunchRecordDO.getShouldPunchTime())) {
|
||||
AttendanceWorkDTO dto = new AttendanceWorkDTO();
|
||||
dto.setWorkTypeStr("下班打卡");
|
||||
dto.setData("工作幸苦了,记得打卡哦~");
|
||||
map.put(attendancePunchRecordDO.getUserId(), dto);
|
||||
attendancePunchRecordDO.setRemindFlag(Constants.TRUE);
|
||||
editList.add(attendancePunchRecordDO);
|
||||
}
|
||||
}
|
||||
//获取到所有的用户id
|
||||
if (MapUtil.isEmpty(map)) {
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
List<Long> userIds = new ArrayList<>(map.keySet());
|
||||
List<AdminUserDO> userList = adminUserService.getUserList(userIds);
|
||||
List<AdminUserDO> users = userList.stream().filter(a -> StrUtil.isNotEmpty(a.getOpenId())).collect(Collectors.toList());
|
||||
String templateId = "5yHyXhrsyqXi8s4hYhvaeMtz9kT5OPvDCe3h6G1T-OE";
|
||||
List<SubscribeMessageReqDTO> dtos = new ArrayList<>();
|
||||
for (AdminUserDO user : users) {
|
||||
AttendanceWorkDTO attendanceWorkDTO = map.get(user.getId());
|
||||
SubscribeMessageReqDTO dto = new SubscribeMessageReqDTO();
|
||||
dto.setToUser(user.getOpenId());
|
||||
dto.setTemplateId(templateId);
|
||||
MsgData data = new MsgData();
|
||||
data.setName("thing9");
|
||||
data.setValue(attendanceWorkDTO.getWorkTypeStr());
|
||||
dto.addData(data);
|
||||
data = new MsgData();
|
||||
data.setName("thing6");
|
||||
data.setValue(attendanceWorkDTO.getData());
|
||||
dto.addData(data);
|
||||
dto.setPage("subPages/attendance/index");
|
||||
dtos.add(dto);
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(dtos)) {
|
||||
for (SubscribeMessageReqDTO dto : dtos) {
|
||||
subscribeMessageSendApi.sendPunchReminder(dto);
|
||||
}
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(editList)) {
|
||||
attendancePunchRecordService.batchUpdate(editList);
|
||||
}
|
||||
// 返回执行成功
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.system.job.equipment;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
|
||||
import cn.iocoder.yudao.framework.websocket.core.session.WebSocketSessionManager;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.AttendanceMachineDO;
|
||||
@ -32,18 +33,15 @@ public class AttendanceMachineJob {
|
||||
// 获得所有在线的设备
|
||||
List<AttendanceMachineDO> attendanceMachineDOS = attendanceMachineService.getListByStatus();
|
||||
for (AttendanceMachineDO reqDO : attendanceMachineDOS) {
|
||||
|
||||
// redis数据不存在,则为离线状态
|
||||
if (stringRedisTemplate.opsForValue().get(reqDO.getDeviceNo()) == null) {
|
||||
|
||||
String data = stringRedisTemplate.opsForValue().get(reqDO.getDeviceNo());
|
||||
if (StrUtil.isEmpty(data)) {
|
||||
attendanceMachineService.updateAttendanceMachineStatus(reqDO.getDeviceNo(), 0, null);
|
||||
|
||||
//同步 删除对应sessionId
|
||||
WebSocketSessionManager webSocketSessionManager = SpringContentUtils.getBean(WebSocketSessionManager.class);
|
||||
webSocketSessionManager.removeSession(webSocketSessionManager.getSessionByDeviceNum(reqDO.getDeviceNo()));
|
||||
}else {
|
||||
|
||||
attendanceMachineService.updateAttendanceMachineStatus(reqDO.getDeviceNo(), 1, stringRedisTemplate.opsForValue().get(reqDO.getDeviceNo()));
|
||||
} else {
|
||||
attendanceMachineService.updateAttendanceMachineStatus(reqDO.getDeviceNo(), 1, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,11 +112,10 @@ public class DeptAssetsInOutStockServiceImpl implements DeptAssetsInOutStockServ
|
||||
// - 如果是部门入库 则更新该部门的资产
|
||||
List<DeptAssetsInOutStockSaveReqVO> stockSaveReqVOS = inOutStockByDeptMap.get(vo.getInDeptId());
|
||||
if (!stockSaveReqVOS.isEmpty()) {
|
||||
Integer num = 0;
|
||||
for (DeptAssetsInOutStockSaveReqVO stockSaveReqVO : stockSaveReqVOS) {
|
||||
num += stockSaveReqVO.getNum();
|
||||
Map<Long, Integer> stockSaveMaps = stockSaveReqVOS.stream().collect(Collectors.groupingBy(DeptAssetsInOutStockSaveReqVO::getAssetsId, Collectors.summingInt(DeptAssetsInOutStockSaveReqVO::getNum)));
|
||||
for (Map.Entry<Long, Integer> entry : stockSaveMaps.entrySet()) {
|
||||
deptInStockMap.put(vo.getInDeptId() + "_" + entry.getKey(), entry.getValue());
|
||||
}
|
||||
deptInStockMap.put(vo.getInDeptId() + "_" + vo.getAssetsId(), num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,6 +163,7 @@ public class AttendanceServiceImpl implements AttendanceService {
|
||||
//取绝对值 如果status是负数则变为正数
|
||||
.setLateTime(Constants.ONE.equals(status) ? Math.abs(LocalDateTimeUtil.between(dto.getLocalDateTime(), pageVO.getShouldPunchTime(), ChronoUnit.MILLIS)) : 0L)
|
||||
.setLeaveEarlyTime(Constants.TWO.equals(status) ? Math.abs(LocalDateTimeUtil.between(dto.getLocalDateTime(), pageVO.getShouldPunchTime(), ChronoUnit.MILLIS)) : 0L)
|
||||
.setWorkOvertimeTime(Constants.ZERO.equals(status) && Constants.ONE.equals(pageVO.getPunchType()) ? Math.abs(LocalDateTimeUtil.between(dto.getLocalDateTime(), pageVO.getShouldPunchTime(), ChronoUnit.MILLIS)) : 0L)
|
||||
.setRemark(dto.getRemark())
|
||||
.setImage(dto.getImage())
|
||||
.setPunchAddress(dto.getPunchAddress());
|
||||
@ -214,10 +215,17 @@ public class AttendanceServiceImpl implements AttendanceService {
|
||||
Boolean flag = stringRedisTemplate.hasKey(key);
|
||||
// 缓存不存在
|
||||
if (Boolean.FALSE.equals(flag)) {
|
||||
String url = "https://cdn.jsdelivr.net/gh/NateScarlet/holiday-cn@master/" + year + ".json";
|
||||
String json = HttpUtil.get(url, 0);
|
||||
String url = "https://timor.tech/api/holiday/year/" + year;
|
||||
String json = HttpUtil.get(url, 3000);
|
||||
Map<String, String> map = new HashMap<>();
|
||||
JSONObject jsonObject = JSONUtil.parseObj(json);
|
||||
Map<String, String> map = jsonObject.getBeanList("days", HolidayVO.class).stream().collect(Collectors.toMap(HolidayVO::getDate, HolidayVO::getIsOffDay));
|
||||
Object o = jsonObject.get("holiday");
|
||||
//将o转为json对象并且循环获取对象中所有的属性
|
||||
JSONObject data = JSONUtil.parseObj(o);
|
||||
data.forEach((k, v) -> {
|
||||
JSONObject item = JSONUtil.parseObj(v);
|
||||
map.put(item.get("date").toString(), item.get("holiday").toString());
|
||||
});
|
||||
stringRedisTemplate.opsForHash().putAll(key, map);
|
||||
// -- 删除去年的
|
||||
String lastKey = "holiday_" + (Integer.parseInt(year) - 1);
|
||||
@ -753,9 +761,6 @@ public class AttendanceServiceImpl implements AttendanceService {
|
||||
@Override
|
||||
public void exportAttendanceExcel(HttpServletResponse response, ExportAttendanceExcelDTO dto) {
|
||||
|
||||
// 导出 Excel
|
||||
// ExcelUtils.write(response, "考勤组人员.xls", "数据", AttendanceGroupUserRespVO.class,
|
||||
// BeanUtils.toBean(list, AttendanceGroupUserRespVO.class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,6 +234,7 @@ public class AttendanceFixedServiceImpl implements AttendanceFixedService, Punch
|
||||
}
|
||||
vo.setAttendanceGroupShiftId(attendanceFixedDO.getAttendanceGroupShiftId());
|
||||
attendanceService.calculatePunch(dto, vo);
|
||||
vo.setAttendanceGroupId(activationGroup.getId());
|
||||
return vo;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.attendance.groupshiftitem.Attend
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.attendance.punchrecord.AttendancePunchRecordMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.attendance.scheduling.AttendanceSchedulingMapper;
|
||||
import cn.iocoder.yudao.module.system.service.attendance.group.AttendanceGroupService;
|
||||
import cn.iocoder.yudao.module.system.service.attendance.punch.dto.AttendanceOnTheDayDTO;
|
||||
import cn.iocoder.yudao.module.system.service.attendance.punchrecord.AttendancePunchRecordService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
@ -248,7 +249,10 @@ public class AttendanceGroupShiftServiceImpl implements AttendanceGroupShiftServ
|
||||
// -- 删除当前考勤组预留的考勤记录
|
||||
attendancePunchRecordMapper.delete(new LambdaQueryWrapper<AttendancePunchRecordDO>()
|
||||
.in(AttendancePunchRecordDO::getAttendanceGroupId, groupIds)
|
||||
.eq(AttendancePunchRecordDO::getNextDayFlag, Constants.TRUE));
|
||||
.and(a -> a.eq(AttendancePunchRecordDO::getNextDayFlag, Constants.TRUE)
|
||||
.or()
|
||||
.eq(AttendancePunchRecordDO::getStatus, AttendanceOnTheDayDTO.PUNCH_STATUS_UN_PUNCH))
|
||||
);
|
||||
// -- 重新计算 - 插入到redis 和数据中
|
||||
attendancePunchRecordService.defaultPersistence(groupIds, LocalDateTime.now());
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.attendance.groupuser.Attend
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.attendance.punchrecord.AttendancePunchRecordDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.attendance.groupuser.AttendanceGroupUserMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.attendance.punchrecord.AttendancePunchRecordMapper;
|
||||
import cn.iocoder.yudao.module.system.service.attendance.punch.dto.AttendanceOnTheDayDTO;
|
||||
import cn.iocoder.yudao.module.system.service.attendance.punchrecord.AttendancePunchRecordService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
@ -130,7 +131,10 @@ public class AttendanceGroupUserServiceImpl implements AttendanceGroupUserServic
|
||||
attendancePunchRecordMapper.delete(new LambdaQueryWrapper<AttendancePunchRecordDO>()
|
||||
.eq(AttendancePunchRecordDO::getAttendanceGroupId, vo.getAttendanceGroupId())
|
||||
.in(AttendancePunchRecordDO::getUserId, vo.getDelUserIds())
|
||||
.eq(AttendancePunchRecordDO::getNextDayFlag, Constants.TRUE));
|
||||
.and(a -> a.eq(AttendancePunchRecordDO::getNextDayFlag, Constants.TRUE)
|
||||
.or()
|
||||
.eq(AttendancePunchRecordDO::getStatus, AttendanceOnTheDayDTO.PUNCH_STATUS_UN_PUNCH))
|
||||
);
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(vo.getSaveUserIds())) {
|
||||
attendancePunchRecordService.defaultPersistence(vo.getAttendanceGroupId(), vo.getSaveUserIds(), LocalDateTime.now());
|
||||
|
@ -68,6 +68,7 @@ public interface AttendancePunchRecordService {
|
||||
|
||||
/**
|
||||
* 预设考勤
|
||||
*
|
||||
* @param groupId
|
||||
* @param userIds
|
||||
* @param localDateTime
|
||||
@ -96,4 +97,18 @@ public interface AttendancePunchRecordService {
|
||||
*/
|
||||
void defaultPersistence(Map<Long, Long> map, Map<Long, AttendanceGroupDO> groupMap, Map<Long, List<Long>> groupUserMap,
|
||||
Map<Long, List<AttendanceGroupShiftItemDO>> itemMaps, String time, LocalDateTime localDateTime);
|
||||
|
||||
/**
|
||||
* 获取未提醒列表 获取当天的未打卡并且未提醒记录
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<AttendancePunchRecordDO> getNotReminded(LocalDateTime localDateTime);
|
||||
|
||||
/**
|
||||
* 批量更新
|
||||
*
|
||||
* @param editList
|
||||
*/
|
||||
void batchUpdate(List<AttendancePunchRecordDO> editList);
|
||||
}
|
@ -153,6 +153,7 @@ public class AttendancePunchRecordServiceImpl implements AttendancePunchRecordSe
|
||||
}
|
||||
this.defaultPersistence(attendanceGroupDOS, attendanceGroupUserDOS, localDateTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defaultPersistence(List<AttendanceGroupDO> attendanceGroupDOS, List<AttendanceGroupUserDO> attendanceGroupUserDOS, LocalDateTime localDateTime) {
|
||||
// 获取所有考勤组
|
||||
@ -231,6 +232,20 @@ public class AttendancePunchRecordServiceImpl implements AttendancePunchRecordSe
|
||||
this.saveBatch(attendancePunchRecordDOList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AttendancePunchRecordDO> getNotReminded(LocalDateTime localDateTime) {
|
||||
String targetDayStr = localDateTime.format(Constants.REPO_DATE_FORMAT);
|
||||
return punchRecordMapper.selectList(new LambdaQueryWrapper<AttendancePunchRecordDO>()
|
||||
.eq(AttendancePunchRecordDO::getDayTime, targetDayStr)
|
||||
.eq(AttendancePunchRecordDO::getStatus, AttendanceOnTheDayDTO.PUNCH_STATUS_UN_PUNCH)
|
||||
.eq(AttendancePunchRecordDO::getRemindFlag, Constants.FALSE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchUpdate(List<AttendancePunchRecordDO> editList) {
|
||||
punchRecordMapper.updateBatch(editList);
|
||||
}
|
||||
|
||||
private Map<Long, Long> getAttendanceGroupShiftIdGroupByGroup(List<AttendanceGroupDO> attendanceGroupDOS, LocalDateTime localDateTime) {
|
||||
Map<Long, Long> map = new HashMap<>();
|
||||
List<AttendanceGroupDO> fixedList = attendanceGroupDOS.stream().filter(a -> a.getType().equals(1)).collect(Collectors.toList());
|
||||
|
@ -229,6 +229,7 @@ public class AttendanceSchedulingServiceImpl implements AttendanceSchedulingServ
|
||||
}
|
||||
vo.setAttendanceGroupShiftId(attendanceSchedulingDO.getAttendanceGroupShiftId());
|
||||
attendanceService.calculatePunch(dto, vo);
|
||||
vo.setAttendanceGroupId(activationGroup.getId());
|
||||
return vo;
|
||||
}
|
||||
|
||||
|
@ -111,10 +111,9 @@ public class AttendanceMachineServiceImpl implements AttendanceMachineService {
|
||||
|
||||
@Override
|
||||
public void updateAttendanceMachineStatus(String deviceNo, Integer status, String dateTime) {
|
||||
|
||||
AttendanceMachineDO updateDO = new AttendanceMachineDO();
|
||||
updateDO.setStatus(status);
|
||||
updateDO.setUpdater(getLoginUserId().toString());
|
||||
// updateDO.setUpdater(getLoginUserId().toString());
|
||||
if (status == 1) {
|
||||
updateDO.setRequestTime(LocalDateTime.parse(dateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
}
|
||||
@ -130,7 +129,7 @@ public class AttendanceMachineServiceImpl implements AttendanceMachineService {
|
||||
if (attendanceMachineDO == null) {
|
||||
|
||||
throw exception(ATTENDANCE_MACHINE_NOT_EXISTS);
|
||||
}else {
|
||||
} else {
|
||||
|
||||
if (!passwordEncoder.matches(updateReqVO.getOldPassword(), attendanceMachineDO.getPassword())) {
|
||||
|
||||
@ -221,7 +220,7 @@ public class AttendanceMachineServiceImpl implements AttendanceMachineService {
|
||||
|
||||
deviceNo = new ArrayList<>();
|
||||
deviceNo.add(addReqVO.getDeviceNo());
|
||||
}else {
|
||||
} else {
|
||||
|
||||
if (!deviceNo.contains(addReqVO.getDeviceNo())) {
|
||||
|
||||
@ -232,7 +231,7 @@ public class AttendanceMachineServiceImpl implements AttendanceMachineService {
|
||||
//设备 用户绑定设备
|
||||
data.setAttendanceMachineNos(deviceNo);
|
||||
});
|
||||
}else if (addReqVO.getMethod() == 1) {
|
||||
} else if (addReqVO.getMethod() == 1) {
|
||||
|
||||
usersExtDO.forEach(data -> {
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
SELECT
|
||||
a.id,
|
||||
a.util,
|
||||
a.assets_no,
|
||||
a.item_json,
|
||||
a.name,
|
||||
a.amount,
|
||||
@ -57,6 +58,9 @@
|
||||
<if test="reqVO.assetsNo != null and reqVO.assetsNo != ''">
|
||||
and a.assets_no like concat('%', #{reqVO.keyWord}, '%')
|
||||
</if>
|
||||
<if test="reqVO.typeId != null">
|
||||
and a.type_id = #{reqVO.typeId}
|
||||
</if>
|
||||
<if test="reqVO.keyWord != null and reqVO.keyWord != ''">
|
||||
and (
|
||||
a.name like concat('%', #{reqVO.keyWord}, '%')
|
||||
|
@ -14,6 +14,7 @@
|
||||
SELECT a.id,
|
||||
a.assets_id,
|
||||
b.name as assetsName,
|
||||
b.assets_no as assetsNo,
|
||||
a.use_user_id,
|
||||
c.nickname as useUserName,
|
||||
a.use_dept_id,
|
||||
@ -36,6 +37,7 @@
|
||||
left join system_users as d on a.principal_user_id = d.id
|
||||
left join system_dept as e on a.use_dept_id = e.id
|
||||
<where>
|
||||
a.deleted = 0
|
||||
<if test="vo.useUserId != null">
|
||||
and a.use_user_id = #{vo.useUserId}
|
||||
</if>
|
||||
@ -65,7 +67,7 @@
|
||||
and a.create_time <= #{vo.createTime[1]}
|
||||
</if>
|
||||
</if>
|
||||
order by a.create_time desc
|
||||
</where>
|
||||
order by a.create_time desc
|
||||
</select>
|
||||
</mapper>
|
@ -63,7 +63,7 @@ public class FactoryInfoSaveReqVO {
|
||||
private BigDecimal lat;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
// @NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "负责人编号", example = "126")
|
||||
|
Loading…
Reference in New Issue
Block a user