This commit is contained in:
zt
2025-12-08 19:57:28 +08:00
parent 511bf33914
commit a29c9c8d4d
21 changed files with 530 additions and 23 deletions

View File

@ -140,7 +140,7 @@ public class SubConstructionUserController extends BaseController {
* *
* @param id 主键 * @param id 主键
*/ */
@SaCheckPermission("contractor:constructionUser:query") // @SaCheckPermission("contractor:constructionUser:query")
@GetMapping("/{id}") @GetMapping("/{id}")
public R<SubConstructionUserVo> getInfo(@NotNull(message = "主键不能为空") public R<SubConstructionUserVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) { @PathVariable Long id) {

View File

@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 施工人员文件存储 * 施工人员文件存储
@ -45,6 +46,21 @@ public class SubConstructionUserFileController extends BaseController {
return R.ok(constructionUserFileService.queryList(req)); return R.ok(constructionUserFileService.queryList(req));
} }
/**
* 下载用户文件的ZIP按类型分文件夹
* @param userId 用户ID
*/
@GetMapping("/downloadFiles")
public void downloadUserFilesByType(Long userId,String type, HttpServletResponse response) {
try {
constructionUserFileService.generateTypeGroupZip(userId,type, response);
} catch (Exception e) {
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
/** /**
* 导出施工人员文件存储列表 * 导出施工人员文件存储列表
*/ */

View File

@ -34,4 +34,11 @@ public class SubConstructionUserChangeProjectReq implements Serializable {
*/ */
@NotNull(message = "分包公司id不能为空") @NotNull(message = "分包公司id不能为空")
private Long contractorId; private Long contractorId;
/**
* 工种
*/
private String typeOfWork;
} }

View File

@ -9,12 +9,15 @@ import org.dromara.common.excel.convert.ExcelDictConvert;
import org.dromara.common.translation.annotation.Translation; import org.dromara.common.translation.annotation.Translation;
import org.dromara.common.translation.constant.TransConstant; import org.dromara.common.translation.constant.TransConstant;
import org.dromara.contractor.domain.SubConstructionUser; import org.dromara.contractor.domain.SubConstructionUser;
import org.dromara.contractor.domain.vo.constructionuserfile.SubConstructionUserFileVo;
import org.dromara.project.domain.vo.constructionuserexit.BusConstructionUserExitVo;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
@ -295,5 +298,29 @@ public class SubConstructionUserVo implements Serializable {
*/ */
private Long sysUserId; private Long sysUserId;
/**
* 岗位默认为0普通员工1组长
*/
private String postId; private String postId;
/**
* 分包管理人员ID
*/
private String fbId;
/**
* 分包管理人员名称
*/
@Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "fbId")
private String fbName;
/**
* 文件
*/
List<SubConstructionUserFileVo> subConstructionUserFileVos;
/**
* 记录
*/
List<BusConstructionUserExitVo> busConstructionUserExitVos;
} }

View File

@ -9,6 +9,7 @@ import org.dromara.contractor.domain.dto.constructionuserfile.SubConstructionUse
import org.dromara.contractor.domain.dto.constructionuserfile.SubConstructionUserFileSaveReq; import org.dromara.contractor.domain.dto.constructionuserfile.SubConstructionUserFileSaveReq;
import org.dromara.contractor.domain.dto.constructionuserfile.SubConstructionUserFileTemplateReq; import org.dromara.contractor.domain.dto.constructionuserfile.SubConstructionUserFileTemplateReq;
import org.dromara.contractor.domain.vo.constructionuserfile.SubConstructionUserFileVo; import org.dromara.contractor.domain.vo.constructionuserfile.SubConstructionUserFileVo;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
@ -82,4 +83,12 @@ public interface ISubConstructionUserFileService extends IService<SubConstructio
Map<String,String> getFileByUserId(Long userId); Map<String,String> getFileByUserId(Long userId);
/**
* 获取施工人员文件列表
*/
Map<String,List<SubConstructionUserFileVo>> fileList(Long userId);
void generateTypeGroupZip(Long userId,String type, HttpServletResponse response) throws Exception;
} }

View File

@ -45,6 +45,9 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.*; import java.util.*;
@ -470,6 +473,94 @@ public class SubConstructionUserFileServiceImpl extends ServiceImpl<SubConstruct
return resultMap; return resultMap;
} }
@Override
public Map<String, List<SubConstructionUserFileVo>> fileList(Long userId) {
List<SubConstructionUserFileVo> subConstructionUserFileVos = baseMapper.selectVoList(Wrappers.<SubConstructionUserFile>lambdaQuery()
.eq(SubConstructionUserFile::getUserId, userId));
Map<String, List<SubConstructionUserFileVo>> resultMap = subConstructionUserFileVos.stream().collect(Collectors.groupingBy(SubConstructionUserFileVo::getFileType));
return resultMap;
}
@Override
public void generateTypeGroupZip(Long userId,String type, HttpServletResponse response) throws Exception {
// 1. 查询该用户的所有文件
List<SubConstructionUserFile> list = lambdaQuery()
.eq(SubConstructionUserFile::getUserId, userId)
.eq(StrUtil.isNotBlank(type),SubConstructionUserFile::getFileType, type)
.list();
if (list.isEmpty()) {
throw new ServiceException("该用户没有文件");
}
List<SysDictDataVo> userFileType = dictTypeService.selectDictDataByType("user_file_type");
Map<String, String> collect = userFileType.stream().collect(Collectors.toMap(SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel));
// 3. 设置响应头ZIP文件下载
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=\"user_files.zip\"");
// 4. 压缩流直接写入响应(无临时文件)
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
// 遍历每个文件类型分组
for (SubConstructionUserFile entry : list) {
String fileType = entry.getFileType(); // 文件夹名称:文件类型(如"01"
String fileTypeName = collect.get(fileType);
String fileUrl = entry.getPath();
if (StringUtils.isBlank(fileUrl)) {
continue;
}
String[] split = fileUrl.split(",");
List<Long> ossIds = Arrays.stream(split).map(Long::valueOf).toList();
List<SysOssVo> sysOssVos = ossService.listByIds(ossIds);
for (SysOssVo sysOssVo : sysOssVos) {
String ossVoUrl = sysOssVo.getUrl();
if (StringUtils.isBlank(ossVoUrl)) {
continue;
}
String zipEntryName = fileTypeName + "/" + sysOssVo.getOriginalName();
ZipEntry zipEntry = new ZipEntry(zipEntryName);
zipOut.putNextEntry(zipEntry);
// 下载远程文件并写入ZIP
URL url = new URL(ossVoUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(10000);
try (InputStream in = connection.getInputStream()) {
byte[] buffer = new byte[1024 * 8];
int len;
while ((len = in.read(buffer)) != -1) {
zipOut.write(buffer, 0, len);
}
} finally {
connection.disconnect();
zipOut.closeEntry(); // 关闭当前条目
}
}
}
}
}
/** /**
* 递归扫描指定目录,找到 “姓名-Id” 格式的文件夹并解析 * 递归扫描指定目录,找到 “姓名-Id” 格式的文件夹并解析
*/ */

View File

@ -38,9 +38,11 @@ import org.dromara.contractor.domain.SubConstructionUser;
import org.dromara.contractor.domain.SubConstructionUserFile; import org.dromara.contractor.domain.SubConstructionUserFile;
import org.dromara.contractor.domain.SubContractor; import org.dromara.contractor.domain.SubContractor;
import org.dromara.contractor.domain.dto.constructionuser.*; import org.dromara.contractor.domain.dto.constructionuser.*;
import org.dromara.contractor.domain.dto.constructionuserfile.SubConstructionUserFileQueryReq;
import org.dromara.contractor.domain.enums.SubConstructionUserFileStatusEnum; import org.dromara.contractor.domain.enums.SubConstructionUserFileStatusEnum;
import org.dromara.contractor.domain.exportvo.BusConstructionUserExportVo; import org.dromara.contractor.domain.exportvo.BusConstructionUserExportVo;
import org.dromara.contractor.domain.vo.constructionuser.*; import org.dromara.contractor.domain.vo.constructionuser.*;
import org.dromara.contractor.domain.vo.constructionuserfile.SubConstructionUserFileVo;
import org.dromara.contractor.domain.vo.contractor.SubContractorVo; import org.dromara.contractor.domain.vo.contractor.SubContractorVo;
import org.dromara.contractor.mapper.SubConstructionUserMapper; import org.dromara.contractor.mapper.SubConstructionUserMapper;
import org.dromara.contractor.service.ISubConstructionUserFileService; import org.dromara.contractor.service.ISubConstructionUserFileService;
@ -48,10 +50,12 @@ import org.dromara.contractor.service.ISubConstructionUserService;
import org.dromara.contractor.service.ISubContractorService; import org.dromara.contractor.service.ISubContractorService;
import org.dromara.project.domain.*; import org.dromara.project.domain.*;
import org.dromara.project.domain.dto.attendance.TodayUserDto; import org.dromara.project.domain.dto.attendance.TodayUserDto;
import org.dromara.project.domain.dto.constructionuserexit.BusConstructionUserExitQueryReq;
import org.dromara.project.domain.enums.BusAttendanceClockStatusEnum; import org.dromara.project.domain.enums.BusAttendanceClockStatusEnum;
import org.dromara.project.domain.enums.BusAttendanceCommuterEnum; import org.dromara.project.domain.enums.BusAttendanceCommuterEnum;
import org.dromara.project.domain.enums.BusConstructionUserAttendanceStatusEnum; import org.dromara.project.domain.enums.BusConstructionUserAttendanceStatusEnum;
import org.dromara.project.domain.vo.attendance.AttendanceTodayUserVo; import org.dromara.project.domain.vo.attendance.AttendanceTodayUserVo;
import org.dromara.project.domain.vo.constructionuserexit.BusConstructionUserExitVo;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamAppVo; import org.dromara.project.domain.vo.projectteam.BusProjectTeamAppVo;
import org.dromara.project.service.*; import org.dromara.project.service.*;
import org.dromara.system.domain.SysUser; import org.dromara.system.domain.SysUser;
@ -157,6 +161,10 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU
@Resource @Resource
private AsyncUtil asyncUtil; private AsyncUtil asyncUtil;
@Resource
@Lazy
private IBusConstructionUserExitService busConstructionUserExitService;
/** /**
* 查询施工人员 * 查询施工人员
@ -171,7 +179,16 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU
if (constructionUser == null) { if (constructionUser == null) {
throw new ServiceException("施工人员信息不存在", HttpStatus.NOT_FOUND); throw new ServiceException("施工人员信息不存在", HttpStatus.NOT_FOUND);
} }
return this.getVo(constructionUser, isHidden); SubConstructionUserVo vo = this.getVo(constructionUser, isHidden);
SubConstructionUserFileQueryReq req = new SubConstructionUserFileQueryReq();
req.setUserId(constructionUser.getSysUserId());
List<SubConstructionUserFileVo> subConstructionUserFileVos = constructionUserFileService.queryList(req);
vo.setSubConstructionUserFileVos(subConstructionUserFileVos);
BusConstructionUserExitQueryReq busConstructionUserExitQueryReq = new BusConstructionUserExitQueryReq();
busConstructionUserExitQueryReq.setUserId(constructionUser.getSysUserId());
List<BusConstructionUserExitVo> busConstructionUserExitVos = busConstructionUserExitService.queryList(busConstructionUserExitQueryReq);
vo.setBusConstructionUserExitVos(busConstructionUserExitVos);
return vo;
} }
/** /**
@ -661,7 +678,9 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU
LambdaUpdateWrapper<SubConstructionUser> lambdaUpdate = Wrappers.lambdaUpdate(SubConstructionUser.class) LambdaUpdateWrapper<SubConstructionUser> lambdaUpdate = Wrappers.lambdaUpdate(SubConstructionUser.class)
.eq(SubConstructionUser::getId, id) .eq(SubConstructionUser::getId, id)
.set(SubConstructionUser::getProjectId, req.getProjectId()) .set(SubConstructionUser::getProjectId, req.getProjectId())
.set(SubConstructionUser::getContractorId, req.getContractorId()); .set(SubConstructionUser::getContractorId, req.getContractorId())
.set(SubConstructionUser::getTypeOfWork, req.getTypeOfWork())
;
userProjectRelevancyService.deleteByUserId(constructionUser.getSysUserId()); userProjectRelevancyService.deleteByUserId(constructionUser.getSysUserId());
@ -895,6 +914,22 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU
Integer age = Math.max(Period.between(sfzBirth, LocalDate.now()).getYears(), 0); Integer age = Math.max(Period.between(sfzBirth, LocalDate.now()).getYears(), 0);
constructionUserVo.setAge(age); constructionUserVo.setAge(age);
} }
//班组信息
if (constructionUser.getTeamId() != null) {
BusProjectTeam byId = projectTeamService.getById(constructionUser.getTeamId());
if (byId != null) {
constructionUserVo.setTeamId(byId.getId());
constructionUserVo.setTeamName(byId.getTeamName());
constructionUserVo.setFbId(byId.getUserId());
BusProjectTeamMember one = projectTeamMemberService.getOne(Wrappers.<BusProjectTeamMember>lambdaQuery()
.eq(BusProjectTeamMember::getTeamId, constructionUser.getTeamId())
.last("limit 1")
);
if (one != null) {
constructionUserVo.setPostId(one.getPostId());
}
}
}
return constructionUserVo; return constructionUserVo;
} }

View File

@ -67,6 +67,14 @@ public class BusAttendanceController extends BaseController {
return R.ok(busAttendanceService.listAttendanceMonthListByUserId(req)); return R.ok(busAttendanceService.listAttendanceMonthListByUserId(req));
} }
/**
* 统计施工人员月份考勤列表
*/
@GetMapping("/count/month/byUserId")
public R<BusAttendanceMonthByUserIdCountVo> countAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req) {
return R.ok(busAttendanceService.countAttendanceMonthListByUserId(req));
}
@GetMapping("/sub/list/month/byUserId") @GetMapping("/sub/list/month/byUserId")
public R<List<BusAttendanceMonthByUserIdVo>> subListAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req) { public R<List<BusAttendanceMonthByUserIdVo>> subListAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req) {
return R.ok(busAttendanceService.subListAttendanceMonthListByUserId(req)); return R.ok(busAttendanceService.subListAttendanceMonthListByUserId(req));

View File

@ -23,6 +23,7 @@ import org.dromara.project.domain.dto.projectteam.BusProjectTeamQueryReq;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamUpdateReq; import org.dromara.project.domain.dto.projectteam.BusProjectTeamUpdateReq;
import org.dromara.project.domain.vo.BusProjectPunchrangeVo; import org.dromara.project.domain.vo.BusProjectPunchrangeVo;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamAppVo; import org.dromara.project.domain.vo.projectteam.BusProjectTeamAppVo;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamCountVo;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamForemanVo; import org.dromara.project.domain.vo.projectteam.BusProjectTeamForemanVo;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamVo; import org.dromara.project.domain.vo.projectteam.BusProjectTeamVo;
import org.dromara.project.service.IBusProjectPunchrangeService; import org.dromara.project.service.IBusProjectPunchrangeService;
@ -181,4 +182,10 @@ public class BusProjectTeamController extends BaseController {
return R.ok(busProjectTeamService.queryList(req)); return R.ok(busProjectTeamService.queryList(req));
} }
@GetMapping("/teamCount")
public R<BusProjectTeamCountVo> teamCount(BusProjectTeamQueryReq req) {
return R.ok(busProjectTeamService.teamCount(req));
}
} }

View File

@ -72,5 +72,29 @@ public class BusConstructionUserExit implements Serializable {
*/ */
private String remark; private String remark;
/**
* 工种
*/
private String typeOfWork;
/**
* 项目名称
*/
private String projectName;
/**
* 分包公司id
*/
private Long contractorId;
/**
* 分包公司名称
*/
private String contractorName;
/**
* 班组名称
*/
private String teamName;
} }

View File

@ -33,6 +33,17 @@ public class BusAttendanceListByDay {
*/ */
private String clockStatus; private String clockStatus;
/**
* 人脸照
*/
private String facePic;
private String url;
public static BusAttendanceListByDay build(BusAttendance attendance) { public static BusAttendanceListByDay build(BusAttendance attendance) {
if (attendance == null) { if (attendance == null) {
return null; return null;
@ -41,6 +52,7 @@ public class BusAttendanceListByDay {
attendanceListByDay.setClockType(attendance.getClockType()); attendanceListByDay.setClockType(attendance.getClockType());
attendanceListByDay.setClockTime(attendance.getClockTime()); attendanceListByDay.setClockTime(attendance.getClockTime());
attendanceListByDay.setClockStatus(attendance.getClockStatus()); attendanceListByDay.setClockStatus(attendance.getClockStatus());
attendanceListByDay.setFacePic(attendance.getFacePic());
return attendanceListByDay; return attendanceListByDay;
} }

View File

@ -0,0 +1,34 @@
package org.dromara.project.domain.vo.attendance;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
/**
* @author lilemy
* @date 2025/4/8 16:58
*/
@Data
public class BusAttendanceMonthByUserIdCountVo implements Serializable {
@Serial
private static final long serialVersionUID = -6172238396618801431L;
/**
* 出勤天数
*/
private Long full;
/**
* 迟到和早退次数
*/
private Long half;
/**
* 请假次数
*/
private Long leave;
}

View File

@ -37,6 +37,11 @@ public class BusAttendanceMonthByUserIdVo implements Serializable {
*/ */
private String Status; private String Status;
/**
* 当天打卡状态
*/
private Integer week;
/** /**
* 当天打卡记录 * 当天打卡记录
*/ */

View File

@ -96,5 +96,28 @@ public class BusConstructionUserExitVo implements Serializable {
@ExcelProperty(value = "备注") @ExcelProperty(value = "备注")
private String remark; private String remark;
/**
* 工种
*/
private String typeOfWork;
/**
* 项目名称
*/
private String projectName;
/**
* 分包公司id
*/
private Long contractorId;
/**
* 分包公司名称
*/
private String contractorName;
/**
* 班组名称
*/
private String teamName;
} }

View File

@ -0,0 +1,45 @@
package org.dromara.project.domain.vo.projectteam;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import org.dromara.project.domain.BusProjectTeam;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 项目班组视图对象 bus_project_team
*
* @author lilemy
* @date 2025-03-07
*/
@Data
public class BusProjectTeamCountVo {
/**
* 总班组
*/
private Integer total=0;
/**
* 总人数
*/
private Long peopleNumber=0L;
/**
* 限制打卡组数
*/
private Long limitNumber=0L;
/**
* 出勤班组数
*/
private Long attendanceNumber=0L;
}

View File

@ -44,6 +44,10 @@ public interface IBusAttendanceService extends IService<BusAttendance>{
*/ */
List<BusAttendanceMonthByUserIdVo> listAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req); List<BusAttendanceMonthByUserIdVo> listAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req);
/**
* 统计用户每月考勤
*/
BusAttendanceMonthByUserIdCountVo countAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req);
List<BusAttendanceMonthByUserIdVo> subListAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req); List<BusAttendanceMonthByUserIdVo> subListAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req);

View File

@ -11,10 +11,7 @@ import org.dromara.project.domain.BusProjectTeam;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamCreateReq; import org.dromara.project.domain.dto.projectteam.BusProjectTeamCreateReq;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamQueryReq; import org.dromara.project.domain.dto.projectteam.BusProjectTeamQueryReq;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamUpdateReq; import org.dromara.project.domain.dto.projectteam.BusProjectTeamUpdateReq;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamAppVo; import org.dromara.project.domain.vo.projectteam.*;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamForemanVo;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamVo;
import org.dromara.project.domain.vo.projectteam.TeamManageVo;
import org.dromara.quality.domain.vo.qualityinspection.QltQualityInspectionVo; import org.dromara.quality.domain.vo.qualityinspection.QltQualityInspectionVo;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -129,4 +126,7 @@ public interface IBusProjectTeamService extends IService<BusProjectTeam> {
List<TeamManageVo> getManager(Long teamId); List<TeamManageVo> getManager(Long teamId);
List<BusProjectTeam> selectByPunchRangeIn(List<String> punchRangeList); List<BusProjectTeam> selectByPunchRangeIn(List<String> punchRangeList);
BusProjectTeamCountVo teamCount(BusProjectTeamQueryReq req);
} }

View File

@ -62,6 +62,7 @@ import java.math.BigDecimal;
import java.time.*; import java.time.*;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalAdjusters;
import java.time.temporal.ValueRange;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -179,10 +180,29 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
Date start = DateUtils.toDate(yearMonth.atDay(1)); Date start = DateUtils.toDate(yearMonth.atDay(1));
Date end = DateUtils.toDate(yearMonth.atEndOfMonth()); Date end = DateUtils.toDate(yearMonth.atEndOfMonth());
// 查询当月考勤记录 // 查询当月考勤记录
Map<LocalDate, List<BusAttendance>> dateListMap = this.lambdaQuery() List<BusAttendance> list = this.lambdaQuery()
.eq(BusAttendance::getUserId, constructionUser.getSysUserId()) .eq(BusAttendance::getUserId, constructionUser.getSysUserId())
.between(BusAttendance::getClockDate, start, end) .between(BusAttendance::getClockDate, start, end)
.list() .list();
//转成Long
// 转换逻辑将字符串解析为Long
List<Long> longList = list.stream()
.filter(attendance -> StringUtils.isNotBlank(attendance.getFacePic())) // 过滤空字符串
.map(attendance -> {
try {
// 假设facePic是纯数字字符串如"123456"
return Long.parseLong(attendance.getFacePic());
} catch (NumberFormatException e) {
// 处理转换失败的情况(如非数字字符串)
// 可选:抛异常/返回null/忽略此处示例返回null后续可过滤
return null;
}
})
.filter(java.util.Objects::nonNull) // 过滤转换失败的null
.collect(Collectors.toList());
List<SysOssVo> sysOssVos = ossService.listByIds(longList);
Map<Long, String> ossMap = sysOssVos.stream().collect(Collectors.toMap(SysOssVo::getOssId, SysOssVo::getUrl));
Map<LocalDate, List<BusAttendance>> dateListMap = list
.stream().collect(Collectors.groupingBy(BusAttendance::getClockDate)); .stream().collect(Collectors.groupingBy(BusAttendance::getClockDate));
// 遍历每天,计算考勤状态 // 遍历每天,计算考勤状态
List<BusAttendanceMonthByUserIdVo> respList = new ArrayList<>(); List<BusAttendanceMonthByUserIdVo> respList = new ArrayList<>();
@ -190,6 +210,10 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
BusAttendanceMonthByUserIdVo resp = new BusAttendanceMonthByUserIdVo(); BusAttendanceMonthByUserIdVo resp = new BusAttendanceMonthByUserIdVo();
resp.setId(userId); resp.setId(userId);
resp.setClockDate(date); resp.setClockDate(date);
//星期几
DayOfWeek dayOfWeek = date.getDayOfWeek();
int dayNumber = dayOfWeek.getValue();
resp.setWeek(dayNumber);
List<BusAttendanceListByDay> attendanceListByDayList = new ArrayList<>(); List<BusAttendanceListByDay> attendanceListByDayList = new ArrayList<>();
String clockInStatus = null; String clockInStatus = null;
String clockOutStatus = null; String clockOutStatus = null;
@ -198,6 +222,12 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
for (BusAttendance attendance : attendanceList) { for (BusAttendance attendance : attendanceList) {
// 获取考勤记录 // 获取考勤记录
BusAttendanceListByDay day = BusAttendanceListByDay.build(attendance); BusAttendanceListByDay day = BusAttendanceListByDay.build(attendance);
try {
Long l = Long.valueOf(attendance.getFacePic());
day.setUrl(ossMap.get(l));
} catch (Exception e) {
log.error("人脸照解析失败", e);
}
attendanceListByDayList.add(day); attendanceListByDayList.add(day);
// 获取上下班状态 // 获取上下班状态
if (BusAttendanceCommuterEnum.CLOCKIN.getValue().equals(attendance.getClockType())) { if (BusAttendanceCommuterEnum.CLOCKIN.getValue().equals(attendance.getClockType())) {
@ -224,11 +254,52 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
resp.setAttendanceList(attendanceListByDayList); resp.setAttendanceList(attendanceListByDayList);
respList.add(resp); respList.add(resp);
}); });
// 按打卡日期序排列 // 按打卡日期序排列
respList.sort(Comparator.comparing(BusAttendanceMonthByUserIdVo::getClockDate)); respList.sort(Comparator.comparing(BusAttendanceMonthByUserIdVo::getClockDate).reversed());
return respList; return respList;
} }
@Override
public BusAttendanceMonthByUserIdCountVo countAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req) {
Long userId = req.getUserId();
String clockMonth = req.getClockMonth();
SubConstructionUser constructionUser = constructionUserService.getById(userId);
if (constructionUser == null) {
throw new ServiceException("实名认证信息不存在", HttpStatus.ERROR);
}
// 解析月份
YearMonth yearMonth;
if (StringUtils.isNotBlank(clockMonth)) {
// 校验月份格式
if (!DateConstant.YEAR_MONTH_PATTERN.matcher(clockMonth).matches()) {
throw new ServiceException("月份格式不正确", HttpStatus.ERROR);
}
yearMonth = YearMonth.parse(clockMonth);
} else {
// 如果月份为空,则默认查询当前月份
yearMonth = YearMonth.now();
}
// 计算当月第一天 / 最后一天
Date start = DateUtils.toDate(yearMonth.atDay(1));
Date end = DateUtils.toDate(yearMonth.atEndOfMonth());
// 查询当月考勤记录
List<BusAttendance> list = this.lambdaQuery()
.eq(BusAttendance::getUserId, constructionUser.getSysUserId())
.between(BusAttendance::getClockDate, start, end)
.list();
BusAttendanceMonthByUserIdCountVo vo = new BusAttendanceMonthByUserIdCountVo();
long count = list.stream().filter(attendance -> ATTENDANCE_LIST.contains(attendance.getClockType()))
.map(BusAttendance::getClockDate).distinct().count();
vo.setFull(count);
long late = list.stream().filter(attendance -> LATE.getValue().equals(attendance.getClockStatus()) || LEAVEEARLY.getValue().equals(attendance.getClockStatus())).count();
vo.setHalf(late);
long leave = list.stream().filter(attendance -> LEAVE.getValue().equals(attendance.getClockStatus())).count();
vo.setLeave(leave);
return vo;
}
@Override @Override
public List<BusAttendanceMonthByUserIdVo> subListAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req) { public List<BusAttendanceMonthByUserIdVo> subListAttendanceMonthListByUserId(BusAttendanceMonthByUserIdReq req) {
Long userId = req.getUserId(); Long userId = req.getUserId();

View File

@ -14,8 +14,12 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.contractor.domain.SubConstructionUser; import org.dromara.contractor.domain.SubConstructionUser;
import org.dromara.contractor.domain.SubContractor;
import org.dromara.contractor.service.ISubConstructionUserService; import org.dromara.contractor.service.ISubConstructionUserService;
import org.dromara.contractor.service.ISubContractorService;
import org.dromara.project.domain.BusConstructionUserExit; import org.dromara.project.domain.BusConstructionUserExit;
import org.dromara.project.domain.BusProject;
import org.dromara.project.domain.BusProjectTeam;
import org.dromara.project.domain.BusProjectTeamMember; import org.dromara.project.domain.BusProjectTeamMember;
import org.dromara.project.domain.dto.constructionuserexit.BusConstructionUserExitCreateReq; import org.dromara.project.domain.dto.constructionuserexit.BusConstructionUserExitCreateReq;
import org.dromara.project.domain.dto.constructionuserexit.BusConstructionUserExitQueryReq; import org.dromara.project.domain.dto.constructionuserexit.BusConstructionUserExitQueryReq;
@ -23,7 +27,9 @@ import org.dromara.project.domain.dto.constructionuserexit.BusConstructionUserEx
import org.dromara.project.domain.vo.constructionuserexit.BusConstructionUserExitVo; import org.dromara.project.domain.vo.constructionuserexit.BusConstructionUserExitVo;
import org.dromara.project.mapper.BusConstructionUserExitMapper; import org.dromara.project.mapper.BusConstructionUserExitMapper;
import org.dromara.project.service.IBusConstructionUserExitService; import org.dromara.project.service.IBusConstructionUserExitService;
import org.dromara.project.service.IBusProjectService;
import org.dromara.project.service.IBusProjectTeamMemberService; import org.dromara.project.service.IBusProjectTeamMemberService;
import org.dromara.project.service.IBusProjectTeamService;
import org.dromara.system.domain.vo.SysOssVo; import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.service.ISysOssService; import org.dromara.system.service.ISysOssService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -55,6 +61,19 @@ public class BusConstructionUserExitServiceImpl extends ServiceImpl<BusConstruct
@Resource @Resource
private ISubConstructionUserService constructionUserService; private ISubConstructionUserService constructionUserService;
@Resource
@Lazy
private IBusProjectTeamService projectTeamService;
@Resource
@Lazy
private IBusProjectService projectService;
@Resource
@Lazy
private ISubContractorService subContractorService;
/** /**
* 查询施工人员入场退场记录信息 * 查询施工人员入场退场记录信息
* *
@ -208,6 +227,21 @@ public class BusConstructionUserExitServiceImpl extends ServiceImpl<BusConstruct
constructionUserExit.setEntryDate(constructionUser.getEntryDate()); constructionUserExit.setEntryDate(constructionUser.getEntryDate());
constructionUserExit.setLeaveDate(new Date()); constructionUserExit.setLeaveDate(new Date());
constructionUserExit.setRemark(req.getRemark()); constructionUserExit.setRemark(req.getRemark());
constructionUserExit.setTypeOfWork(constructionUser.getTypeOfWork());
constructionUserExit.setProjectId(constructionUser.getProjectId());
BusProject project = projectService.getById(constructionUser.getProjectId());
if(project!=null){
constructionUserExit.setProjectName(project.getProjectName());
}
constructionUserExit.setContractorId(constructionUser.getContractorId());
SubContractor subContractor = subContractorService.getById(constructionUser.getContractorId());
if(subContractor!=null){
constructionUserExit.setContractorName(subContractor.getName());
}
BusProjectTeam projectTeam = projectTeamService.getById(constructionUser.getTeamId());
if(projectTeam!=null){
constructionUserExit.setTeamName(projectTeam.getTeamName());
}
boolean save = this.save(constructionUserExit); boolean save = this.save(constructionUserExit);
if (!save) { if (!save) {
throw new ServiceException("施工人员退场失败,数据库异常", HttpStatus.ERROR); throw new ServiceException("施工人员退场失败,数据库异常", HttpStatus.ERROR);

View File

@ -19,11 +19,10 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.utils.AsyncUtil; import org.dromara.common.utils.AsyncUtil;
import org.dromara.common.utils.IdCardEncryptorUtil; import org.dromara.common.utils.IdCardEncryptorUtil;
import org.dromara.contractor.domain.SubConstructionUser; import org.dromara.contractor.domain.SubConstructionUser;
import org.dromara.contractor.domain.SubContractor;
import org.dromara.contractor.service.ISubConstructionUserService; import org.dromara.contractor.service.ISubConstructionUserService;
import org.dromara.project.domain.BusConstructionUserExit; import org.dromara.contractor.service.ISubContractorService;
import org.dromara.project.domain.BusProjectTeam; import org.dromara.project.domain.*;
import org.dromara.project.domain.BusProjectTeamMember;
import org.dromara.project.domain.BusUserProjectRelevancy;
import org.dromara.project.domain.dto.projectteammember.BusProjectTeamMemberCreateReq; import org.dromara.project.domain.dto.projectteammember.BusProjectTeamMemberCreateReq;
import org.dromara.project.domain.dto.projectteammember.BusProjectTeamMemberExitReq; import org.dromara.project.domain.dto.projectteammember.BusProjectTeamMemberExitReq;
import org.dromara.project.domain.dto.projectteammember.BusProjectTeamMemberQueryReq; import org.dromara.project.domain.dto.projectteammember.BusProjectTeamMemberQueryReq;
@ -41,6 +40,7 @@ import org.dromara.system.service.ISysOssService;
import org.dromara.system.service.ISysRoleService; import org.dromara.system.service.ISysRoleService;
import org.dromara.system.service.ISysUserService; import org.dromara.system.service.ISysUserService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -93,6 +93,11 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl<BusProjectTeamM
@Resource @Resource
private AsyncUtil asyncUtil; private AsyncUtil asyncUtil;
@Resource
@Lazy
private ISubContractorService subContractorService;
// @Resource // @Resource
// private ClarityPmAsyncMethod clarityPmAsyncMethod; // private ClarityPmAsyncMethod clarityPmAsyncMethod;
@ -349,10 +354,25 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl<BusProjectTeamM
SubConstructionUser constructionUser = constructionUserService.getBySysUserId(memberId); SubConstructionUser constructionUser = constructionUserService.getBySysUserId(memberId);
BusConstructionUserExit constructionUserExit = new BusConstructionUserExit(); BusConstructionUserExit constructionUserExit = new BusConstructionUserExit();
constructionUserExit.setProjectId(constructionUser.getProjectId()); constructionUserExit.setProjectId(constructionUser.getProjectId());
BusProject project = projectService.getById(constructionUser.getProjectId());
if(project!=null){
constructionUserExit.setProjectName(project.getProjectName());
}
constructionUserExit.setContractorId(constructionUser.getContractorId());
SubContractor subContractor = subContractorService.getById(constructionUser.getContractorId());
if(subContractor!=null){
constructionUserExit.setContractorName(subContractor.getName());
}
constructionUserExit.setUserId(constructionUser.getSysUserId()); constructionUserExit.setUserId(constructionUser.getSysUserId());
constructionUserExit.setSalaryVoucherFile(salaryVoucherFile); constructionUserExit.setSalaryVoucherFile(salaryVoucherFile);
constructionUserExit.setSalaryConfirmationFile(salaryConfirmationFile); constructionUserExit.setSalaryConfirmationFile(salaryConfirmationFile);
constructionUserExit.setTeamId(constructionUser.getTeamId()); constructionUserExit.setTeamId(constructionUser.getTeamId());
BusProjectTeam projectTeam = projectTeamService.getById(constructionUser.getTeamId());
if(projectTeam!=null){
constructionUserExit.setTeamName(projectTeam.getTeamName());
}
constructionUserExit.setTypeOfWork(constructionUser.getTypeOfWork());
String sfzNumber = constructionUser.getSfzNumber(); String sfzNumber = constructionUser.getSfzNumber();
if (StringUtils.isNotBlank(sfzNumber)) { if (StringUtils.isNotBlank(sfzNumber)) {
sfzNumber = idCardEncryptorUtil.decrypt(sfzNumber); sfzNumber = idCardEncryptorUtil.decrypt(sfzNumber);

View File

@ -19,20 +19,15 @@ import org.dromara.contractor.domain.SubConstructionUser;
import org.dromara.contractor.domain.SubContractor; import org.dromara.contractor.domain.SubContractor;
import org.dromara.contractor.service.ISubConstructionUserService; import org.dromara.contractor.service.ISubConstructionUserService;
import org.dromara.contractor.service.ISubContractorService; import org.dromara.contractor.service.ISubContractorService;
import org.dromara.project.domain.BusProject; import org.dromara.project.domain.*;
import org.dromara.project.domain.BusProjectPunchrange;
import org.dromara.project.domain.BusProjectTeam;
import org.dromara.project.domain.BusProjectTeamMember;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamCreateReq; import org.dromara.project.domain.dto.projectteam.BusProjectTeamCreateReq;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamQueryReq; import org.dromara.project.domain.dto.projectteam.BusProjectTeamQueryReq;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamUpdateReq; import org.dromara.project.domain.dto.projectteam.BusProjectTeamUpdateReq;
import org.dromara.project.domain.enums.BusAttendanceClockStatusEnum;
import org.dromara.project.domain.enums.BusProjectTeamMemberPostEnum; import org.dromara.project.domain.enums.BusProjectTeamMemberPostEnum;
import org.dromara.project.domain.vo.projectteam.*; import org.dromara.project.domain.vo.projectteam.*;
import org.dromara.project.mapper.BusProjectTeamMapper; import org.dromara.project.mapper.BusProjectTeamMapper;
import org.dromara.project.service.IBusProjectPunchrangeService; import org.dromara.project.service.*;
import org.dromara.project.service.IBusProjectService;
import org.dromara.project.service.IBusProjectTeamMemberService;
import org.dromara.project.service.IBusProjectTeamService;
import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysUserService; import org.dromara.system.service.ISysUserService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -40,6 +35,7 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -74,6 +70,11 @@ public class BusProjectTeamServiceImpl extends ServiceImpl<BusProjectTeamMapper,
private ISubContractorService contractorService; private ISubContractorService contractorService;
@Resource
@Lazy
private IBusAttendanceService attendanceService;
/** /**
* 查询项目班组 * 查询项目班组
* *
@ -544,4 +545,38 @@ public class BusProjectTeamServiceImpl extends ServiceImpl<BusProjectTeamMapper,
public List<BusProjectTeam> selectByPunchRangeIn(List<String> punchRangeList) { public List<BusProjectTeam> selectByPunchRangeIn(List<String> punchRangeList) {
return baseMapper.selectByPunchRangeIn(punchRangeList); return baseMapper.selectByPunchRangeIn(punchRangeList);
} }
@Override
public BusProjectTeamCountVo teamCount(BusProjectTeamQueryReq req) {
BusProjectTeamCountVo vo = new BusProjectTeamCountVo();
List<BusProjectTeam> list = lambdaQuery().eq(BusProjectTeam::getProjectId, req.getProjectId()).list();
vo.setTotal(list.size());
List<Long> list1 = list.stream().map(BusProjectTeam::getId).toList();
if(CollUtil.isNotEmpty(list1)){
long count = constructionUserService.count(Wrappers.<SubConstructionUser>lambdaQuery()
.eq(SubConstructionUser::getProjectId, req.getProjectId())
.in(SubConstructionUser::getTeamId, list1)
);
vo.setPeopleNumber(count);
}
long count = list.stream().filter(projectTeam -> "0".equals(projectTeam.getIsClockIn())).count();
vo.setLimitNumber(count);
List<BusAttendance> list2 = attendanceService.lambdaQuery()
.eq(BusAttendance::getProjectId, req.getProjectId())
.eq(BusAttendance::getClockDate, LocalDate.now())
.in(BusAttendance::getClockStatus, BusAttendanceClockStatusEnum.ATTENDANCE_LIST)
.list();
List<Long> list11 = list2.stream().map(BusAttendance::getUserId).toList();
if(CollUtil.isNotEmpty(list11)){
long count1 = constructionUserService.count(Wrappers.<SubConstructionUser>lambdaQuery()
.eq(SubConstructionUser::getProjectId, req.getProjectId())
.in(SubConstructionUser::getTeamId, list11)
);
vo.setPeopleNumber(count1);
}
return vo;
}
} }