Compare commits
104 Commits
936145138e
...
dev
Author | SHA1 | Date | |
---|---|---|---|
a8cb16ab3f | |||
2c45762c66 | |||
056b28af31 | |||
7dd6d97a3e | |||
697beb67c4 | |||
4d627af3a1 | |||
ab332c462f | |||
0f3d1e38be | |||
4392a287cc | |||
f38538be33 | |||
ede1e501b4 | |||
4a2b62cf92 | |||
325f392e8f | |||
5b991396c2 | |||
c75563b46a | |||
724ebf8dbd | |||
a52b9078a0 | |||
9d682a3290 | |||
abad289c2b | |||
820188863e | |||
113b5debc9 | |||
6b4cd4ae0d | |||
261dd0b643 | |||
71f3810e51 | |||
fa835684d4 | |||
e19ef3003a | |||
8a18223d06 | |||
c90828f98e | |||
2ecb0063bf | |||
998547e63f | |||
78829ef5e7 | |||
da0dd8f78f | |||
96d0406931 | |||
d7616960c6 | |||
66e8495859 | |||
95c2858a64 | |||
5cbb0c630b | |||
e0cc521291 | |||
ff9f49b1d9 | |||
b738bb821d | |||
2cea57646d | |||
ab5cd491d6 | |||
3f3e20a64b | |||
f5d9cb7fc1 | |||
5b05d2eb40 | |||
fbffc18a9f | |||
490820d080 | |||
8e9b7c9b14 | |||
ae3738c098 | |||
127059e934 | |||
742e67af23 | |||
4e61a4afe9 | |||
43d249d68a | |||
dc8a89f05e | |||
17d4041ef3 | |||
d19cda78b3 | |||
2f0b548f20 | |||
f1aed20560 | |||
8c412d033b | |||
a929225ed5 | |||
3b6b1d53a9 | |||
81162852a2 | |||
f584e6233c | |||
e8da350f0b | |||
e916829032 | |||
8c131cb9a5 | |||
9aef0d4b86 | |||
de5c569f88 | |||
79edeb6ccd | |||
a3ef525ab6 | |||
659e4e3d5f | |||
96e6c75949 | |||
711c473749 | |||
4636aa3c05 | |||
788f13fa7b | |||
a588b94310 | |||
b44de3ff49 | |||
5d643fbc6a | |||
19fd73f4c8 | |||
a07792c8e3 | |||
8a29ffdd2e | |||
d46f672b9a | |||
d6528845e4 | |||
0ff805683f | |||
3f79a955b3 | |||
971c8c277d | |||
12f02638a2 | |||
b1c21b1f88 | |||
642d5c73ca | |||
d7054d6f02 | |||
e85bbca73b | |||
3f5396e347 | |||
c9041df9b8 | |||
87e510aafc | |||
4e4497a07f | |||
7c4f6b8add | |||
7daf2ada66 | |||
073f614a21 | |||
1878a7dab3 | |||
aa31eb97b9 | |||
4f8776930e | |||
f171238029 | |||
377892f691 | |||
7e0cd7c946 |
BIN
xinnengyuan/fonts/simhei.ttf
Normal file
BIN
xinnengyuan/fonts/simhei.ttf
Normal file
Binary file not shown.
@ -307,7 +307,6 @@
|
||||
<artifactId>snail-job-client-job-core</artifactId>
|
||||
<version>${snailjob.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 加密包引入 -->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
|
@ -6,6 +6,7 @@ import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -41,16 +42,20 @@ import org.dromara.web.domain.vo.TenantListVo;
|
||||
import org.dromara.web.service.IAuthStrategy;
|
||||
import org.dromara.web.service.SysLoginService;
|
||||
import org.dromara.web.service.SysRegisterService;
|
||||
import org.dromara.websocket.domain.ChatGroup;
|
||||
import org.dromara.websocket.service.Impl.ChatGroupServiceImpl;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 认证
|
||||
@ -72,6 +77,7 @@ public class AuthController {
|
||||
private final ISysSocialService socialUserService;
|
||||
private final ISysClientService clientService;
|
||||
private final ScheduledExecutorService scheduledExecutorService;
|
||||
private final ChatGroupServiceImpl chatGroupService;
|
||||
|
||||
|
||||
/**
|
||||
@ -103,10 +109,7 @@ public class AuthController {
|
||||
|
||||
// Long userId = LoginHelper.getUserId();
|
||||
// scheduledExecutorService.schedule(() -> {
|
||||
// SseMessageDto dto = new SseMessageDto();
|
||||
// dto.setMessage("欢迎登录新能源项目管理系统");
|
||||
// dto.setUserIds(List.of(userId));
|
||||
// SseMessageUtils.publishMessage(dto);
|
||||
// chatGroupService.createSystem(userId,client.getClientKey());
|
||||
// }, 5, TimeUnit.SECONDS);
|
||||
return R.ok(loginVo);
|
||||
}
|
||||
@ -193,6 +196,12 @@ public class AuthController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/app/register")
|
||||
public R<Void> appRegister(@Validated @RequestBody RegisterBody user) {
|
||||
registerService.appRegister(user);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录页面租户下拉框
|
||||
*
|
||||
|
@ -55,7 +55,8 @@ public class UserActionListener implements SaTokenListener {
|
||||
String username = (String) loginModel.getExtra(LoginHelper.USER_NAME_KEY);
|
||||
String tenantId = (String) loginModel.getExtra(LoginHelper.TENANT_KEY);
|
||||
dto.setUserName(username);
|
||||
dto.setClientKey((String) loginModel.getExtra(LoginHelper.CLIENT_KEY));
|
||||
String clientId = (String) loginModel.getExtra(LoginHelper.CLIENT_KEY);
|
||||
dto.setClientKey(clientId);
|
||||
dto.setDeviceType(loginModel.getDevice());
|
||||
dto.setDeptName((String) loginModel.getExtra(LoginHelper.DEPT_NAME_KEY));
|
||||
TenantHelper.dynamic(tenantId, () -> {
|
||||
@ -75,7 +76,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
SpringUtils.context().publishEvent(logininforEvent);
|
||||
// 更新登录信息
|
||||
loginService.recordLoginInfo((Long) loginModel.getExtra(LoginHelper.USER_KEY), ip);
|
||||
log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
|
||||
log.info("user doLogin, userId:{}, token:{}, clientid{}", loginId, tokenValue, clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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("注册失败,密码需满足8–18位,包含大小写字母、数字、特殊字符中的至少三种组合");
|
||||
}
|
||||
// 验证码开关
|
||||
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"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
*
|
||||
|
@ -13,13 +13,13 @@ 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` 表
|
||||
token: "SJ_cKqBTPzCsWA3VyuCfFoccmuIEGXjr5KT"
|
||||
server:
|
||||
host: 192.168.110.119
|
||||
host: 127.0.0.1
|
||||
port: 17888
|
||||
# 命名空间UUID 详见 script/sql/ry_job.sql `sj_namespace`表`unique_id`字段
|
||||
namespace: ${spring.profiles.active}
|
||||
@ -53,13 +53,13 @@ spring:
|
||||
username: xinnengyuandev
|
||||
password: StRWCZdZirysNSs2
|
||||
# 从库数据源
|
||||
# slave:
|
||||
# lazy: true
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: com.mysql.cj.jdbc.Driver
|
||||
# url: jdbc:mysql://192.168.110.2:13386/zmkgdev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
|
||||
# username: zmkgdev
|
||||
# password: JhYxREf25AXdy3h8
|
||||
# slave:
|
||||
# lazy: true
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: com.mysql.cj.jdbc.Driver
|
||||
# url: jdbc:mysql://192.168.110.2:13386/zmkgdev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
|
||||
# username: zmkgdev
|
||||
# password: JhYxREf25AXdy3h8
|
||||
# oracle:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: oracle.jdbc.OracleDriver
|
||||
|
@ -273,7 +273,7 @@ weather:
|
||||
api-host: n35rk53njv.re.qweatherapi.com
|
||||
# dxf转 geojson 执行文件名
|
||||
dxf2GeoJson:
|
||||
file-name: main
|
||||
file-name: main.exe
|
||||
ys7:
|
||||
app-key: 3acf9f1a43dc4209841e0893003db0a2
|
||||
app-secret: 4bbf3e9394f55d3af6e3af27b2d3db36
|
||||
|
@ -125,6 +125,8 @@ security:
|
||||
# todo 仅测试
|
||||
- /facility/matrix/**
|
||||
- /**/changxie/callback/**
|
||||
- /gps/equipment/dataAcceptance
|
||||
- /resource/oss/upload
|
||||
|
||||
# 多租户配置
|
||||
tenant:
|
||||
@ -194,6 +196,7 @@ api-decrypt:
|
||||
- /actuator/** # 放行监控接口
|
||||
- /other/ys7Device/webhook # 放行萤石云设备回调接口
|
||||
- /auth/register # 放行注册接口
|
||||
- /gps/equipment/dataAcceptance # GPS数据接收接口
|
||||
|
||||
springdoc:
|
||||
api-docs:
|
||||
@ -247,8 +250,8 @@ springdoc:
|
||||
packages-to-scan: org.dromara.design
|
||||
- group: 13.工作流模块
|
||||
packages-to-scan: org.dromara.workflow
|
||||
- group: 14.罗成模块
|
||||
packages-to-scan: org.dromara.cory
|
||||
# - group: 14.罗成模块
|
||||
# packages-to-scan: org.dromara.cory
|
||||
- group: 15.无人机模块
|
||||
packages-to-scan: org.dromara.drone
|
||||
- group: 20.代码生成模块
|
||||
@ -269,11 +272,13 @@ springdoc:
|
||||
packages-to-scan: org.dromara.bigscreen
|
||||
- group: 22.投标管理模块
|
||||
packages-to-scan: org.dromara.bidding
|
||||
- group: 23.GPS定位模块
|
||||
packages-to-scan: org.dromara.gps
|
||||
|
||||
# - group: 20.合同模块
|
||||
# packages-to-scan: org.dromara.ctr
|
||||
# - group: 21.招标模块
|
||||
# packages-to-scan: org.dromara.tender
|
||||
- group: 24.招标模块
|
||||
packages-to-scan: org.dromara.tender
|
||||
|
||||
|
||||
# knife4j的增强配置,不需要增强可以不配
|
||||
@ -328,12 +333,13 @@ sse:
|
||||
copy: /task/taskCopyList
|
||||
project: /personnel-management/project
|
||||
violationRecord: /safety-management/ai/violationRecord
|
||||
drawing: /design-management/volumeCatalog
|
||||
|
||||
|
||||
--- # websocket
|
||||
websocket:
|
||||
# 如果关闭 需要和前端开关一起关闭
|
||||
enabled: false
|
||||
enabled: true
|
||||
# 路径
|
||||
path: /resource/websocket
|
||||
# 设置访问源地址
|
||||
|
@ -1,8 +1,14 @@
|
||||
package org.dromara.test;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.contractor.domain.SubConstructionUser;
|
||||
import org.dromara.contractor.service.ISubConstructionUserService;
|
||||
import org.dromara.contractor.service.ISubUserSalaryDetailService;
|
||||
import org.dromara.design.service.IDesTechnicalStandardService;
|
||||
import org.dromara.facility.domain.FacMatrix;
|
||||
import org.dromara.facility.service.IFacMatrixService;
|
||||
@ -11,9 +17,12 @@ import org.dromara.progress.service.IPgsProgressCategoryService;
|
||||
import org.dromara.progress.service.IPgsProgressCategoryTemplateService;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.dromara.system.service.ISysDeptService;
|
||||
import org.dromara.tender.service.impl.TenderSupplierInputServiceImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -45,6 +54,14 @@ public class DemoTest {
|
||||
|
||||
@Resource
|
||||
private ISysDeptService deptService;
|
||||
@Autowired
|
||||
private TenderSupplierInputServiceImpl tenderSupplierInputService;
|
||||
|
||||
@Resource
|
||||
private ISubConstructionUserService constructionUserService;
|
||||
|
||||
@Resource
|
||||
private ISubUserSalaryDetailService userSalaryDetailService;
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
@ -99,4 +116,28 @@ public class DemoTest {
|
||||
deptService.selectProjectIdById(100L);
|
||||
deptService.selectProjectIdById(1937478258803171329L);
|
||||
}*/
|
||||
|
||||
@Test
|
||||
void tenderExport() {
|
||||
// 同步修改用户表的team_id字段并添加入场时间
|
||||
LambdaUpdateWrapper<SubConstructionUser> constructionUserLuw = Wrappers.lambdaUpdate(SubConstructionUser.class)
|
||||
.in(SubConstructionUser::getId, 1961446214960435201L, 1963077776210710529L, 1963080543771832321L, 1963151975159324673L)
|
||||
.set(SubConstructionUser::getEntryDate, new Date());
|
||||
constructionUserService.update(constructionUserLuw);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSalary() {
|
||||
List<SubConstructionUser> list = constructionUserService.lambdaQuery()
|
||||
.eq(SubConstructionUser::getProjectId, 1897160897167638529L)
|
||||
.list();
|
||||
if (CollUtil.isNotEmpty(list)) {
|
||||
for (SubConstructionUser user : list) {
|
||||
for (int i = 1; i < 7; i++) {
|
||||
userSalaryDetailService.insertByAttendance(user.getSysUserId(), LocalDate.now().minusDays(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -80,4 +80,9 @@ public interface CacheNames {
|
||||
*/
|
||||
String ONLINE_TOKEN = "online_tokens";
|
||||
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
String PROJECT_NAME = "project_name#30d";
|
||||
|
||||
}
|
||||
|
@ -30,4 +30,12 @@ public class RegisterBody extends LoginBody {
|
||||
|
||||
private String userType;
|
||||
|
||||
private Long projectId;
|
||||
|
||||
private String email;
|
||||
|
||||
private String phonenumber;
|
||||
|
||||
private Long deptId;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
package org.dromara.common.core.service;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-10 16:15
|
||||
*/
|
||||
public interface ProjectService {
|
||||
|
||||
/**
|
||||
* 通过项目ID查询项目名称
|
||||
*
|
||||
* @param projectId 项目ID
|
||||
* @return 项目名称
|
||||
*/
|
||||
String selectProjectNameById(Long projectId);
|
||||
|
||||
}
|
@ -74,7 +74,7 @@ public interface UserService {
|
||||
* @param roleIds 角色ids
|
||||
* @return 用户
|
||||
*/
|
||||
List<UserDTO> selectUsersByRoleIds(List<Long> roleIds);
|
||||
List<UserDTO> selectUsersByRoleIds(List<Long> roleIds,Long projectId);
|
||||
|
||||
/**
|
||||
* 通过部门ID查询用户
|
||||
|
@ -376,4 +376,19 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验日期范围
|
||||
*
|
||||
* @param startDate 开始日期
|
||||
* @param endDate 结束日期
|
||||
* @return true 表示日期范围有效,false 表示日期范围无效
|
||||
*/
|
||||
public static boolean isValidDateRange(LocalDate startDate, LocalDate endDate) {
|
||||
try {
|
||||
return !startDate.isAfter(endDate); // start <= end
|
||||
} catch (DateTimeParseException e) {
|
||||
return false; // 格式非法
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public class MybatisPlusConfig {
|
||||
public PaginationInnerInterceptor paginationInnerInterceptor() {
|
||||
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
|
||||
// 分页合理化
|
||||
paginationInnerInterceptor.setOverflow(true);
|
||||
paginationInnerInterceptor.setOverflow(false);
|
||||
return paginationInnerInterceptor;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,8 @@ public class SseProperties {
|
||||
|
||||
private String violationRecord;
|
||||
|
||||
private String drawing;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -32,4 +32,9 @@ public interface TransConstant {
|
||||
*/
|
||||
String OSS_ID_TO_URL = "oss_id_to_url";
|
||||
|
||||
/**
|
||||
* 项目id转名称
|
||||
*/
|
||||
String PROJECT_ID_TO_NAME = "project_id_to_name";
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
package org.dromara.common.translation.core.impl;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.dromara.common.core.service.ProjectService;
|
||||
import org.dromara.common.translation.annotation.TranslationType;
|
||||
import org.dromara.common.translation.constant.TransConstant;
|
||||
import org.dromara.common.translation.core.TranslationInterface;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-10 16:13
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@TranslationType(type = TransConstant.PROJECT_ID_TO_NAME)
|
||||
public class ProjectNameTranslationImpl implements TranslationInterface<String> {
|
||||
|
||||
@Resource
|
||||
private ProjectService projectService;
|
||||
|
||||
/**
|
||||
* 翻译
|
||||
*
|
||||
* @param key 需要被翻译的键(不为空)
|
||||
* @param other 其他参数
|
||||
* @return 返回键对应的值
|
||||
*/
|
||||
@Override
|
||||
public String translation(Object key, String other) {
|
||||
if (key instanceof Long id) {
|
||||
return projectService.selectProjectNameById(id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -4,3 +4,4 @@ org.dromara.common.translation.core.impl.DictTypeTranslationImpl
|
||||
org.dromara.common.translation.core.impl.OssUrlTranslationImpl
|
||||
org.dromara.common.translation.core.impl.UserNameTranslationImpl
|
||||
org.dromara.common.translation.core.impl.NicknameTranslationImpl
|
||||
org.dromara.common.translation.core.impl.ProjectNameTranslationImpl
|
||||
|
@ -12,6 +12,8 @@ public interface WebSocketConstants {
|
||||
*/
|
||||
String LOGIN_USER_KEY = "loginUser";
|
||||
|
||||
String PROJECT_ID = "projectId";
|
||||
|
||||
/**
|
||||
* 订阅的频道
|
||||
*/
|
||||
|
@ -13,6 +13,7 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.dromara.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY;
|
||||
import static org.dromara.common.websocket.constant.WebSocketConstants.PROJECT_ID;
|
||||
|
||||
/**
|
||||
* WebSocketHandler 实现类
|
||||
@ -27,14 +28,17 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
|
||||
*/
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws IOException {
|
||||
LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
|
||||
if (ObjectUtil.isNull(loginUser)) {
|
||||
// LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
|
||||
Long loginUser = (Long) session.getAttributes().get(PROJECT_ID);
|
||||
// if (ObjectUtil.isNull(loginUser) ) {
|
||||
if (loginUser == null ) {
|
||||
session.close(CloseStatus.BAD_DATA);
|
||||
log.info("[connect] invalid token received. sessionId: {}", session.getId());
|
||||
return;
|
||||
}
|
||||
WebSocketSessionHolder.addSession(loginUser.getUserId(), session);
|
||||
log.info("[connect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
|
||||
WebSocketSessionHolder.addSession(loginUser, session);
|
||||
// WebSocketSessionHolder.addSession(loginUser.getUserId(), session);
|
||||
// log.info("[connect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,11 +51,13 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
|
||||
@Override
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
|
||||
// 从WebSocket会话中获取登录用户信息
|
||||
LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
|
||||
// LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
|
||||
Long loginUser = (Long) session.getAttributes().get(PROJECT_ID);
|
||||
|
||||
// 创建WebSocket消息DTO对象
|
||||
WebSocketMessageDto webSocketMessageDto = new WebSocketMessageDto();
|
||||
webSocketMessageDto.setSessionKeys(List.of(loginUser.getUserId()));
|
||||
// webSocketMessageDto.setSessionKeys(List.of(loginUser.getUserId()));
|
||||
webSocketMessageDto.setSessionKeys(List.of(loginUser));
|
||||
webSocketMessageDto.setMessage(message.getPayload());
|
||||
WebSocketUtils.publishMessage(webSocketMessageDto);
|
||||
}
|
||||
@ -100,13 +106,16 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
|
||||
*/
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
|
||||
LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
|
||||
if (ObjectUtil.isNull(loginUser)) {
|
||||
// LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
|
||||
Long loginUser = (Long) session.getAttributes().get(PROJECT_ID);
|
||||
// if (ObjectUtil.isNull(loginUser)) {
|
||||
if (loginUser != null ) {
|
||||
log.info("[disconnect] invalid token received. sessionId: {}", session.getId());
|
||||
return;
|
||||
}
|
||||
WebSocketSessionHolder.removeSession(loginUser.getUserId());
|
||||
log.info("[disconnect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
|
||||
// WebSocketSessionHolder.removeSession(loginUser.getUserId());
|
||||
WebSocketSessionHolder.removeSession(loginUser);
|
||||
// log.info("[disconnect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,7 @@ import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.dromara.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY;
|
||||
import static org.dromara.common.websocket.constant.WebSocketConstants.PROJECT_ID;
|
||||
|
||||
/**
|
||||
* WebSocket握手请求的拦截器
|
||||
@ -44,6 +45,8 @@ public class PlusWebSocketInterceptor implements HandshakeInterceptor {
|
||||
String headerCid = ServletUtils.getRequest().getHeader(LoginHelper.CLIENT_KEY);
|
||||
String paramCid = ServletUtils.getParameter(LoginHelper.CLIENT_KEY);
|
||||
String clientId = StpUtil.getExtra(LoginHelper.CLIENT_KEY).toString();
|
||||
String projectIdStr = ServletUtils.getRequest().getParameter("projectId");
|
||||
Long projectId = Long.parseLong(projectIdStr);
|
||||
if (!StringUtils.equalsAny(clientId, headerCid, paramCid)) {
|
||||
// token 无效
|
||||
throw NotLoginException.newInstance(StpUtil.getLoginType(),
|
||||
@ -52,6 +55,7 @@ public class PlusWebSocketInterceptor implements HandshakeInterceptor {
|
||||
}
|
||||
|
||||
attributes.put(LOGIN_USER_KEY, loginUser);
|
||||
attributes.put(PROJECT_ID,projectId);
|
||||
return true;
|
||||
} catch (NotLoginException e) {
|
||||
log.error("WebSocket 认证失败'{}',无法访问系统资源", e.getMessage());
|
||||
|
@ -17,6 +17,16 @@
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>technology.tabula</groupId>-->
|
||||
<!-- <artifactId>tabula</artifactId>-->
|
||||
<!-- <version>1.0.4</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
|
||||
<!-- JSON解析(FastJSON) -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
@ -73,18 +83,32 @@
|
||||
</dependency>
|
||||
|
||||
<!-- 在pdf上生成二维码 -->
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>layout</artifactId>
|
||||
<version>7.2.5</version>
|
||||
</dependency>
|
||||
<!-- iText 7 核心模块(必须,layout依赖此模块) -->
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>kernel</artifactId>
|
||||
<version>7.2.5</version> <!-- 与layout版本严格一致 -->
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!-- 支持中文字体 -->
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>itext-asian</artifactId>
|
||||
<version>5.2.0</version>
|
||||
</dependency>
|
||||
<!-- iText -->
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>itextpdf</artifactId>
|
||||
<version>5.5.13.3</version>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.itextpdf</groupId>-->
|
||||
<!-- <artifactId>itext-asian</artifactId>-->
|
||||
<!-- <version>5.2.0</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <!– iText –>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.itextpdf</groupId>-->
|
||||
<!-- <artifactId>itextpdf</artifactId>-->
|
||||
<!-- <version>5.5.13.3</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- ZXing -->
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
@ -108,6 +132,11 @@
|
||||
<artifactId>ruoyi-common-doc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-job</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-mybatis</artifactId>
|
||||
@ -216,6 +245,17 @@
|
||||
<version>5.3.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.25.0-GA</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
@ -3,7 +3,9 @@ package org.dromara.bidding.controller;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.dromara.bidding.domain.bo.BusBiddingLimitListBo;
|
||||
import org.dromara.bidding.domain.bo.BiddingAllVersionNumbersReq;
|
||||
import org.dromara.bidding.domain.vo.BusBiddingLimitListVo;
|
||||
@ -22,6 +24,8 @@ import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -38,6 +42,8 @@ public class BusBiddingLimitListController extends BaseController {
|
||||
|
||||
private final IBusBiddingLimitListService busBiddingLimitListService;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 查询成本-投标列表
|
||||
*/
|
||||
@ -101,8 +107,8 @@ public class BusBiddingLimitListController extends BaseController {
|
||||
@Log(title = "成本-投标", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/importExcelFile")
|
||||
public R<Void> importExcelFile(Long projectId, @RequestParam("file") MultipartFile file) {
|
||||
return toAjax(busBiddingLimitListService.importExcelFile(projectId, file));
|
||||
public R<Void> importExcelFile(BusBiddingLimitListBo bo, @RequestParam("file") MultipartFile file) {
|
||||
return toAjax(busBiddingLimitListService.importExcelFile(bo, file));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,6 +42,14 @@ public class BusBiddingLimitVersions extends BaseEntity {
|
||||
*/
|
||||
private String versions;
|
||||
|
||||
|
||||
/**
|
||||
* 版本号名称
|
||||
*/
|
||||
private String versionsName;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* excel文件
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.dromara.bidding.domain.bo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import org.dromara.bidding.domain.BusBiddingLimitList;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
@ -91,4 +92,6 @@ public class BusBiddingLimitListBo extends BaseEntity {
|
||||
private String remark;
|
||||
|
||||
|
||||
private Long type;
|
||||
|
||||
}
|
||||
|
@ -44,6 +44,14 @@ public class BusBiddingLimitVersionsBo extends BaseEntity {
|
||||
@NotBlank(message = "版本号不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String versions;
|
||||
|
||||
|
||||
/**
|
||||
* 版本号名称
|
||||
*/
|
||||
private String versionsName;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* excel文件
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.dromara.bidding.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import org.dromara.bidding.domain.BusBiddingLimitList;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
@ -77,6 +78,7 @@ public class BusBiddingLimitListVo implements Serializable {
|
||||
* 名称
|
||||
*/
|
||||
@ExcelProperty(value = "名称")
|
||||
@ColumnWidth(50)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
|
@ -52,6 +52,14 @@ public class BusBiddingLimitVersionsVo implements Serializable {
|
||||
@ExcelProperty(value = "版本号")
|
||||
private String versions;
|
||||
|
||||
|
||||
/**
|
||||
* 版本号名称
|
||||
*/
|
||||
private String versionsName;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* excel文件
|
||||
*/
|
||||
|
@ -79,7 +79,7 @@ public interface IBusBiddingLimitListService extends IService<BusBiddingLimitLis
|
||||
*/
|
||||
List<BusBiddingLimitListVo> getTree(BusBiddingLimitListBo bo);
|
||||
|
||||
Boolean importExcelFile(Long projectId, MultipartFile file);
|
||||
Boolean importExcelFile(BusBiddingLimitListBo projectId, MultipartFile file);
|
||||
|
||||
List<BusBiddingLimitVersionsVo> obtainAllVersionNumbers(BiddingAllVersionNumbersReq bo);
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.dromara.bidding.service;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.dromara.bidding.domain.vo.BusBiddingLimitVersionsVo;
|
||||
import org.dromara.bidding.domain.bo.BusBiddingLimitVersionsBo;
|
||||
import org.dromara.bidding.domain.BusBiddingLimitVersions;
|
||||
@ -67,4 +69,8 @@ public interface IBusBiddingLimitVersionsService extends IService<BusBiddingLimi
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
BusBiddingLimitVersions queryByProjectId( String versions, Long projectId);
|
||||
|
||||
BusBiddingLimitVersions getByProjectIdVersions(Long projectId, String versions);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.bidding.domain.BusBiddingLimitList;
|
||||
import org.dromara.bidding.domain.BusBiddingLimitVersions;
|
||||
import org.dromara.bidding.domain.bo.BusBiddingLimitListBo;
|
||||
import org.dromara.bidding.domain.bo.BusBiddingLimitVersionsBo;
|
||||
import org.dromara.bidding.domain.bo.BiddingAllVersionNumbersReq;
|
||||
@ -17,14 +18,13 @@ import org.dromara.bidding.mapper.BusBiddingLimitListMapper;
|
||||
import org.dromara.bidding.service.IBusBiddingLimitListService;
|
||||
import org.dromara.bidding.service.IBusBiddingLimitVersionsService;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.enums.BusinessStatusEnum;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.utils.excel.ExcelDynamicReader;
|
||||
import org.dromara.tender.domain.BusBillofquantitiesLimitList;
|
||||
import org.dromara.tender.domain.bo.BusBillofquantitiesLimitListBo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -179,13 +179,17 @@ public class BusBiddingLimitListServiceImpl extends ServiceImpl<BusBiddingLimitL
|
||||
|
||||
@Override
|
||||
public List<BusBiddingLimitListVo> getTree(BusBiddingLimitListBo bo) {
|
||||
BusBiddingLimitVersions biddingLimitVersions = busBiddingLimitVersionsService.queryByProjectId(bo.getVersions(),bo.getProjectId());
|
||||
if (biddingLimitVersions == null || (bo.getType() == 1L && !BusinessStatusEnum.FINISH.getStatus().equals(biddingLimitVersions.getStatus()))) {
|
||||
return null;
|
||||
}
|
||||
//获取所有数据
|
||||
List<BusBiddingLimitListVo> listVoList = queryList(bo);
|
||||
//过滤数量和单价为空的数据并计算总价
|
||||
listVoList.stream().filter(vo -> vo.getUnitPrice() != null && vo.getUnitPrice().compareTo(BigDecimal.ZERO) != 0)
|
||||
.filter(vo -> vo.getQuantity() != null && vo.getQuantity().compareTo(BigDecimal.ZERO) != 0)
|
||||
.forEach(item -> {
|
||||
item.setPrice(item.getUnitPrice().multiply(item.getQuantity()).setScale(2, RoundingMode.HALF_UP));
|
||||
item.setPrice(item.getUnitPrice().multiply(item.getQuantity()).setScale(4, RoundingMode.HALF_UP));
|
||||
});
|
||||
|
||||
//构建父子映射
|
||||
@ -226,14 +230,22 @@ public class BusBiddingLimitListServiceImpl extends ServiceImpl<BusBiddingLimitL
|
||||
BigDecimal totalPrice = node.getChildren().stream()
|
||||
.map(BusBiddingLimitListVo::getPrice)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
.setScale(4, RoundingMode.HALF_UP);
|
||||
node.setPrice(totalPrice);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean importExcelFile(Long projectId, MultipartFile file) {
|
||||
public Boolean importExcelFile(BusBiddingLimitListBo bo, MultipartFile file) {
|
||||
BusBiddingLimitVersions biddingLimitVersions = busBiddingLimitVersionsService.getByProjectIdVersions(bo.getProjectId(),bo.getVersions());
|
||||
|
||||
if (biddingLimitVersions == null) {
|
||||
throw new ServiceException("版本号不存在!!!");
|
||||
}
|
||||
if (BusinessStatusEnum.FINISH.getStatus().equals(biddingLimitVersions.getStatus())) {
|
||||
throw new ServiceException("数据已审核完成,不允许修改!!!");
|
||||
}
|
||||
|
||||
// 跳过1行(表头),读取0到6列(共7列),映射到ExcelData实体类
|
||||
List<BusBiddingLimitListBo> dataList = null;
|
||||
@ -242,7 +254,7 @@ public class BusBiddingLimitListServiceImpl extends ServiceImpl<BusBiddingLimitL
|
||||
file, // 上传的文件
|
||||
1, // 跳过1行(表头)
|
||||
0, // 从第0列开始
|
||||
12, // 到第12列结束
|
||||
13, // 到第12列结束
|
||||
BusBiddingLimitListBo.class // 目标实体类
|
||||
);
|
||||
} catch (Exception e) {
|
||||
@ -265,7 +277,6 @@ public class BusBiddingLimitListServiceImpl extends ServiceImpl<BusBiddingLimitL
|
||||
busBillofquantities.add(limitList);
|
||||
});
|
||||
log.info(busBillofquantities.toString());
|
||||
|
||||
return this.updateBatchById(busBillofquantities);
|
||||
}
|
||||
|
||||
|
@ -1,30 +1,29 @@
|
||||
package org.dromara.bidding.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.bidding.domain.BusBiddingLimitVersions;
|
||||
import org.dromara.bidding.domain.bo.BusBiddingLimitVersionsBo;
|
||||
import org.dromara.bidding.domain.vo.BusBiddingLimitVersionsVo;
|
||||
import org.dromara.bidding.mapper.BusBiddingLimitVersionsMapper;
|
||||
import org.dromara.bidding.service.IBusBiddingLimitVersionsService;
|
||||
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessTaskEvent;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.design.domain.BusBillofquantitiesVersions;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.dromara.bidding.domain.bo.BusBiddingLimitVersionsBo;
|
||||
import org.dromara.bidding.domain.vo.BusBiddingLimitVersionsVo;
|
||||
import org.dromara.bidding.domain.BusBiddingLimitVersions;
|
||||
import org.dromara.bidding.mapper.BusBiddingLimitVersionsMapper;
|
||||
import org.dromara.bidding.service.IBusBiddingLimitVersionsService;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 成本- 投标版本Service业务层处理
|
||||
@ -46,7 +45,7 @@ public class BusBiddingLimitVersionsServiceImpl extends ServiceImpl<BusBiddingLi
|
||||
* @return 成本- 投标版本
|
||||
*/
|
||||
@Override
|
||||
public BusBiddingLimitVersionsVo queryById(Long id){
|
||||
public BusBiddingLimitVersionsVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
@ -120,7 +119,7 @@ public class BusBiddingLimitVersionsServiceImpl extends ServiceImpl<BusBiddingLi
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(BusBiddingLimitVersions entity){
|
||||
private void validEntityBeforeSave(BusBiddingLimitVersions entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
@ -133,12 +132,26 @@ public class BusBiddingLimitVersionsServiceImpl extends ServiceImpl<BusBiddingLi
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BusBiddingLimitVersions queryByProjectId(String versions, Long projectId) {
|
||||
return baseMapper.selectOne(new LambdaQueryWrapper<BusBiddingLimitVersions>()
|
||||
.eq(BusBiddingLimitVersions::getProjectId, projectId)
|
||||
.eq(BusBiddingLimitVersions::getVersions, versions));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BusBiddingLimitVersions getByProjectIdVersions(Long projectId, String versions) {
|
||||
return baseMapper.selectOne(new LambdaQueryWrapper<BusBiddingLimitVersions>()
|
||||
.eq(BusBiddingLimitVersions::getProjectId, projectId)
|
||||
.eq(BusBiddingLimitVersions::getVersions, versions));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等)
|
||||
@ -147,7 +160,7 @@ public class BusBiddingLimitVersionsServiceImpl extends ServiceImpl<BusBiddingLi
|
||||
*
|
||||
* @param processEvent 参数
|
||||
*/
|
||||
@org.springframework.context.event.EventListener(condition = "#processEvent.flowCode.endsWith('biddingLimitList')")
|
||||
@EventListener(condition = "#processEvent.flowCode.endsWith('biddingLimitList')")
|
||||
public void processPlansHandlErequipmentList(ProcessEvent processEvent) {
|
||||
log.info("物资设备清单审核任务执行了{}", processEvent.toString());
|
||||
String id = processEvent.getBusinessId();
|
||||
@ -177,7 +190,7 @@ public class BusBiddingLimitVersionsServiceImpl extends ServiceImpl<BusBiddingLi
|
||||
*
|
||||
* @param processTaskEvent 参数
|
||||
*/
|
||||
@org.springframework.context.event.EventListener(condition = "#processTaskEvent.flowCode.endsWith('biddingLimitList')")
|
||||
@EventListener(condition = "#processTaskEvent.flowCode.endsWith('biddingLimitList')")
|
||||
public void processTaskPlansHandlerEquipmentList(ProcessTaskEvent processTaskEvent) {
|
||||
log.info("物资设备清单审核任务创建了{}", processTaskEvent.toString());
|
||||
}
|
||||
|
@ -0,0 +1,220 @@
|
||||
package org.dromara.bigscreen.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.dromara.bigscreen.domain.dto.WeatherQueryReq;
|
||||
import org.dromara.bigscreen.domain.vo.*;
|
||||
import org.dromara.bigscreen.service.EnterpriseBigScreenService;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.manager.weathermanager.vo.WeatherVo;
|
||||
import org.dromara.project.domain.BusAttendance;
|
||||
import org.dromara.project.domain.BusProject;
|
||||
import org.dromara.project.domain.BusUserProjectRelevancy;
|
||||
import org.dromara.project.service.IBusAttendanceService;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.dromara.project.service.IBusUserProjectRelevancyService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 企业级大屏
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-09-09 14:55
|
||||
*/
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/enterprise/big/screen")
|
||||
public class EnterpriseBigScreenController {
|
||||
|
||||
@Resource
|
||||
private EnterpriseBigScreenService enterpriseBigScreenService;
|
||||
|
||||
@Resource
|
||||
private IBusUserProjectRelevancyService userProjectRelevancyService;
|
||||
|
||||
@Resource
|
||||
private IBusAttendanceService attendanceService;
|
||||
|
||||
@Resource
|
||||
private IBusProjectService projectService;
|
||||
|
||||
|
||||
/**
|
||||
* 获取关键指标
|
||||
*/
|
||||
@SaCheckPermission("enterprise:bigScreen:keyIndex")
|
||||
@GetMapping("/keyIndex")
|
||||
public R<EnterpriseKeyIndexVo> getEnterpriseKeyIndex() {
|
||||
return R.ok(enterpriseBigScreenService.getEnterpriseKeyIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目进度分析
|
||||
*/
|
||||
@SaCheckPermission("enterprise:bigScreen:projectProgress")
|
||||
@GetMapping("/projectProgress")
|
||||
public R<ProjectProgressAnalysisVo> getProjectProgress() {
|
||||
return R.ok(enterpriseBigScreenService.getProjectProgressAnalysis());
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目产值对比
|
||||
*/
|
||||
@SaCheckPermission("enterprise:bigScreen:projectOutputValueComparison")
|
||||
@GetMapping("/projectOutputValueComparison")
|
||||
public R<List<OutputValueComparisonVo>> getProjectOutputValueComparison() {
|
||||
return R.ok(enterpriseBigScreenService.getProjectOutputValueComparison());
|
||||
}
|
||||
|
||||
/**
|
||||
* 风险预警
|
||||
*/
|
||||
@SaCheckPermission("enterprise:bigScreen:riskEarlyWarning")
|
||||
@GetMapping("/riskEarlyWarning")
|
||||
public R<List<RiskEarlyWarningVo>> getRiskEarlyWarning() {
|
||||
return R.ok(enterpriseBigScreenService.getRiskEarlyWarning());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询天气
|
||||
*/
|
||||
@SaCheckPermission("enterprise:bigScreen:weather")
|
||||
@GetMapping("/weather")
|
||||
public R<List<WeatherVo>> getProjectWeather(WeatherQueryReq req) {
|
||||
return R.ok(enterpriseBigScreenService.getWeather3DaysList(req));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询安全天数
|
||||
*/
|
||||
@SaCheckPermission("enterprise:bigScreen:safetyDay")
|
||||
@GetMapping("/safetyDay")
|
||||
public R<Long> getProjectSafetyDay() {
|
||||
LocalDate date = LocalDate.of(2023, 1, 1);
|
||||
LocalDate now = LocalDate.now();
|
||||
long days = Math.abs(ChronoUnit.DAYS.between(date, now));
|
||||
return R.ok(days);
|
||||
}
|
||||
|
||||
/**
|
||||
* 人数统计
|
||||
*/
|
||||
@SaCheckPermission("enterprise:bigScreen:peopleCount")
|
||||
@GetMapping("/peopleCount")
|
||||
public R<PeopleCountVo> getProjectPeopleCount() {
|
||||
PeopleCountVo peopleCountVo = new PeopleCountVo();
|
||||
|
||||
List<BusUserProjectRelevancy> list = userProjectRelevancyService.list();
|
||||
//0系统管理员 1普通人员 2项目管理员 3分包人员
|
||||
peopleCountVo.setConstructionPersonnelCount(list.stream().filter(item -> "1".equals(item.getUserType()))
|
||||
.map(BusUserProjectRelevancy::getUserId)
|
||||
.distinct().count());
|
||||
|
||||
peopleCountVo.setManagersCount(list.stream().filter(item -> "2".equals(item.getUserType()))
|
||||
.map(BusUserProjectRelevancy::getUserId)
|
||||
.distinct().count());
|
||||
|
||||
peopleCountVo.setSubcontractorsCount(list.stream().filter(item -> "3".equals(item.getUserType()))
|
||||
.map(BusUserProjectRelevancy::getUserId)
|
||||
.distinct().count());
|
||||
|
||||
return R.ok(peopleCountVo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 出勤人数统计
|
||||
*/
|
||||
@SaCheckPermission("enterprise:bigScreen:allAttendanceCount")
|
||||
@GetMapping("/allAttendanceCount")
|
||||
public R<TodayAttendanceCountVo> getAllAttendanceCount() {
|
||||
TodayAttendanceCountVo todayAttendanceCountVo = new TodayAttendanceCountVo();
|
||||
List<BusAttendance> list = attendanceService.list(Wrappers.<BusAttendance>lambdaQuery()
|
||||
.eq(BusAttendance::getClockDate, LocalDate.now())
|
||||
.in(BusAttendance::getClockStatus, Arrays.asList("1", "2", "3"))
|
||||
);
|
||||
|
||||
long attendanceCount = list.stream().map(BusAttendance::getUserId).distinct().count();
|
||||
todayAttendanceCountVo.setAttendanceCount(attendanceCount);
|
||||
|
||||
// 查询总人数
|
||||
List<BusUserProjectRelevancy> relevancyList = userProjectRelevancyService.list();
|
||||
long totalUserCount = relevancyList.stream().map(BusUserProjectRelevancy::getUserId).distinct().count();
|
||||
|
||||
// 计算考勤率(保留一位小数)
|
||||
if (totalUserCount > 0) {
|
||||
BigDecimal rate = new BigDecimal(attendanceCount * 100)
|
||||
.divide(new BigDecimal(totalUserCount), 1, RoundingMode.HALF_UP);
|
||||
todayAttendanceCountVo.setAttendanceRate(rate.doubleValue());
|
||||
} else {
|
||||
todayAttendanceCountVo.setAttendanceRate(0.0);
|
||||
}
|
||||
return R.ok(todayAttendanceCountVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 每个项目的出勤人数
|
||||
*/
|
||||
@SaCheckPermission("enterprise:bigScreen:projectAttendanceCount")
|
||||
@GetMapping("/projectAttendanceCount")
|
||||
public R<List<ProjectAttendanceCountVo>> getProjectAttendanceCount() {
|
||||
|
||||
ArrayList<ProjectAttendanceCountVo> projectAttendanceCountVos = new ArrayList<>();
|
||||
|
||||
List<BusAttendance> list = attendanceService.list(Wrappers.<BusAttendance>lambdaQuery()
|
||||
.eq(BusAttendance::getClockDate, LocalDate.now())
|
||||
.in(BusAttendance::getClockStatus, Arrays.asList("1", "2", "3"))
|
||||
);
|
||||
List<BusUserProjectRelevancy> relevancyList = userProjectRelevancyService.list();
|
||||
|
||||
// 转换为 Map<projectId, 去重后的 userId 数量>
|
||||
Map<Long, Integer> projectUserCountMap = relevancyList.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
BusUserProjectRelevancy::getProjectId,
|
||||
Collectors.mapping(
|
||||
BusUserProjectRelevancy::getUserId,
|
||||
Collectors.collectingAndThen(
|
||||
Collectors.toSet(),
|
||||
Set::size
|
||||
)
|
||||
)
|
||||
));
|
||||
for (Long projectId : projectUserCountMap.keySet()) {
|
||||
ProjectAttendanceCountVo projectAttendanceCountVo = new ProjectAttendanceCountVo();
|
||||
BusProject byId = projectService.getById(projectId);
|
||||
|
||||
if (byId == null) {
|
||||
continue;
|
||||
}
|
||||
projectAttendanceCountVo.setProjectName(byId.getProjectName());
|
||||
long count = list.stream().filter(item -> item.getProjectId().equals(projectId))
|
||||
.map(BusAttendance::getUserId)
|
||||
.distinct()
|
||||
.count();
|
||||
Integer i = projectUserCountMap.get(projectId);
|
||||
BigDecimal rate = new BigDecimal("0.0");
|
||||
if (i > 0) {
|
||||
rate = new BigDecimal(count * 100)
|
||||
.divide(new BigDecimal(projectUserCountMap.get(projectId)), 1, RoundingMode.HALF_UP);
|
||||
}
|
||||
projectAttendanceCountVo.setAttendanceRate(rate.doubleValue());
|
||||
projectAttendanceCountVos.add(projectAttendanceCountVo);
|
||||
}
|
||||
|
||||
return R.ok(projectAttendanceCountVos);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -11,13 +11,13 @@ import org.dromara.ctr.domain.CtrExpensesContract;
|
||||
import org.dromara.ctr.domain.CtrIncomeContract;
|
||||
import org.dromara.ctr.service.ICtrExpensesContractService;
|
||||
import org.dromara.ctr.service.ICtrIncomeContractService;
|
||||
import org.dromara.manager.weathermanager.vo.WeatherVo;
|
||||
import org.dromara.out.domain.OutSettlementValueOwner;
|
||||
import org.dromara.out.domain.OutSettlementValueSubcontract;
|
||||
import org.dromara.out.service.IOutSettlementValueOwnerService;
|
||||
import org.dromara.out.service.IOutSettlementValueSubcontractService;
|
||||
import org.dromara.project.domain.vo.project.BusProjectGisVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@ -114,7 +114,7 @@ public class MoneyBigScreenController {
|
||||
.eq(CtrIncomeContract::getProjectId, projectId)
|
||||
.last("limit 1")
|
||||
);
|
||||
if (contract != null && contract.getPayRatio()!= null) {
|
||||
if (contract != null && contract.getPayRatio() != null) {
|
||||
actualAmount = actualAmount.add(projectMonthlyAmountMap.get(projectId).multiply(contract.getPayRatio()).divide(HUNDRED));
|
||||
}
|
||||
|
||||
@ -169,7 +169,7 @@ public class MoneyBigScreenController {
|
||||
.last("limit 1")
|
||||
);
|
||||
|
||||
if (contract != null && contract.getPayRatio()!= null) {
|
||||
if (contract != null && contract.getPayRatio() != null) {
|
||||
actualAmount = actualAmount.add(projectAmountMap.get(contractCode).multiply(contract.getPayRatio()).divide(HUNDRED));
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ public class MoneyBigScreenController {
|
||||
.filter(contract -> contract.getAmount() != null && contract.getAmount().compareTo(THIRD_PHASE) >= 0)
|
||||
.count();
|
||||
|
||||
return R.ok(new MoneyContractCountVo(4, 4, 6, 6));
|
||||
return R.ok(new MoneyContractCountVo(4, 4, 6, 6));
|
||||
// return R.ok(new MoneyContractCountVo(lessThan1M, between1MAnd5M, between5MAnd10M, greaterThanOrEqualTo10M));
|
||||
|
||||
}
|
||||
@ -350,7 +350,7 @@ public class MoneyBigScreenController {
|
||||
.eq(CtrIncomeContract::getProjectId, projectId)
|
||||
.last("limit 1")
|
||||
);
|
||||
if (contract != null && contract.getPayRatio()!= null) {
|
||||
if (contract != null && contract.getPayRatio() != null) {
|
||||
incomeAmount = incomeAmount.add(incomeGroupedByProject.get(projectId).multiply(contract.getPayRatio()).divide(HUNDRED));
|
||||
}
|
||||
}
|
||||
@ -380,7 +380,7 @@ public class MoneyBigScreenController {
|
||||
.last("limit 1")
|
||||
);
|
||||
|
||||
if (contract != null && contract.getPayRatio()!= null) {
|
||||
if (contract != null && contract.getPayRatio() != null) {
|
||||
expensesAmount = expensesAmount.add(expenseGroupedByContract.get(contractCode).multiply(contract.getPayRatio()).divide(HUNDRED));
|
||||
}
|
||||
}
|
||||
@ -448,7 +448,7 @@ public class MoneyBigScreenController {
|
||||
.eq(CtrIncomeContract::getProjectId, projectId)
|
||||
.last("limit 1")
|
||||
);
|
||||
if (contract != null && contract.getPayRatio()!= null) {
|
||||
if (contract != null && contract.getPayRatio() != null) {
|
||||
incomeAmount = incomeAmount.add(incomeGroupedByProject.get(projectId).multiply(contract.getPayRatio()).divide(HUNDRED));
|
||||
}
|
||||
}
|
||||
@ -478,7 +478,7 @@ public class MoneyBigScreenController {
|
||||
.last("limit 1")
|
||||
);
|
||||
|
||||
if (contract != null && contract.getPayRatio()!= null) {
|
||||
if (contract != null && contract.getPayRatio() != null) {
|
||||
expensesAmount = expensesAmount.add(expenseGroupedByContract.get(contractCode).multiply(contract.getPayRatio()).divide(HUNDRED));
|
||||
}
|
||||
}
|
||||
@ -511,7 +511,7 @@ public class MoneyBigScreenController {
|
||||
.filter(java.util.Objects::nonNull) // 过滤掉 null 值
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
List<OutSettlementValueSubcontract> subcontractList = settlementValueSubcontractService.list();
|
||||
List<OutSettlementValueSubcontract> subcontractList = settlementValueSubcontractService.list();
|
||||
|
||||
BigDecimal expensesCash = subcontractList.stream()
|
||||
.map(OutSettlementValueSubcontract::getSettlementValue)
|
||||
@ -526,8 +526,6 @@ public class MoneyBigScreenController {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前月份的开始时间和结束时间
|
||||
*
|
||||
@ -548,8 +546,8 @@ public class MoneyBigScreenController {
|
||||
*/
|
||||
@SaCheckPermission("project:bigScreen:weather")
|
||||
@GetMapping("/weather/{projectId}")
|
||||
public R<List<BusProjectWeatherVo>> getProjectWeather(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long projectId) {
|
||||
public R<List<WeatherVo>> getProjectWeather(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long projectId) {
|
||||
return R.ok(moneyBigScreenService.getProjectWeather(projectId));
|
||||
}
|
||||
|
||||
|
@ -11,21 +11,27 @@ import org.dromara.bigscreen.domain.vo.ProjectPeopleVo;
|
||||
import org.dromara.bigscreen.domain.vo.ProjectSafetyInspectionVo;
|
||||
import org.dromara.bigscreen.service.ProjectBigScreenService;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.gps.domain.bo.GpsEquipmentBo;
|
||||
import org.dromara.gps.domain.vo.GpsEquipmentSonVo;
|
||||
import org.dromara.gps.service.IGpsEquipmentService;
|
||||
import org.dromara.land.domain.BusLandBlock;
|
||||
import org.dromara.land.domain.BusLandTransferLedger;
|
||||
import org.dromara.land.service.IBusLandBlockService;
|
||||
import org.dromara.land.service.IBusLandTransferLedgerService;
|
||||
import org.dromara.other.domain.OthYs7Device;
|
||||
import org.dromara.other.service.IOthYs7DeviceService;
|
||||
import org.dromara.manager.weathermanager.vo.WeatherVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
||||
import org.dromara.project.domain.vo.projectnews.BusProjectNewsVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@ -49,6 +55,10 @@ public class ProjectBigScreenController {
|
||||
|
||||
private final IBusLandBlockService busLandBlockService;
|
||||
|
||||
private final IGpsEquipmentService gpsEquipmentService;
|
||||
|
||||
private final IOthYs7DeviceService othYs7DeviceService;
|
||||
|
||||
/**
|
||||
* 查询项目土地统计
|
||||
*/
|
||||
@ -103,8 +113,8 @@ public class ProjectBigScreenController {
|
||||
*/
|
||||
@SaCheckPermission("project:bigScreen:weather")
|
||||
@GetMapping("/weather/{projectId}")
|
||||
public R<List<BusProjectWeatherVo>> getProjectWeather(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long projectId) {
|
||||
public R<List<WeatherVo>> getProjectWeather(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long projectId) {
|
||||
return R.ok(projectBigScreenService.getProjectWeather(projectId));
|
||||
}
|
||||
|
||||
@ -167,4 +177,179 @@ public class ProjectBigScreenController {
|
||||
@PathVariable Long projectId) {
|
||||
return R.ok(projectBigScreenService.getProjectGeneralize(projectId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询设备列表
|
||||
*/
|
||||
@SaCheckPermission("project:bigScreen:getClientList")
|
||||
@GetMapping("/getClientList/{projectId}")
|
||||
public R<List<Map<String,Object>>> getClientList(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long projectId) {
|
||||
List<GpsEquipmentSonVo> voList = gpsEquipmentService.getClientList(projectId);
|
||||
// List<OthYs7Device> othYs7DeviceList = othYs7DeviceService.lambdaQuery()
|
||||
// .eq(OthYs7Device::getProjectId, projectId)
|
||||
// .list();
|
||||
List<Map<String, Object>> maps = new ArrayList<>();
|
||||
Map<String, Object> gpsMap = new HashMap<>();
|
||||
Map<String, Object> wrjMap = new HashMap<>();
|
||||
Map<String, Object> sxtMap = new HashMap<>();
|
||||
List<Map<String, Object>> gpsChildrenMap = new ArrayList<>();
|
||||
// List<Map<String, Object>> wrjChildrenMap = new ArrayList<>();
|
||||
// List<Map<String, Object>> sxtChildrenMap = new ArrayList<>();
|
||||
if (voList != null && !voList.isEmpty()) {
|
||||
for (GpsEquipmentSonVo item : voList) {
|
||||
Map<String, Object> gps = new HashMap<>();
|
||||
gps.put("id", item.getClientId());
|
||||
gps.put("label", item.getClientId());
|
||||
gps.put("name", item.getDeviceName());
|
||||
gps.put("type", "positioningDevice");
|
||||
gps.put("lat", item.getLocLatitude());
|
||||
gps.put("lng", item.getLocLongitude());
|
||||
gps.put("alt", item.getLocAltitude());
|
||||
gpsChildrenMap.add(gps);
|
||||
}
|
||||
}
|
||||
// if (othYs7DeviceList != null && !othYs7DeviceList.isEmpty()) {
|
||||
// for (OthYs7Device item : othYs7DeviceList) {
|
||||
// Map<String, Object> sxt = new HashMap<>();
|
||||
// sxt.put("id", item.getDeviceSerial());
|
||||
// sxt.put("label", item.getDeviceSerial());
|
||||
// sxt.put("name", item.getDeviceName());
|
||||
// sxt.put("type", "shexiangtou");
|
||||
//// sxt.put("lat", item.getLocLatitude());
|
||||
//// sxt.put("lng", item.getLocLongitude());
|
||||
//// sxt.put("alt", item.getLocAltitude());
|
||||
// sxtChildrenMap.add(sxt);
|
||||
// }
|
||||
// }
|
||||
List<Map<String, Object>> maps1 = setSxt();
|
||||
List<Map<String, Object>> maps2 = setWrj();
|
||||
|
||||
gpsMap.put("id",1);
|
||||
gpsMap.put("label","定位设备");
|
||||
gpsMap.put("children",gpsChildrenMap);
|
||||
sxtMap.put("id",2);
|
||||
sxtMap.put("label","摄像头");
|
||||
// sxtMap.put("children",sxtChildrenMap);
|
||||
sxtMap.put("children",maps1);
|
||||
wrjMap.put("id",3);
|
||||
wrjMap.put("label","无人机");
|
||||
// wrjMap.put("children",wrjChildrenMap);
|
||||
wrjMap.put("children",maps2);
|
||||
|
||||
|
||||
maps.add(gpsMap);
|
||||
maps.add(wrjMap);
|
||||
maps.add(sxtMap);
|
||||
return R.ok(maps);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询GPS设备用户列表
|
||||
*/
|
||||
@SaCheckPermission("project:bigScreen:getList")
|
||||
@GetMapping("/getList")
|
||||
public R<List<String>> getList(Long projectId) {
|
||||
return R.ok(projectBigScreenService.getList(projectId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增GPS设备详细
|
||||
*/
|
||||
@SaCheckPermission("project:bigScreen:setList")
|
||||
@Log(title = "GPS设备详细", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/setList")
|
||||
public void setList(@RequestBody GpsEquipmentBo bo) {
|
||||
projectBigScreenService.setList(bo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public List<Map<String, Object>> setSxt(){
|
||||
List<Map<String, Object>> sxtChildrenMap = new ArrayList<>();
|
||||
HashMap<String, Object> map1 = new HashMap<>();
|
||||
map1.put("id", "55");
|
||||
map1.put("label", "1222222");
|
||||
map1.put("name", "22");
|
||||
map1.put("type", "camera");
|
||||
map1.put("lng", 106.48349615411811);
|
||||
map1.put("lat", 29.54856374364732);
|
||||
map1.put("alt", 0);
|
||||
HashMap<String, Object> map2 = new HashMap<>();
|
||||
map2.put("id", "56");
|
||||
map2.put("label", "1222223");
|
||||
map2.put("name", "23");
|
||||
map2.put("type", "camera");
|
||||
map2.put("lng", 106.48442273257676);
|
||||
map2.put("lat", 29.53841670498476);
|
||||
map2.put("alt", 0);
|
||||
HashMap<String, Object> map3 = new HashMap<>();
|
||||
map3.put("id", "57");
|
||||
map3.put("label", "1222224");
|
||||
map3.put("name", "24");
|
||||
map3.put("type", "camera");
|
||||
map3.put("lng", 106.49197896482423);
|
||||
map3.put("lat", 29.52931974282576);
|
||||
map3.put("alt", 0);
|
||||
HashMap<String, Object> map4 = new HashMap<>();
|
||||
map4.put("id", "58");
|
||||
map4.put("label", "1222225");
|
||||
map4.put("name", "25");
|
||||
map4.put("type", "camera");
|
||||
map4.put("lng", 106.50293584930655);
|
||||
map4.put("lat", 29.533025743929034);
|
||||
map4.put("alt", 0);
|
||||
|
||||
sxtChildrenMap.add(map1);
|
||||
sxtChildrenMap.add(map2);
|
||||
sxtChildrenMap.add(map3);
|
||||
sxtChildrenMap.add(map4);
|
||||
|
||||
return sxtChildrenMap;
|
||||
}
|
||||
public List<Map<String, Object>> setWrj(){
|
||||
List<Map<String, Object>> sxtChildrenMap = new ArrayList<>();
|
||||
HashMap<String, Object> map1 = new HashMap<>();
|
||||
map1.put("id", "65");
|
||||
map1.put("label", "6222222");
|
||||
map1.put("name", "32");
|
||||
map1.put("type", "drone");
|
||||
map1.put("lng", 106.49556855602525);
|
||||
map1.put("lat", 29.534393226355515);
|
||||
map1.put("alt", 0);
|
||||
HashMap<String, Object> map2 = new HashMap<>();
|
||||
map2.put("id", "66");
|
||||
map2.put("label", "2222223");
|
||||
map2.put("name", "33");
|
||||
map2.put("type", "drone");
|
||||
map2.put("lng", 106.49142431645038);
|
||||
map2.put("lat", 29.534472802500083);
|
||||
map2.put("alt", 0);
|
||||
HashMap<String, Object> map3 = new HashMap<>();
|
||||
map3.put("id", "67");
|
||||
map3.put("label", "2222224");
|
||||
map3.put("name", "34");
|
||||
map3.put("type", "drone");
|
||||
map3.put("lng", 106.49142125177437);
|
||||
map3.put("lat", 29.541881138875755);
|
||||
map3.put("alt", 0);
|
||||
HashMap<String, Object> map4 = new HashMap<>();
|
||||
map4.put("id", "68");
|
||||
map4.put("label", "2222225");
|
||||
map4.put("name", "35");
|
||||
map4.put("type", "drone");
|
||||
map4.put("lng", 106.50256649933792);
|
||||
map4.put("lat", 29.54260793685717);
|
||||
map4.put("alt", 0);
|
||||
|
||||
sxtChildrenMap.add(map1);
|
||||
sxtChildrenMap.add(map2);
|
||||
sxtChildrenMap.add(map3);
|
||||
sxtChildrenMap.add(map4);
|
||||
|
||||
return sxtChildrenMap;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
package org.dromara.bigscreen.domain.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-09 15:16
|
||||
*/
|
||||
@Data
|
||||
public class WeatherQueryReq implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -2550570761981859666L;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
@NotBlank(message = "经度不能为空")
|
||||
private String lng;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
@NotBlank(message = "纬度不能为空")
|
||||
private String lat;
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package org.dromara.bigscreen.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-09 15:59
|
||||
*/
|
||||
@Data
|
||||
public class EnterpriseKeyIndexVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -3987781906203623727L;
|
||||
|
||||
/**
|
||||
* 在建项目数量
|
||||
*/
|
||||
private Long ongoingProject;
|
||||
|
||||
/**
|
||||
* 合同总额(单位:亿元)
|
||||
*/
|
||||
private BigDecimal totalContractAmount;
|
||||
|
||||
/**
|
||||
* 总容量
|
||||
*/
|
||||
private BigDecimal totalCapacity;
|
||||
|
||||
/**
|
||||
* 今日施工项目数量
|
||||
*/
|
||||
private Long todayProject;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package org.dromara.bigscreen.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-09 19:12
|
||||
*/
|
||||
@Data
|
||||
public class OutputValueComparisonVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -6902563869975528076L;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
private String projectName;
|
||||
|
||||
/**
|
||||
* 计划产值
|
||||
*/
|
||||
private BigDecimal planValue;
|
||||
|
||||
/**
|
||||
* 实际产值
|
||||
*/
|
||||
private BigDecimal actualValue;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package org.dromara.bigscreen.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PeopleCountVo {
|
||||
|
||||
/**
|
||||
* 施工人员
|
||||
*/
|
||||
private Long constructionPersonnelCount;
|
||||
|
||||
/**
|
||||
* 分包人员
|
||||
*/
|
||||
private Long SubcontractorsCount;
|
||||
|
||||
/**
|
||||
* 管理人员
|
||||
*/
|
||||
private Long managersCount;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package org.dromara.bigscreen.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-09 16:04
|
||||
*/
|
||||
@Data
|
||||
public class PeopleOverviewVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -4353811031023888101L;
|
||||
|
||||
/**
|
||||
* 出勤人数
|
||||
*/
|
||||
private Long attendanceNumber;
|
||||
|
||||
/**
|
||||
* 出勤率
|
||||
*/
|
||||
private BigDecimal attendanceRate;
|
||||
|
||||
/**
|
||||
* 施工人员数量
|
||||
*/
|
||||
private Long constructorNumber;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package org.dromara.bigscreen.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ProjectAttendanceCountVo {
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
private String projectName;
|
||||
|
||||
/**
|
||||
* 考勤人数
|
||||
*/
|
||||
private Long attendanceCount;
|
||||
|
||||
/**
|
||||
* 考勤率
|
||||
*/
|
||||
private Double attendanceRate;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package org.dromara.bigscreen.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-09 16:51
|
||||
*/
|
||||
@Data
|
||||
public class ProjectProgressAnalysisVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -2170524608375159201L;
|
||||
|
||||
/**
|
||||
* 并网总容量 (MW)
|
||||
*/
|
||||
private BigDecimal gridConnectedCapacity;
|
||||
|
||||
/**
|
||||
* 计划总容量 (MW)
|
||||
*/
|
||||
private BigDecimal plannedCapacity;
|
||||
|
||||
/**
|
||||
* 延期项目数量
|
||||
*/
|
||||
private Integer delayedProjectCount;
|
||||
|
||||
/**
|
||||
* 项目进度详情
|
||||
*/
|
||||
List<ProjectProgressDetailVo> projectProgressDetailList;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package org.dromara.bigscreen.domain.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-09 16:55
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ProjectProgressDetailVo {
|
||||
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
private String projectName;
|
||||
|
||||
/**
|
||||
* 项目容量
|
||||
*/
|
||||
private BigDecimal projectCapacity;
|
||||
|
||||
/**
|
||||
* 施工进度百分比 (0~100)
|
||||
*/
|
||||
private BigDecimal completionRate;
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package org.dromara.bigscreen.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-09 20:04
|
||||
*/
|
||||
@Data
|
||||
public class RiskEarlyWarningVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 5250172770638676715L;
|
||||
|
||||
/**
|
||||
* 时间
|
||||
*/
|
||||
private LocalDate date;
|
||||
|
||||
/**
|
||||
* 风险类型
|
||||
*/
|
||||
private String riskType;
|
||||
|
||||
/**
|
||||
* 报警内容
|
||||
*/
|
||||
private String alarmContent;
|
||||
|
||||
/**
|
||||
* 威胁等级
|
||||
*/
|
||||
private String dangerLevel;
|
||||
|
||||
/**
|
||||
* 来源
|
||||
*/
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* 告警等级
|
||||
*/
|
||||
private String alarmLevel;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.dromara.bigscreen.domain.vo;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TodayAttendanceCountVo {
|
||||
|
||||
/**
|
||||
* 考勤人员数量
|
||||
*/
|
||||
private Long attendanceCount;
|
||||
|
||||
/**
|
||||
* 出勤率
|
||||
*/
|
||||
private Double attendanceRate;
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package org.dromara.bigscreen.service;
|
||||
|
||||
import org.dromara.bigscreen.domain.dto.WeatherQueryReq;
|
||||
import org.dromara.bigscreen.domain.vo.EnterpriseKeyIndexVo;
|
||||
import org.dromara.bigscreen.domain.vo.OutputValueComparisonVo;
|
||||
import org.dromara.bigscreen.domain.vo.ProjectProgressAnalysisVo;
|
||||
import org.dromara.bigscreen.domain.vo.RiskEarlyWarningVo;
|
||||
import org.dromara.manager.weathermanager.vo.WeatherVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-09 15:31
|
||||
*/
|
||||
public interface EnterpriseBigScreenService {
|
||||
|
||||
/**
|
||||
* 获取关键指标
|
||||
*
|
||||
* @return 关键指标
|
||||
*/
|
||||
EnterpriseKeyIndexVo getEnterpriseKeyIndex();
|
||||
|
||||
/**
|
||||
* 获取项目进度分析
|
||||
*
|
||||
* @return 项目进度分析
|
||||
*/
|
||||
ProjectProgressAnalysisVo getProjectProgressAnalysis();
|
||||
|
||||
/**
|
||||
* 获取项目产值对比
|
||||
*
|
||||
* @return 项目产值对比
|
||||
*/
|
||||
List<OutputValueComparisonVo> getProjectOutputValueComparison();
|
||||
|
||||
/**
|
||||
* 获取风险预警
|
||||
*
|
||||
* @return 风险预警
|
||||
*/
|
||||
List<RiskEarlyWarningVo> getRiskEarlyWarning();
|
||||
|
||||
/**
|
||||
* 获取3天的天气列表
|
||||
*
|
||||
* @param req 查询参数
|
||||
* @return 天气列表
|
||||
*/
|
||||
List<WeatherVo> getWeather3DaysList(WeatherQueryReq req);
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package org.dromara.bigscreen.service;
|
||||
|
||||
import org.dromara.manager.weathermanager.vo.WeatherVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectGisVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -25,7 +25,7 @@ public interface MoneyBigScreenService {
|
||||
* @param projectId 项目id
|
||||
* @return 项目天气
|
||||
*/
|
||||
List<BusProjectWeatherVo> getProjectWeather(Long projectId);
|
||||
List<WeatherVo> getProjectWeather(Long projectId);
|
||||
|
||||
/**
|
||||
* 获取项目安全天数
|
||||
|
@ -3,8 +3,9 @@ package org.dromara.bigscreen.service;
|
||||
import org.dromara.bigscreen.domain.vo.ProjectImageProgressVo;
|
||||
import org.dromara.bigscreen.domain.vo.ProjectPeopleVo;
|
||||
import org.dromara.bigscreen.domain.vo.ProjectSafetyInspectionVo;
|
||||
import org.dromara.manager.weathermanager.vo.WeatherVo;
|
||||
import org.dromara.gps.domain.bo.GpsEquipmentBo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
||||
import org.dromara.project.domain.vo.projectnews.BusProjectNewsVo;
|
||||
|
||||
import java.util.List;
|
||||
@ -21,7 +22,7 @@ public interface ProjectBigScreenService {
|
||||
* @param projectId 项目id
|
||||
* @return 项目天气
|
||||
*/
|
||||
List<BusProjectWeatherVo> getProjectWeather(Long projectId);
|
||||
List<WeatherVo> getProjectWeather(Long projectId);
|
||||
|
||||
/**
|
||||
* 获取项目安全天数
|
||||
@ -70,4 +71,8 @@ public interface ProjectBigScreenService {
|
||||
* @return 项目概括
|
||||
*/
|
||||
String getProjectGeneralize(Long projectId);
|
||||
|
||||
List<String> getList(Long projectId);
|
||||
|
||||
void setList(GpsEquipmentBo bo);
|
||||
}
|
||||
|
@ -0,0 +1,383 @@
|
||||
package org.dromara.bigscreen.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.dromara.bigscreen.domain.dto.WeatherQueryReq;
|
||||
import org.dromara.bigscreen.domain.vo.*;
|
||||
import org.dromara.bigscreen.service.EnterpriseBigScreenService;
|
||||
import org.dromara.common.core.enums.BusinessStatusEnum;
|
||||
import org.dromara.common.core.utils.DateUtils;
|
||||
import org.dromara.common.utils.BigDecimalUtil;
|
||||
import org.dromara.ctr.domain.CtrExpensesContract;
|
||||
import org.dromara.ctr.domain.CtrIncomeContract;
|
||||
import org.dromara.ctr.service.ICtrExpensesContractService;
|
||||
import org.dromara.ctr.service.ICtrIncomeContractService;
|
||||
import org.dromara.manager.weathermanager.WeatherConstant;
|
||||
import org.dromara.manager.weathermanager.WeatherManager;
|
||||
import org.dromara.manager.weathermanager.vo.WeatherVo;
|
||||
import org.dromara.out.domain.BusProcurement;
|
||||
import org.dromara.out.domain.OutConstructionValue;
|
||||
import org.dromara.out.domain.OutMonthPlanAudit;
|
||||
import org.dromara.out.domain.OutValueAllocation;
|
||||
import org.dromara.out.service.IBusProcurementService;
|
||||
import org.dromara.out.service.IOutConstructionValueService;
|
||||
import org.dromara.out.service.IOutMonthPlanAuditService;
|
||||
import org.dromara.out.service.IOutValueAllocationService;
|
||||
import org.dromara.progress.domain.PgsProgressCategory;
|
||||
import org.dromara.progress.domain.PgsProgressPlanDetail;
|
||||
import org.dromara.progress.service.IPgsProgressCategoryService;
|
||||
import org.dromara.progress.service.IPgsProgressPlanDetailService;
|
||||
import org.dromara.project.domain.BusProject;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.dromara.safety.domain.HseRecognizeRecord;
|
||||
import org.dromara.safety.domain.HseViolationLevel;
|
||||
import org.dromara.safety.domain.HseViolationRecord;
|
||||
import org.dromara.safety.service.IHseRecognizeRecordService;
|
||||
import org.dromara.safety.service.IHseViolationLevelService;
|
||||
import org.dromara.safety.service.IHseViolationRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-09 15:32
|
||||
*/
|
||||
@Service
|
||||
public class EnterpriseBigScreenServiceImpl implements EnterpriseBigScreenService {
|
||||
|
||||
@Resource
|
||||
private WeatherManager weatherManager;
|
||||
|
||||
@Resource
|
||||
private IBusProjectService projectService;
|
||||
|
||||
@Resource
|
||||
private IPgsProgressCategoryService progressCategoryService;
|
||||
|
||||
@Resource
|
||||
private IPgsProgressPlanDetailService progressPlanDetailService;
|
||||
|
||||
@Resource
|
||||
private ICtrIncomeContractService incomeContractService;
|
||||
|
||||
@Resource
|
||||
private ICtrExpensesContractService expensesContractService;
|
||||
|
||||
@Resource
|
||||
private IOutValueAllocationService outValueAllocationService;
|
||||
|
||||
@Resource
|
||||
private IOutMonthPlanAuditService outMonthPlanAuditService;
|
||||
|
||||
@Resource
|
||||
private IOutConstructionValueService outConstructionValueService;
|
||||
|
||||
@Resource
|
||||
private IHseViolationRecordService hseViolationRecordService;
|
||||
|
||||
@Resource
|
||||
private IHseViolationLevelService hseViolationLevelService;
|
||||
|
||||
@Resource
|
||||
private IBusProcurementService busProcurementService;
|
||||
|
||||
@Resource
|
||||
private IHseRecognizeRecordService hseRecognizeRecordService;
|
||||
|
||||
/**
|
||||
* 获取关键指标
|
||||
*
|
||||
* @return 关键指标
|
||||
*/
|
||||
@Override
|
||||
public EnterpriseKeyIndexVo getEnterpriseKeyIndex() {
|
||||
EnterpriseKeyIndexVo vo = new EnterpriseKeyIndexVo();
|
||||
// 在建项目
|
||||
List<BusProject> projectList = projectService.lambdaQuery()
|
||||
.eq(BusProject::getStatus, 0)
|
||||
.eq(BusProject::getPId, 0)
|
||||
.list();
|
||||
// 总容量
|
||||
BigDecimal totalCapacity = projectList.stream().map(BusProject::getActual)
|
||||
.filter(s -> s != null && !s.isBlank()) // 过滤掉空值
|
||||
.map(BigDecimal::new) // 转成 BigDecimal
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
// 总合同金额
|
||||
List<CtrIncomeContract> incomeContractList = incomeContractService.lambdaQuery()
|
||||
.select(CtrIncomeContract::getAmount)
|
||||
.list();
|
||||
BigDecimal totalIncomeAmount = incomeContractList.stream()
|
||||
.map(CtrIncomeContract::getAmount)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
List<CtrExpensesContract> expensesContractList = expensesContractService.lambdaQuery()
|
||||
.select(CtrExpensesContract::getAmount)
|
||||
.list();
|
||||
BigDecimal totalExpensesAmount = expensesContractList.stream()
|
||||
.map(CtrExpensesContract::getAmount)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
// 今日施工项目数量
|
||||
Long todayProject = progressPlanDetailService.lambdaQuery()
|
||||
.select(PgsProgressPlanDetail::getProjectId)
|
||||
.eq(PgsProgressPlanDetail::getDate, LocalDate.now())
|
||||
.groupBy(PgsProgressPlanDetail::getProjectId)
|
||||
.count();
|
||||
vo.setOngoingProject((long) projectList.size());
|
||||
vo.setTotalCapacity(totalCapacity);
|
||||
vo.setTotalContractAmount(totalIncomeAmount.add(totalExpensesAmount));
|
||||
vo.setTodayProject(todayProject);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目进度分析
|
||||
*
|
||||
* @return 项目进度分析
|
||||
*/
|
||||
@Override
|
||||
public ProjectProgressAnalysisVo getProjectProgressAnalysis() {
|
||||
ProjectProgressAnalysisVo vo = new ProjectProgressAnalysisVo();
|
||||
// 1. 查询顶级项目
|
||||
List<BusProject> projectList = projectService.lambdaQuery()
|
||||
.select(BusProject::getId, BusProject::getProjectName, BusProject::getActual, BusProject::getPlan)
|
||||
.eq(BusProject::getStatus, 0)
|
||||
.eq(BusProject::getPId, 0)
|
||||
.list();
|
||||
if (CollUtil.isEmpty(projectList)) {
|
||||
return vo;
|
||||
}
|
||||
// 2. 拿到顶级项目 id
|
||||
List<Long> projectIds = projectList.stream()
|
||||
.map(BusProject::getId)
|
||||
.distinct()
|
||||
.toList();
|
||||
// 3. 查询子项目(pId 在顶级项目id里)
|
||||
List<BusProject> subProject = projectService.lambdaQuery()
|
||||
.select(BusProject::getId, BusProject::getPId)
|
||||
.in(BusProject::getPId, projectIds)
|
||||
.list();
|
||||
// 4. 按父项目id分组子项目
|
||||
Map<Long, List<BusProject>> subProjectMap = subProject.stream()
|
||||
.collect(Collectors.groupingBy(BusProject::getPId));
|
||||
// 5. 查询所有子项目的进度分类
|
||||
List<PgsProgressCategory> progressCategoryList = progressCategoryService.lambdaQuery()
|
||||
.select(PgsProgressCategory::getId,
|
||||
PgsProgressCategory::getProjectId,
|
||||
PgsProgressCategory::getCompleted,
|
||||
PgsProgressCategory::getTotal)
|
||||
.in(CollUtil.isNotEmpty(subProject),
|
||||
PgsProgressCategory::getProjectId,
|
||||
subProject.stream().map(BusProject::getId).toList())
|
||||
.list();
|
||||
// 6. 按子项目id分组进度分类
|
||||
Map<Long, List<PgsProgressCategory>> progressCategoryMap = progressCategoryList.stream()
|
||||
.collect(Collectors.groupingBy(PgsProgressCategory::getProjectId));
|
||||
// 并网容量 =(完工产值/计划总产值)* 计划容量
|
||||
List<OutputValueComparisonVo> list = getProjectOutputValueComparison();
|
||||
BigDecimal actualValue = list.stream()
|
||||
.map(OutputValueComparisonVo::getActualValue)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal planValue = list.stream()
|
||||
.map(OutputValueComparisonVo::getPlanValue)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal plannedCapacity = projectList.stream().map(BusProject::getPlan)
|
||||
.filter(s -> s != null && !s.isBlank()) // 过滤掉空值
|
||||
.map(BigDecimal::new) // 转成 BigDecimal
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal gridConnectedCapacity = BigDecimal.ZERO;
|
||||
if (planValue.compareTo(BigDecimal.ZERO) != 0) {
|
||||
gridConnectedCapacity = plannedCapacity.multiply(actualValue.divide(planValue, 2, RoundingMode.HALF_UP));
|
||||
}
|
||||
vo.setGridConnectedCapacity(gridConnectedCapacity);
|
||||
List<ProjectProgressDetailVo> detailVoList = projectList.stream().map(project -> {
|
||||
ProjectProgressDetailVo detailVo = new ProjectProgressDetailVo();
|
||||
detailVo.setProjectName(project.getProjectName());
|
||||
detailVo.setProjectCapacity(new BigDecimal(project.getActual()));
|
||||
List<BusProject> children = subProjectMap.getOrDefault(project.getId(), List.of());
|
||||
List<PgsProgressCategory> categoryList = new ArrayList<>();
|
||||
for (BusProject child : children) {
|
||||
categoryList.addAll(progressCategoryMap.getOrDefault(child.getId(), List.of()));
|
||||
}
|
||||
if (CollUtil.isNotEmpty(categoryList)) {
|
||||
BigDecimal completed = categoryList.stream().map(PgsProgressCategory::getCompleted)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal total = categoryList.stream().map(PgsProgressCategory::getTotal)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
detailVo.setCompletionRate(BigDecimalUtil.toPercentage(completed, total));
|
||||
}
|
||||
return detailVo;
|
||||
}).toList();
|
||||
vo.setGridConnectedCapacity(gridConnectedCapacity);
|
||||
vo.setPlannedCapacity(plannedCapacity);
|
||||
// todo 获取延迟项目数
|
||||
vo.setDelayedProjectCount(0);
|
||||
vo.setProjectProgressDetailList(detailVoList);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目产值对比
|
||||
*
|
||||
* @return 项目产值对比
|
||||
*/
|
||||
@Override
|
||||
public List<OutputValueComparisonVo> getProjectOutputValueComparison() {
|
||||
// 查询顶级项目
|
||||
List<BusProject> projectList = projectService.lambdaQuery()
|
||||
.select(BusProject::getId, BusProject::getProjectName, BusProject::getActual, BusProject::getPlan)
|
||||
.eq(BusProject::getStatus, 0)
|
||||
.eq(BusProject::getPId, 0)
|
||||
.list();
|
||||
// 计划产值
|
||||
List<OutValueAllocation> planList = outValueAllocationService.lambdaQuery()
|
||||
.select(OutValueAllocation::getProjectId, OutValueAllocation::getOwnerTotalValue)
|
||||
.list();
|
||||
Map<Long, BigDecimal> planMap = planList.stream()
|
||||
.collect(Collectors.toMap(OutValueAllocation::getProjectId, OutValueAllocation::getOwnerTotalValue));
|
||||
// 实际产值
|
||||
// 施工产值
|
||||
List<OutConstructionValue> constructionValueList = outConstructionValueService.lambdaQuery()
|
||||
.select(OutConstructionValue::getProjectId, OutConstructionValue::getOwnerValue)
|
||||
.eq(OutConstructionValue::getAuditStatus, BusinessStatusEnum.FINISH.getStatus())
|
||||
.list();
|
||||
// 采购产值
|
||||
List<BusProcurement> purchaseValueList = busProcurementService.lambdaQuery()
|
||||
.select(BusProcurement::getProjectId, BusProcurement::getAcceptedQuantity, BusProcurement::getUnitPrice)
|
||||
.list();
|
||||
// 设计产值
|
||||
List<OutMonthPlanAudit> designValueList = outMonthPlanAuditService.lambdaQuery()
|
||||
.select(OutMonthPlanAudit::getProjectId, OutMonthPlanAudit::getDesignValue)
|
||||
.eq(OutMonthPlanAudit::getType, "1")
|
||||
.list();
|
||||
// 封装数据
|
||||
return projectList.stream().map(project -> {
|
||||
OutputValueComparisonVo vo = new OutputValueComparisonVo();
|
||||
vo.setProjectId(project.getId());
|
||||
vo.setProjectName(project.getProjectName());
|
||||
vo.setPlanValue(planMap.getOrDefault(project.getId(), BigDecimal.ZERO));
|
||||
BigDecimal actualValue = BigDecimal.ZERO;
|
||||
// 设计产值
|
||||
List<OutMonthPlanAudit> designValue = designValueList.stream()
|
||||
.filter(design -> design.getProjectId().equals(project.getId()))
|
||||
.toList();
|
||||
if (CollUtil.isNotEmpty(designValue)) {
|
||||
BigDecimal dValue = designValue.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(OutMonthPlanAudit::getDesignValue)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
actualValue = actualValue.add(dValue);
|
||||
}
|
||||
// 施工产值
|
||||
List<OutConstructionValue> constructionValue = constructionValueList.stream()
|
||||
.filter(construction -> construction.getProjectId().equals(project.getId()))
|
||||
.toList();
|
||||
if (CollUtil.isNotEmpty(constructionValue)) {
|
||||
BigDecimal cValue = constructionValue.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(OutConstructionValue::getOwnerValue)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
actualValue = actualValue.add(cValue);
|
||||
}
|
||||
// 采购产值
|
||||
List<BusProcurement> purchaseValue = purchaseValueList.stream()
|
||||
.filter(purchase -> purchase.getProjectId().equals(project.getId()))
|
||||
.toList();
|
||||
if (CollUtil.isNotEmpty(purchaseValue)) {
|
||||
BigDecimal pValue = purchaseValue.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(purchase -> purchase.getAcceptedQuantity() != null && purchase.getUnitPrice() != null)
|
||||
.map(purchase -> purchase.getAcceptedQuantity().multiply(purchase.getUnitPrice()))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
actualValue = actualValue.add(pValue);
|
||||
}
|
||||
vo.setActualValue(actualValue);
|
||||
return vo;
|
||||
}).filter(vo -> vo.getActualValue().compareTo(BigDecimal.ZERO) > 0)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取风险预警
|
||||
*
|
||||
* @return 风险预警
|
||||
*/
|
||||
@Override
|
||||
public List<RiskEarlyWarningVo> getRiskEarlyWarning() {
|
||||
List<HseViolationRecord> recordList = hseViolationRecordService.lambdaQuery()
|
||||
.last("limit 10")
|
||||
.list();
|
||||
recordList = recordList.stream()
|
||||
.filter(record -> record.getReviewType() == null || record.getReviewType().equals("2"))
|
||||
.toList();
|
||||
if (CollUtil.isEmpty(recordList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 项目映射
|
||||
Set<Long> projectIds = recordList.stream()
|
||||
.map(HseViolationRecord::getProjectId)
|
||||
.collect(Collectors.toSet());
|
||||
List<BusProject> projectList = projectService.lambdaQuery()
|
||||
.select(BusProject::getId, BusProject::getProjectName)
|
||||
.in(BusProject::getId, projectIds)
|
||||
.list();
|
||||
Map<Long, String> projectMap = projectList.stream()
|
||||
.collect(Collectors.toMap(BusProject::getId, BusProject::getProjectName));
|
||||
// 风险映射
|
||||
Set<Long> levelIds = recordList.stream()
|
||||
.map(HseViolationRecord::getLevelId)
|
||||
.collect(Collectors.toSet());
|
||||
List<HseViolationLevel> levelList = hseViolationLevelService.lambdaQuery()
|
||||
.select(HseViolationLevel::getId, HseViolationLevel::getRiskType, HseViolationLevel::getViolationLevel)
|
||||
.in(HseViolationLevel::getId, levelIds)
|
||||
.list();
|
||||
Map<Long, HseViolationLevel> levelMap = levelList.stream()
|
||||
.collect(Collectors.toMap(HseViolationLevel::getId, level -> level));
|
||||
// 识别记录映射
|
||||
Set<Long> recognizeIds = recordList.stream()
|
||||
.map(HseViolationRecord::getRecognizeId)
|
||||
.collect(Collectors.toSet());
|
||||
List<HseRecognizeRecord> recognizeRecordList = hseRecognizeRecordService.lambdaQuery()
|
||||
.in(HseRecognizeRecord::getId, recognizeIds)
|
||||
.list();
|
||||
Map<Long, HseRecognizeRecord> recognizeRecordMap = recognizeRecordList.stream()
|
||||
.collect(Collectors.toMap(HseRecognizeRecord::getId, recognize -> recognize));
|
||||
return recordList.stream().map(record -> {
|
||||
RiskEarlyWarningVo vo = new RiskEarlyWarningVo();
|
||||
Date violationTime = record.getViolationTime() != null ? record.getViolationTime() : record.getCreateTime();
|
||||
vo.setDate(DateUtils.toLocalDate(violationTime));
|
||||
vo.setSource(projectMap.getOrDefault(record.getProjectId(), "未知项目"));
|
||||
vo.setRiskType(record.getViolationType());
|
||||
if (levelMap.containsKey(record.getLevelId())) {
|
||||
HseViolationLevel level = levelMap.get(record.getLevelId());
|
||||
vo.setAlarmLevel(level.getRiskType());
|
||||
vo.setDangerLevel(level.getViolationLevel());
|
||||
}
|
||||
if (recognizeRecordMap.containsKey(record.getRecognizeId())) {
|
||||
HseRecognizeRecord hseRecognizeRecord = recognizeRecordMap.get(record.getRecognizeId());
|
||||
vo.setAlarmContent(hseRecognizeRecord.getDescription());
|
||||
}
|
||||
return vo;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取3天的天气列表
|
||||
*
|
||||
* @param req 查询参数
|
||||
* @return 天气列表
|
||||
*/
|
||||
@Override
|
||||
public List<WeatherVo> getWeather3DaysList(WeatherQueryReq req) {
|
||||
return weatherManager.getWeatherListVo(req.getLng(), req.getLat(), WeatherConstant.THREE_DAYS_WEATHER_PATH);
|
||||
}
|
||||
}
|
@ -4,10 +4,10 @@ import jakarta.annotation.Resource;
|
||||
import org.dromara.bigscreen.service.MoneyBigScreenService;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.manager.weathermanager.vo.WeatherVo;
|
||||
import org.dromara.project.domain.BusProject;
|
||||
import org.dromara.project.domain.vo.project.BusProjectGisVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -40,7 +40,7 @@ public class MoneyBigScreenServiceImpl implements MoneyBigScreenService {
|
||||
* @return 项目天气
|
||||
*/
|
||||
@Override
|
||||
public List<BusProjectWeatherVo> getProjectWeather(Long projectId) {
|
||||
public List<WeatherVo> getProjectWeather(Long projectId) {
|
||||
checkProject(projectId);
|
||||
return projectService.getWeather(projectId);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package org.dromara.bigscreen.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.dromara.bigscreen.domain.vo.ProjectImageProgressVo;
|
||||
import org.dromara.bigscreen.domain.vo.ProjectPeopleVo;
|
||||
@ -11,14 +11,19 @@ import org.dromara.bigscreen.domain.vo.ProjectTeamAttendanceVo;
|
||||
import org.dromara.bigscreen.service.ProjectBigScreenService;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.redis.utils.RedisUtils;
|
||||
import org.dromara.common.utils.BigDecimalUtil;
|
||||
import org.dromara.contractor.domain.SubConstructionUser;
|
||||
import org.dromara.contractor.service.ISubConstructionUserService;
|
||||
import org.dromara.gps.domain.bo.GpsEquipmentBo;
|
||||
import org.dromara.manager.weathermanager.vo.WeatherVo;
|
||||
import org.dromara.progress.domain.PgsProgressCategory;
|
||||
import org.dromara.progress.domain.enums.PgsProgressUnitTypeEnum;
|
||||
import org.dromara.progress.service.IPgsProgressCategoryService;
|
||||
import org.dromara.project.domain.BusProject;
|
||||
import org.dromara.project.domain.BusProjectTeam;
|
||||
import org.dromara.project.domain.BusProjectTeamMember;
|
||||
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
|
||||
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
|
||||
import org.dromara.project.domain.vo.projectnews.BusProjectNewsVo;
|
||||
import org.dromara.project.service.*;
|
||||
import org.dromara.safety.domain.HseRecognizeRecord;
|
||||
@ -27,11 +32,9 @@ import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -62,6 +65,9 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService {
|
||||
@Resource
|
||||
private IBusProjectTeamMemberService projectTeamMemberService;
|
||||
|
||||
@Resource
|
||||
private IPgsProgressCategoryService progressCategoryService;
|
||||
|
||||
/**
|
||||
* 获取项目天气
|
||||
*
|
||||
@ -69,7 +75,7 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService {
|
||||
* @return 项目天气
|
||||
*/
|
||||
@Override
|
||||
public List<BusProjectWeatherVo> getProjectWeather(Long projectId) {
|
||||
public List<WeatherVo> getProjectWeather(Long projectId) {
|
||||
checkProject(projectId);
|
||||
return projectService.getWeather(projectId);
|
||||
}
|
||||
@ -203,50 +209,130 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService {
|
||||
@Override
|
||||
public ProjectImageProgressVo getProjectImageProgress(Long projectId) {
|
||||
checkProject(projectId);
|
||||
// 生成 0 ~ 100 的随机 double
|
||||
double random = RandomUtil.randomDouble(0, 100);
|
||||
|
||||
// 保留两位小数(四舍五入)
|
||||
double result = NumberUtil.round(random, 2).doubleValue();
|
||||
ProjectImageProgressVo vo = new ProjectImageProgressVo();
|
||||
vo.setAreaPercentage(BigDecimal.valueOf(result));
|
||||
// 生成 0 ~ 100 的随机 double
|
||||
double random1 = RandomUtil.randomDouble(0, 100);
|
||||
|
||||
// 保留两位小数(四舍五入)
|
||||
double result1 = NumberUtil.round(random1, 2).doubleValue();
|
||||
vo.setRoadPercentage(BigDecimal.valueOf(result1));
|
||||
// 生成 0 ~ 100 的随机 double
|
||||
double random2 = RandomUtil.randomDouble(0, 100);
|
||||
|
||||
// 保留两位小数(四舍五入)
|
||||
double result2 = NumberUtil.round(random2, 2).doubleValue();
|
||||
vo.setCollectorLinePercentage(BigDecimal.valueOf(result2));
|
||||
// 生成 0 ~ 100 的随机 double
|
||||
double random3 = RandomUtil.randomDouble(0, 100);
|
||||
|
||||
// 保留两位小数(四舍五入)
|
||||
double result3 = NumberUtil.round(random3, 2).doubleValue();
|
||||
vo.setExportLinePercentage(BigDecimal.valueOf(result3));
|
||||
// 生成 0 ~ 100 的随机 double
|
||||
double random4 = RandomUtil.randomDouble(0, 100);
|
||||
|
||||
// 保留两位小数(四舍五入)
|
||||
double result4 = NumberUtil.round(random4, 2).doubleValue();
|
||||
vo.setSubstationPercentage(BigDecimal.valueOf(result4));
|
||||
// 生成 0 ~ 100 的随机 double
|
||||
double random5 = RandomUtil.randomDouble(0, 100);
|
||||
|
||||
// 保留两位小数(四舍五入)
|
||||
double result5 = NumberUtil.round(random5, 2).doubleValue();
|
||||
vo.setBoxTransformerPercentage(BigDecimal.valueOf(result5));
|
||||
|
||||
// 生成 0 ~ 100 的随机 double
|
||||
double random6 = RandomUtil.randomDouble(0, 100);
|
||||
|
||||
// 保留两位小数(四舍五入)
|
||||
double result6 = NumberUtil.round(random6, 2).doubleValue();
|
||||
vo.setTotalPercentage(BigDecimal.valueOf(result6));
|
||||
// 获取所有子项目列表
|
||||
List<BusProject> subProjectList = projectService.lambdaQuery()
|
||||
.eq(BusProject::getPId, projectId)
|
||||
.list();
|
||||
if (CollUtil.isEmpty(subProjectList)) {
|
||||
return vo;
|
||||
}
|
||||
// 子项目id列表
|
||||
List<Long> subProjectIds = subProjectList.stream().map(BusProject::getId).toList();
|
||||
// 计算集电线路
|
||||
vo.setCollectorLinePercentage(BigDecimal.valueOf(0.00));
|
||||
// 计算送出线路
|
||||
vo.setExportLinePercentage(BigDecimal.valueOf(0.00));
|
||||
// 计算升压站
|
||||
vo.setSubstationPercentage(BigDecimal.valueOf(0.00));
|
||||
// 计算光伏场区
|
||||
vo.setAreaPercentage(BigDecimal.valueOf(0.00));
|
||||
// 计算道路
|
||||
vo.setRoadPercentage(BigDecimal.valueOf(0.00));
|
||||
// 计算箱变
|
||||
vo.setBoxTransformerPercentage(BigDecimal.ZERO);
|
||||
// 获取集电线路、送出线路、升压站数据
|
||||
List<PgsProgressCategory> progressCategoryList = progressCategoryService.lambdaQuery()
|
||||
.in(PgsProgressCategory::getProjectId, subProjectIds)
|
||||
.in(PgsProgressCategory::getName, "集电线路", "送出线路", "升压站", "光伏场区")
|
||||
.eq(PgsProgressCategory::getParentId, 0L)
|
||||
.list();
|
||||
if (CollUtil.isNotEmpty(progressCategoryList)) {
|
||||
List<Long> categoryIds = progressCategoryList.stream().map(PgsProgressCategory::getId).distinct().toList();
|
||||
List<PgsProgressCategory> leafNodesByTopIds = progressCategoryService.getLeafNodesByTopIds(categoryIds);
|
||||
Map<String, List<PgsProgressCategory>> categoryMap = progressCategoryList.stream()
|
||||
.collect(Collectors.groupingBy(PgsProgressCategory::getName));
|
||||
// 计算集电线路
|
||||
if (categoryMap.containsKey("集电线路")) {
|
||||
List<PgsProgressCategory> categoryList = categoryMap.get("集电线路");
|
||||
List<Long> ids = categoryList.stream().map(PgsProgressCategory::getId).distinct().toList();
|
||||
List<PgsProgressCategory> list = leafNodesByTopIds.stream()
|
||||
.filter(node -> {
|
||||
Set<Long> ancestorSet = Arrays.stream(node.getAncestors().split(",")).map(Long::parseLong).collect(Collectors.toSet());
|
||||
return ids.stream().anyMatch(ancestorSet::contains);
|
||||
}).toList();
|
||||
BigDecimal percentage = progressCategoryService.getCompletedPercentage(list);
|
||||
if (percentage.compareTo(BigDecimal.ZERO) > 0) {
|
||||
vo.setCollectorLinePercentage(percentage);
|
||||
}
|
||||
}
|
||||
// 计算送出线路
|
||||
if (categoryMap.containsKey("送出线路")) {
|
||||
List<PgsProgressCategory> categoryList = categoryMap.get("送出线路");
|
||||
List<Long> ids = categoryList.stream().map(PgsProgressCategory::getId).distinct().toList();
|
||||
List<PgsProgressCategory> list = leafNodesByTopIds.stream()
|
||||
.filter(node -> {
|
||||
Set<Long> ancestorSet = Arrays.stream(node.getAncestors().split(",")).map(Long::parseLong).collect(Collectors.toSet());
|
||||
return ids.stream().anyMatch(ancestorSet::contains);
|
||||
}).toList();
|
||||
BigDecimal percentage = progressCategoryService.getCompletedPercentage(list);
|
||||
if (percentage.compareTo(BigDecimal.ZERO) > 0) {
|
||||
vo.setExportLinePercentage(percentage);
|
||||
}
|
||||
}
|
||||
// 计算升压站
|
||||
if (categoryMap.containsKey("升压站")) {
|
||||
List<PgsProgressCategory> categoryList = categoryMap.get("升压站");
|
||||
List<Long> ids = categoryList.stream().map(PgsProgressCategory::getId).distinct().toList();
|
||||
List<PgsProgressCategory> list = leafNodesByTopIds.stream()
|
||||
.filter(node -> {
|
||||
Set<Long> ancestorSet = Arrays.stream(node.getAncestors().split(",")).map(Long::parseLong).collect(Collectors.toSet());
|
||||
return ids.stream().anyMatch(ancestorSet::contains);
|
||||
}).toList();
|
||||
BigDecimal percentage = progressCategoryService.getCompletedPercentage(list);
|
||||
if (percentage.compareTo(BigDecimal.ZERO) > 0) {
|
||||
vo.setSubstationPercentage(percentage);
|
||||
}
|
||||
}
|
||||
// 计算光伏场区
|
||||
if (categoryMap.containsKey("光伏场区")) {
|
||||
List<PgsProgressCategory> categoryList = categoryMap.get("光伏场区");
|
||||
List<Long> ids = categoryList.stream().map(PgsProgressCategory::getId).distinct().toList();
|
||||
List<PgsProgressCategory> list = leafNodesByTopIds.stream()
|
||||
.filter(node -> {
|
||||
Set<Long> ancestorSet = Arrays.stream(node.getAncestors().split(",")).map(Long::parseLong).collect(Collectors.toSet());
|
||||
return ids.stream().anyMatch(ancestorSet::contains);
|
||||
}).toList();
|
||||
BigDecimal percentage = progressCategoryService.getCompletedPercentage(list);
|
||||
if (percentage.compareTo(BigDecimal.ZERO) > 0) {
|
||||
vo.setAreaPercentage(percentage);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 计算道路
|
||||
List<PgsProgressCategory> roadCategoryList = progressCategoryService.lambdaQuery()
|
||||
.in(PgsProgressCategory::getProjectId, subProjectIds)
|
||||
.like(PgsProgressCategory::getName, "道路")
|
||||
.ne(PgsProgressCategory::getUnitType, PgsProgressUnitTypeEnum.NULL.getValue())
|
||||
.list();
|
||||
if (CollUtil.isNotEmpty(roadCategoryList)) {
|
||||
BigDecimal percentage = progressCategoryService.getCompletedPercentage(roadCategoryList);
|
||||
if (percentage.compareTo(BigDecimal.ZERO) > 0) {
|
||||
vo.setRoadPercentage(percentage);
|
||||
}
|
||||
}
|
||||
// 计算箱变
|
||||
List<PgsProgressCategory> boxTransformerCategoryList = progressCategoryService.lambdaQuery()
|
||||
.in(PgsProgressCategory::getProjectId, subProjectIds)
|
||||
.like(PgsProgressCategory::getName, "箱变")
|
||||
.ne(PgsProgressCategory::getUnitType, PgsProgressUnitTypeEnum.NULL.getValue())
|
||||
.list();
|
||||
if (CollUtil.isNotEmpty(boxTransformerCategoryList)) {
|
||||
BigDecimal percentage = progressCategoryService.getCompletedPercentage(boxTransformerCategoryList);
|
||||
if (percentage.compareTo(BigDecimal.ZERO) > 0) {
|
||||
vo.setBoxTransformerPercentage(percentage);
|
||||
}
|
||||
}
|
||||
// 计算总进度
|
||||
vo.setTotalPercentage(
|
||||
vo.getCollectorLinePercentage()
|
||||
.add(vo.getExportLinePercentage())
|
||||
.add(vo.getSubstationPercentage())
|
||||
.add(vo.getAreaPercentage())
|
||||
.add(vo.getRoadPercentage())
|
||||
.add(vo.getBoxTransformerPercentage())
|
||||
.divide(BigDecimal.valueOf(6), 2, RoundingMode.HALF_UP) // 保留两位小数
|
||||
);
|
||||
return vo;
|
||||
}
|
||||
|
||||
@ -276,4 +362,26 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService {
|
||||
throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getList(Long projectId) {
|
||||
if (projectId == null){
|
||||
throw new ServiceException("项目id不能为空!!!");
|
||||
}
|
||||
Object object = RedisUtils.getCacheObject("xmjdp:" + projectId);
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
JSONArray objects = JSONUtil.parseArray(object);
|
||||
return objects.toList(String.class);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setList(GpsEquipmentBo bo) {
|
||||
if (bo.getProjectId() == null){
|
||||
throw new ServiceException("项目id不能为空!!!");
|
||||
}
|
||||
RedisUtils.setCacheObject("xmjdp:"+bo.getProjectId(), bo.getIdList());
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +123,7 @@ public class BusMrpBaseController extends BaseController {
|
||||
/**
|
||||
* 批量新增或修改
|
||||
*/
|
||||
@SaCheckPermission("cailiaoshebei:mrpBase:addbatch")
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/batch")
|
||||
public R<Void> batchAddOrUpdate(@RequestBody BusMrpDto dto) {
|
||||
@ -133,17 +134,15 @@ public class BusMrpBaseController extends BaseController {
|
||||
* 获取剩余量
|
||||
*/
|
||||
@GetMapping("/remaining")
|
||||
public R<Integer> remaining(Long suppliespriceId) {
|
||||
BigDecimal remaining = busMrpBaseService.remaining(suppliespriceId);
|
||||
BusBillofquantities byId = busBillofquantitiesService.getById(suppliespriceId);
|
||||
return R.ok(byId.getQuantity().subtract(remaining).intValue());
|
||||
public R<BigDecimal> remaining(Long suppliespriceId,Long mrpBaseId) {
|
||||
return R.ok(busMrpBaseService.remaining(suppliespriceId,mrpBaseId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导入物资需求批次计划
|
||||
*/
|
||||
@SaCheckPermission("cailiaoshebei:mrpBase:add")
|
||||
@SaCheckPermission("cailiaoshebei:mrpBase:import")
|
||||
@Log(title = "物资-批次需求计划基础信息", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/import")
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.dromara.cailiaoshebei.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
@ -33,8 +34,12 @@ import org.dromara.design.service.IBusBillofquantitiesVersionsService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 物资-采购联系单
|
||||
@ -67,6 +72,8 @@ public class BusPurchaseDocController extends BaseController {
|
||||
return busPurchaseDocService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 导出物资-采购联系单列表
|
||||
*/
|
||||
@ -81,7 +88,7 @@ public class BusPurchaseDocController extends BaseController {
|
||||
/**
|
||||
* 根据主键导出物资-采购联系单
|
||||
*/
|
||||
@SaCheckPermission("cailiaoshebei:purchaseDoc:downloadWord")
|
||||
@SaCheckPermission("cailiaoshebei:purchaseDoc:exportWord")
|
||||
@Log(title = "物资-采购联系单", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export/word")
|
||||
public void exportWordById(@NotNull(message = "主键不能为空") Long id,
|
||||
@ -106,7 +113,7 @@ public class BusPurchaseDocController extends BaseController {
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
@SaCheckPermission("cailiaoshebei:purchaseDoc:queryPdf")
|
||||
@SaCheckPermission("cailiaoshebei:purchaseDoc:pdf")
|
||||
@GetMapping("/pdf/{id}")
|
||||
public R<String> getPic(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
@ -157,13 +164,23 @@ public class BusPurchaseDocController extends BaseController {
|
||||
@PathVariable("id") Long id) {
|
||||
List<BusPlanDocAssociation> list = planDocAssociationService.list(Wrappers.lambdaQuery(BusPlanDocAssociation.class)
|
||||
.eq(BusPlanDocAssociation::getDocId, id));
|
||||
List<Long> list1 = list.stream().map(BusPlanDocAssociation::getPlanId).toList();
|
||||
if (list1.isEmpty()) {
|
||||
if (CollectionUtil.isEmpty(list)) {
|
||||
return R.ok(new ArrayList<>());
|
||||
}
|
||||
Map<Long, BigDecimal> collect = list.stream()
|
||||
.filter(Objects::nonNull) // 过滤空对象
|
||||
.collect(Collectors.toMap(
|
||||
BusPlanDocAssociation::getPlanId,
|
||||
BusPlanDocAssociation::getDemandQuantity,
|
||||
(existing, replacement) -> existing // 保留第一个遇到的重复键
|
||||
));
|
||||
BusMaterialbatchdemandplanBo bo = new BusMaterialbatchdemandplanBo();
|
||||
bo.setIds(list1);
|
||||
return R.ok(materialbatchdemandplanService.queryList(bo));
|
||||
bo.setIds(new ArrayList<>(collect.keySet()));
|
||||
List<BusMaterialbatchdemandplanVo> busMaterialbatchdemandplanVos = materialbatchdemandplanService.queryList(bo);
|
||||
for (BusMaterialbatchdemandplanVo busMaterialbatchdemandplanVo : busMaterialbatchdemandplanVos) {
|
||||
busMaterialbatchdemandplanVo.setDemandQuantity(collect.get(busMaterialbatchdemandplanVo.getId()).longValue());
|
||||
}
|
||||
return R.ok(busMaterialbatchdemandplanVos);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -107,7 +107,7 @@ public class BusPurchaseUserController extends BaseController {
|
||||
/**
|
||||
* 新增或修改物资采购人员
|
||||
*/
|
||||
@SaCheckPermission("cailiaoshebei:purchaseUser:add")
|
||||
@SaCheckPermission("cailiaoshebei:purchaseUser:addOrUpdate")
|
||||
@Log(title = "物资采购人员", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/addOrUpdate")
|
||||
@ -121,7 +121,7 @@ public class BusPurchaseUserController extends BaseController {
|
||||
*
|
||||
* @param projectId 项目id
|
||||
*/
|
||||
@SaCheckPermission("cailiaoshebei:purchaseUser:query")
|
||||
@SaCheckPermission("cailiaoshebei:purchaseUser:byProject")
|
||||
@GetMapping("/byProject/{projectId}")
|
||||
public R<BusPurchaseUserVo> getInfoByProject(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long projectId) {
|
||||
|
@ -1,32 +1,33 @@
|
||||
package org.dromara.cailiaoshebei.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.cailiaoshebei.domain.bo.BusTotalsupplyplanAuditBo;
|
||||
import org.dromara.cailiaoshebei.domain.bo.BusTotalsupplyplanBo;
|
||||
import org.dromara.cailiaoshebei.domain.bo.MasterDataReq;
|
||||
import org.dromara.cailiaoshebei.domain.bo.TotalsupplyplanQueryListReq;
|
||||
import org.dromara.cailiaoshebei.domain.dto.MasterDataReqDto;
|
||||
import org.dromara.cailiaoshebei.domain.vo.BusTotalsupplyplanAuditVo;
|
||||
import org.dromara.cailiaoshebei.domain.vo.BusTotalsupplyplanVo;
|
||||
import org.dromara.cailiaoshebei.service.IBusTotalsupplyplanAuditService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.cailiaoshebei.service.IBusTotalsupplyplanService;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.cailiaoshebei.domain.vo.BusTotalsupplyplanVo;
|
||||
import org.dromara.cailiaoshebei.domain.bo.BusTotalsupplyplanBo;
|
||||
import org.dromara.cailiaoshebei.service.IBusTotalsupplyplanService;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
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.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 物资-总供应计划
|
||||
@ -82,6 +83,16 @@ public class BusTotalsupplyplanController extends BaseController {
|
||||
ExcelUtil.exportExcel(list, "物资-总供应计划", BusTotalsupplyplanVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入物资-总供应计划数据
|
||||
*/
|
||||
@SaCheckPermission("design:totalsupplyplan:import")
|
||||
@Log(title = "物资-总供应计划", businessType = BusinessType.IMPORT)
|
||||
@PostMapping("/import")
|
||||
public R<Void> importData(@RequestPart("file") MultipartFile file) {
|
||||
return toAjax(busTotalsupplyplanService.importData(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物资-总供应计划详细信息
|
||||
*
|
||||
@ -90,7 +101,7 @@ public class BusTotalsupplyplanController extends BaseController {
|
||||
@SaCheckPermission("design:totalsupplyplan:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<BusTotalsupplyplanVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
@PathVariable Long id) {
|
||||
return R.ok(busTotalsupplyplanService.queryById(id));
|
||||
}
|
||||
|
||||
@ -116,6 +127,17 @@ public class BusTotalsupplyplanController extends BaseController {
|
||||
return toAjax(busTotalsupplyplanService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改物资-总供应计划
|
||||
*/
|
||||
@SaCheckPermission("design:totalsupplyplan:batchEdit")
|
||||
@Log(title = "物资-总供应计划", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/batchEdit")
|
||||
public R<Void> batchEdit(@Validated(EditGroup.class) @RequestBody List<BusTotalsupplyplanBo> boList) {
|
||||
return toAjax(busTotalsupplyplanService.updateBatch(boList));
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 删除物资-总供应计划
|
||||
// *
|
||||
|
@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 物资-批次需求计划与采购单关联对象 bus_plan_doc_association
|
||||
@ -37,6 +38,11 @@ public class BusPlanDocAssociation extends BaseEntity {
|
||||
*/
|
||||
private Long planId;
|
||||
|
||||
/**
|
||||
* 需求数量
|
||||
*/
|
||||
private BigDecimal demandQuantity;
|
||||
|
||||
/**
|
||||
* 采购联系单id
|
||||
*/
|
||||
|
@ -1,14 +1,14 @@
|
||||
package org.dromara.cailiaoshebei.domain;
|
||||
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 物资-总供应计划对象 bus_totalsupplyplan
|
||||
@ -35,6 +35,16 @@ public class BusTotalsupplyplan extends BaseEntity {
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 批次ID
|
||||
*/
|
||||
private String sid;
|
||||
|
||||
/**
|
||||
* 批次父ID
|
||||
*/
|
||||
private String pid;
|
||||
|
||||
/**
|
||||
* 批次号
|
||||
*/
|
||||
|
@ -114,4 +114,10 @@ public class BusMaterialbatchdemandplanBo extends BaseEntity {
|
||||
* 主键集合
|
||||
*/
|
||||
private List<Long> ids;
|
||||
|
||||
|
||||
/**
|
||||
* 供应商id
|
||||
*/
|
||||
private Long supplierId;
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 物资-批次需求计划与采购单关联业务对象 bus_plan_doc_association
|
||||
*
|
||||
@ -41,5 +43,8 @@ public class BusPlanDocAssociationBo extends BaseEntity {
|
||||
*/
|
||||
private Long docId;
|
||||
|
||||
|
||||
/**
|
||||
* 需求数量
|
||||
*/
|
||||
private BigDecimal demandQuantity;
|
||||
}
|
||||
|
@ -28,6 +28,11 @@ public class BusTotalsupplyplanBo extends BaseEntity {
|
||||
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 项目Id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 批次号
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.dromara.cailiaoshebei.domain.vo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
@ -43,6 +44,11 @@ public class BusMaterialbatchdemandplanVo implements Serializable {
|
||||
@ExcelProperty(value = "批次ID")
|
||||
private String batchId;
|
||||
|
||||
/**
|
||||
* 批次号
|
||||
*/
|
||||
private String batchNumber;
|
||||
|
||||
/**
|
||||
* 基础信息ID
|
||||
*/
|
||||
@ -125,4 +131,9 @@ public class BusMaterialbatchdemandplanVo implements Serializable {
|
||||
*/
|
||||
private String qs;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private BigDecimal remaining;
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
@ -52,5 +53,8 @@ public class BusPlanDocAssociationVo implements Serializable {
|
||||
@ExcelProperty(value = "采购联系单id")
|
||||
private Long docId;
|
||||
|
||||
|
||||
/**
|
||||
* 需求数量
|
||||
*/
|
||||
private BigDecimal demandQuantity;
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
package org.dromara.cailiaoshebei.domain.vo;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.dromara.cailiaoshebei.domain.BusTotalsupplyplan;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.cailiaoshebei.domain.BusTotalsupplyplan;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
@ -43,48 +42,49 @@ public class BusTotalsupplyplanVo implements Serializable {
|
||||
@ExcelProperty(value = "项目Id")
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 批次ID
|
||||
*/
|
||||
private String sid;
|
||||
|
||||
/**
|
||||
* 批次父ID
|
||||
*/
|
||||
private String pid;
|
||||
|
||||
/**
|
||||
* 编制日期
|
||||
*/
|
||||
@ExcelProperty(value = "编制日期")
|
||||
private Date compileDate;
|
||||
|
||||
/**
|
||||
* 计划编号
|
||||
*/
|
||||
@ExcelProperty(value = "计划编号")
|
||||
private String planNumber;
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@ExcelProperty(value = "编号")
|
||||
private String num;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@ExcelProperty(value = "名称")
|
||||
@ExcelProperty(value = "工程或费用名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 规格
|
||||
*/
|
||||
@ExcelProperty(value = "规格")
|
||||
private String specification;
|
||||
|
||||
/**
|
||||
* 材质
|
||||
*/
|
||||
@ExcelProperty(value = "材质")
|
||||
private String texture;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
@ExcelProperty(value = "单位")
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 规格
|
||||
*/
|
||||
@ExcelProperty(value = "规格型号")
|
||||
private String specification;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@ -97,34 +97,39 @@ public class BusTotalsupplyplanVo implements Serializable {
|
||||
@ExcelProperty(value = "品牌")
|
||||
private String brand;
|
||||
|
||||
/**
|
||||
* 材质
|
||||
*/
|
||||
@ExcelProperty(value = "材质")
|
||||
private String texture;
|
||||
|
||||
/**
|
||||
* 质量标准
|
||||
*/
|
||||
@ExcelProperty(value = "质量标准")
|
||||
private String qualityStandard;
|
||||
|
||||
/**
|
||||
* 预计使用日期
|
||||
*/
|
||||
@ExcelProperty(value = "预计使用日期")
|
||||
private Date dateService;
|
||||
|
||||
/**
|
||||
* 交货地点
|
||||
*/
|
||||
@ExcelProperty(value = "交货地点")
|
||||
private String deliveryPoints;
|
||||
|
||||
/**
|
||||
* 使用部位
|
||||
*/
|
||||
@ExcelProperty(value = "使用部位")
|
||||
private String partUsed;
|
||||
|
||||
/**
|
||||
* 交货地点
|
||||
*/
|
||||
@ExcelProperty(value = "交货地点")
|
||||
private String deliveryPoints;
|
||||
|
||||
/**
|
||||
* 预计使用日期
|
||||
*/
|
||||
@ExcelProperty(value = "预计使用日期")
|
||||
private Date dateService;
|
||||
|
||||
/**
|
||||
* 审核状态
|
||||
*/
|
||||
@ExcelProperty(value = "审核状态")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
|
@ -87,5 +87,5 @@ public interface IBusMrpBaseService extends IService<BusMrpBase>{
|
||||
/**
|
||||
* 获取物资已有数量
|
||||
*/
|
||||
BigDecimal remaining(Long suppliespriceId);
|
||||
BigDecimal remaining(Long suppliespriceId,Long mrpBaseId);
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
package org.dromara.cailiaoshebei.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.dromara.cailiaoshebei.domain.BusTotalsupplyplan;
|
||||
import org.dromara.cailiaoshebei.domain.bo.BusTotalsupplyplanBo;
|
||||
import org.dromara.cailiaoshebei.domain.bo.MasterDataReq;
|
||||
import org.dromara.cailiaoshebei.domain.dto.MasterDataReqDto;
|
||||
import org.dromara.cailiaoshebei.domain.vo.BusTotalsupplyplanVo;
|
||||
import org.dromara.cailiaoshebei.domain.bo.BusTotalsupplyplanBo;
|
||||
import org.dromara.cailiaoshebei.domain.BusTotalsupplyplan;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@ -18,7 +19,7 @@ import java.util.List;
|
||||
* @author Lion Li
|
||||
* @date 2025-08-13
|
||||
*/
|
||||
public interface IBusTotalsupplyplanService extends IService<BusTotalsupplyplan>{
|
||||
public interface IBusTotalsupplyplanService extends IService<BusTotalsupplyplan> {
|
||||
|
||||
/**
|
||||
* 查询物资-总供应计划
|
||||
@ -78,4 +79,20 @@ public interface IBusTotalsupplyplanService extends IService<BusTotalsupplyplan>
|
||||
* @return 主数据列表
|
||||
*/
|
||||
MasterDataReqDto masterData(MasterDataReq bo);
|
||||
|
||||
/**
|
||||
* 批量更新
|
||||
*
|
||||
* @param boList 批量更新
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
Boolean updateBatch(List<BusTotalsupplyplanBo> boList);
|
||||
|
||||
/**
|
||||
* 导入数据
|
||||
*
|
||||
* @param file 导入数据
|
||||
* @return 是否导入成功
|
||||
*/
|
||||
Boolean importData(MultipartFile file);
|
||||
}
|
||||
|
@ -22,6 +22,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.tender.domain.bo.BusBiddingPlanBo;
|
||||
import org.dromara.tender.domain.vo.BusBiddingPlanVo;
|
||||
import org.dromara.tender.domain.vo.BusBillofquantitiesLimitListVo;
|
||||
import org.dromara.tender.service.IBusBiddingPlanService;
|
||||
import org.dromara.tender.service.ITenderSupplierInputService;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
@ -34,9 +39,7 @@ import org.dromara.cailiaoshebei.mapper.BusMaterialbatchdemandplanMapper;
|
||||
import org.dromara.cailiaoshebei.service.IBusMaterialbatchdemandplanService;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 物资-批次需求计划Service业务层处理
|
||||
@ -60,6 +63,10 @@ public class BusMaterialbatchdemandplanServiceImpl extends ServiceImpl<BusMateri
|
||||
@Autowired
|
||||
private IBusMaterialsorderService busMaterialsorderService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private IBusBiddingPlanService busBiddingPlanService;
|
||||
|
||||
/**
|
||||
* 查询物资-批次需求计划
|
||||
*
|
||||
@ -82,6 +89,25 @@ public class BusMaterialbatchdemandplanServiceImpl extends ServiceImpl<BusMateri
|
||||
public TableDataInfo<BusMaterialbatchdemandplanVo> queryPageList(BusMaterialbatchdemandplanBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<BusMaterialbatchdemandplan> lqw = buildQueryWrapper(bo);
|
||||
Page<BusMaterialbatchdemandplanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
if (bo.getSupplierId()!=null){
|
||||
BusBiddingPlanBo bo1 = new BusBiddingPlanBo();
|
||||
bo1.setProjectId(bo.getProjectId());
|
||||
bo1.setType("2");
|
||||
bo1.setWinningBidderId(bo.getSupplierId());
|
||||
List<BusBillofquantitiesLimitListVo> busBiddingPlanVos = busBiddingPlanService.getBillofquantitiesLimitListVo(bo1);
|
||||
if (busBiddingPlanVos == null || busBiddingPlanVos.isEmpty()) {
|
||||
throw new ServiceException("该供应商暂无材料");
|
||||
}
|
||||
Set<String> hashSet = new HashSet<>();
|
||||
busBiddingPlanVos.stream().forEach(vo -> {
|
||||
hashSet.add(vo.getName()+"+"+vo.getSpecification());
|
||||
});
|
||||
List<BusMaterialbatchdemandplanVo> list = result.getRecords().stream().filter(vo -> {
|
||||
String key = vo.getName() + "+" + vo.getSpecification(); // 拼接字符串(需与 Set 中格式一致)
|
||||
return hashSet.contains(key); // 仅保留 Set 中存在的数据
|
||||
}).toList();
|
||||
result.setRecords(list);
|
||||
}
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB
|
||||
|
||||
private final IBusBillofquantitiesService busBillofquantitiesService;
|
||||
|
||||
|
||||
/**
|
||||
* 查询物资-批次需求计划基础信息
|
||||
*
|
||||
@ -77,6 +78,10 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB
|
||||
BusMaterialbatchdemandplanBo planBo = new BusMaterialbatchdemandplanBo();
|
||||
planBo.setMrpBaseId(id);
|
||||
List<BusMaterialbatchdemandplanVo> voList = planservice.queryList(planBo);
|
||||
for (BusMaterialbatchdemandplanVo vo : voList) {
|
||||
BigDecimal remaining = remaining(vo.getSuppliespriceId(), id);
|
||||
vo.setRemaining(remaining);
|
||||
}
|
||||
busMrpVo.setMrpBaseBo(busMrpBaseVo);
|
||||
busMrpVo.setPlanList(voList);
|
||||
|
||||
@ -266,20 +271,22 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB
|
||||
|
||||
|
||||
@Override
|
||||
public BigDecimal remaining(Long suppliespriceId) {
|
||||
|
||||
public BigDecimal remaining(Long suppliespriceId,Long mrpBaseId) {
|
||||
BusBillofquantities byId = busBillofquantitiesService.getById(suppliespriceId);
|
||||
// 获取数据库中已有的数量
|
||||
List<BusMaterialbatchdemandplan> existingList = planservice.list(
|
||||
Wrappers.lambdaQuery(BusMaterialbatchdemandplan.class)
|
||||
.eq(BusMaterialbatchdemandplan::getSuppliespriceId, suppliespriceId) // 排除当前批次
|
||||
.eq(BusMaterialbatchdemandplan::getSuppliespriceId, suppliespriceId)
|
||||
.ne(mrpBaseId!=null,BusMaterialbatchdemandplan::getMrpBaseId, mrpBaseId)// 排除当前批次
|
||||
);
|
||||
if(CollectionUtil.isEmpty(existingList)){
|
||||
return BigDecimal.ZERO;
|
||||
BigDecimal reduce = BigDecimal.ZERO;
|
||||
if(CollectionUtil.isNotEmpty(existingList)){
|
||||
reduce = existingList.stream()
|
||||
.map(BusMaterialbatchdemandplan::getDemandQuantity)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
|
||||
return existingList.stream()
|
||||
.map(BusMaterialbatchdemandplan::getDemandQuantity)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
return byId.getQuantity().subtract(reduce);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,6 +57,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.FileNameMap;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
@ -69,6 +70,7 @@ import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 物资-采购联系单Service业务层处理
|
||||
@ -184,6 +186,7 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper,
|
||||
|
||||
BusPurchaseDoc add = MapstructUtils.convert(bo, BusPurchaseDoc.class);
|
||||
validEntityBeforeSave(add);
|
||||
validNum(bo.getAssociationList());
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
@ -199,6 +202,30 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper,
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
||||
public void validNum(List<BusPlanDocAssociationBo> associationList){
|
||||
|
||||
for (BusPlanDocAssociationBo association : associationList) {
|
||||
|
||||
BusMaterialbatchdemandplan byId = materialbatchdemandplanService.getById(association.getPlanId());
|
||||
|
||||
List<BusPlanDocAssociation> list = planDocAssociationService.list(Wrappers.lambdaQuery(BusPlanDocAssociation.class)
|
||||
.eq(BusPlanDocAssociation::getPlanId, association.getPlanId()));
|
||||
BigDecimal total = list.stream()
|
||||
.map(BusPlanDocAssociation::getDemandQuantity)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
if(total.add(association.getDemandQuantity()).compareTo(byId.getDemandQuantity()) > 0){
|
||||
throw new ServiceException("材料:" + byId.getName() + "已超出计划单的物料批次需求计划数量");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 修改物资-采购联系单
|
||||
*
|
||||
@ -210,11 +237,10 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper,
|
||||
BusPurchaseDoc update = MapstructUtils.convert(bo, BusPurchaseDoc.class);
|
||||
validEntityBeforeSave(update);
|
||||
|
||||
planDocAssociationService.remove(Wrappers.<BusPlanDocAssociation>lambdaQuery()
|
||||
.eq(BusPlanDocAssociation::getProjectId, update.getProjectId())
|
||||
.eq(BusPlanDocAssociation::getDocId, update.getId()));
|
||||
|
||||
if (CollectionUtil.isNotEmpty(bo.getAssociationList())) {
|
||||
planDocAssociationService.remove(Wrappers.<BusPlanDocAssociation>lambdaQuery()
|
||||
.eq(BusPlanDocAssociation::getProjectId, update.getProjectId())
|
||||
.eq(BusPlanDocAssociation::getDocId, update.getId()));
|
||||
List<BusPlanDocAssociation> convert = MapstructUtils.convert(bo.getAssociationList(), BusPlanDocAssociation.class);
|
||||
convert.forEach(item -> {
|
||||
item.setProjectId(update.getProjectId());
|
||||
@ -321,8 +347,9 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper,
|
||||
.eq(BusPlanDocAssociation::getDocId, purchaseDoc.getId())
|
||||
.list();
|
||||
if (CollUtil.isNotEmpty(planDocAssociationList)) {
|
||||
List<Long> planIds = planDocAssociationList.stream().map(BusPlanDocAssociation::getPlanId).toList();
|
||||
items = materialbatchdemandplanService.listByIds(planIds);
|
||||
Map<Long, BigDecimal> map = planDocAssociationList.stream().collect(Collectors.toMap(BusPlanDocAssociation::getPlanId, BusPlanDocAssociation::getDemandQuantity));
|
||||
items = materialbatchdemandplanService.listByIds(map.keySet());
|
||||
items.forEach(item -> item.setDemandQuantity(map.get(item.getId())));
|
||||
}
|
||||
BusPurchaseDocWordDto data = this.getReplacementDto(purchaseDoc, items);
|
||||
Path newTargetDir = Paths.get(System.getProperty("user.dir"), constant.getBusPurchaseDocFileUrl(purchaseDoc, now));
|
||||
@ -505,6 +532,7 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper,
|
||||
BeanUtils.copyProperties(item, itemDto);
|
||||
itemDto.setNum(i);
|
||||
itemDto.setChildName(item.getName());
|
||||
itemDto.setDemandQuantity(item.getDemandQuantity() != null ? item.getDemandQuantity().longValue() : null);
|
||||
dtoItems.add(itemDto);
|
||||
}
|
||||
dto.setItems(dtoItems);
|
||||
|
@ -1,34 +1,40 @@
|
||||
package org.dromara.cailiaoshebei.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.ExcelReader;
|
||||
import com.alibaba.excel.read.metadata.ReadSheet;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.cailiaoshebei.domain.BusTotalsupplyplan;
|
||||
import org.dromara.cailiaoshebei.domain.BusTotalsupplyplanAudit;
|
||||
import org.dromara.cailiaoshebei.domain.bo.BusTotalsupplyplanBo;
|
||||
import org.dromara.cailiaoshebei.domain.bo.MasterDataReq;
|
||||
import org.dromara.cailiaoshebei.domain.dto.MasterDataReqDto;
|
||||
import org.dromara.cailiaoshebei.domain.vo.BusTotalsupplyplanVo;
|
||||
import org.dromara.cailiaoshebei.mapper.BusTotalsupplyplanMapper;
|
||||
import org.dromara.cailiaoshebei.service.IBusTotalsupplyplanAuditService;
|
||||
import org.dromara.cailiaoshebei.service.IBusTotalsupplyplanService;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessTaskEvent;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.excel.core.DefaultExcelListener;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.cailiaoshebei.domain.BusTotalsupplyplanAudit;
|
||||
import org.dromara.cailiaoshebei.service.IBusTotalsupplyplanAuditService;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.dromara.cailiaoshebei.domain.bo.BusTotalsupplyplanBo;
|
||||
import org.dromara.cailiaoshebei.domain.vo.BusTotalsupplyplanVo;
|
||||
import org.dromara.cailiaoshebei.domain.BusTotalsupplyplan;
|
||||
import org.dromara.cailiaoshebei.mapper.BusTotalsupplyplanMapper;
|
||||
import org.dromara.cailiaoshebei.service.IBusTotalsupplyplanService;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 物资-总供应计划Service业务层处理
|
||||
@ -39,14 +45,11 @@ import java.util.Collection;
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
@Slf4j
|
||||
public class BusTotalsupplyplanServiceImpl extends ServiceImpl<BusTotalsupplyplanMapper, BusTotalsupplyplan> implements IBusTotalsupplyplanService {
|
||||
|
||||
private final BusTotalsupplyplanMapper baseMapper;
|
||||
public class BusTotalsupplyplanServiceImpl extends ServiceImpl<BusTotalsupplyplanMapper, BusTotalsupplyplan>
|
||||
implements IBusTotalsupplyplanService {
|
||||
|
||||
private final IBusTotalsupplyplanAuditService busTotalsupplyplanAuditService;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 查询物资-总供应计划
|
||||
*
|
||||
@ -54,7 +57,7 @@ public class BusTotalsupplyplanServiceImpl extends ServiceImpl<BusTotalsupplypla
|
||||
* @return 物资-总供应计划
|
||||
*/
|
||||
@Override
|
||||
public BusTotalsupplyplanVo queryById(Long id){
|
||||
public BusTotalsupplyplanVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
@ -80,20 +83,35 @@ public class BusTotalsupplyplanServiceImpl extends ServiceImpl<BusTotalsupplypla
|
||||
*/
|
||||
@Override
|
||||
public List<BusTotalsupplyplanVo> queryList(BusTotalsupplyplanBo bo) {
|
||||
// 1. 先构建查询条件(MyBatis Plus 的 LambdaQueryWrapper)
|
||||
LambdaQueryWrapper<BusTotalsupplyplan> lqw = buildQueryWrapper(bo);
|
||||
// 2. 查出所有 pid(有子节点的 sid)
|
||||
List<String> parentIds = baseMapper.selectList(
|
||||
Wrappers.<BusTotalsupplyplan>lambdaQuery()
|
||||
.select(BusTotalsupplyplan::getPid)
|
||||
.isNotNull(BusTotalsupplyplan::getPid)
|
||||
).stream()
|
||||
.map(BusTotalsupplyplan::getPid)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.toList();
|
||||
// 3. 在查询条件的基础上,加上 notIn 过滤(排除父节点,只取叶子节点)
|
||||
lqw.notIn(!parentIds.isEmpty(), BusTotalsupplyplan::getSid, parentIds);
|
||||
// 4. 查询叶子节点
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<BusTotalsupplyplan> buildQueryWrapper(BusTotalsupplyplanBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<BusTotalsupplyplan> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByDesc(BusTotalsupplyplan::getId);
|
||||
lqw.eq(bo.getProjectId() != null ,BusTotalsupplyplan::getProjectId,bo.getProjectId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getTexture()), BusTotalsupplyplan::getTexture, bo.getTexture());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getBrand()), BusTotalsupplyplan::getBrand, bo.getBrand());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getQualityStandard()), BusTotalsupplyplan::getQualityStandard, bo.getQualityStandard());
|
||||
lqw.eq(bo.getDateService() != null, BusTotalsupplyplan::getDateService, bo.getDateService());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getDeliveryPoints()), BusTotalsupplyplan::getDeliveryPoints, bo.getDeliveryPoints());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getPartUsed()), BusTotalsupplyplan::getPartUsed, bo.getPartUsed());
|
||||
lqw.orderByAsc(BusTotalsupplyplan::getId);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
@ -130,7 +148,7 @@ public class BusTotalsupplyplanServiceImpl extends ServiceImpl<BusTotalsupplypla
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(BusTotalsupplyplan entity){
|
||||
private void validEntityBeforeSave(BusTotalsupplyplan entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
@ -143,7 +161,7 @@ public class BusTotalsupplyplanServiceImpl extends ServiceImpl<BusTotalsupplypla
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
@ -162,6 +180,78 @@ public class BusTotalsupplyplanServiceImpl extends ServiceImpl<BusTotalsupplypla
|
||||
return masterDataReqDto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新
|
||||
*
|
||||
* @param boList 批量更新
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateBatch(List<BusTotalsupplyplanBo> boList) {
|
||||
List<BusTotalsupplyplan> list = BeanUtil.copyToList(boList, BusTotalsupplyplan.class);
|
||||
for (BusTotalsupplyplan busTotalsupplyplan : list) {
|
||||
validEntityBeforeSave(busTotalsupplyplan);
|
||||
}
|
||||
return this.updateBatchById(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入数据
|
||||
*
|
||||
* @param file 导入数据
|
||||
* @return 是否导入成功
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean importData(MultipartFile file) {
|
||||
// 检查文件是否为空
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new ServiceException("上传文件不能为空", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
// 检查文件大小
|
||||
if (file.getSize() == 0) {
|
||||
throw new ServiceException("上传文件不能为空文件", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
// 检查文件名
|
||||
if (file.getOriginalFilename() == null || file.getOriginalFilename().isEmpty()) {
|
||||
throw new ServiceException("文件名不能为空", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
try {
|
||||
// 使用EasyExcel读取所有sheet
|
||||
List<BusTotalsupplyplanVo> allData = new ArrayList<>();
|
||||
// 创建Excel读取监听器
|
||||
DefaultExcelListener<BusTotalsupplyplanVo> listener = new DefaultExcelListener<>(false);
|
||||
// 读取Excel文件
|
||||
ExcelReader excelReader = EasyExcel.read(file.getInputStream(), BusTotalsupplyplanVo.class, listener).build();
|
||||
// 获取所有sheet
|
||||
List<ReadSheet> sheetList = excelReader.excelExecutor().sheetList();
|
||||
// 遍历所有sheet
|
||||
for (ReadSheet readSheet : sheetList) {
|
||||
// 为每个sheet创建新的监听器实例
|
||||
DefaultExcelListener<BusTotalsupplyplanVo> sheetListener = new DefaultExcelListener<>(false);
|
||||
// 读取当前sheet数据
|
||||
EasyExcel.read(file.getInputStream(), BusTotalsupplyplanVo.class, sheetListener)
|
||||
.sheet(readSheet.getSheetNo())
|
||||
.doRead();
|
||||
// 将当前sheet的数据添加到总数据中
|
||||
allData.addAll(sheetListener.getExcelResult().getList());
|
||||
}
|
||||
// 关闭读取器
|
||||
excelReader.finish();
|
||||
if (allData.isEmpty()) {
|
||||
throw new ServiceException("未读取到有效数据", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
// 处理导入的数据
|
||||
List<BusTotalsupplyplan> list = BeanUtil.copyToList(allData, BusTotalsupplyplan.class);
|
||||
// 批量更新
|
||||
return this.updateBatchById(list);
|
||||
} catch (Exception e) {
|
||||
log.error("物资供货总计划,导入Excel文件失败", e);
|
||||
throw new ServiceException("导入失败: " + e.getMessage(), HttpStatus.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等)
|
||||
* 正常使用只需#processEvent.flowCode=='leave1'
|
||||
@ -169,7 +259,7 @@ public class BusTotalsupplyplanServiceImpl extends ServiceImpl<BusTotalsupplypla
|
||||
*
|
||||
* @param processEvent 参数
|
||||
*/
|
||||
@org.springframework.context.event.EventListener(condition = "#processEvent.flowCode.endsWith('totalsupplyplan')")
|
||||
@EventListener(condition = "#processEvent.flowCode.endsWith('totalsupplyplan')")
|
||||
public void processPlansHandler(ProcessEvent processEvent) {
|
||||
log.info("物资总供应计划审核任务执行了{}", processEvent.toString());
|
||||
String id = processEvent.getBusinessId();
|
||||
@ -190,7 +280,7 @@ public class BusTotalsupplyplanServiceImpl extends ServiceImpl<BusTotalsupplypla
|
||||
*
|
||||
* @param processTaskEvent 参数
|
||||
*/
|
||||
@org.springframework.context.event.EventListener(condition = "#processTaskEvent.flowCode.endsWith('totalsupplyplan')")
|
||||
@EventListener(condition = "#processTaskEvent.flowCode.endsWith('totalsupplyplan')")
|
||||
public void processTaskPlansHandler(ProcessTaskEvent processTaskEvent) {
|
||||
log.info("物资总供应计划审核任务创建了{}", processTaskEvent.toString());
|
||||
}
|
||||
|
@ -18,9 +18,11 @@ public class BigDecimalUtil {
|
||||
*/
|
||||
public static BigDecimal toPercentage(BigDecimal dividend, BigDecimal divisor) {
|
||||
if (dividend == null || divisor == null || divisor.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
return BigDecimal.valueOf(0.00);
|
||||
}
|
||||
return dividend.divide(divisor, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
|
||||
return dividend
|
||||
.multiply(new BigDecimal("100"))
|
||||
.divide(divisor, 2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,6 +46,9 @@ public class IdCardEncryptorUtil {
|
||||
* @return 解密后的身份证号码
|
||||
*/
|
||||
public String decrypt(String encrypted) {
|
||||
if (encrypted == null) {
|
||||
return null;
|
||||
}
|
||||
return aes.decryptStr(encrypted);
|
||||
}
|
||||
}
|
||||
|
@ -6,33 +6,27 @@ import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.MultiFormatWriter;
|
||||
import com.google.zxing.client.j2se.MatrixToImageWriter;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.itextpdf.text.DocumentException;
|
||||
import com.itextpdf.text.Image;
|
||||
import com.itextpdf.text.pdf.PdfContentByte;
|
||||
import com.itextpdf.text.pdf.PdfReader;
|
||||
import com.itextpdf.text.pdf.PdfStamper;
|
||||
import org.dromara.system.domain.vo.SysOssVo;
|
||||
import com.itextpdf.io.image.ImageData;
|
||||
import com.itextpdf.io.image.ImageDataFactory;
|
||||
import com.itextpdf.kernel.geom.Rectangle;
|
||||
import com.itextpdf.kernel.pdf.*;
|
||||
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
|
||||
import com.itextpdf.layout.Canvas;
|
||||
import com.itextpdf.layout.element.Image;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.FileNameMap;
|
||||
import java.net.URLConnection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025/7/7 9:56
|
||||
* @date 2025/7/7
|
||||
*/
|
||||
public class PdfBoxQrCodeGenerator {
|
||||
|
||||
/**
|
||||
* 生成二维码图片并返回路径
|
||||
*
|
||||
* @param text 二维码文本
|
||||
* @param width 二维码宽度
|
||||
* @param height 二维码高度
|
||||
* @param outputPath 二维码图片保存路径
|
||||
* @return 二维码图片保存路径
|
||||
*/
|
||||
public static String generateQRCodeImage(String text, int width, int height, String outputPath) throws Exception {
|
||||
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height);
|
||||
@ -42,11 +36,6 @@ public class PdfBoxQrCodeGenerator {
|
||||
|
||||
/**
|
||||
* 获取二维码图片字节数组
|
||||
*
|
||||
* @param text 二维码文本
|
||||
* @param width 二维码宽度
|
||||
* @param height 二维码高度
|
||||
* @return 二维码图片字节数组
|
||||
*/
|
||||
public static byte[] generateQRCodeBytes(String text, int width, int height) {
|
||||
BufferedImage image = QrCodeUtil.generate(text, width, height);
|
||||
@ -56,79 +45,502 @@ public class PdfBoxQrCodeGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取二维码图片字节数组
|
||||
*
|
||||
* @param text 二维码文本
|
||||
* @return 二维码图片字节数组
|
||||
* 获取二维码图片字节数组(默认200x200)
|
||||
*/
|
||||
public static byte[] generateQRCodeBytes(String text) {
|
||||
return generateQRCodeBytes(text, 200, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在PDF指定位置添加二维码
|
||||
*
|
||||
* @param srcPdf 原PDF文件路径
|
||||
* @param destPdf 新PDF文件路径
|
||||
* @param qrImagePath 二维码图片路径
|
||||
* @param pageNum 页码
|
||||
* @param x 坐标
|
||||
* @param y 坐标
|
||||
* 在PDF指定位置添加二维码(基于图片路径)
|
||||
*/
|
||||
public static void addQRCodeToPDF(String srcPdf, String destPdf, String qrImagePath, int pageNum, float x, float y) throws IOException, DocumentException {
|
||||
PdfReader reader = new PdfReader(srcPdf);
|
||||
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPdf));
|
||||
PdfContentByte content = stamper.getOverContent(pageNum);
|
||||
Image image = Image.getInstance(qrImagePath);
|
||||
image.setAbsolutePosition(x, y); // 坐标:左下角为原点
|
||||
image.scaleAbsolute(100, 100); // 设置二维码大小
|
||||
|
||||
content.addImage(image);
|
||||
stamper.close();
|
||||
reader.close();
|
||||
public static void addQRCodeToPDF(String srcPdf, String destPdf, String qrImagePath, int pageNum, float x, float y)
|
||||
throws IOException {
|
||||
byte[] qrBytes = java.nio.file.Files.readAllBytes(new File(qrImagePath).toPath());
|
||||
addQRCodeToPDF(srcPdf, destPdf, qrBytes, pageNum, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在PDF指定位置添加二维码
|
||||
*
|
||||
* @param srcPdf 原PDF文件路径
|
||||
* @param destPdf 新PDF文件路径
|
||||
* @param qrCodeBytes 二维码图片字节数组
|
||||
* @param pageNum 页码
|
||||
* @param x 坐标
|
||||
* @param y 坐标
|
||||
* 在PDF指定位置添加二维码(基于字节数组)
|
||||
*/
|
||||
public static void addQRCodeToPDF(String srcPdf, String destPdf, byte[] qrCodeBytes, int pageNum, float x, float y) throws IOException, DocumentException {
|
||||
public static void addQRCodeToPDF(String srcPdf, String destPdf, byte[] qrCodeBytes, int pageNum, float x, float y)
|
||||
throws IOException {
|
||||
PdfReader reader = new PdfReader(srcPdf);
|
||||
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPdf));
|
||||
PdfContentByte content = stamper.getOverContent(pageNum);
|
||||
PdfWriter writer = new PdfWriter(destPdf);
|
||||
PdfDocument pdfDoc = new PdfDocument(reader, writer);
|
||||
|
||||
Image image = Image.getInstance(qrCodeBytes);
|
||||
image.setAbsolutePosition(x, y); // 坐标:左下角为原点
|
||||
image.scaleAbsolute(100, 100); // 设置二维码大小
|
||||
PdfPage page = pdfDoc.getPage(pageNum);
|
||||
|
||||
content.addImage(image);
|
||||
stamper.close();
|
||||
reader.close();
|
||||
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(100, 100)
|
||||
.setFixedPosition(x, y);
|
||||
canvas.add(image);
|
||||
}
|
||||
|
||||
pdfDoc.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在PDF指定位置添加二维码并返回数据流
|
||||
*
|
||||
* @param srcPdf 原PDF文件路径
|
||||
* @param qrCodeBytes 二维码图片字节数组
|
||||
* @param pageNum 页码
|
||||
* @param x 坐标
|
||||
* @param y 坐标
|
||||
* @return 插入二维码后的PDF文件流
|
||||
*/
|
||||
// public static ByteArrayOutputStream addQRCodeToPDF(String srcPdf, byte[] qrCodeBytes, int pageNum, float x, float y) throws IOException, DocumentException {
|
||||
public static ByteArrayOutputStream addQRCodeToPDF(String srcPdf, byte[] qrCodeBytes, int pageNum, float x, float y)
|
||||
throws IOException {
|
||||
PdfReader reader = new PdfReader(srcPdf);
|
||||
ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
|
||||
PdfWriter writer = new PdfWriter(pdfOut);
|
||||
PdfDocument pdfDoc = new PdfDocument(reader, writer);
|
||||
|
||||
PdfPage page = pdfDoc.getPage(pageNum);
|
||||
|
||||
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(100, 100)
|
||||
.setFixedPosition(x, y);
|
||||
canvas.add(image);
|
||||
}
|
||||
|
||||
pdfDoc.close();
|
||||
return pdfOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在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);
|
||||
// }
|
||||
//
|
||||
// PdfReader reader = new PdfReader(srcPdf);
|
||||
// ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
|
||||
// PdfStamper stamper = new PdfStamper(reader, pdfOut);
|
||||
// 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("图纸管理 => 审核结束,向文件添加二维码失败");
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// 固定的边距(点)
|
||||
private static final float MARGIN = 10.0f;
|
||||
// 二维码大小比例(页面宽高中较小值的20%)
|
||||
private static final float QR_SIZE_RATIO = 0.2f;
|
||||
|
||||
// 二维码大小比例(页面宽高中较小值的20%)
|
||||
private static final float QR_SIZE = 60.0f;
|
||||
|
||||
// 竖坐标
|
||||
private static final float V_QR_X = 232.0f;
|
||||
|
||||
// 竖坐标
|
||||
private static final float V_QR_Y = 679.5f;
|
||||
|
||||
// 横坐标
|
||||
private static final float H_QR_X = 1116.5f;
|
||||
|
||||
// 横坐标
|
||||
private static final float H_QR_Y = 34.0f;
|
||||
|
||||
public static ByteArrayOutputStream addQRCodeToPDFOnAllPages(String srcPdf, byte[] qrCodeBytes, boolean isChangeFile)
|
||||
throws IOException {
|
||||
|
||||
PdfReader reader;
|
||||
if (srcPdf.startsWith("http://") || srcPdf.startsWith("https://")) {
|
||||
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 {
|
||||
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++) {
|
||||
if (pageNum == 1 && isChangeFile) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PdfPage page = pdfDoc.getPage(pageNum);
|
||||
|
||||
// 获取页面的所有边界框信息
|
||||
Rectangle mediaBox = page.getMediaBox();
|
||||
Rectangle cropBox = page.getCropBox();
|
||||
|
||||
// 使用CropBox作为主要参考,因为它定义了页面的可见区域
|
||||
Rectangle visibleArea = (cropBox != null) ? cropBox : mediaBox;
|
||||
|
||||
// 计算页面宽高中较小的值
|
||||
// float minDimension = Math.min(visibleArea.getWidth(), visibleArea.getHeight());
|
||||
|
||||
// 动态计算二维码大小(页面宽高中较小值的20%)
|
||||
// float qrSize = minDimension * QR_SIZE_RATIO;
|
||||
|
||||
// 输出页面尺寸信息
|
||||
// System.out.println("页面 " + pageNum + " 尺寸: " + visibleArea.getWidth() + "x" + visibleArea.getHeight());
|
||||
// System.out.println("页面 " + pageNum + " 二维码大小 (点): " + qrSize);
|
||||
|
||||
// 计算左上角的位置(PDF坐标系:原点在左下角)
|
||||
// float qrX = visibleArea.getLeft() + MARGIN;
|
||||
// float qrY = visibleArea.getTop() - qrSize - MARGIN;
|
||||
|
||||
// 打印二维码位置信息
|
||||
// System.out.println("页面 " + pageNum + " 左上角二维码位置: x=" + qrX + ", y=" + qrY);
|
||||
float qrX;
|
||||
float qrY;
|
||||
if (visibleArea.getWidth() > visibleArea.getHeight()) {
|
||||
qrX = H_QR_X;
|
||||
qrY = H_QR_Y;
|
||||
} else {
|
||||
qrX = V_QR_X;
|
||||
qrY = V_QR_Y;
|
||||
}
|
||||
try {
|
||||
// 使用Canvas API添加左上角二维码
|
||||
addQRCodeWithCanvas(pdfDoc, page, qrCodeBytes, qrX, qrY, QR_SIZE);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("在页面 " + pageNum + " 添加二维码时出错: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
pdfDoc.close();
|
||||
return pdfOut;
|
||||
}
|
||||
|
||||
// 使用Canvas API添加图像
|
||||
private static void addQRCodeWithCanvas(PdfDocument pdfDoc, PdfPage page,
|
||||
byte[] qrCodeBytes, float x, float y, float size) throws IOException {
|
||||
|
||||
// 创建Canvas对象 - 使用PdfPage和Rectangle构造函数
|
||||
Canvas canvas = new Canvas(page, page.getPageSize());
|
||||
|
||||
// 创建图像数据
|
||||
ImageData imageData = ImageDataFactory.create(qrCodeBytes);
|
||||
|
||||
// 创建Image对象
|
||||
Image image = new Image(imageData);
|
||||
|
||||
// 设置图像位置和大小
|
||||
image.setFixedPosition(x, y);
|
||||
image.setWidth(size);
|
||||
image.setHeight(size);
|
||||
|
||||
// 添加图像到Canvas
|
||||
canvas.add(image);
|
||||
|
||||
// 关闭Canvas
|
||||
canvas.close();
|
||||
|
||||
System.out.println("Canvas方法设置位置: x=" + x + ", y=" + y);
|
||||
}
|
||||
|
||||
// main方法示例
|
||||
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";
|
||||
BufferedImage image = QrCodeUtil.generate(params, 200, 200);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ImgUtil.write(image, ImgUtil.IMAGE_TYPE_PNG, out);
|
||||
byte[] bytes = out.toByteArray();
|
||||
|
||||
try {
|
||||
System.out.println("二维码字节大小: " + bytes.length + " 字节");
|
||||
|
||||
// 先保存二维码图片用于验证
|
||||
try (FileOutputStream qrOut = new FileOutputStream("C:\\Users\\YuanJie\\Desktop\\qrcode.png")) {
|
||||
qrOut.write(bytes);
|
||||
System.out.println("二维码图片已保存到桌面,用于验证二维码是否生成正确");
|
||||
}
|
||||
|
||||
// 在每一页添加二维码
|
||||
ByteArrayOutputStream byteArrayOutputStream = addQRCodeToPDFOnAllPages(path, bytes, false);
|
||||
|
||||
try (FileOutputStream fileOut = new FileOutputStream(outputPath)) {
|
||||
byteArrayOutputStream.writeTo(fileOut);
|
||||
}
|
||||
|
||||
File outputFile = new File(outputPath);
|
||||
System.out.println("PDF文件已成功生成到: " + outputPath);
|
||||
System.out.println("生成的PDF大小: " + outputFile.length() + " 字节");
|
||||
|
||||
if (outputFile.length() == new File(path).length()) {
|
||||
System.out.println("警告:输出文件大小与原文件相同,可能二维码未正确添加");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("图纸管理 => 审核结束,向文件添加二维码失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//package org.dromara.common.utils;
|
||||
//
|
||||
//import cn.hutool.core.img.ImgUtil;
|
||||
//import cn.hutool.extra.qrcode.QrCodeUtil;
|
||||
//import com.google.zxing.BarcodeFormat;
|
||||
//import com.google.zxing.MultiFormatWriter;
|
||||
//import com.google.zxing.client.j2se.MatrixToImageWriter;
|
||||
//import com.google.zxing.common.BitMatrix;
|
||||
//import com.itextpdf.text.DocumentException;
|
||||
//import com.itextpdf.text.Image;
|
||||
//import com.itextpdf.text.pdf.PdfContentByte;
|
||||
//import com.itextpdf.text.pdf.PdfReader;
|
||||
//import com.itextpdf.text.pdf.PdfStamper;
|
||||
//import org.dromara.system.domain.vo.SysOssVo;
|
||||
//
|
||||
//import java.awt.image.BufferedImage;
|
||||
//import java.io.*;
|
||||
//import java.net.FileNameMap;
|
||||
//import java.net.URLConnection;
|
||||
//import java.util.concurrent.CompletableFuture;
|
||||
//
|
||||
///**
|
||||
// * @author lilemy
|
||||
// * @date 2025/7/7 9:56
|
||||
// */
|
||||
//public class PdfBoxQrCodeGenerator {
|
||||
//
|
||||
// /**
|
||||
// * 生成二维码图片并返回路径
|
||||
// *
|
||||
// * @param text 二维码文本
|
||||
// * @param width 二维码宽度
|
||||
// * @param height 二维码高度
|
||||
// * @param outputPath 二维码图片保存路径
|
||||
// * @return 二维码图片保存路径
|
||||
// */
|
||||
// public static String generateQRCodeImage(String text, int width, int height, String outputPath) throws Exception {
|
||||
// BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height);
|
||||
// MatrixToImageWriter.writeToPath(bitMatrix, "PNG", new File(outputPath).toPath());
|
||||
// return outputPath;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取二维码图片字节数组
|
||||
// *
|
||||
// * @param text 二维码文本
|
||||
// * @param width 二维码宽度
|
||||
// * @param height 二维码高度
|
||||
// * @return 二维码图片字节数组
|
||||
// */
|
||||
// public static byte[] generateQRCodeBytes(String text, int width, int height) {
|
||||
// BufferedImage image = QrCodeUtil.generate(text, width, height);
|
||||
// ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
// ImgUtil.write(image, ImgUtil.IMAGE_TYPE_PNG, out);
|
||||
// return out.toByteArray();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取二维码图片字节数组
|
||||
// *
|
||||
// * @param text 二维码文本
|
||||
// * @return 二维码图片字节数组
|
||||
// */
|
||||
// public static byte[] generateQRCodeBytes(String text) {
|
||||
// return generateQRCodeBytes(text, 200, 200);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 在PDF指定位置添加二维码
|
||||
// *
|
||||
// * @param srcPdf 原PDF文件路径
|
||||
// * @param destPdf 新PDF文件路径
|
||||
// * @param qrImagePath 二维码图片路径
|
||||
// * @param pageNum 页码
|
||||
// * @param x 坐标
|
||||
// * @param y 坐标
|
||||
// */
|
||||
// public static void addQRCodeToPDF(String srcPdf, String destPdf, String qrImagePath, int pageNum, float x, float y) throws IOException, DocumentException {
|
||||
// PdfReader reader = new PdfReader(srcPdf);
|
||||
// PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPdf));
|
||||
// PdfContentByte content = stamper.getOverContent(pageNum);
|
||||
// Image image = Image.getInstance(qrImagePath);
|
||||
// image.setAbsolutePosition(x, y); // 坐标:左下角为原点
|
||||
// image.scaleAbsolute(100, 100); // 设置二维码大小
|
||||
//
|
||||
// content.addImage(image);
|
||||
// stamper.close();
|
||||
// reader.close();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 在PDF指定位置添加二维码
|
||||
// *
|
||||
// * @param srcPdf 原PDF文件路径
|
||||
// * @param destPdf 新PDF文件路径
|
||||
// * @param qrCodeBytes 二维码图片字节数组
|
||||
// * @param pageNum 页码
|
||||
// * @param x 坐标
|
||||
// * @param y 坐标
|
||||
// */
|
||||
// public static void addQRCodeToPDF(String srcPdf, String destPdf, byte[] qrCodeBytes, int pageNum, float x, float y) throws IOException, DocumentException {
|
||||
// PdfReader reader = new PdfReader(srcPdf);
|
||||
// PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPdf));
|
||||
// PdfContentByte content = stamper.getOverContent(pageNum);
|
||||
//
|
||||
// Image image = Image.getInstance(qrCodeBytes);
|
||||
// image.setAbsolutePosition(x, y); // 坐标:左下角为原点
|
||||
// image.scaleAbsolute(100, 100); // 设置二维码大小
|
||||
@ -136,142 +548,168 @@ public class PdfBoxQrCodeGenerator {
|
||||
// content.addImage(image);
|
||||
// stamper.close();
|
||||
// reader.close();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 在PDF指定位置添加二维码并返回数据流
|
||||
// *
|
||||
// * @param srcPdf 原PDF文件路径
|
||||
// * @param qrCodeBytes 二维码图片字节数组
|
||||
// * @param pageNum 页码
|
||||
// * @param x 坐标
|
||||
// * @param y 坐标
|
||||
// * @return 插入二维码后的PDF文件流
|
||||
// */
|
||||
//// public static ByteArrayOutputStream addQRCodeToPDF(String srcPdf, byte[] qrCodeBytes, int pageNum, float x, float y) throws IOException, DocumentException {
|
||||
////
|
||||
//// PdfReader reader = new PdfReader(srcPdf);
|
||||
//// ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
|
||||
//// PdfStamper stamper = new PdfStamper(reader, pdfOut);
|
||||
////
|
||||
//// PdfContentByte content = stamper.getOverContent(pageNum);
|
||||
//// Image image = Image.getInstance(qrCodeBytes);
|
||||
//// image.setAbsolutePosition(x, y); // 坐标:左下角为原点
|
||||
//// image.scaleAbsolute(100, 100); // 设置二维码大小
|
||||
////
|
||||
//// content.addImage(image);
|
||||
//// stamper.close();
|
||||
//// reader.close();
|
||||
////
|
||||
//// return pdfOut;
|
||||
//// }
|
||||
// /**
|
||||
// * 在PDF每一页的指定位置添加二维码并返回数据流(根据页面方向自动调整位置)
|
||||
// *
|
||||
// * @param srcPdf 原PDF文件路径(可以是本地路径或网络地址)
|
||||
// * @param qrCodeBytes 二维码图片字节数组
|
||||
// * @return 插入二维码后的PDF文件流
|
||||
// */
|
||||
// public static ByteArrayOutputStream addQRCodeToPDFOnAllPages(String srcPdf, byte[] qrCodeBytes, boolean isChangeFile)
|
||||
// throws IOException, DocumentException {
|
||||
//
|
||||
// PdfReader reader = null;
|
||||
// PdfStamper stamper = null;
|
||||
// ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
|
||||
//
|
||||
// try {
|
||||
// // 判断是网络地址还是本地文件路径
|
||||
// if (srcPdf.startsWith("http://") || srcPdf.startsWith("https://")) {
|
||||
// // 网络地址:从URL读取PDF
|
||||
// java.net.URL url = new java.net.URL(srcPdf);
|
||||
// java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
// connection.setConnectTimeout(10000); // 连接超时10秒
|
||||
// connection.setReadTimeout(30000); // 读取超时30秒
|
||||
// connection.setRequestMethod("GET");
|
||||
//
|
||||
// int responseCode = connection.getResponseCode();
|
||||
// if (responseCode != java.net.HttpURLConnection.HTTP_OK) {
|
||||
// throw new IOException("无法从URL获取PDF文件,HTTP响应码: " + responseCode + ", URL: " + srcPdf);
|
||||
// }
|
||||
//
|
||||
// java.io.InputStream inputStream = connection.getInputStream();
|
||||
// reader = new PdfReader(inputStream);
|
||||
// } else {
|
||||
// // 本地文件路径:检查文件是否存在
|
||||
// File srcFile = new File(srcPdf);
|
||||
// if (!srcFile.exists()) {
|
||||
// throw new IOException("源PDF文件不存在: " + srcPdf);
|
||||
// }
|
||||
// reader = new PdfReader(srcPdf);
|
||||
// }
|
||||
//
|
||||
// stamper = new PdfStamper(reader, pdfOut);
|
||||
//
|
||||
// int numberOfPages = reader.getNumberOfPages();
|
||||
//
|
||||
// // 遍历每一页并添加二维码
|
||||
// for (int pageNum = 1; pageNum <= numberOfPages; pageNum++) {
|
||||
// // 获取页面尺寸
|
||||
// com.itextpdf.text.Rectangle pageSize = reader.getPageSize(pageNum);
|
||||
// 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); // 距离右边90点
|
||||
// qrY = 24; // 距离底部24点
|
||||
// newWidth = 67;
|
||||
// newHeight = 79;
|
||||
// } else {
|
||||
// // 竖版页面:二维码放在左上角
|
||||
// qrX = 226; // 距离左边226点
|
||||
// qrY = pageHeight - 185; // 距离顶部185点
|
||||
// newWidth = 69;
|
||||
// newHeight = 80;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// PdfContentByte content = stamper.getOverContent(pageNum);
|
||||
// Image image = Image.getInstance(qrCodeBytes);
|
||||
// image.setAbsolutePosition(qrX, qrY); // 坐标:左下角为原点
|
||||
// image.scaleAbsolute(newWidth, newHeight); // 设置二维码大小
|
||||
// content.addImage(image);
|
||||
// }
|
||||
//
|
||||
// } finally {
|
||||
// if (stamper != null) {
|
||||
// try {
|
||||
// stamper.close();
|
||||
// } catch (Exception e) {
|
||||
// // 忽略关闭异常
|
||||
// }
|
||||
// }
|
||||
// if (reader != null) {
|
||||
// try {
|
||||
// reader.close();
|
||||
// } catch (Exception e) {
|
||||
// // 忽略关闭异常
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return pdfOut;
|
||||
// }
|
||||
/**
|
||||
* 在PDF每一页的指定位置添加二维码并返回数据流(根据页面方向自动调整位置)
|
||||
*
|
||||
* @param srcPdf 原PDF文件路径(可以是本地路径或网络地址)
|
||||
* @param qrCodeBytes 二维码图片字节数组
|
||||
* @return 插入二维码后的PDF文件流
|
||||
*/
|
||||
public static ByteArrayOutputStream addQRCodeToPDFOnAllPages(String srcPdf, byte[] qrCodeBytes, boolean isChangeFile)
|
||||
throws IOException, DocumentException {
|
||||
|
||||
PdfReader reader = null;
|
||||
PdfStamper stamper = null;
|
||||
ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
|
||||
|
||||
try {
|
||||
// 判断是网络地址还是本地文件路径
|
||||
if (srcPdf.startsWith("http://") || srcPdf.startsWith("https://")) {
|
||||
// 网络地址:从URL读取PDF
|
||||
java.net.URL url = new java.net.URL(srcPdf);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
connection.setConnectTimeout(10000); // 连接超时10秒
|
||||
connection.setReadTimeout(30000); // 读取超时30秒
|
||||
connection.setRequestMethod("GET");
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
if (responseCode != java.net.HttpURLConnection.HTTP_OK) {
|
||||
throw new IOException("无法从URL获取PDF文件,HTTP响应码: " + responseCode + ", URL: " + srcPdf);
|
||||
}
|
||||
|
||||
java.io.InputStream inputStream = connection.getInputStream();
|
||||
reader = new PdfReader(inputStream);
|
||||
} else {
|
||||
// 本地文件路径:检查文件是否存在
|
||||
File srcFile = new File(srcPdf);
|
||||
if (!srcFile.exists()) {
|
||||
throw new IOException("源PDF文件不存在: " + srcPdf);
|
||||
}
|
||||
reader = new PdfReader(srcPdf);
|
||||
}
|
||||
|
||||
stamper = new PdfStamper(reader, pdfOut);
|
||||
|
||||
int numberOfPages = reader.getNumberOfPages();
|
||||
|
||||
// 遍历每一页并添加二维码
|
||||
for (int pageNum = 1; pageNum <= numberOfPages; pageNum++) {
|
||||
// 获取页面尺寸
|
||||
com.itextpdf.text.Rectangle pageSize = reader.getPageSize(pageNum);
|
||||
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); // 距离右边90点
|
||||
qrY = 24; // 距离底部24点
|
||||
newWidth = 67;
|
||||
newHeight = 79;
|
||||
} else {
|
||||
// 竖版页面:二维码放在左上角
|
||||
qrX = 226; // 距离左边226点
|
||||
qrY = pageHeight - 185; // 距离顶部185点
|
||||
newWidth = 69;
|
||||
newHeight = 80;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PdfContentByte content = stamper.getOverContent(pageNum);
|
||||
Image image = Image.getInstance(qrCodeBytes);
|
||||
image.setAbsolutePosition(qrX, qrY); // 坐标:左下角为原点
|
||||
image.scaleAbsolute(newWidth, newHeight); // 设置二维码大小
|
||||
content.addImage(image);
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (stamper != null) {
|
||||
try {
|
||||
stamper.close();
|
||||
} catch (Exception e) {
|
||||
// 忽略关闭异常
|
||||
}
|
||||
}
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (Exception e) {
|
||||
// 忽略关闭异常
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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("图纸管理 => 审核结束,向文件添加二维码失败, 错误");
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//
|
||||
// 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("图纸管理 => 审核结束,向文件添加二维码失败, 错误");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
@ -2,6 +2,7 @@ package org.dromara.common.utils.baiduUtil;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.utils.baiduUtil.entity.face.ComparisonRes;
|
||||
import org.dromara.common.utils.baiduUtil.entity.face.HumanFaceReq;
|
||||
import org.dromara.common.utils.baiduUtil.entity.face.HumanFaceRes;
|
||||
@ -23,6 +24,7 @@ import java.util.List;
|
||||
* @Version 1.0
|
||||
* 处理百度人脸相关逻辑:人脸检测、人脸对比
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class BaiDuFace {
|
||||
|
||||
@ -92,7 +94,8 @@ public class BaiDuFace {
|
||||
|
||||
// 7. 处理API返回错误
|
||||
if (faceRep.getErrorCode() != 0) {
|
||||
throw new RuntimeException("错误码说明:" + faceRep.getErrorMsg());
|
||||
log.warn("百度人脸API返回错误码:{}", faceRep.getErrorCode());
|
||||
throw new RuntimeException("未检测到有效人脸信息");
|
||||
}
|
||||
|
||||
// 8. 验证人脸信息(无人脸时抛出异常)
|
||||
|
@ -1,21 +0,0 @@
|
||||
package org.dromara.contractor.config;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.dromara.contractor.interceptor.ContractorInterceptor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Resource
|
||||
private ContractorInterceptor contractorInterceptor;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(contractorInterceptor)
|
||||
.addPathPatterns("/contractor/**") // 拦截所有 /contractor 开头
|
||||
.excludePathPatterns("/contractor/contractor/**"); // 排除具体路径
|
||||
}
|
||||
}
|
@ -17,13 +17,20 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.contractor.domain.dto.constructionuser.*;
|
||||
import org.dromara.contractor.domain.exportvo.BusConstructionUserExportVo;
|
||||
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserAttendanceMonthVo;
|
||||
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserAttendanceTotalVo;
|
||||
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserGisVo;
|
||||
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserVo;
|
||||
import org.dromara.contractor.domain.vo.constructionuser.*;
|
||||
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.dromara.system.domain.vo.SysOssVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -41,6 +48,12 @@ public class SubConstructionUserController extends BaseController {
|
||||
|
||||
private final ISubConstructionUserService constructionUserService;
|
||||
|
||||
private final IBusProjectTeamService busProjectTeamService;
|
||||
|
||||
private final IBusProjectTeamMemberService busProjectTeamMemberService;
|
||||
|
||||
private final IBusProjectService projectService;
|
||||
|
||||
/**
|
||||
* 查询施工人员列表
|
||||
*/
|
||||
@ -53,7 +66,7 @@ public class SubConstructionUserController extends BaseController {
|
||||
/**
|
||||
* 查询每个施工人员总的考勤列表
|
||||
*/
|
||||
@SaCheckPermission(value = {"contractor:constructionUser:list", "project:attendance:list"})
|
||||
@SaCheckPermission(value = {"contractor:constructionUser:listAttendanceTotal", "project:attendance:listAttendanceTotal"})
|
||||
@GetMapping("/list/attendance/total")
|
||||
public TableDataInfo<SubConstructionUserAttendanceTotalVo> listAttendanceTotal(SubConstructionUserAttendanceQueryReq req,
|
||||
PageQuery pageQuery) {
|
||||
@ -63,7 +76,7 @@ public class SubConstructionUserController extends BaseController {
|
||||
/**
|
||||
* 查询施工人员月份考勤列表
|
||||
*/
|
||||
@SaCheckPermission("contractor:constructionUser:list")
|
||||
@SaCheckPermission("contractor:constructionUser:listAttendanceMonth")
|
||||
@GetMapping("/list/attendance/month")
|
||||
public R<List<SubConstructionUserAttendanceMonthVo>> listAttendanceMonth(SubConstructionUserAttendanceMonthReq req) {
|
||||
return R.ok(constructionUserService.queryAttendanceMonthList(req));
|
||||
@ -89,13 +102,13 @@ public class SubConstructionUserController extends BaseController {
|
||||
@GetMapping("/{id}")
|
||||
public R<SubConstructionUserVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(constructionUserService.queryById(id));
|
||||
return R.ok(constructionUserService.queryById(id, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询大屏施工人员信息
|
||||
*/
|
||||
@SaCheckPermission("contractor:constructionUser:query")
|
||||
@SaCheckPermission("contractor:constructionUser:gis")
|
||||
@GetMapping("/gis")
|
||||
public R<SubConstructionUserGisVo> getGisData(SubConstructionUserGisReq req) {
|
||||
return R.ok(constructionUserService.getGisData(req));
|
||||
@ -126,7 +139,7 @@ public class SubConstructionUserController extends BaseController {
|
||||
/**
|
||||
* 修改施工人员工资
|
||||
*/
|
||||
@SaCheckPermission("contractor:constructionUser:edit")
|
||||
@SaCheckPermission("contractor:constructionUser:salary")
|
||||
@Log(title = "施工人员", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/salary")
|
||||
@ -137,7 +150,7 @@ public class SubConstructionUserController extends BaseController {
|
||||
/**
|
||||
* 修改施工人员打卡状态
|
||||
*/
|
||||
@SaCheckPermission("contractor:constructionUser:edit")
|
||||
@SaCheckPermission("contractor:constructionUser:clock")
|
||||
@Log(title = "施工人员", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/clock")
|
||||
@ -148,7 +161,7 @@ public class SubConstructionUserController extends BaseController {
|
||||
/**
|
||||
* 批量修改施工人员状态
|
||||
*/
|
||||
@SaCheckPermission("contractor:constructionUser:edit")
|
||||
@SaCheckPermission("contractor:constructionUser:batchStatus")
|
||||
@Log(title = "施工人员", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/batch/status")
|
||||
@ -159,7 +172,7 @@ public class SubConstructionUserController extends BaseController {
|
||||
/**
|
||||
* 根据项目id批量修改施工人员打卡状态
|
||||
*/
|
||||
@SaCheckPermission("contractor:constructionUser:edit")
|
||||
@SaCheckPermission("contractor:constructionUser:batchClock")
|
||||
@Log(title = "施工人员", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/batch/clock")
|
||||
@ -170,7 +183,7 @@ public class SubConstructionUserController extends BaseController {
|
||||
/**
|
||||
* 施工人员迁移
|
||||
*/
|
||||
@SaCheckPermission("contractor:constructionUser:migration")
|
||||
@SaCheckPermission("contractor:constructionUser:changeProject")
|
||||
@Log(title = "施工人员", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/change/project")
|
||||
@ -190,4 +203,63 @@ 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据身份证图片获取身份证信息
|
||||
*/
|
||||
@SaCheckPermission("contractor:constructionUser:add")
|
||||
@Log(title = "施工人员", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/idCard")
|
||||
public R<SubConstructionUserOrcIdCardVo> getIdCardMessage(@RequestParam("file") MultipartFile file, String idCardSide) {
|
||||
return R.ok(constructionUserService.getIdCardMessageByPic(file, idCardSide));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据银行卡图片获取银行卡信息
|
||||
*/
|
||||
@SaCheckPermission("contractor:constructionUser:add")
|
||||
@Log(title = "施工人员", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/bankCard")
|
||||
public R<SubConstructionUserOrcBankVo> getBankCardMessage(@RequestParam("file") MultipartFile file) {
|
||||
return R.ok(constructionUserService.getBankCardMessageByPic(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸识别
|
||||
*/
|
||||
@SaCheckPermission("contractor:constructionUser:add")
|
||||
@Log(title = "施工人员", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/face/recognize")
|
||||
public R<SysOssVo> faceRecognize(@RequestParam("file") MultipartFile file) {
|
||||
return R.ok(constructionUserService.faceRecognize(file));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ public class SubConstructionUserFileController extends BaseController {
|
||||
/**
|
||||
* 下载施工人员文件存储模板
|
||||
*/
|
||||
@SaCheckPermission(value = {"project:constructionUserFile:download", "contractor:constructionUserFile:download"}, mode = SaMode.OR)
|
||||
@SaCheckPermission(value = {"project:constructionUserFile:exportFileTemplate", "contractor:constructionUserFile:exportFileTemplate"}, mode = SaMode.OR)
|
||||
@Log(title = "施工人员文件存储", businessType = BusinessType.EXPORT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/exportFileTemplate")
|
||||
@ -70,7 +70,7 @@ public class SubConstructionUserFileController extends BaseController {
|
||||
/**
|
||||
* 上传施工人员文件压缩包,批量导入存储施工人员文件
|
||||
*/
|
||||
@SaCheckPermission(value = {"project:constructionUserFile:upload", "contractor:constructionUserFile:upload"}, mode = SaMode.OR)
|
||||
@SaCheckPermission(value = {"project:constructionUserFile:uploadZip", "contractor:constructionUserFile:uploadZip"}, mode = SaMode.OR)
|
||||
@Log(title = "施工人员文件存储", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/upload/zip")
|
||||
|
@ -6,8 +6,6 @@ import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
@ -49,16 +47,6 @@ public class SubContractorController extends BaseController {
|
||||
return contractorService.queryPageList(req, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询没有绑定部门的分包单位列表
|
||||
*/
|
||||
@SaCheckPermission("contractor:contractor:listNoDept")
|
||||
@GetMapping("/listNoDept/{projectId}")
|
||||
public List<SubContractorVo> listNoDept(@NotNull(message = "项目主键不能为空")
|
||||
@PathVariable Long projectId) {
|
||||
return contractorService.queryListNoDept(projectId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据项目id查询分包方管理人员信息列表
|
||||
*/
|
||||
@ -99,7 +87,7 @@ public class SubContractorController extends BaseController {
|
||||
@Log(title = "分包单位", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Long> add(@Validated(AddGroup.class) @RequestBody SubContractorCreateReq req) {
|
||||
public R<Long> add(@Validated @RequestBody SubContractorCreateReq req) {
|
||||
return R.ok(contractorService.insertByBo(req));
|
||||
}
|
||||
|
||||
@ -110,7 +98,7 @@ public class SubContractorController extends BaseController {
|
||||
@Log(title = "分包单位", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SubContractorUpdateReq req) {
|
||||
public R<Void> edit(@Validated @RequestBody SubContractorUpdateReq req) {
|
||||
return toAjax(contractorService.updateByBo(req));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,80 @@
|
||||
package org.dromara.contractor.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
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.web.core.BaseController;
|
||||
import org.dromara.contractor.domain.dto.salaryperiod.SubSalaryPeriodCreateReq;
|
||||
import org.dromara.contractor.domain.dto.salaryperiod.SubSalaryPeriodQueryReq;
|
||||
import org.dromara.contractor.domain.vo.salaryperiod.SubSalaryPeriodVo;
|
||||
import org.dromara.contractor.service.ISubSalaryPeriodService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 工资结算周期
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-09-04
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/contractor/salaryPeriod")
|
||||
public class SubSalaryPeriodController extends BaseController {
|
||||
|
||||
private final ISubSalaryPeriodService subSalaryPeriodService;
|
||||
|
||||
/**
|
||||
* 查询工资结算周期列表
|
||||
*/
|
||||
@SaCheckPermission("contractor:salaryPeriod:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<SubSalaryPeriodVo> list(SubSalaryPeriodQueryReq req, PageQuery pageQuery) {
|
||||
return subSalaryPeriodService.queryPageList(req, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出工资结算周期列表
|
||||
*/
|
||||
@SaCheckPermission("contractor:salaryPeriod:export")
|
||||
@Log(title = "工资结算周期", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(SubSalaryPeriodQueryReq req, HttpServletResponse response) {
|
||||
List<SubSalaryPeriodVo> list = subSalaryPeriodService.queryList(req);
|
||||
ExcelUtil.exportExcel(list, "工资结算周期", SubSalaryPeriodVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取工资结算周期详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
@SaCheckPermission("contractor:salaryPeriod:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<SubSalaryPeriodVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(subSalaryPeriodService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增工资结算周期
|
||||
*/
|
||||
@SaCheckPermission("contractor:salaryPeriod:add")
|
||||
@Log(title = "工资结算周期", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated @RequestBody SubSalaryPeriodCreateReq req) {
|
||||
return toAjax(subSalaryPeriodService.insertByBo(req));
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package org.dromara.contractor.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
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.web.core.BaseController;
|
||||
import org.dromara.contractor.domain.dto.usersalarydetail.SubUserSalaryDetailQueryReq;
|
||||
import org.dromara.contractor.domain.vo.usersalarydetail.SubUserSalaryDetailVo;
|
||||
import org.dromara.contractor.service.ISubUserSalaryDetailService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 员工每日工资
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-09-04
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/contractor/userSalaryDetail")
|
||||
public class SubUserSalaryDetailController extends BaseController {
|
||||
|
||||
private final ISubUserSalaryDetailService subUserSalaryDetailService;
|
||||
|
||||
/**
|
||||
* 查询员工每日工资列表
|
||||
*/
|
||||
@SaCheckPermission("contractor:userSalaryDetail:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<SubUserSalaryDetailVo> list(SubUserSalaryDetailQueryReq req, PageQuery pageQuery) {
|
||||
return subUserSalaryDetailService.queryPageList(req, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出员工每日工资列表
|
||||
*/
|
||||
@SaCheckPermission("contractor:userSalaryDetail:export")
|
||||
@Log(title = "员工每日工资", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(SubUserSalaryDetailQueryReq req, HttpServletResponse response) {
|
||||
List<SubUserSalaryDetailVo> list = subUserSalaryDetailService.queryList(req);
|
||||
ExcelUtil.exportExcel(list, "员工每日工资", SubUserSalaryDetailVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取员工每日工资详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
@SaCheckPermission("contractor:userSalaryDetail:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<SubUserSalaryDetailVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(subUserSalaryDetailService.queryById(id));
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +1,27 @@
|
||||
package org.dromara.contractor.controller.app;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
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.contractor.domain.SubConstructionUser;
|
||||
import org.dromara.contractor.domain.dto.constructionuser.SubConstructionUserAuthenticationReq;
|
||||
import org.dromara.contractor.domain.dto.constructionuser.SubConstructionUserQueryReq;
|
||||
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserAppVo;
|
||||
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserOrcBankVo;
|
||||
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserOrcIdCardVo;
|
||||
import org.dromara.contractor.domain.vo.constructionuser.SubConstructionUserVo;
|
||||
import org.dromara.contractor.service.ISubConstructionUserService;
|
||||
import org.dromara.project.domain.dto.projectteammember.BusProjectTeamMemberCreateReq;
|
||||
import org.dromara.project.service.IBusProjectTeamMemberService;
|
||||
import org.dromara.system.domain.vo.SysOssVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@ -29,13 +40,58 @@ public class SubConstructionUserAppController {
|
||||
@Resource
|
||||
private ISubConstructionUserService constructionUserService;
|
||||
|
||||
@Resource
|
||||
private IBusProjectTeamMemberService busProjectTeamMemberService;
|
||||
|
||||
/**
|
||||
* 查询施工人员列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<SubConstructionUserVo> queryList(SubConstructionUserQueryReq req, PageQuery pageQuery) {
|
||||
return constructionUserService.queryPageList(req, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户实名信息
|
||||
*/
|
||||
@GetMapping("/loginUser")
|
||||
public R<SubConstructionUserVo> getLoginUserInfo() {
|
||||
SubConstructionUser constructionUser = constructionUserService.getBySysUserId(LoginHelper.getUserId());
|
||||
return R.ok(constructionUserService.getVo(constructionUser));
|
||||
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查询施工人员信息
|
||||
*/
|
||||
@GetMapping("/user/{userId}")
|
||||
public R<SubConstructionUserVo> queryByUserId(@NotNull(message = "用户主键不能为空")
|
||||
@PathVariable Long userId) {
|
||||
SubConstructionUser constructionUser = constructionUserService.getBySysUserId(userId);
|
||||
if (constructionUser == null) {
|
||||
return R.fail("查询施工人员不存在");
|
||||
}
|
||||
return R.ok(constructionUserService.getVo(constructionUser, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询施工人员信息
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public R<SubConstructionUserVo> queryById(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(constructionUserService.queryById(id, true));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,6 +121,15 @@ public class SubConstructionUserAppController {
|
||||
return R.ok(constructionUserService.insertByAuthentication(req));
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸识别
|
||||
*/
|
||||
@Log(title = "施工人员", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/face/recognize")
|
||||
public R<SysOssVo> faceRecognize(@RequestParam("file") MultipartFile file) {
|
||||
return R.ok(constructionUserService.faceRecognize(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* 施工人员人脸比对
|
||||
*/
|
||||
@ -74,4 +139,21 @@ public class SubConstructionUserAppController {
|
||||
return R.ok(constructionUserService.faceComparison(file));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询未分配施工人员列表
|
||||
*/
|
||||
@GetMapping("/undistributedList")
|
||||
public TableDataInfo<SubConstructionUserAppVo> queryUndistributedList(SubConstructionUserQueryReq req, PageQuery pageQuery) {
|
||||
return constructionUserService.queryUndistributedList(req, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加项目班组
|
||||
*/
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/addTeam")
|
||||
public R<Long> add(@Validated(AddGroup.class) @RequestBody BusProjectTeamMemberCreateReq req) {
|
||||
return R.ok(busProjectTeamMemberService.insertByBo(req));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
package org.dromara.contractor.controller.app;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.contractor.domain.dto.constructionuserfile.SubConstructionUserFileQueryReq;
|
||||
import org.dromara.contractor.domain.vo.constructionuserfile.SubConstructionUserFileVo;
|
||||
import org.dromara.contractor.service.ISubConstructionUserFileService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 施工人员文件存储 app 接口
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-09-02 17:20
|
||||
*/
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/app/contractor/constructionUserFile")
|
||||
public class SubConstructionUserFileAppController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private ISubConstructionUserFileService constructionUserFileService;
|
||||
|
||||
/**
|
||||
* 查询施工人员文件存储列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public R<List<SubConstructionUserFileVo>> list(SubConstructionUserFileQueryReq req) {
|
||||
return R.ok(constructionUserFileService.queryList(req));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package org.dromara.contractor.controller.app;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.contractor.domain.vo.contractor.SubContractorManagerVo;
|
||||
import org.dromara.contractor.domain.vo.contractor.SubManagerVo;
|
||||
import org.dromara.contractor.service.ISubContractorService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分包单位 app 接口
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-09-03 15:09
|
||||
*/
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/app/contractor/contractor")
|
||||
public class SubContractorAppController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private ISubContractorService contractorService;
|
||||
|
||||
/**
|
||||
* 根据项目id查询分包方管理人员信息列表
|
||||
*/
|
||||
@GetMapping("/listManager/{projectId}")
|
||||
public R<List<SubContractorManagerVo>> listManager(@NotNull(message = "项目id不能为空")
|
||||
@PathVariable Long projectId) {
|
||||
return R.ok(contractorService.queryManagerListByProjectId(projectId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分包方id查询分包方管理人员信息列表
|
||||
*/
|
||||
@GetMapping("/listManagerById/{id}")
|
||||
public R<List<SubManagerVo>> listManagerById(@NotNull(message = "分包方主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(contractorService.queryManagerListById(id));
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package org.dromara.contractor.controller.app;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
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.web.core.BaseController;
|
||||
import org.dromara.contractor.domain.dto.salaryperiod.SubSalaryPeriodCreateReq;
|
||||
import org.dromara.contractor.domain.dto.salaryperiod.SubSalaryPeriodQueryReq;
|
||||
import org.dromara.contractor.domain.vo.salaryperiod.SubSalaryPeriodVo;
|
||||
import org.dromara.contractor.service.ISubSalaryPeriodService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 工资结算周期 app 接口
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-09-04 14:13
|
||||
*/
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/app/contractor/salaryPeriod")
|
||||
public class SubSalaryPeriodAppController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private ISubSalaryPeriodService salaryPeriodService;
|
||||
|
||||
/**
|
||||
* 查询工资结算周期列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<SubSalaryPeriodVo> list(SubSalaryPeriodQueryReq req, PageQuery pageQuery) {
|
||||
return salaryPeriodService.queryPageList(req, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取工资结算周期详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public R<SubSalaryPeriodVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(salaryPeriodService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增工资结算周期
|
||||
*/
|
||||
@Log(title = "工资结算周期", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated @RequestBody SubSalaryPeriodCreateReq req) {
|
||||
return toAjax(salaryPeriodService.insertByBo(req));
|
||||
}
|
||||
}
|
@ -7,6 +7,8 @@ import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@ -102,12 +104,12 @@ public class SubConstructionUser extends BaseEntity {
|
||||
/**
|
||||
* 身份证有效开始期
|
||||
*/
|
||||
private String sfzStart;
|
||||
private LocalDate sfzStart;
|
||||
|
||||
/**
|
||||
* 身份证有效结束期
|
||||
*/
|
||||
private String sfzEnd;
|
||||
private LocalDate sfzEnd;
|
||||
|
||||
/**
|
||||
* 身份证地址
|
||||
@ -117,7 +119,7 @@ public class SubConstructionUser extends BaseEntity {
|
||||
/**
|
||||
* 身份证出生日期
|
||||
*/
|
||||
private String sfzBirth;
|
||||
private LocalDate sfzBirth;
|
||||
|
||||
/**
|
||||
* 籍贯
|
||||
@ -177,13 +179,18 @@ public class SubConstructionUser extends BaseEntity {
|
||||
/**
|
||||
* 薪水
|
||||
*/
|
||||
private Long salary;
|
||||
private BigDecimal salary;
|
||||
|
||||
/**
|
||||
* 用户角色
|
||||
*/
|
||||
private String userRole;
|
||||
|
||||
/**
|
||||
* 退场状态(0未退场 1退场未提交材料 2已退场)
|
||||
*/
|
||||
private String exitStatus;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
@ -40,6 +40,11 @@ public class SubContractor extends BaseEntity {
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 供应商id
|
||||
*/
|
||||
private Long supplierId;
|
||||
|
||||
/**
|
||||
* 公司名称
|
||||
*/
|
||||
|
@ -0,0 +1,78 @@
|
||||
package org.dromara.contractor.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 工资结算周期对象 sub_salary_period
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-09-04
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sub_salary_period")
|
||||
public class SubSalaryPeriod extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 班组id
|
||||
*/
|
||||
private Long teamId;
|
||||
|
||||
/**
|
||||
* 开始日期
|
||||
*/
|
||||
private LocalDate startDate;
|
||||
|
||||
/**
|
||||
* 结束日期
|
||||
*/
|
||||
private LocalDate endDate;
|
||||
|
||||
/**
|
||||
* 总天数
|
||||
*/
|
||||
private Long totalDays;
|
||||
|
||||
/**
|
||||
* 总工资
|
||||
*/
|
||||
private BigDecimal totalWage;
|
||||
|
||||
/**
|
||||
* 总人数
|
||||
*/
|
||||
private Integer totalPeople;
|
||||
|
||||
/**
|
||||
* 状态 0-未开始 1-进行中 2-已完成
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package org.dromara.contractor.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 员工每日工资对象 sub_user_salary_detail
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-09-04
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sub_user_salary_detail")
|
||||
public class SubUserSalaryDetail extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 班组id
|
||||
*/
|
||||
private Long teamId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 用户名字
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 日报日期
|
||||
*/
|
||||
private LocalDate reportDate;
|
||||
|
||||
/**
|
||||
* 当日工资
|
||||
*/
|
||||
private BigDecimal dailySalary;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package org.dromara.contractor.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 员工工资周期对象 sub_user_salary_period
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-09-04
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sub_user_salary_period")
|
||||
public class SubUserSalaryPeriod extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 工资周期id
|
||||
*/
|
||||
private Long periodId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 出勤天数
|
||||
*/
|
||||
private Long workDays;
|
||||
|
||||
/**
|
||||
* 总工资
|
||||
*/
|
||||
private BigDecimal totalWage;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
package org.dromara.contractor.domain.dto.constructionuser;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
@ -16,6 +18,12 @@ public class SubConstructionUserAuthenticationReq implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1001024234468070802L;
|
||||
|
||||
/**
|
||||
* 人脸照
|
||||
*/
|
||||
@NotBlank(message = "人脸照不能为空")
|
||||
private String facePic;
|
||||
|
||||
/**
|
||||
* 人员姓名
|
||||
*/
|
||||
@ -60,14 +68,14 @@ public class SubConstructionUserAuthenticationReq implements Serializable {
|
||||
/**
|
||||
* 身份证有效开始期
|
||||
*/
|
||||
@NotBlank(message = "身份证有效开始期不能为空")
|
||||
private String sfzStart;
|
||||
@NotNull(message = "身份证有效开始期不能为空")
|
||||
private LocalDate sfzStart;
|
||||
|
||||
/**
|
||||
* 身份证有效结束期
|
||||
*/
|
||||
@NotBlank(message = "身份证有效结束期不能为空")
|
||||
private String sfzEnd;
|
||||
@NotNull(message = "身份证有效结束期不能为空")
|
||||
private LocalDate sfzEnd;
|
||||
|
||||
/**
|
||||
* 身份证地址
|
||||
@ -78,8 +86,8 @@ public class SubConstructionUserAuthenticationReq implements Serializable {
|
||||
/**
|
||||
* 身份证出生日期
|
||||
*/
|
||||
@NotBlank(message = "身份证出生日期不能为空")
|
||||
private String sfzBirth;
|
||||
@NotNull(message = "身份证出生日期不能为空")
|
||||
private LocalDate sfzBirth;
|
||||
|
||||
/**
|
||||
* 籍贯
|
||||
|
@ -4,6 +4,8 @@ import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
@ -55,11 +57,66 @@ public class SubConstructionUserCreateReq implements Serializable {
|
||||
*/
|
||||
private String nation;
|
||||
|
||||
/**
|
||||
* 身份证正面图片
|
||||
*/
|
||||
private String sfzFrontPic;
|
||||
|
||||
/**
|
||||
* 身份证反面图片
|
||||
*/
|
||||
private String sfzBackPic;
|
||||
|
||||
/**
|
||||
* 身份证号码
|
||||
*/
|
||||
private String sfzNumber;
|
||||
|
||||
/**
|
||||
* 身份证有效开始期
|
||||
*/
|
||||
private LocalDate sfzStart;
|
||||
|
||||
/**
|
||||
* 身份证有效结束期
|
||||
*/
|
||||
private LocalDate sfzEnd;
|
||||
|
||||
/**
|
||||
* 身份证地址
|
||||
*/
|
||||
private String sfzSite;
|
||||
|
||||
/**
|
||||
* 身份证出生日期
|
||||
*/
|
||||
private LocalDate sfzBirth;
|
||||
|
||||
/**
|
||||
* 籍贯
|
||||
*/
|
||||
private String nativePlace;
|
||||
|
||||
/**
|
||||
* 银行卡图片
|
||||
*/
|
||||
private String yhkPic;
|
||||
|
||||
/**
|
||||
* 银行卡号
|
||||
*/
|
||||
private String yhkNumber;
|
||||
|
||||
/**
|
||||
* 开户行
|
||||
*/
|
||||
private String yhkOpeningBank;
|
||||
|
||||
/**
|
||||
* 持卡人
|
||||
*/
|
||||
private String yhkCardholder;
|
||||
|
||||
/**
|
||||
* 工种(字典type_of_work)
|
||||
*/
|
||||
@ -83,7 +140,7 @@ public class SubConstructionUserCreateReq implements Serializable {
|
||||
/**
|
||||
* 薪水
|
||||
*/
|
||||
private Long salary;
|
||||
private BigDecimal salary;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
|
@ -85,4 +85,20 @@ public class SubConstructionUserQueryReq implements Serializable {
|
||||
*/
|
||||
private String notUserRole;
|
||||
|
||||
/**
|
||||
* 进场时间(枚举)
|
||||
*/
|
||||
private String entryDate;
|
||||
|
||||
/**
|
||||
* 工作状态(枚举)
|
||||
*/
|
||||
private String workStatus;
|
||||
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
@ -90,7 +91,7 @@ public class SubConstructionUserUpdateReq implements Serializable {
|
||||
/**
|
||||
* 薪水
|
||||
*/
|
||||
private Long salary;
|
||||
private BigDecimal salary;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
|
@ -5,6 +5,7 @@ import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
@ -25,6 +26,6 @@ public class SubConstructionUserUpdateSalaryReq implements Serializable {
|
||||
/**
|
||||
* 薪水
|
||||
*/
|
||||
private Long salary;
|
||||
private BigDecimal salary;
|
||||
|
||||
}
|
||||
|
@ -15,11 +15,6 @@ public class SubConstructionUserFileQueryReq implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 552027602186820020L;
|
||||
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@ -30,9 +25,4 @@ public class SubConstructionUserFileQueryReq implements Serializable {
|
||||
*/
|
||||
private String fileType;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.dromara.contractor.domain.dto.contractor;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
@ -19,21 +21,31 @@ public class SubContractorCreateReq implements Serializable {
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
@NotNull(message = "项目不能为空")
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 公司名称
|
||||
*/
|
||||
@NotBlank(message = "公司名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 供应商id
|
||||
*/
|
||||
@NotNull(message = "供应商不能为空")
|
||||
private Long supplierId;
|
||||
|
||||
/**
|
||||
* 负责人
|
||||
*/
|
||||
@NotBlank(message = "负责人不能为空")
|
||||
private String principal;
|
||||
|
||||
/**
|
||||
* 负责人联系电话
|
||||
*/
|
||||
@NotBlank(message = "负责人联系电话不能为空")
|
||||
private String principalPhone;
|
||||
|
||||
/**
|
||||
@ -54,6 +66,7 @@ public class SubContractorCreateReq implements Serializable {
|
||||
/**
|
||||
* 分包类型
|
||||
*/
|
||||
@NotBlank(message = "分包类型不能为空")
|
||||
private String contractorType;
|
||||
|
||||
/**
|
||||
|
@ -15,16 +15,16 @@ public class SubContractorQueryReq implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 3252651952758479341L;
|
||||
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 供应商id
|
||||
*/
|
||||
private Long supplierId;
|
||||
|
||||
/**
|
||||
* 公司名称
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.dromara.contractor.domain.dto.contractor;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
@ -19,6 +20,7 @@ public class SubContractorUpdateReq implements Serializable {
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
@NotNull(message = "主键不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
@ -31,6 +33,11 @@ public class SubContractorUpdateReq implements Serializable {
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 供应商id
|
||||
*/
|
||||
private Long supplierId;
|
||||
|
||||
/**
|
||||
* 负责人
|
||||
*/
|
||||
|
@ -0,0 +1,44 @@
|
||||
package org.dromara.contractor.domain.dto.salaryperiod;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-04 11:29
|
||||
*/
|
||||
@Data
|
||||
public class SubSalaryPeriodCreateReq implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -728942003745404575L;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
@NotNull(message = "项目id不能为空")
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 班组id
|
||||
*/
|
||||
@NotNull(message = "班组id不能为空")
|
||||
private Long teamId;
|
||||
|
||||
/**
|
||||
* 开始日期
|
||||
*/
|
||||
@NotNull(message = "开始日期不能为空")
|
||||
private LocalDate startDate;
|
||||
|
||||
/**
|
||||
* 结束日期
|
||||
*/
|
||||
@NotNull(message = "结束日期不能为空")
|
||||
private LocalDate endDate;
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package org.dromara.contractor.domain.dto.salaryperiod;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-04 11:29
|
||||
*/
|
||||
@Data
|
||||
public class SubSalaryPeriodQueryReq implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -1693221222192776848L;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 班组id
|
||||
*/
|
||||
private Long teamId;
|
||||
|
||||
/**
|
||||
* 开始日期
|
||||
*/
|
||||
private LocalDate startDate;
|
||||
|
||||
/**
|
||||
* 结束日期
|
||||
*/
|
||||
private LocalDate endDate;
|
||||
|
||||
/**
|
||||
* 日期
|
||||
*/
|
||||
private LocalDate date;
|
||||
|
||||
/**
|
||||
* 状态 0-未开始 1-进行中 2-已完成
|
||||
*/
|
||||
private String status;
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user