Compare commits

...

13 Commits

Author SHA1 Message Date
e049241b85 更新获得指定厂区得员工接口,根据员工姓名模糊查询 2025-07-17 17:17:22 +08:00
cb74cb0533 更新获得指定厂区得员工接口,根据员工姓名模糊查询 2025-07-17 16:53:38 +08:00
aikai
875a3ff406 feat(smartfactory): 增加工种筛选功能并优化考勤记录逻辑
- 在 StaffAttendanceRecordReqVO 中添加 workTypeId 字段,用于工种筛选
- 修改 StaffService 接口,增加按工种筛选的 getListByFactory 方法
- 重构 StaffAttendanceRecordServiceImpl 中的 convertRecord 方法,提高代码可读性和维护性
- 优化 StaffSalaryServiceImpl 中的扣款金额计算逻辑
- 在 StaffMapper 和 StaffSalaryMapper 中添加创建时间降序排序
2025-07-17 14:23:36 +08:00
aikai
224a758f11 feat(smartfactory): 新增获取登录用户工厂列表接口
新增接口用于获取登录用户所属工厂列表,无工厂类型限制。主要变化如下:
- 在 FactoryInfoController 中添加 getFactoryALlListByLoginUser 方法
- 在 FactoryInfoService接口中定义 getFactoryALlListByLoginUser 方法
- 在 FactoryInfoServiceImpl 中实现 getFactoryALlListByLoginUser 方法
- 修改 FactoryInfoMapper 接口,增加 selectListByType 方法的重载版本
2025-07-16 14:56:34 +08:00
aikai
f477c366c4 refactor(erp): 更新其它出库单接口和数据结构
- 移除了不必要的导入语句- 添加了 Collections 的导入,用于处理客户信息
- 修改了客户信息的获取方式,从 ErpCustomerDO 改为 AdminUserResp
2025-07-16 10:52:26 +08:00
aikai
7c32e1f429 feat(module-erp): 更新应用配置
- 新增 Nacos 注册中心和配置中心相关配置
- 调整数据库连接池初始大小和最小空闲连接数- 移除 MQ 消息队列、定时任务和日志文件配置
- 更新芋道相关配置,关闭演示模式
- 在 bootstrap.yaml 中添加 MyBatis Mapper 日志配置
2025-07-14 11:59:06 +08:00
aikai
47958a7a0d build(erp): 更新应用配置文件
- 移除 Nacos配置
- 更新数据库配置- 新增 MQ 消息队列配置(RocketMQ、RabbitMQ、Kafka)
-调整定时任务配置
- 更新日志级别配置
2025-07-14 10:38:32 +08:00
aikai
79390abd30 feat(bpm): 开支日报表增加支付状态筛选功能
- 在 BpmOAExpensesMapper.xml 中添加支付状态的查询条件
- 在 BpmOAExpensesPageReqVO 中添加 status 字段用于接收支付状态参数
2025-07-11 22:51:52 +08:00
aikai
535bacddb6 fix(bpm): 修复报销单据中部门名称为空时的空指针异常
- 在获取 paymentCompanyName 时,增加对 deptMap 中值的空值检查
- 避免在 deptMap 中不存在对应部门时抛出空指针异常
- 优化代码的健壮性和异常处理
2025-07-11 17:11:55 +08:00
aikai
87420cb376 feat(bpm): 添加管理成本作为费用大类
在费用大类中新增了管理成本选项,以满足企业对管理费用的报销需求。这项改动将有助于更全面地覆盖企业的各种费用类型,提高报销系统的适用性和灵活性。
2025-07-11 16:57:10 +08:00
aikai
dc1f7b19aa refactor(bpm): 移除报销单中设置付款公司名称的代码
- 删除了 BpmProcessInstanceServiceImpl 中与付款公司名称相关的代码
- 优化了报销单数据的处理逻辑,提高了代码的可读性和维护性
2025-07-11 16:44:07 +08:00
3d6737bc57 报销打印 - 对付款公司paymentCompanyName赋值 2025-07-11 16:41:57 +08:00
aikai
19a7b00caf feat(bpm): 为报销单添加支付公司名称
- 在 BpmOAReimbursementServiceImpl 中,为 BpmOAReimbursementRespVO 对象添加支付公司名称- 通过 deptMap 获取支付公司的名称,并设置到 BpmOAReimbursementRespVO 中
2025-07-11 16:39:33 +08:00
23 changed files with 231 additions and 168 deletions

View File

@ -7,8 +7,6 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 开支日报分页 Request VO")
@Data
@NoArgsConstructor
@ -25,6 +23,9 @@ public class BpmOAExpensesPageReqVO extends PageParam {
@Schema(description = "费用类型 | 字典值参照bpm_oa_expenses_type")
private Integer type;
@Schema(description = "支付状态 | 0未支付 1已支付")
private Integer status;
@Schema(description = "费用板块 | 1叉车 2打包 3搬运 4运输")
private Integer costSection;

View File

@ -335,6 +335,7 @@ public class BpmOAExpensesServiceImpl extends BpmOABaseService implements BpmOAE
costSectionMap.put(2, "打包");
costSectionMap.put(3, "搬运");
costSectionMap.put(4, "运输");
costSectionMap.put(5, "管理成本");
List<DictDataRespDTO> bpmOaExpensesType = dictDataApi.getDictDataList("bpm_oa_expenses_type").getCheckedData();
Map<String, String> typeMap = bpmOaExpensesType.stream().collect(Collectors.toMap(DictDataRespDTO::getValue, DictDataRespDTO::getLabel));
List<BpmOAExpensesExportVO> vos = new ArrayList<>();

View File

@ -362,6 +362,8 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
List<ReimbursementDTO> reimbursementDTOS = BeanUtils.toBean(reimbursements, ReimbursementDTO.class);
BpmOAReimbursementRespVO bpmOAReimbursementRespVO = BeanUtils.toBean(reimbursementDO, BpmOAReimbursementRespVO.class);
DeptRespDTO deptRespDTO = deptMap.get(reimbursementDO.getPaymentCompany());
bpmOAReimbursementRespVO.setPaymentCompanyName(deptRespDTO == null ? null : deptRespDTO.getName());
bpmOAReimbursementRespVO.setReimbursements(BpmOAReimbursementConvert.INSTANCE.convertList(reimbursementDTOS, deptMap)); //拼接数据
return bpmOAReimbursementRespVO;

View File

@ -29,7 +29,6 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessCcDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.*;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;

View File

@ -40,6 +40,9 @@
<if test="pageReqVO.userId != null">
AND b.user_id = #{pageReqVO.userId}
</if>
<if test="pageReqVO.status != null">
AND b.status = #{pageReqVO.status}
</if>
<if test="pageReqVO.factoryId != null">
AND a.dept_id = #{pageReqVO.factoryId}
</if>

View File

@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProduc
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
@ -33,6 +32,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -103,13 +103,16 @@ public class ErpStockOutController {
List<ErpStockOutItemDO> stockOutItemList = stockOutService.getStockOutItemListByOutId(id);
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
Map<Long, AdminUserRespDTO> customerMap = adminUserApi.getUserMap(Collections.singletonList(stockOut.getCustomerId()));
return success(BeanUtils.toBean(stockOut, ErpStockOutRespVO.class, stockOutVO ->
stockOutVO.setItems(BeanUtils.toBean(stockOutItemList, ErpStockOutRespVO.Item.class, item -> {
ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()));
}))));
})).setCustomerName(customerMap.get(stockOut.getCustomerId()) != null ? customerMap.get(stockOut.getCustomerId()).getNickname() : null)
));
}
@GetMapping("/page")
@ -144,7 +147,7 @@ public class ErpStockOutController {
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
// 1.3 客户信息
Map<Long, ErpCustomerDO> customerMap = customerService.getCustomerMap(
Map<Long, AdminUserRespDTO> customerMap = adminUserApi.getUserMap(
convertSet(pageResult.getList(), ErpStockOutDO::getCustomerId));
// 1.4 管理员信息
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
@ -155,7 +158,7 @@ public class ErpStockOutController {
item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()))));
stockOut.setProductNames(CollUtil.join(stockOut.getItems(), "", ErpStockOutRespVO.Item::getProductName));
MapUtils.findAndThen(customerMap, stockOut.getCustomerId(), supplier -> stockOut.setCustomerName(supplier.getName()));
MapUtils.findAndThen(customerMap, stockOut.getCustomerId(), supplier -> stockOut.setCustomerName(supplier.getNickname()));
MapUtils.findAndThen(userMap, Long.parseLong(stockOut.getCreator()), user -> stockOut.setCreatorName(user.getNickname()));
});
}

View File

@ -6,6 +6,7 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@ -15,6 +16,7 @@ import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.AUDIT_STATUS;
@Schema(description = "管理后台 - ERP 其它出库单 Response VO")
@Data
@Accessors(chain = true)
@ExcelIgnoreUnannotated
public class ErpStockOutRespVO {

View File

@ -17,11 +17,11 @@ import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
@ -66,7 +66,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
// 1.1 校验出库项的有效性
List<ErpStockOutItemDO> stockOutItems = validateStockOutItems(createReqVO.getItems());
// 1.2 校验客户
customerService.validateCustomer(createReqVO.getCustomerId());
// customerService.validateCustomer(createReqVO.getCustomerId());
// 1.3 生成出库单号并校验唯一性
String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_OUT_NO_PREFIX);
if (stockOutMapper.selectByNo(no) != null) {
@ -94,7 +94,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
throw exception(STOCK_OUT_UPDATE_FAIL_APPROVE, stockOut.getNo());
}
// 1.2 校验客户
customerService.validateCustomer(updateReqVO.getCustomerId());
// customerService.validateCustomer(updateReqVO.getCustomerId());
// 1.3 校验出库项的有效性
List<ErpStockOutItemDO> stockOutItems = validateStockOutItems(updateReqVO.getItems());

View File

@ -4,23 +4,19 @@ spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
username: # Nacos 账号
password: # Nacos 密码
discovery: # 【配置中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
namespace: prod # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
config: # 【注册中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
namespace: prod # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项
autoconfigure:
exclude:
- de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置
datasource:
druid: # Druid 【监控】相关的全局配置
web-stat-filter:
@ -42,8 +38,8 @@ spring:
multi-statement-allow: true
dynamic: # 多数据源配置
druid: # Druid 【连接池】相关的全局配置
initial-size: 1 # 初始连接数
min-idle: 1 # 最小连接池数量
initial-size: 5 # 初始连接数
min-idle: 10 # 最小连接池数量
max-active: 20 # 最大连接池数量
max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
@ -73,12 +69,9 @@ spring:
database: 0 # 数据库索引
password: yhtkj@2024! # 密码,建议生产环境开启
--- #################### MQ 消息队列相关配置 ####################
--- #################### 定时任务相关配置 ####################
xxl:
job:
enabled: false # 是否开启调度中心,默认为 true 开启
admin:
addresses: http://127.0.0.1:9090/xxl-job-admin # 调度中心部署跟地址
--- #################### 服务保障相关配置 ####################
@ -106,20 +99,11 @@ spring:
instance:
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
# 日志文件配置
logging:
level:
# 配置自己写的 MyBatis Mapper 打印日志
cn.iocoder.yudao.module.erp.dal.mysql: debug
org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿先禁用Spring Boot 3.X 存在部分错误的 WARN 提示
--- #################### 芋道相关配置 ####################
# 芋道配置项,设置当前项目所有自定义的配置
yudao:
env: # 多环境的配置项
tag: ${HOSTNAME}
security:
mock-enable: true
access-log: # 访问日志的配置项
enable: false
demo: false # 关闭演示模式

View File

@ -13,3 +13,6 @@ server:
logging:
file:
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
level:
# 配置自己写的 MyBatis Mapper 打印日志
cn.iocoder.yudao.module.erp.dal.mysql: debug

View File

@ -149,8 +149,9 @@ public class StaffAttendanceRecordController {
// 查询该厂区员工在 其他厂区得考勤记录
List<StaffAttendanceRecordDO> otherRecordDOS = staffAttendanceRecordService.getOtherRecord(reqVO);
// 获取工厂员工列表
List<StaffDO> staffDOS = staffService.getListByFactory(reqVO.getFactoryId(), true);
// 获取工厂员工列表支持工种筛选
List<Integer> workTypeIds = reqVO.getWorkTypeId() != null ? Collections.singletonList(reqVO.getWorkTypeId()) : null;
List<StaffDO> staffDOS = staffService.getListByFactory(reqVO.getFactoryId(), true, workTypeIds);
Map<Long, StaffDO> staffMap = convertMap(staffDOS, StaffDO::getId);
if (CollUtil.isNotEmpty(recordDOS)) {
@ -180,7 +181,7 @@ public class StaffAttendanceRecordController {
recordRespVO.addAll(otherRespVO);
return success(recordRespVO);
}else {
} else {
// 判断是否 新增考勤情况
if (reqVO.getFactoryId() != null && reqVO.getMonth() != null && reqVO.getType() != null) {
@ -196,7 +197,7 @@ public class StaffAttendanceRecordController {
.setStaffName(staffDO.getNickName())
.setWorkTypeId(staffDO.getWorkTypeId());
return success(Collections.singletonList(respVO));
}else {
} else {
List<StaffAttendanceRecordRespVO> respVO = staffDOS.stream()
.map(staffDO -> new StaffAttendanceRecordRespVO()
.setStaffId(staffDO.getId())

View File

@ -20,4 +20,7 @@ public class StaffAttendanceRecordReqVO {
@Schema(description = "考勤方式 | 1.正常月份 2.25号开始计算至下个月24号", example = "1")
private Integer type;
@Schema(description = "工种id", example = "1")
private Integer workTypeId;
}

View File

@ -142,6 +142,15 @@ public class FactoryInfoController {
return success(BeanUtils.toBean(factoryInfo, FactorySimpleRespVO.class));
}
@GetMapping("/factory-list-all")
@Operation(summary = "取登录用户工厂列表, 登陆用户无工厂则拉取所有工厂 | 用于前端下拉框 | 无工厂类型限制")
@PreAuthorize("@ss.hasPermission('smartfactory:factory-info:query')")
public CommonResult<List<FactorySimpleRespVO>> getFactoryALlListByLoginUser() {
List<FactoryInfoDO> factoryInfo = factoryInfoService.getFactoryALlListByLoginUser();
return success(BeanUtils.toBean(factoryInfo, FactorySimpleRespVO.class));
}
@GetMapping("/get-tree")
@Operation(summary = "获得工厂树结构")
@PreAuthorize("@ss.hasPermission('smartfactory:factory-info:query')")

View File

@ -99,8 +99,9 @@ public class StaffController {
@Parameter(name = "factoryId", description = "厂区编号", required = true, example = "1024")
@Parameter(name = "isIn", description = "是否获取该厂区得员工", required = true, example = "1024")
public CommonResult<List<StaffRespVO>> getListByFactory(@RequestParam("factoryId") Long factoryId,
@RequestParam("isIn") Boolean isIn) {
List<StaffDO> staffs = staffService.getListByFactory(factoryId, isIn);
@RequestParam("isIn") Boolean isIn,
@RequestParam(value = "name",required = false) String name) {
List<StaffDO> staffs = staffService.getListByFactory(factoryId, isIn, name);
return success(BeanUtils.toBean(staffs, StaffRespVO.class));
}

View File

@ -34,11 +34,14 @@ public interface FactoryInfoMapper extends BaseMapperX<FactoryInfoDO> {
}
default List<FactoryInfoDO> selectListByType(List<Long> factoryId) {
return this.selectListByType(factoryId, Arrays.asList("2","3"));
}
default List<FactoryInfoDO> selectListByType(List<Long> factoryId, List<String> types) {
return selectList(new LambdaQueryWrapperX<FactoryInfoDO>()
.eq(FactoryInfoDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
.inIfPresent(FactoryInfoDO::getId, factoryId)
.inIfPresent(FactoryInfoDO::getType, Arrays.asList(2,3)));
.inIfPresent(FactoryInfoDO::getType, types));
}
/**

View File

@ -76,7 +76,7 @@ public interface StaffMapper extends BaseMapperX<StaffDO> {
query.eqIfPresent(StaffDO::getFactoryId, pageReqVO.getFactoryId());
query.eqIfPresent(StaffDO::getWorkTypeId, pageReqVO.getWorkTypeId());
query.eqIfPresent(StaffDO::getId, pageReqVO.getStaffId());
query.orderByDesc(StaffSalaryDO::getCreateTime);
return selectJoinPage(pageReqVO, StaffSalaryRespVO.class, query);
}

View File

@ -41,7 +41,7 @@ public interface StaffSalaryMapper extends BaseMapperX<StaffSalaryDO> {
query.eqIfPresent(StaffSalaryDO::getStatus, reqVO.getStatus());
query.eqIfPresent(StaffSalaryDO::getIsGrant, reqVO.getIsGrant());
query.apply(Objects.nonNull(reqVO.getWorkTypeId()), "staff.work_type_id = {0} ", reqVO.getWorkTypeId());
query.orderByDesc(StaffSalaryDO::getCreateTime);
return selectJoinPage(reqVO, StaffSalaryRespVO.class, query);
}

View File

@ -124,7 +124,7 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
List<StaffAttendanceRecordDO> lastMonthRecord = staffAttendanceRecordMapper.selectList(new LambdaQueryWrapperX<StaffAttendanceRecordDO>()
.eq(StaffAttendanceRecordDO::getStaffId, staffId)
.betweenIfPresent(StaffAttendanceRecordDO::getPunchTime, new LocalDate[]{ beginDate, lastMonthEnd }));
.betweenIfPresent(StaffAttendanceRecordDO::getPunchTime, new LocalDate[]{beginDate, lastMonthEnd}));
recordDOS.addAll(lastMonthRecord);
}
@ -176,7 +176,7 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
// 获取查询月份得第25日日期
LocalDate lastMonthEnd = now.withDayOfMonth(25);
date = new LocalDate[]{ beginDate, lastMonthEnd };
date = new LocalDate[]{beginDate, lastMonthEnd};
}
return staffAttendanceRecordMapper.selectRecordList(reqVO, date);
}
@ -216,48 +216,20 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
public List<StaffAttendanceRecordRespVO> convertRecord(StaffAttendanceRecordReqVO reqVO,
List<StaffAttendanceRecordDO> recordDOS,
List<StaffAttendanceRecordDO> otherRecordDOS) {
// 根据考勤类型 生成对应得日期数据
List<AttendanceRecordVO> punchTimeList = new ArrayList<>();
// 根据考勤类型生成对应的日期列表
List<AttendanceRecordVO> punchTimeList = generatePunchTimeList(reqVO);
// 获取所选月份的第一天
LocalDate now = LocalDate.parse(reqVO.getMonth() + "-01", DateTimeFormatter.ISO_LOCAL_DATE);
if (reqVO.getType() == 1) {
// 获取上月26日日期
LocalDate beginDate = now.minusMonths(1).withDayOfMonth(26);
// 本月25日日期
LocalDate lastMonthEnd = now.withDayOfMonth(25);
while (!beginDate.isAfter(lastMonthEnd)) {
AttendanceRecordVO attendanceRecordVO = new AttendanceRecordVO()
.setPunchTime(beginDate);
punchTimeList.add(attendanceRecordVO);
beginDate = beginDate.plusDays(1);
}
}
if (reqVO.getType() == 2) {
// 获取所选月份的第一天
LocalDate firstDayOfMonth = LocalDate.parse(reqVO.getMonth() + "-01", DateTimeFormatter.ISO_LOCAL_DATE);
// 生成当月每一天的 LocalDate
for (int i = 0; i < firstDayOfMonth.lengthOfMonth(); i++) {
AttendanceRecordVO attendanceRecordVO = new AttendanceRecordVO()
.setPunchTime(firstDayOfMonth.plusDays(i));
punchTimeList.add(attendanceRecordVO);
}
}
// 获取员工信息
// 获取员工信息 - 在当前厂区打卡的员工信息
List<StaffDO> staffDOS = staffService.getList(convertSet(recordDOS, StaffAttendanceRecordDO::getStaffId));
Map<Long, StaffDO> staffMap = convertMap(staffDOS, StaffDO::getId);
// 获取厂区信息
// 获取厂区信息 - 获取员工所打卡的所有厂区ids - 获取所有厂区信息
Set<Long> factoryIds = convertSet(recordDOS, StaffAttendanceRecordDO::getFactoryId);
factoryIds.addAll(convertList(otherRecordDOS, StaffAttendanceRecordDO::getFactoryId));
List<FactoryInfoDO> factoryDOS = factoryInfoService.getFactoryList(factoryIds);
Map<Long, FactoryInfoDO> factoryMap = convertMap(factoryDOS, FactoryInfoDO::getId);
// 根据用户 分组打卡记录
// 根据用户分组打卡记录
Map<Long, List<StaffAttendanceRecordDO>> recordMap = convertMultiMap(recordDOS, StaffAttendanceRecordDO::getStaffId);
// 重组数据
@ -275,10 +247,12 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
reqVO.getType(),
reqVO.getMonth());
// 筛选同一个工厂打卡数据并按日期建立映射
Map<LocalDate, AttendanceRecordVO> records = entry.getValue().stream()
.filter(record -> record.getFactoryId().equals(reqVO.getFactoryId())) // 筛选同一个工厂打卡数据
.filter(record -> record.getFactoryId().equals(reqVO.getFactoryId()))
.map(item -> BeanUtils.toBean(item, AttendanceRecordVO.class))
.collect(Collectors.toMap(AttendanceRecordVO::getPunchTime, value -> value));
// 设置打卡数据
List<AttendanceRecordVO> recordVOS = punchTimeList.stream()
.map(record -> {
@ -289,44 +263,16 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
return recordVO;
}).collect(Collectors.toList());
respVO.setRecords(recordVOS);
// 设置员工名称
respVO.setStaffName(staffMap.get(entry.getKey()).getNickName());
// 设置工种
respVO.setWorkTypeId(staffMap.get(entry.getKey()).getWorkTypeId());
// 设置厂区名称
// 设置员工名称工种厂区名称
StaffDO staffDO = staffMap.get(entry.getKey());
respVO.setStaffName(staffDO.getNickName());
respVO.setWorkTypeId(staffDO.getWorkTypeId());
respVO.setFactoryName(factoryMap.get(reqVO.getFactoryId()) != null ? factoryMap.get(reqVO.getFactoryId()).getName() : null);
// 处理其他厂区的考勤记录
if (CollUtil.isNotEmpty(otherRecordDOS)) {
// 获得该员工 在其他工厂的考勤记录
Map<Long, List<StaffAttendanceRecordDO>> factoryRecordMap = convertMultiMap(otherRecordDOS, StaffAttendanceRecordDO::getFactoryId);
List<StaffAttendanceRecordRespVO> childRespVO = otherRecordDOS.stream()
.map(recordDO -> new StaffAttendanceRecordRespVO(
recordDO.getStaffId(),
recordDO.getFactoryId(),
recordDO.getType(),
recordDO.getMonth()))
.distinct()
.collect(Collectors.toList());
childRespVO.forEach(vo -> {
if (!staffMap.containsKey(vo.getStaffId())) {
return;
}
// 设置员工名称
vo.setStaffName(staffMap.get(vo.getStaffId()).getNickName());
// 设置工种
vo.setWorkTypeId(staffMap.get(vo.getStaffId()).getWorkTypeId());
// 设置厂区名称
vo.setFactoryName(factoryMap.get(vo.getFactoryId()) != null ? factoryMap.get(vo.getFactoryId()).getName() : null);
if (factoryRecordMap.containsKey(vo.getFactoryId())) {
// 设置打卡记录
vo.setRecords(BeanUtils.toBean(factoryRecordMap.get(vo.getFactoryId()), AttendanceRecordVO.class));
}
});
// 插入其他考勤记录
List<StaffAttendanceRecordRespVO> childRespVO = processOtherFactoryRecords(otherRecordDOS, staffMap, factoryMap);
respVO.setChildRecords(childRespVO);
}
@ -336,4 +282,65 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
return respVOs;
}
/**
* 根据考勤类型生成对应的日期列表
*/
private List<AttendanceRecordVO> generatePunchTimeList(StaffAttendanceRecordReqVO reqVO) {
List<AttendanceRecordVO> punchTimeList = new ArrayList<>();
LocalDate now = LocalDate.parse(reqVO.getMonth() + "-01", DateTimeFormatter.ISO_LOCAL_DATE);
if (reqVO.getType() == 1) {
LocalDate beginDate = now.minusMonths(1).withDayOfMonth(26);
LocalDate lastMonthEnd = now.withDayOfMonth(25);
while (!beginDate.isAfter(lastMonthEnd)) {
punchTimeList.add(new AttendanceRecordVO().setPunchTime(beginDate));
beginDate = beginDate.plusDays(1);
}
} else if (reqVO.getType() == 2) {
LocalDate firstDayOfMonth = now;
int lengthOfMonth = firstDayOfMonth.lengthOfMonth();
for (int i = 0; i < lengthOfMonth; i++) {
punchTimeList.add(new AttendanceRecordVO().setPunchTime(firstDayOfMonth.plusDays(i)));
}
}
return punchTimeList;
}
/**
* 处理其他厂区的考勤记录
*/
private List<StaffAttendanceRecordRespVO> processOtherFactoryRecords(List<StaffAttendanceRecordDO> otherRecordDOS,
Map<Long, StaffDO> staffMap,
Map<Long, FactoryInfoDO> factoryMap) {
Map<Long, List<StaffAttendanceRecordDO>> factoryRecordMap = convertMultiMap(otherRecordDOS, StaffAttendanceRecordDO::getFactoryId);
return otherRecordDOS.stream()
.map(recordDO -> new StaffAttendanceRecordRespVO(
recordDO.getStaffId(),
recordDO.getFactoryId(),
recordDO.getType(),
recordDO.getMonth()))
.distinct()
.peek(vo -> {
if (staffMap.containsKey(vo.getStaffId())) {
StaffDO staffDO = staffMap.get(vo.getStaffId());
vo.setStaffName(staffDO.getNickName());
vo.setWorkTypeId(staffDO.getWorkTypeId());
if (factoryMap.containsKey(vo.getFactoryId())) {
vo.setFactoryName(factoryMap.get(vo.getFactoryId()).getName());
}
if (factoryRecordMap.containsKey(vo.getFactoryId())) {
vo.setRecords(BeanUtils.toBean(factoryRecordMap.get(vo.getFactoryId()), AttendanceRecordVO.class));
}
}
})
.filter(vo -> staffMap.containsKey(vo.getStaffId()))
.collect(Collectors.toList());
}
}

View File

@ -164,4 +164,10 @@ public interface FactoryInfoService {
* @return 工厂列表
*/
List<FactoryInfoDO> getList();
/**
* 取登录用户工厂列表, 登陆用户无工厂则拉取所有工厂 | 用于前端下拉框 | 无工厂类型限制
* @return
*/
List<FactoryInfoDO> getFactoryALlListByLoginUser();
}

View File

@ -9,7 +9,10 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factoryinfo.vo.*;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factoryinfo.vo.FactoryInfoPageReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factoryinfo.vo.FactoryInfoSaveReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factoryinfo.vo.FactoryProfitVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factoryinfo.vo.FactoryUpdateStatusReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.screendata.factory.vo.FactoryRollDataRespVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.screendata.factory.vo.ProvincesDataRespVO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factoryinfo.FactoryInfoDO;
@ -23,6 +26,7 @@ import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespD
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@ -32,7 +36,8 @@ import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.FACTORY_INFO_NOT_EXISTS;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.FACTOYRY_EXISTS_STAFF;
@ -42,6 +47,7 @@ import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.FACT
*
* @author 姚君
*/
@Slf4j
@Service
@Validated
public class FactoryInfoServiceImpl implements FactoryInfoService {
@ -239,27 +245,7 @@ public class FactoryInfoServiceImpl implements FactoryInfoService {
@Override
public List<FactoryInfoDO> getFactoryListByAuthority() {
List<Long> factoryIds = new ArrayList<>();
DeptDataPermissionRespDTO deptDataPermission = permissionApi.getDeptDataPermission(getLoginUserId()).getCheckedData();
// 如果当前登录用户数据权限 不是查看全部数据
if (!deptDataPermission.getAll()) {
// 获取自己所在工厂
DeptRespDTO respDTO = deptApi.getDept(userApi.getUser(getLoginUserId()).getCheckedData().getDeptId()).getCheckedData();
if (respDTO != null && respDTO.getFactoryId() != null) {
factoryIds.add(respDTO.getFactoryId());
}
// 查找担任负责人的工厂信息
List<DeptRespDTO> deptRespDTO = deptApi.getDeptByLeaderId(getLoginUserId()).getCheckedData();
if (deptRespDTO != null) {
factoryIds.addAll(convertList(deptRespDTO, DeptRespDTO::getFactoryId));
}
}
List<Long> factoryIds = this.getFactoryIdsByUserId(getLoginUserId());
return factoryInfoMapper.selectListByType(factoryIds);
}
@ -319,19 +305,19 @@ public class FactoryInfoServiceImpl implements FactoryInfoService {
// 获取打包扣款明细
List<SettlementItemDTO.Deduction> packageDeduction = item.stream()
.filter(data -> data.getBusinessType() == 1)
.flatMap( data -> data.getDeductionItems().stream())
.flatMap(data -> data.getDeductionItems().stream())
.collect(Collectors.toList());
// 获取叉车扣款明细
List<SettlementItemDTO.Deduction> forkliftDeduction = item.stream()
.filter(data -> data.getBusinessType() == 2)
.flatMap( data -> data.getDeductionItems().stream())
.flatMap(data -> data.getDeductionItems().stream())
.collect(Collectors.toList());
// 获取搬运扣款明细
List<SettlementItemDTO.Deduction> porterageDeduction = item.stream()
.filter(data -> data.getBusinessType() == 3)
.flatMap( data -> data.getDeductionItems().stream())
.flatMap(data -> data.getDeductionItems().stream())
.collect(Collectors.toList());
// 设置打包扣款
@ -340,7 +326,7 @@ public class FactoryInfoServiceImpl implements FactoryInfoService {
vo.setForkliftDeductionItem(getDeduction(forkliftDeduction));
// 设置搬运扣款
vo.setPorterageDeductionItem(getDeduction(porterageDeduction));
}else {
} else {
// 设置打包扣款
vo.setPackageDeductionItem(getDeduction(null));
// 设置叉车扣款
@ -399,7 +385,7 @@ public class FactoryInfoServiceImpl implements FactoryInfoService {
return factoryInfoMapper.selectList(new LambdaQueryWrapperX<FactoryInfoDO>()
.eq(FactoryInfoDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
.in(FactoryInfoDO::getType, Arrays.asList(0,1)));
.in(FactoryInfoDO::getType, Arrays.asList(0, 1)));
}
@Override
@ -430,4 +416,38 @@ public class FactoryInfoServiceImpl implements FactoryInfoService {
.eq(FactoryInfoDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
.orderByAsc(FactoryInfoDO::getType));
}
@Override
public List<FactoryInfoDO> getFactoryALlListByLoginUser() {
List<Long> factoryIds = this.getFactoryIdsByUserId(getLoginUserId());
return factoryInfoMapper.selectListByType(factoryIds, null);
}
/**
* 根据当前登录用户获取到工厂ID - {获取当前登录用户所在部门 - 根据所在部门找到所对应的工厂(如果所在部门没有工厂则全部) 返回对应工厂id}
*
* @param userId
* @return
*/
public List<Long> getFactoryIdsByUserId(Long userId) {
List<Long> factoryIds = new ArrayList<>();
DeptDataPermissionRespDTO deptDataPermission = permissionApi.getDeptDataPermission(userId).getCheckedData();
// 如果当前登录用户数据权限 不是查看全部数据
if (!deptDataPermission.getAll()) {
// 获取自己所在工厂
DeptRespDTO respDTO = deptApi.getDept(userApi.getUser(userId).getCheckedData().getDeptId()).getCheckedData();
if (respDTO != null && respDTO.getFactoryId() != null) {
factoryIds.add(respDTO.getFactoryId());
}
// 查找担任负责人的工厂信息
List<DeptRespDTO> deptRespDTO = deptApi.getDeptByLeaderId(userId).getCheckedData();
if (deptRespDTO != null) {
factoryIds.addAll(convertList(deptRespDTO, DeptRespDTO::getFactoryId));
}
}
return factoryIds;
}
}

View File

@ -90,7 +90,9 @@ public interface StaffService {
* @param isIn 是否获取该厂区员工
* @return 员工列表
*/
List<StaffDO> getListByFactory(Long factoryId, Boolean isIn);
List<StaffDO> getListByFactory(Long factoryId, Boolean isIn, String name);
List<StaffDO> getListByFactory(Long factoryId, Boolean isIn, List<Integer> workTypeIds);
/**
* 获取指定厂区得员工列表

View File

@ -249,11 +249,21 @@ public class StaffServiceImpl implements StaffService {
}
@Override
public List<StaffDO> getListByFactory(Long factoryId, Boolean isIn) {
public List<StaffDO> getListByFactory(Long factoryId, Boolean isIn, String name) {
return staffMapper.selectList(new LambdaQueryWrapperX<StaffDO>()
.eq(isIn, StaffDO::getFactoryId, factoryId)
.ne(!isIn, StaffDO::getFactoryId, factoryId)
.ne(StaffDO::getStatus, 0));
.ne(StaffDO::getStatus, 0)
.like(StrUtil.isNotEmpty(name),StaffDO::getNickName, name));
}
@Override
public List<StaffDO> getListByFactory(Long factoryId, Boolean isIn, List<Integer> workTypeIds) {
return staffMapper.selectList(new LambdaQueryWrapperX<StaffDO>()
.eq(isIn, StaffDO::getFactoryId, factoryId)
.ne(!isIn, StaffDO::getFactoryId, factoryId)
.ne(StaffDO::getStatus, 0)
.in(CollUtil.isNotEmpty(workTypeIds), StaffDO::getWorkTypeId, workTypeIds));
}
@Override

View File

@ -111,7 +111,7 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
if (pageReqVO.getMonth() != null && pageReqVO.getStatus() == null) {
return staffMapper.selectSalaryPage(pageReqVO);
}else {
} else {
return staffSalaryMapper.selectSalaryPage(pageReqVO);
}
}
@ -154,7 +154,7 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
firstDayOfMonth.minusMonths(1).withDayOfMonth(26),
firstDayOfMonth.withDayOfMonth(25)
};
}else if (type == 2) {
} else if (type == 2) {
date = new LocalDate[]{
firstDayOfMonth,
@ -217,6 +217,8 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
.setKey("insurance")
.setValue("50")
));
// 设置扣款金额
salaryDO.setDeductionAmount(BigDecimal.valueOf(50));
// 计算应发工资
BigDecimal salary = staffDO.getSalary();
@ -226,14 +228,14 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
// 设置应发工资
salaryDO.setPayableAmount(salary);
// 设置实发工资
salaryDO.setRealAmount(salary.subtract(BigDecimal.valueOf(50)));
salaryDO.setRealAmount(salary.subtract(salaryDO.getDeductionAmount()));
} else {
BigDecimal payableAmount = salary.divide(BigDecimal.valueOf(workDays), 0, RoundingMode.DOWN)
.multiply(BigDecimal.valueOf(salaryDO.getAttendanceDays()));
// 设置应发工资
salaryDO.setPayableAmount(payableAmount);
// 设置实发工资
salaryDO.setRealAmount(payableAmount.subtract(BigDecimal.valueOf(50)));
salaryDO.setRealAmount(payableAmount.subtract(salaryDO.getDeductionAmount()));
}
// 设置薪资主体数据
@ -262,10 +264,11 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
.setId(id)
.setIsGrant(isGrant))
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(salaryDOS)) {
// 更新
staffSalaryMapper.updateBatch(salaryDOS);
}
}
@Override
public SalaryTotalVO getStaffSalaryTotal(StaffSalaryPageReqVO pageReqVO) {