修改了工单bug
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run

This commit is contained in:
yuyongle 2025-08-13 10:21:58 +08:00
parent 7b74451547
commit e73d6abf62
12 changed files with 224 additions and 21 deletions

View File

@ -0,0 +1,47 @@
package org.dromara.property.controller.mobile;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
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;
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.property.domain.bo.InspectionPointBo;
import org.dromara.property.domain.vo.InspectionPointVo;
import org.dromara.property.service.IInspectionPointService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 巡检点
* 前端访问路由地址为:/property/point
*
* @author mocheng
* @date 2025-07-11
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/mobile/point")
public class MInspectionPointController extends BaseController {
private final IInspectionPointService inspectionPointService;
/**
* 扫码签到
*/
@PostMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody InspectionPointBo bo) {
return toAjax(inspectionPointService.updateByBo(bo));
}
}

View File

@ -1,6 +1,4 @@
package org.dromara.property.domain;
import cn.idev.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

View File

@ -97,7 +97,9 @@ public class CostItemsBo extends BaseEntity {
/**
* 计费单价
*/
@NotBlank(message = "计费单价", groups = { AddGroup.class, EditGroup.class })
@NotNull(message = "计费单价不能为空", groups = { AddGroup.class, EditGroup.class })
@DecimalMin(value = "0.00", inclusive = false, message = "计费单价必须大于0")
@ExcelProperty("计费单价")
private BigDecimal unitPrice;
/**

View File

@ -7,11 +7,11 @@ package org.dromara.property.domain.enums;
**/
public enum MeetAttachStatusEnum {
/**
* 待确认
* 上架
*/
ENAABLE("上架", "0"),
/**
* 待提货
* 下架
*/
DEACTIVATE("下架", "1");

View File

@ -3,7 +3,7 @@ package org.dromara.property.domain.enums;
/**
* @Author:yuyongle
* @Date:2025/7/4 10:35
* @Description:
* @Description:会议室状态枚举
**/
public enum MeetStatusEnum {
/**

View File

@ -0,0 +1,33 @@
package org.dromara.property.domain.enums;
/**
* @Author:yuyongle
* @Date:2025/8/11 10:59
* @Description:工单状态枚举
**/
public enum WorkOrderStatusEnum {
CREATE_ORDER("创建工单", "0"),
DISPATCHED("已派单", "1"),
ROB_ORDER("已抢单", "2"),
IN_HAND("处理中", "3"),
DONE("已完成", "4"),
ABANDON("已废弃", "5");
private final String name;
private final String value;
WorkOrderStatusEnum(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
}

View File

@ -99,9 +99,11 @@ public class CostCarChargeServiceImpl implements ICostCarChargeService {
lqw.eq(bo.getFloorId() != null, CostCarCharge::getFloorId, bo.getFloorId());
lqw.eq(StringUtils.isNotBlank(bo.getLocation()), CostCarCharge::getLocation, bo.getLocation());
lqw.eq(StringUtils.isNotBlank(bo.getState()), CostCarCharge::getState, bo.getState());
lqw.eq(StringUtils.isNotBlank(bo.getChargeStatus()), CostCarCharge::getChargeStatus, bo.getChargeStatus());
lqw.eq(bo.getCostItemsId() != null, CostCarCharge::getCostItemsId, bo.getCostItemsId());
lqw.eq(bo.getStarTime() != null, CostCarCharge::getStarTime, bo.getStarTime());
lqw.eq(bo.getEndTime() != null, CostCarCharge::getEndTime, bo.getEndTime());
lqw.eq(StringUtils.isNotBlank(bo.getState()), CostCarCharge::getState, bo.getState());
lqw.eq(StringUtils.isNotBlank(bo.getSearchValue()), CostCarCharge::getSearchValue, bo.getSearchValue());
return lqw;
}

View File

@ -78,6 +78,7 @@ public class CostItemsServiceImpl implements ICostItemsService {
lqw.orderByAsc(CostItems::getId);
lqw.eq(StringUtils.isNotBlank(bo.getCostType()), CostItems::getCostType, bo.getCostType());
lqw.eq(StringUtils.isNotBlank(bo.getChargeItem()), CostItems::getChargeItem, bo.getChargeItem());
lqw.eq(StringUtils.isNotBlank(bo.getChargeNo()), CostItems::getChargeNo, bo.getChargeNo());
lqw.eq(StringUtils.isNotBlank(bo.getCostMark()), CostItems::getCostMark, bo.getCostMark());
lqw.eq(StringUtils.isNotBlank(bo.getPaymentType()), CostItems::getPaymentType, bo.getPaymentType());
lqw.eq(bo.getChargeCycle() != null, CostItems::getChargeCycle, bo.getChargeCycle());

View File

@ -178,15 +178,16 @@ public class MachineMaintainPlanServiceImpl implements IMachineMaintainPlanServi
*/
private void validEntityBeforebo(Long id, MachineMaintainPlanBo bo) {
//TODO 做一些数据校验,如唯一约束
Assert.isTrue(CollUtil.isNotEmpty(bo.getMachineMaintainPlanStaffBoList()), "巡检人员不存在");
QueryWrapper<MachineMaintainPlanStaff> staffLambdaQueryWrapper = new QueryWrapper<>();
staffLambdaQueryWrapper.eq("maintain_plan_id", id);
machineMaintainPlanStaffMapper.delete(staffLambdaQueryWrapper);
List<MachineMaintainPlanStaffBo> machineMaintainPlanStaffBoList = bo.getMachineMaintainPlanStaffBoList();
machineMaintainPlanStaffBoList.stream().forEach(s->{
s.setMaintainPlanId(id);
});
machineMaintainPlanStaffMapper.insertBatch(BeanUtil.copyToList(machineMaintainPlanStaffBoList, MachineMaintainPlanStaff.class));
if(CollUtil.isNotEmpty(bo.getMachineMaintainPlanStaffBoList())){
QueryWrapper<MachineMaintainPlanStaff> staffLambdaQueryWrapper = new QueryWrapper<>();
staffLambdaQueryWrapper.eq("maintain_plan_id", id);
machineMaintainPlanStaffMapper.delete(staffLambdaQueryWrapper);
List<MachineMaintainPlanStaffBo> machineMaintainPlanStaffBoList = bo.getMachineMaintainPlanStaffBoList();
machineMaintainPlanStaffBoList.stream().forEach(s->{
s.setMaintainPlanId(id);
});
machineMaintainPlanStaffMapper.insertBatch(BeanUtil.copyToList(machineMaintainPlanStaffBoList, MachineMaintainPlanStaff.class));
}
}
/**

View File

@ -7,6 +7,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.property.domain.InspectionPlanStaff;
import org.dromara.property.domain.InspectionTask;
import org.dromara.property.domain.bo.InspectionPlanBo;
@ -41,6 +42,7 @@ import static org.dromara.common.mybatis.core.mapper.BaseMapperPlus.log;
* @Date:2025/7/11 15:28
* @Description: 巡检任务定时处理器
**/
@Slf4j
@Component
@RequiredArgsConstructor
//@Validated

View File

@ -8,6 +8,7 @@ import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.property.domain.MachineMaintainPlanStaff;
import org.dromara.property.domain.MachineMaintainTask;
import org.dromara.property.domain.bo.MachineMaintainPlanBo;
@ -42,6 +43,7 @@ import static org.dromara.common.mybatis.core.mapper.BaseMapperPlus.log;
* @Date:2025/7/17 09:25
* @Description:
**/
@Slf4j
@Component
@RequiredArgsConstructor
//@Validated
@ -64,6 +66,7 @@ public class MachineTasks {
List<MachineMaintainPlanVo> machineMaintainPlanVoList = machineMaintainPlanService.queryList(machineMaintainPlanBo);
// 如果没有有效计划直接返回
if (ObjectUtil.isEmpty(machineMaintainPlanVoList)) {
log.info("暂时没有有效的计划");
return;
}
machineMaintainPlanVoList.stream().forEach(plan->{

View File

@ -2,17 +2,31 @@ package org.dromara.property.tasks;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.property.domain.AttendanceUserGroup;
import org.dromara.property.domain.ServiceWorkOrders;
import org.dromara.property.domain.ServiceWorkOrdersRecord;
import org.dromara.property.domain.enums.WorkOrderStatusEnum;
import org.dromara.property.mapper.AttendanceUserGroupMapper;
import org.dromara.property.mapper.ServiceWorkOrdersMapper;
import org.dromara.property.mapper.ServiceWorkOrdersRecordMapper;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import org.dromara.common.log.annotation.Log;
import org.springframework.transaction.annotation.Transactional;
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;
/**
* @Author:yuyongle
@ -20,23 +34,123 @@ import org.dromara.common.log.annotation.Log;
* @Description:自动派单
**/
@Slf4j
@Component
//@Component
//@RequiredArgsConstructor
@RequiredArgsConstructor
@RestController
@RequestMapping("/serviceWorkOrderTasks")
public class ServiceWorkOrderTasks {
private ServiceWorkOrdersMapper workOrdersMapper;
private ServiceWorkOrdersRecordMapper workOrdersRecordMapper;
private AttendanceUserGroupMapper attendanceUserGroupMapper;
//查询状态为创建工单的工单
/**
* 查询状态为创建工单的工单,查询当天排班人员,为工单自动派单
*/
// @Transactional(rollbackFor = Exception.class)
// @Scheduled(cron = "0 0 */1 * * ?")
@GetMapping("/serviceWorkOrderTaskId")
private void handleServiceWorkOrder() {
List<ServiceWorkOrders> serviceWorkOrderList = workOrdersMapper.selectList(
new LambdaQueryWrapper<ServiceWorkOrders>()
.eq(ServiceWorkOrders::getStatus, "0"));
.eq(ServiceWorkOrders::getStatus, WorkOrderStatusEnum.CREATE_ORDER.getValue()));
if(CollUtil.isNotEmpty(serviceWorkOrderList)){
serviceWorkOrderList.stream().forEach(s->{
//查询今天上班的人员
LocalDate today = LocalDate.now();
List<AttendanceUserGroup> attendanceUserGroups = attendanceUserGroupMapper.selectList(
new LambdaQueryWrapper<AttendanceUserGroup>()
.eq(AttendanceUserGroup::getStartDate, today)
);
if(CollUtil.isNotEmpty(attendanceUserGroups)){
attendanceUserGroups.stream().forEach(s1->{
ServiceWorkOrdersRecord serviceWorkOrdersRecord = new ServiceWorkOrdersRecord();
serviceWorkOrdersRecord.setOrderId(s.getId());
serviceWorkOrdersRecord.setStatus(WorkOrderStatusEnum.DISPATCHED.getValue());
serviceWorkOrdersRecord.setHandler(s1.getEmployeeId());
workOrdersRecordMapper.insert(serviceWorkOrdersRecord);
s.setStatus(WorkOrderStatusEnum.DISPATCHED.getValue());
s.setHandler(s1.getEmployeeId());
workOrdersMapper.updateById(s);
log.info("派单工单号为:{}",s.getOrderNo());
log.info("处理人为:{}",s1.getEmployeeId());
});
}else {
log.info("当天无排班人员");
}
});
}else {
log.info("派单工单为:{}",serviceWorkOrderList.size());
}
}
/**
* 处理超过30分钟的工单
*/
// @Transactional(rollbackFor = Exception.class)
// @Scheduled(cron = "0 0 */1 * * ?")
@GetMapping("/thirtyWorkOrderTaskId")
private void thirtyHandleServiceWorkOrder() {
// 1. 查询当前状态为已派单的工单
List<ServiceWorkOrders> serviceWorkOrderList = workOrdersMapper.selectList(
new LambdaQueryWrapper<ServiceWorkOrders>()
.eq(ServiceWorkOrders::getStatus, WorkOrderStatusEnum.DISPATCHED.getValue())
);
LocalDate today = LocalDate.now();
// 2. 查询今天有排班的人员
List<AttendanceUserGroup> attendanceUserGroups = attendanceUserGroupMapper.selectList(
new LambdaQueryWrapper<AttendanceUserGroup>()
.eq(AttendanceUserGroup::getStartDate, today)
);
if (CollUtil.isEmpty(serviceWorkOrderList) || CollUtil.isEmpty(attendanceUserGroups)) {
log.info("当前无可处理的超时工单或今日无排班人员");
return;
}
Date now = new Date();
// 3. 遍历超时工单
serviceWorkOrderList.forEach(workOrder -> {
// 查询该工单的最新记录可能有多条记录
ServiceWorkOrdersRecord latestRecord = workOrdersRecordMapper.selectOne(
new LambdaQueryWrapper<ServiceWorkOrdersRecord>()
.eq(ServiceWorkOrdersRecord::getOrderId, workOrder.getId())
.orderByDesc(ServiceWorkOrdersRecord::getCreateTime)
.last("LIMIT 1") // 获取最新一条记录
);
if (ObjectUtil.isEmpty(latestRecord) || latestRecord.getCreateTime() == null) {
return;
}
// 判断是否超过30分钟
long minutesElapsed = DateUtil.between(latestRecord.getCreateTime(), now, DateUnit.MINUTE);
if (minutesElapsed <= 30) {
return; // 未超时跳过
}
// 4. 标记原记录为废弃
latestRecord.setStatus(WorkOrderStatusEnum.ABANDON.getValue());
workOrdersRecordMapper.updateById(latestRecord);
log.info("工单号:{} 的原记录已废弃,超时未处理", workOrder.getOrderNo());
// 5. 重新派单给今天所有排班人员排除原处理人根据业务决定
boolean hasNewDispatch = false;
for (AttendanceUserGroup group : attendanceUserGroups) {
Long employeeId = group.getEmployeeId();
// 可选避免重新派给原处理人
if (employeeId.equals(latestRecord.getHandler())) {
log.debug("跳过原处理人:{}", employeeId);
continue;
}
// 创建新的派单记录
ServiceWorkOrdersRecord newRecord = new ServiceWorkOrdersRecord();
newRecord.setOrderId(workOrder.getId());
newRecord.setHandler(employeeId);
newRecord.setStatus(WorkOrderStatusEnum.DISPATCHED.getValue());
newRecord.setCreateTime(now);
workOrdersRecordMapper.insert(newRecord);
log.info("工单号:{} 已重新派发给员工ID{}", workOrder.getOrderNo(), employeeId);
// 6. 更新主工单状态可选若只保留最新记录状态也可不更新主表
workOrder.setStatus(WorkOrderStatusEnum.DISPATCHED.getValue()); // 仍为已派单
workOrder.setHandler(employeeId); // 可清空或设为最后一个人根据业务
workOrdersMapper.updateById(workOrder);
}
});
}
}