This commit is contained in:
zt
2025-09-06 13:06:33 +08:00
parent 2cea57646d
commit b738bb821d
28 changed files with 692 additions and 66 deletions

View File

@ -193,6 +193,12 @@ public class AuthController {
return R.ok();
}
@PostMapping("/app/register")
public R<Void> appRegister(@Validated @RequestBody RegisterBody user) {
registerService.appRegister(user);
return R.ok();
}
/**
* 登录页面租户下拉框
*

View File

@ -77,6 +77,46 @@ public class SysRegisterService {
recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.register.success"));
}
/**
* 注册
*/
public void appRegister(RegisterBody registerBody) {
String tenantId = registerBody.getTenantId();
String username = registerBody.getPhonenumber();
String password = registerBody.getPassword();
// 校验用户类型是否存在
String userType = UserType.getUserType(registerBody.getUserType()).getUserType();
// 校验密码是否符合要求
String pattern = "^(?!.*\\s)(?!^[a-zA-Z]+$)(?!^[0-9]+$)(?!^[^a-zA-Z0-9]+$)(?!^[a-zA-Z0-9]+$).{8,18}$";
boolean isValid = password.matches(pattern);
if (!isValid) {
throw new UserException("注册失败密码需满足818位包含大小写字母、数字、特殊字符中的至少三种组合");
}
// 验证码开关
SysUserBo sysUser = new SysUserBo();
sysUser.setUserName(username);
sysUser.setNickName(username);
sysUser.setPhonenumber(username);
sysUser.setPassword(BCrypt.hashpw(password));
sysUser.setUserType(userType);
sysUser.setEmail(registerBody.getEmail());
boolean exist = TenantHelper.dynamic(tenantId, () -> {
return userMapper.exists(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getPhonenumber, sysUser.getPhonenumber()));
});
if (exist) {
throw new UserException("user.register.save.error", username);
}
boolean regFlag = userService.registerUser(sysUser, tenantId);
if (!regFlag) {
throw new UserException("user.register.error");
}
recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.register.success"));
}
/**
* 校验验证码
*

View File

@ -13,7 +13,7 @@ spring.boot.admin.client:
--- # snail-job 配置
snail-job:
enabled: false
enabled: true
# 需要在 SnailJob 后台组管理创建对应名称的组,然后创建任务的时候选择对应的组,才能正确分派任务
group: "ruoyi_group"
# SnailJob 接入验证令牌 详见 script/sql/ry_job.sql `sj_group_config` 表

View File

@ -30,4 +30,12 @@ public class RegisterBody extends LoginBody {
private String userType;
private Long projectId;
private String email;
private String phonenumber;
private Long deptId;
}

View File

@ -111,12 +111,129 @@ public class PdfBoxQrCodeGenerator {
/**
* 在PDF每一页的指定位置添加二维码并返回数据流根据页面方向自动调整位置
*/
// public static ByteArrayOutputStream addQRCodeToPDFOnAllPages(String srcPdf, byte[] qrCodeBytes, boolean isChangeFile)
// throws IOException {
//
// PdfReader reader;
// if (srcPdf.startsWith("http://") || srcPdf.startsWith("https://")) {
// // 网络地址 PDF
// URL url = new URL(srcPdf);
// HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// connection.setConnectTimeout(10000);
// connection.setReadTimeout(30000);
// connection.setRequestMethod("GET");
//
// int responseCode = connection.getResponseCode();
// if (responseCode != HttpURLConnection.HTTP_OK) {
// throw new IOException("无法获取 PDF 文件HTTP响应码: " + responseCode);
// }
// InputStream inputStream = connection.getInputStream();
// reader = new PdfReader(inputStream);
// } else {
// // 本地文件 PDF
// File srcFile = new File(srcPdf);
// if (!srcFile.exists()) {
// throw new IOException("源PDF文件不存在: " + srcPdf);
// }
// reader = new PdfReader(srcPdf);
// }
//
// ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
// PdfWriter writer = new PdfWriter(pdfOut);
// PdfDocument pdfDoc = new PdfDocument(reader, writer);
//
// int numberOfPages = pdfDoc.getNumberOfPages();
//
// for (int pageNum = 1; pageNum <= numberOfPages; pageNum++) {
// PdfPage page = pdfDoc.getPage(pageNum);
// Rectangle pageSize = page.getPageSize();
//
// float pageWidth = pageSize.getWidth();
// float pageHeight = pageSize.getHeight();
//
// float qrX, qrY;
// float newWidth, newHeight;
//
// if (isChangeFile && pageNum == 1) {
// qrX = pageWidth - 143;
// qrY = pageHeight - 213;
// newWidth = 67;
// newHeight = 80;
// } else {
// if (pageWidth > pageHeight) {
// // 横版
// qrX = pageWidth - 90;
// qrY = 24;
// newWidth = 67;
// newHeight = 79;
// } else {
// // 竖版
// qrX = 226;
// qrY = pageHeight - 185;
// newWidth = 69;
// newHeight = 80;
// }
// }
//
// PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDoc);
// try (Canvas canvas = new Canvas(pdfCanvas, page.getPageSize())) {
// ImageData imageData = ImageDataFactory.create(qrCodeBytes);
// Image image = new Image(imageData)
// .scaleAbsolute(newWidth, newHeight)
// .setFixedPosition(qrX, qrY);
// canvas.add(image);
// }
// }
//
// pdfDoc.close();
// return pdfOut;
// }
// public static void main(String[] args) {
// String path = "C:\\Users\\YuanJie\\Desktop\\test.pdf";
// String outputPath = "C:\\Users\\YuanJie\\Desktop\\test1.pdf";
//
// String params = "http://192.168.110.151:7788/codeDetail?id=" + "1957649652924448769";
// byte[] bytes = PdfBoxQrCodeGenerator.generateQRCodeBytes(params);
//
// try {
// System.out.println("二维码字节大小: " + bytes.length + " 字节");
//
// // 在每一页添加二维码
// ByteArrayOutputStream byteArrayOutputStream =
// PdfBoxQrCodeGenerator.addQRCodeToPDFOnAllPages(path, bytes, false);
//
// try (FileOutputStream fileOut = new FileOutputStream(outputPath)) {
// byteArrayOutputStream.writeTo(fileOut);
// }
//
// System.out.println("PDF文件已成功生成到: " + outputPath);
// System.out.println("生成的PDF大小: " + new File(outputPath).length() + " 字节");
//
// } catch (Exception e) {
// e.printStackTrace();
// System.out.println("图纸管理 => 审核结束,向文件添加二维码失败");
// }
// }
/**
* 在PDF每一页的指定位置添加二维码并返回数据流二维码放大10倍居中放置带边界检查
*/
public static ByteArrayOutputStream addQRCodeToPDFOnAllPages(String srcPdf, byte[] qrCodeBytes, boolean isChangeFile)
throws IOException {
PdfReader reader;
if (srcPdf.startsWith("http://") || srcPdf.startsWith("https://")) {
// 网络地址 PDF
URL url = new URL(srcPdf);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10000);
@ -130,7 +247,6 @@ public class PdfBoxQrCodeGenerator {
InputStream inputStream = connection.getInputStream();
reader = new PdfReader(inputStream);
} else {
// 本地文件 PDF
File srcFile = new File(srcPdf);
if (!srcFile.exists()) {
throw new IOException("源PDF文件不存在: " + srcPdf);
@ -144,6 +260,11 @@ public class PdfBoxQrCodeGenerator {
int numberOfPages = pdfDoc.getNumberOfPages();
// 默认放大倍数为10倍
float scaleMultiplier = 10.0f;
float baseQrSize = 80f;
float qrSize = baseQrSize * scaleMultiplier;
for (int pageNum = 1; pageNum <= numberOfPages; pageNum++) {
PdfPage page = pdfDoc.getPage(pageNum);
Rectangle pageSize = page.getPageSize();
@ -151,37 +272,27 @@ public class PdfBoxQrCodeGenerator {
float pageWidth = pageSize.getWidth();
float pageHeight = pageSize.getHeight();
float qrX, qrY;
float newWidth, newHeight;
// 确保二维码尺寸不会超过页面尺寸的80%
float maxQrSize = Math.min(pageWidth, pageHeight) * 0.8f;
float finalQrSize = Math.min(qrSize, maxQrSize);
if (isChangeFile && pageNum == 1) {
qrX = pageWidth - 143;
qrY = pageHeight - 213;
newWidth = 67;
newHeight = 80;
} else {
if (pageWidth > pageHeight) {
// 横版
qrX = pageWidth - 90;
qrY = 24;
newWidth = 67;
newHeight = 79;
} else {
// 竖版
qrX = 226;
qrY = pageHeight - 185;
newWidth = 69;
newHeight = 80;
// 将二维码放在页面中央
float qrX = (pageWidth - finalQrSize) / 2;
float qrY = (pageHeight - finalQrSize) / 2;
try {
PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDoc);
try (Canvas canvas = new Canvas(pdfCanvas, pageSize)) {
ImageData imageData = ImageDataFactory.create(qrCodeBytes);
com.itextpdf.layout.element.Image image = new com.itextpdf.layout.element.Image(imageData);
image.scaleAbsolute(finalQrSize, finalQrSize);
image.setFixedPosition(qrX, qrY);
canvas.add(image);
}
}
PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDoc);
try (Canvas canvas = new Canvas(pdfCanvas, page.getPageSize())) {
ImageData imageData = ImageDataFactory.create(qrCodeBytes);
Image image = new Image(imageData)
.scaleAbsolute(newWidth, newHeight)
.setFixedPosition(qrX, qrY);
canvas.add(image);
} catch (Exception e) {
System.err.println("在页面 " + pageNum + " 添加二维码时出错: " + e.getMessage());
e.printStackTrace();
}
}
@ -189,6 +300,8 @@ public class PdfBoxQrCodeGenerator {
return pdfOut;
}
// 如果使用带放大倍数参数的方法需要修改main方法
public static void main(String[] args) {
String path = "C:\\Users\\YuanJie\\Desktop\\test.pdf";
String outputPath = "C:\\Users\\YuanJie\\Desktop\\test1.pdf";
@ -199,7 +312,13 @@ public class PdfBoxQrCodeGenerator {
try {
System.out.println("二维码字节大小: " + bytes.length + " 字节");
// 在每一页添加二维码
// 先保存二维码图片用于验证
try (FileOutputStream qrOut = new FileOutputStream("C:\\Users\\YuanJie\\Desktop\\qrcode.png")) {
qrOut.write(bytes);
System.out.println("二维码图片已保存到桌面,用于验证二维码是否生成正确");
}
// 在每一页添加二维码放大10倍
ByteArrayOutputStream byteArrayOutputStream =
PdfBoxQrCodeGenerator.addQRCodeToPDFOnAllPages(path, bytes, false);
@ -207,14 +326,45 @@ public class PdfBoxQrCodeGenerator {
byteArrayOutputStream.writeTo(fileOut);
}
File outputFile = new File(outputPath);
System.out.println("PDF文件已成功生成到: " + outputPath);
System.out.println("生成的PDF大小: " + new File(outputPath).length() + " 字节");
System.out.println("生成的PDF大小: " + outputFile.length() + " 字节");
if (outputFile.length() == new File(path).length()) {
System.out.println("警告:输出文件大小与原文件相同,可能二维码未正确添加");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("图纸管理 => 审核结束,向文件添加二维码失败");
}
}
}

View File

@ -22,6 +22,14 @@ import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserAtte
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserGisVo;
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserVo;
import org.dromara.contractor.service.ISubConstructionUserService;
import org.dromara.project.domain.dto.project.BusProjectQueryReq;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamQueryReq;
import org.dromara.project.domain.dto.projectteammember.BusProjectTeamMemberCreateReq;
import org.dromara.project.domain.vo.project.BusProjectVo;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamVo;
import org.dromara.project.service.IBusProjectService;
import org.dromara.project.service.IBusProjectTeamMemberService;
import org.dromara.project.service.IBusProjectTeamService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -41,6 +49,12 @@ public class SubConstructionUserController extends BaseController {
private final ISubConstructionUserService constructionUserService;
private final IBusProjectTeamService busProjectTeamService;
private final IBusProjectTeamMemberService busProjectTeamMemberService;
private final IBusProjectService projectService;
/**
* 查询施工人员列表
*/
@ -190,4 +204,36 @@ public class SubConstructionUserController extends BaseController {
@PathVariable Long[] ids) {
return toAjax(constructionUserService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 查询项目班组列表
*/
@SaCheckPermission("project:projectTeam:addTeam")
@GetMapping("/projectList")
public TableDataInfo<BusProjectVo> list(BusProjectQueryReq req, PageQuery pageQuery) {
return projectService.queryPageList(req, pageQuery);
}
/**
* 查询项目班组列表
*/
@SaCheckPermission("project:projectTeam:addTeam")
@GetMapping("/teamList")
public TableDataInfo<BusProjectTeamVo> teamList(BusProjectTeamQueryReq req, PageQuery pageQuery) {
return busProjectTeamService.queryPageList(req, pageQuery);
}
/**
* 添加项目班组
*/
@SaCheckPermission("project:projectTeam:addTeam")
@RepeatSubmit()
@PostMapping("/addTeam")
public R<Long> add(@Validated(AddGroup.class) @RequestBody BusProjectTeamMemberCreateReq req) {
return R.ok(busProjectTeamMemberService.insertByBo(req));
}
}

View File

@ -50,6 +50,18 @@ public class SubConstructionUserAppController {
return R.ok(constructionUserService.getVo(constructionUser, false));
}
/**
* 获取当前登录用户实名信息
*/
@GetMapping("/isReal")
public R<SubConstructionUserVo> isReal() {
SubConstructionUser constructionUser = constructionUserService.lambdaQuery()
.eq(SubConstructionUser::getSysUserId, LoginHelper.getUserId())
.last("limit 1")
.one();
return R.ok(constructionUserService.getVo(constructionUser, false));
}
/**
* 根据用户id查询施工人员信息
*/

View File

@ -48,6 +48,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.FileNameMap;
import java.net.URLConnection;
@ -446,6 +447,11 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
byte[] bytes = PdfBoxQrCodeGenerator.generateQRCodeBytes(params);
try {
ByteArrayOutputStream baos = PdfBoxQrCodeGenerator.addQRCodeToPDFOnAllPages(ossVo.getUrl(), bytes,isChangeFile);
try (FileOutputStream fileOut = new FileOutputStream("C:\\Users\\YuanJie\\Desktop\\test1.pdf")) {
baos.writeTo(fileOut);
}
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String originalName = ossVo.getOriginalName();
String contentType = fileNameMap.getContentTypeFor(originalName);

View File

@ -117,7 +117,9 @@ public class DesVolumeFileServiceImpl extends ServiceImpl<DesVolumeFileMapper, D
Page<DesVolumeFileJoinVo> page = baseMapper.queryJoinPageList(pageQuery.build(), bo);
for (DesVolumeFileJoinVo vo : page.getRecords()) {
SysOssVo ossVo = ossService.getById(vo.getFileId());
vo.setFileUrl(ossVo.getUrl());
if (ossVo != null) {
vo.setFileUrl(ossVo.getUrl());
}
}
return TableDataInfo.build(page);
}
@ -482,6 +484,7 @@ public class DesVolumeFileServiceImpl extends ServiceImpl<DesVolumeFileMapper, D
return;
}
desVolumeFile.setAuditStatus(processEvent.getStatus());
this.updateById(desVolumeFile);
//如果完成,以前的图纸类型变为作废图纸,状态改为作废 暂定
if (processEvent.getStatus().equals("finish")) {
// this.lambdaUpdate().set(DesVolumeFile::getStatus, "2")
@ -498,8 +501,7 @@ public class DesVolumeFileServiceImpl extends ServiceImpl<DesVolumeFileMapper, D
return null;
});
}
desVolumeFile.setFileId(null);
this.updateById(desVolumeFile);
}
/**
@ -547,6 +549,7 @@ public class DesVolumeFileServiceImpl extends ServiceImpl<DesVolumeFileMapper, D
return;
}
desVolumeFile.setAuditStatus(processEvent.getStatus());
this.updateById(desVolumeFile);
if (processEvent.getStatus().equals("finish")) {
//修改目录状态
volumeCatalogService.update(Wrappers.<DesVolumeCatalog>lambdaUpdate()
@ -561,8 +564,7 @@ public class DesVolumeFileServiceImpl extends ServiceImpl<DesVolumeFileMapper, D
return null;
});
}
desVolumeFile.setFileId(null);
this.updateById(desVolumeFile);
}
/**

View File

@ -13,11 +13,14 @@ import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.project.domain.bo.BusProjectPunchrangeBo;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamCreateReq;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamQueryReq;
import org.dromara.project.domain.dto.projectteam.BusProjectTeamUpdateReq;
import org.dromara.project.domain.vo.BusProjectPunchrangeVo;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamForemanVo;
import org.dromara.project.domain.vo.projectteam.BusProjectTeamVo;
import org.dromara.project.service.IBusProjectPunchrangeService;
import org.dromara.project.service.IBusProjectTeamService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -38,6 +41,7 @@ public class BusProjectTeamController extends BaseController {
private final IBusProjectTeamService busProjectTeamService;
private final IBusProjectPunchrangeService busProjectPunchrangeService;
/**
* 查询项目班组列表
*/
@ -114,4 +118,13 @@ public class BusProjectTeamController extends BaseController {
@PathVariable Long[] ids) {
return toAjax(busProjectTeamService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 考勤范围列表
*/
@SaCheckPermission("project:projectTeam:editPunchRange")
@GetMapping("/rangeList")
public TableDataInfo<BusProjectPunchrangeVo> list(BusProjectPunchrangeBo bo, PageQuery pageQuery) {
return busProjectPunchrangeService.queryPageList(bo, pageQuery);
}
}

View File

@ -16,10 +16,7 @@ import org.dromara.project.domain.dto.attendance.BusAttendancePunchCardByFaceReq
import org.dromara.project.domain.vo.BusAttendanceRuleVo;
import org.dromara.project.domain.vo.BusAttendanceVo;
import org.dromara.project.domain.vo.BusMonthAttendanceVo;
import org.dromara.project.domain.vo.attendance.AttendanceCountVo;
import org.dromara.project.domain.vo.attendance.AttendanceUserCountVo;
import org.dromara.project.domain.vo.attendance.AttendanceUserDataVo;
import org.dromara.project.domain.vo.attendance.AttendanceUserVo;
import org.dromara.project.domain.vo.attendance.*;
import org.dromara.project.service.IBusAttendanceRuleService;
import org.dromara.project.service.IBusAttendanceService;
import org.dromara.project.service.IBusProjectPunchrangeService;
@ -106,7 +103,6 @@ public class BusAttendanceAppController extends BaseController {
return R.ok(attendanceService.getTodayAttendance(projectId));
}
/**
* 获取用户指定月份打卡记录
*/
@ -124,7 +120,6 @@ public class BusAttendanceAppController extends BaseController {
return R.ok(attendanceService.getAbnormalAttendance(projectId));
}
/**
* 统计指定日期的打卡人员数量
*/
@ -133,7 +128,6 @@ public class BusAttendanceAppController extends BaseController {
return R.ok(attendanceService.getAttendanceCount(dto));
}
/**
* 指定日期的打卡人员列表
*/
@ -142,9 +136,6 @@ public class BusAttendanceAppController extends BaseController {
return attendanceService.getAttendanceUser(dto,pageQuery);
}
/**
* 指定月份的打卡人员考勤统计
*/
@ -153,8 +144,6 @@ public class BusAttendanceAppController extends BaseController {
return R.ok(attendanceService.getAttendanceUserCount(dto));
}
/**
* 指定月份的打卡人员考勤数据
*/
@ -164,8 +153,13 @@ public class BusAttendanceAppController extends BaseController {
}
/**
* 指定月份的打卡人员信息
*/
@GetMapping("/getAttendanceUserInfo")
public R<AttendanceUserInfoVo> getAttendanceUserInfo(AttendanceUserCountDto dto){
return R.ok(attendanceService.getAttendanceUserInfo(dto));
}

View File

@ -1,10 +1,16 @@
package org.dromara.project.controller.app;
import cn.dev33.satoken.annotation.SaIgnore;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.project.domain.dto.project.BusProjectQueryReq;
import org.dromara.project.domain.dto.userprojectrelevancy.BusUserProjectRelevancyQueryReq;
import org.dromara.project.domain.vo.project.BusProjectContractorTeamListVo;
import org.dromara.project.domain.vo.project.BusProjectVo;
import org.dromara.project.domain.vo.userprojectrelevancy.BusLoginUserProjectRelevancyVo;
import org.dromara.project.service.IBusProjectService;
import org.dromara.project.service.IBusUserProjectRelevancyService;
@ -58,4 +64,15 @@ public class BusProjectAppController {
Long userId = LoginHelper.getUserId();
return R.ok(userProjectRelevancyService.queryListByUserId(userId));
}
/**
* 注册项目选择列表
*/
@SaIgnore
@GetMapping("/register/list")
public R<List<BusProjectVo>> registerList() {
BusProjectQueryReq busProjectQueryReq = new BusProjectQueryReq();
busProjectQueryReq.setPId(0L);
return R.ok(projectService.queryList(busProjectQueryReq));
}
}

View File

@ -0,0 +1,37 @@
package org.dromara.project.domain.vo.attendance;
import lombok.Data;
import java.util.Date;
@Data
public class AttendanceUserInfoVo {
private Long userId;
/**
* 用户昵称
*/
private String nickName;
/**
* 用户头像
*/
private String avatar;
/**
* 入场时间
*/
private Date entryDate;
/**
* 离场时间
*/
private Date leaveDate;
/**
* 退场状态(0未退场 1退场未提交材料 2已退场)
*/
private String exitStatus;
}

View File

@ -6,11 +6,13 @@ 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.BusProjectPunchrange;
import org.dromara.project.domain.BusProjectTeam;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
@ -69,4 +71,8 @@ public class BusProjectTeamVo implements Serializable {
@ExcelProperty(value = "创建时间")
private Date createTime;
/**
* 打卡范围
*/
List<String> punchRangeList;
}

View File

@ -12,10 +12,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.project.domain.vo.BusMonthAttendanceVo;
import org.dromara.project.domain.vo.attendance.AttendanceCountVo;
import org.dromara.project.domain.vo.attendance.AttendanceUserCountVo;
import org.dromara.project.domain.vo.attendance.AttendanceUserDataVo;
import org.dromara.project.domain.vo.attendance.AttendanceUserVo;
import org.dromara.project.domain.vo.attendance.*;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
@ -151,4 +148,9 @@ public interface IBusAttendanceService extends IService<BusAttendance>{
* 指定月份的打卡人员考勤数据
*/
AttendanceUserDataVo getAttendanceUserData(AttendanceUserCountDto dto);
/**
* 指定月份的打卡人员信息
*/
AttendanceUserInfoVo getAttendanceUserInfo(AttendanceUserCountDto dto);
}

View File

@ -595,8 +595,18 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
LambdaQueryWrapper<SubConstructionUser> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SubConstructionUser::getProjectId, dto.getProjectId());
if("1".equals(dto.getClockStatus()) && CollectionUtil.isEmpty(attendanceUserIds)){
TableDataInfo<AttendanceUserVo> rspData = new TableDataInfo<>();
rspData.setCode(cn.hutool.http.HttpStatus.HTTP_OK);
rspData.setMsg("查询成功");
rspData.setRows(List.of());
rspData.setTotal(0);
return rspData;
}
wrapper.in("1".equals(dto.getClockStatus()),SubConstructionUser::getSysUserId,attendanceUserIds);
wrapper.notIn("2".equals(dto.getClockStatus()),SubConstructionUser::getSysUserId,attendanceUserIds);
wrapper.notIn("2".equals(dto.getClockStatus()) && CollectionUtil.isNotEmpty(attendanceUserIds),SubConstructionUser::getSysUserId,attendanceUserIds);
wrapper.eq(StrUtil.isNotBlank(dto.getTypeOfWork()),SubConstructionUser::getTypeOfWork,dto.getTypeOfWork());
wrapper.eq(dto.getTeamId()!=null,SubConstructionUser::getTeamId,dto.getTeamId());
Page<SubConstructionUser> result = constructionUserService.page(pageQuery.build(), wrapper);
@ -746,5 +756,29 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
}
@Override
public AttendanceUserInfoVo getAttendanceUserInfo(AttendanceUserCountDto dto) {
AttendanceUserInfoVo attendanceUserInfoVo = new AttendanceUserInfoVo();
SysUserVo sysUserVo = userService.selectUserById(dto.getUserId());
if(sysUserVo == null){
throw new ServiceException("用户信息不存在");
}
if(sysUserVo.getAvatar() != null){
SysOssVo byId = ossService.getById(sysUserVo.getAvatar());
attendanceUserInfoVo.setAvatar(byId.getUrl());
}
attendanceUserInfoVo.setUserId(sysUserVo.getUserId());
attendanceUserInfoVo.setNickName(sysUserVo.getNickName());
SubConstructionUser constructionUser = constructionUserService.getBySysUserId(dto.getUserId());
if(constructionUser == null){
throw new ServiceException("施工人员信息不存在");
}
attendanceUserInfoVo.setLeaveDate(constructionUser.getLeaveDate());
attendanceUserInfoVo.setEntryDate(constructionUser.getEntryDate());
attendanceUserInfoVo.setExitStatus(constructionUser.getExitStatus());
return attendanceUserInfoVo;
}
}

View File

@ -1,6 +1,7 @@
package org.dromara.project.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -19,6 +20,7 @@ import org.dromara.contractor.service.ISubConstructionUserService;
import org.dromara.project.domain.BusConstructionUserExit;
import org.dromara.project.domain.BusProjectTeam;
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.BusProjectTeamMemberExitReq;
import org.dromara.project.domain.dto.projectteammember.BusProjectTeamMemberQueryReq;
@ -68,6 +70,9 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl<BusProjectTeamM
@Resource
private IBusConstructionUserExitService constructionUserExitService;
@Resource
private IBusUserProjectRelevancyService userProjectRelevancyService;
/**
* 查询项目班组下的成员
*
@ -149,12 +154,26 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl<BusProjectTeamM
// 同步修改用户表的team_id字段并添加入场时间
LambdaUpdateWrapper<SubConstructionUser> constructionUserLuw = Wrappers.lambdaUpdate(SubConstructionUser.class)
.eq(SubConstructionUser::getId, constructionUser.getId())
.set(SubConstructionUser::getProjectId, req.getProjectId())
.set(SubConstructionUser::getTeamId, projectTeamMember.getTeamId())
.set(SubConstructionUser::getTeamName, projectTeam.getTeamName())
.set(SubConstructionUser::getEntryDate, new Date())
.set(SubConstructionUser::getLeaveDate, null)
.set(SubConstructionUser::getExitStatus, "0");
constructionUserService.update(constructionUserLuw);
List<BusUserProjectRelevancy> list = userProjectRelevancyService.list(Wrappers.lambdaQuery(BusUserProjectRelevancy.class)
.eq(BusUserProjectRelevancy::getUserId, constructionUser.getSysUserId())
.eq(BusUserProjectRelevancy::getProjectId, req.getProjectId())
);
if(CollectionUtil.isEmpty(list)){
BusUserProjectRelevancy relevancy = new BusUserProjectRelevancy();
relevancy.setUserId(constructionUser.getSysUserId());
relevancy.setProjectId(req.getProjectId());
userProjectRelevancyService.save(relevancy);
}
return projectTeamMember.getId();
}

View File

@ -37,10 +37,7 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -67,6 +64,7 @@ public class BusProjectTeamServiceImpl extends ServiceImpl<BusProjectTeamMapper,
@Resource
private IBusProjectPunchrangeService projectPunchrangeService;
/**
* 查询项目班组
*
@ -355,6 +353,22 @@ public class BusProjectTeamServiceImpl extends ServiceImpl<BusProjectTeamMapper,
.eq(BusProjectTeamMember::getTeamId, projectTeam.getId())
.count();
projectTeamVo.setPeopleNumber(peopleNumber);
String punchRange = projectTeam.getPunchRange();
if (StringUtils.isNotBlank(punchRange)) {
try {
// 直接解析为 JSONArray 并转换为 Long 列表
cn.hutool.json.JSONArray jsonArray = JSONUtil.parseArray(punchRange);
List<String> punchRangeList = new ArrayList<>();
for (int i = 0; i < jsonArray.size(); i++) {
punchRangeList.add(jsonArray.getStr(i));
}
projectTeamVo.setPunchRangeList(punchRangeList);
} catch (Exception e) {
projectTeamVo.setPunchRangeList(new ArrayList<>());
}
}
return projectTeamVo;
}

View File

@ -191,6 +191,7 @@ public class QltQualityInspectionServiceImpl extends ServiceImpl<QltQualityInspe
validEntityBeforeSave(qualityInspection);
// 填充默认值
qualityInspection.setInspectionStatus(QltQualityInspectionStatusEnum.INFORM.getValue());
// 写入数据库
boolean save = this.save(qualityInspection);
if (!save) {
@ -291,12 +292,28 @@ public class QltQualityInspectionServiceImpl extends ServiceImpl<QltQualityInspe
List<SysOssVo> ossVoList = ossService.listByIds(ossIdList);
qualityInspectionVo.setInspectionFileList(ossVoList);
}
String inspectionImgFile = qualityInspection.getInspectionImgFile();
if (StringUtils.isNotBlank(inspectionImgFile)) {
List<Long> ossIdList = Arrays.stream(inspectionImgFile.split(",")).map(Long::parseLong).toList();
List<SysOssVo> ossVoList = ossService.listByIds(ossIdList);
qualityInspectionVo.setInspectionImgFileList(ossVoList);
}
String rectificationFile = qualityInspection.getRectificationFile();
if (StringUtils.isNotBlank(rectificationFile)) {
List<Long> ossIdList = Arrays.stream(rectificationFile.split(",")).map(Long::parseLong).toList();
List<SysOssVo> ossVoList = ossService.listByIds(ossIdList);
qualityInspectionVo.setRectificationFileList(ossVoList);
}
String rectificationImgFile = qualityInspection.getRectificationImgFile();
if (StringUtils.isNotBlank(rectificationImgFile)) {
List<Long> ossIdList = Arrays.stream(rectificationImgFile.split(",")).map(Long::parseLong).toList();
List<SysOssVo> ossVoList = ossService.listByIds(ossIdList);
qualityInspectionVo.setRectificationImgFileList(ossVoList);
}
return qualityInspectionVo;
}

View File

@ -0,0 +1,87 @@
package org.dromara.system.controller.app;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.encrypt.annotation.ApiEncrypt;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.bo.SysPostBo;
import org.dromara.system.domain.bo.SysRoleBo;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.dto.role.SysRoleProjectDto;
import org.dromara.system.domain.enums.SysDeptTypeEnum;
import org.dromara.system.domain.vo.*;
import org.dromara.system.listener.SysUserImportListener;
import org.dromara.system.service.*;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 用户信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/app/system/user")
public class SysUserAppController extends BaseController {
private final ISysUserService userService;
private final ISysRoleService roleService;
private final ISysPostService postService;
private final ISysDeptService deptService;
private final ISysTenantService tenantService;
/**
* 判断账号存在不
*/
@SaIgnore
@GetMapping("/accountExist")
public R<Boolean> accountExist(String username) {
SysUserVo sysUserVo = userService.selectUserByUserName(username);
return R.ok(sysUserVo != null);
}
/**
* 获取部门树列表
*/
@SaIgnore
@GetMapping("/deptTree")
public R<List<Tree<Long>>> deptTree(SysDeptBo dept) {
dept.setDeptTypes(Arrays.asList(SysDeptTypeEnum.PROJECT.getCode(), SysDeptTypeEnum.COMPANY.getCode()
, SysDeptTypeEnum.CONTRACT.getCode()));
return R.ok(deptService.selectDeptTreeList(dept));
}
}

View File

@ -24,6 +24,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
/**
* 菜单信息
@ -45,8 +46,13 @@ public class SysMenuController extends BaseController {
*/
@GetMapping("/getRouters/{projectId}")
public R<List<RouterVo>> getRouters(@NotNull(message = "项目主键不能为空")
@PathVariable Long projectId) {
@PathVariable Long projectId,String menuSource) {
List<SysMenu> menus = menuService.selectMenuTreeByUserId(LoginHelper.getUserId(), projectId);
if("2".equals(menuSource)){
menus = menus.stream().filter(menu -> "2".equals(menu.getMenuSource())).collect(Collectors.toList());
}else {
menus = menus.stream().filter(menu -> "1".equals(menu.getMenuSource())).collect(Collectors.toList());
}
return R.ok(menuService.buildMenus(menus));
}
@ -96,8 +102,11 @@ public class SysMenuController extends BaseController {
*/
@SaCheckPermission("system:menu:query")
@GetMapping(value = "/roleMenuTreeselect/{roleId}")
public R<MenuTreeSelectVo> roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
public R<MenuTreeSelectVo> roleMenuTreeselect(@PathVariable("roleId") Long roleId,String menuSource) {
SysMenuBo sysMenuBo = new SysMenuBo();
sysMenuBo.setMenuSource(menuSource);
List<SysMenuVo> menus = menuService.selectMenuList(sysMenuBo,LoginHelper.getUserId());
MenuTreeSelectVo selectVo = new MenuTreeSelectVo();
selectVo.setCheckedKeys(menuService.selectMenuListByRoleId(roleId));
selectVo.setMenus(menuService.buildMenuTreeSelect(menus));

View File

@ -8,6 +8,7 @@ import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.system.domain.SysDept;
import java.io.Serial;
import java.util.List;
/**
* 部门业务对象 sys_dept
@ -87,4 +88,7 @@ public class SysDeptBo extends BaseEntity {
@NotBlank(message = "部门类型不能为空")
private String deptType;
private List<String> deptTypes;
}

View File

@ -0,0 +1,77 @@
package org.dromara.system.domain.dto.role;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.system.domain.SysRole;
/**
* 角色信息业务对象 sys_role
*
* @author Michelle.Chung
*/
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = SysRole.class, reverseConvertGenerate = false)
public class ConPerSysRoleDto extends BaseEntity {
public static final String ROLE_KEY = "base-sgry";
/**
* 角色ID
*/
private Long roleId;
/**
* 部门ID
*/
private Long deptId;
private String roleName = "施工人员";
private String roleKey = "base-sgry";
private Integer roleSort = 1;
private String dataScope = "1";
/**
* 菜单树选择项是否关联显示
*/
private Boolean menuCheckStrictly = true;
/**
* 部门树选择项是否关联显示
*/
private Boolean deptCheckStrictly = true;
/**
* 角色状态0正常 1停用
*/
private String status = "0";
/**
* 备注
*/
private String remark;
/**
* 菜单组
*/
private Long[] menuIds;
/**
* 角色类型 1-web 2-app
*/
private String roleSource = "2";
}

View File

@ -114,4 +114,8 @@ public class SysRoleVo implements Serializable {
return SystemConstants.SUPER_ADMIN_ID.equals(this.roleId);
}
/**
* 角色类型 1-web 2-app
*/
private String roleSource;
}

View File

@ -2,6 +2,7 @@ package org.dromara.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil;
@ -25,6 +26,8 @@ import org.dromara.system.domain.SysPost;
import org.dromara.system.domain.SysRole;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.bo.SysRoleBo;
import org.dromara.system.domain.dto.role.ConPerSysRoleDto;
import org.dromara.system.domain.enums.SysDeptTypeEnum;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.domain.vo.SysPostVo;
@ -33,6 +36,7 @@ import org.dromara.system.mapper.SysPostMapper;
import org.dromara.system.mapper.SysRoleMapper;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysRoleService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
@ -57,6 +61,8 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
private final SysUserMapper userMapper;
private final SysPostMapper postMapper;
private final ISysRoleService roleService;
/**
* 查询部门管理数据
*
@ -93,6 +99,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus());
lqw.eq(StringUtils.isNotBlank(bo.getIsShow()), SysDept::getIsShow, bo.getIsShow());
lqw.eq(StringUtils.isNotBlank(bo.getDeptType()), SysDept::getDeptType, bo.getDeptType());
lqw.in(CollectionUtil.isNotEmpty(bo.getDeptTypes()), SysDept::getDeptType, bo.getDeptTypes());
lqw.orderByAsc(SysDept::getAncestors);
lqw.orderByAsc(SysDept::getParentId);
lqw.orderByAsc(SysDept::getOrderNum);
@ -415,6 +422,18 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
if (insert < 1) {
throw new ServiceException("添加部门失败", HttpStatus.ERROR);
}
if( SysDeptTypeEnum.PROJECT.getCode().equals(bo.getDeptType())){
SysRoleBo sysRoleBo = new SysRoleBo();
ConPerSysRoleDto conPerSysRoleDto = new ConPerSysRoleDto();
conPerSysRoleDto.setDeptId(dept.getDeptId());
BeanUtil.copyProperties(conPerSysRoleDto,sysRoleBo);
roleService.insertRole(sysRoleBo);
}
return insert;
}

View File

@ -107,6 +107,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
QueryWrapper<SysUser> wrapper = Wrappers.query();
wrapper.eq("u.del_flag", SystemConstants.NORMAL)
.eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId())
.like(StringUtils.isNotBlank(user.getNickName()), "u.nick_name", user.getNickName())
.like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
.eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
.like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber())

View File

@ -68,7 +68,8 @@
m.menu_type,
m.icon,
m.order_num,
m.create_time
m.create_time,
m.menu_source
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id and m.status = '0'
left join sys_role r on rm.role_id = r.role_id and r.status = '0'

View File

@ -20,7 +20,8 @@
r.del_flag,
r.create_time,
r.remark,
r.is_special
r.is_special,
r.role_source
from sys_role r
left join sys_user_role sur on sur.role_id = r.role_id
left join sys_user u on u.user_id = sur.user_id