会议接口
This commit is contained in:
1 parent
de0ecc9f59
commit
6ef802ae8c
8 files changed
+238
-8
No files matched your search
+7
@@ -0,0 +1,7 @@
|
||||
package com.bsd.pjcloud.integrated.dto.meeting.app;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MeetingPageDto {
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.bsd.pjcloud.integrated.vo.meeting.app;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Schema(description = "会议室预约请求")
|
||||
public class MeetingBookingReqVo {
|
||||
|
||||
@Schema(description = "会议主题")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "会议说明")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "预约日期")
|
||||
@NotNull
|
||||
private String date;
|
||||
|
||||
@Schema(description = "开始时间")
|
||||
@NotNull
|
||||
private String startTime;
|
||||
|
||||
@Schema(description = "结束时间")
|
||||
@NotNull
|
||||
private String endTime;
|
||||
|
||||
@Schema(description = "参会人员ID列表")
|
||||
private List<Long> attendees;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.bsd.pjcloud.integrated.vo.meeting.app;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "会议室时间段")
|
||||
public class TimeSlotVo {
|
||||
|
||||
@Schema(description = "开始时间")
|
||||
private String startTime;
|
||||
|
||||
@Schema(description = "结束时间")
|
||||
private String endTime;
|
||||
|
||||
@Schema(description = "状态:free-空闲,booked-已预约,disabled-不可用")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "预约人信息")
|
||||
private BookedByVo bookedBy;
|
||||
|
||||
@Data
|
||||
public static class BookedByVo {
|
||||
@Schema(description = "用户ID")
|
||||
private String userId;
|
||||
|
||||
@Schema(description = "用户名称")
|
||||
private String userName;
|
||||
}
|
||||
}
|
||||
+151
-1
@@ -9,11 +9,17 @@ import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.log.annotation.SysLog;
|
||||
import com.bsd.pjcloud.common.security.util.SecurityUtils;
|
||||
import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum;
|
||||
import com.bsd.pjcloud.integrated.dto.meeting.app.MeetingPageDto;
|
||||
import com.bsd.pjcloud.integrated.entity.MeetingBookingEntity;
|
||||
import com.bsd.pjcloud.integrated.entity.MeetingRoomEntity;
|
||||
import com.bsd.pjcloud.integrated.entity.MeetingRoomEquipmentEntity;
|
||||
import com.bsd.pjcloud.integrated.service.MeetingBookingService;
|
||||
import com.bsd.pjcloud.integrated.service.MeetingRoomEquipmentService;
|
||||
import com.bsd.pjcloud.integrated.service.MeetingRoomService;
|
||||
import com.bsd.pjcloud.integrated.vo.meeting.app.MeetingBookingReqVo;
|
||||
import com.bsd.pjcloud.integrated.vo.meeting.app.MeetingRoomPageVo;
|
||||
import com.bsd.pjcloud.integrated.vo.meeting.app.TimeSlotVo;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import com.bsd.pjcloud.common.excel.annotation.ResponseExcel;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
@@ -27,6 +33,11 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.time.LocalTime;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 会议室信息表
|
||||
@@ -45,6 +56,8 @@ public class MeetingRoomController {
|
||||
|
||||
private final MeetingRoomEquipmentService meetingRoomEquipmentService;
|
||||
|
||||
private final MeetingBookingService meetingBookingService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param page 分页对象
|
||||
@@ -144,7 +157,7 @@ public class MeetingRoomController {
|
||||
|
||||
/**---------------------------APP------------------------------*/
|
||||
@GetMapping("/app/page")
|
||||
public R<Page<MeetingRoomPageVo>> appList(@ParameterObject Page page, @ParameterObject MeetingRoomEntity meetingRoom) {
|
||||
public R<Page<MeetingRoomPageVo>> appList(@ParameterObject Page page, @ParameterObject MeetingPageDto meetingRoom) {
|
||||
LambdaQueryWrapper<MeetingRoomEntity> meetingRoomEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
meetingRoomEntityLambdaQueryWrapper.eq(MeetingRoomEntity::getStatus, YesNoEnum.NO.getCode());
|
||||
meetingRoomEntityLambdaQueryWrapper.orderByDesc(MeetingRoomEntity::getSort).orderByDesc(MeetingRoomEntity::getId);
|
||||
@@ -154,4 +167,141 @@ public class MeetingRoomController {
|
||||
|
||||
return R.ok(pageData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 时间段
|
||||
* @param date
|
||||
* @param roomId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/{roomId}/time-slots")
|
||||
public R<List<TimeSlotVo>> timeSlots(@RequestParam(value = "date") String date, @PathVariable("roomId") Long roomId) {
|
||||
// 生成30分钟间隔的时间段
|
||||
List<TimeSlotVo> timeSlots = new ArrayList<>();
|
||||
LocalTime startTime = LocalTime.of(8, 0);
|
||||
LocalTime endTime = LocalTime.of(18, 0);
|
||||
|
||||
while (startTime.isBefore(endTime)) {
|
||||
TimeSlotVo slot = new TimeSlotVo();
|
||||
slot.setStartTime(startTime.format(DateTimeFormatter.ofPattern("HH:mm")));
|
||||
slot.setEndTime(startTime.plusMinutes(30).format(DateTimeFormatter.ofPattern("HH:mm")));
|
||||
slot.setStatus("free");
|
||||
timeSlots.add(slot);
|
||||
startTime = startTime.plusMinutes(30);
|
||||
}
|
||||
|
||||
// 获取当天的预约记录
|
||||
LocalDate bookingDate = LocalDate.parse(date);
|
||||
List<MeetingBookingEntity> bookings = meetingBookingService.list(
|
||||
Wrappers.<MeetingBookingEntity>lambdaQuery()
|
||||
.eq(MeetingBookingEntity::getRoomId, roomId)
|
||||
.eq(MeetingBookingEntity::getBookingDate, bookingDate)
|
||||
.eq(MeetingBookingEntity::getCheckStatus, TaskCheckStatusEnum.RESULT.getCode()) // 已通过的预约
|
||||
);
|
||||
|
||||
// 标记已预约的时间段
|
||||
for (MeetingBookingEntity booking : bookings) {
|
||||
LocalTime bookingStart = booking.getStartTime();
|
||||
LocalTime bookingEnd = booking.getEndTime();
|
||||
|
||||
for (TimeSlotVo slot : timeSlots) {
|
||||
LocalTime slotStart = LocalTime.parse(slot.getStartTime(), DateTimeFormatter.ofPattern("HH:mm"));
|
||||
LocalTime slotEnd = LocalTime.parse(slot.getEndTime(), DateTimeFormatter.ofPattern("HH:mm"));
|
||||
|
||||
// 修改判断逻辑:只要时间段有重叠就标记为已预约
|
||||
if (!(slotEnd.isBefore(bookingStart) || slotStart.isAfter(bookingEnd))) {
|
||||
slot.setStatus("booked");
|
||||
TimeSlotVo.BookedByVo bookedBy = new TimeSlotVo.BookedByVo();
|
||||
bookedBy.setUserId(String.valueOf(booking.getApplicantId()));
|
||||
// TODO: 从用户服务获取用户名
|
||||
bookedBy.setUserName("用户" + booking.getApplicantId());
|
||||
slot.setBookedBy(bookedBy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 标记不可用的时间段(12:00-13:00 午休时间)
|
||||
for (TimeSlotVo slot : timeSlots) {
|
||||
LocalTime slotStart = LocalTime.parse(slot.getStartTime(), DateTimeFormatter.ofPattern("HH:mm"));
|
||||
if (slotStart.isAfter(LocalTime.of(11, 59)) && slotStart.isBefore(LocalTime.of(13, 0))) {
|
||||
slot.setStatus("disabled");
|
||||
}
|
||||
}
|
||||
|
||||
return R.ok(timeSlots);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/{roomId}/book")
|
||||
@Operation(summary = "预约会议室", description = "预约会议室")
|
||||
public R<Boolean> bookMeetingRoom(@PathVariable("roomId") Long roomId, @RequestBody MeetingBookingReqVo reqVo) {
|
||||
// 1. 验证会议室是否存在
|
||||
MeetingRoomEntity room = meetingRoomService.getById(roomId);
|
||||
if (room == null) {
|
||||
return R.failed("会议室不存在");
|
||||
}
|
||||
|
||||
// 2. 验证会议室状态
|
||||
if (!YesNoEnum.NO.getCode().equals(room.getStatus())) {
|
||||
return R.failed("会议室当前不可用");
|
||||
}
|
||||
|
||||
// 3. 转换时间格式
|
||||
LocalDate bookingDate = LocalDate.parse(reqVo.getDate());
|
||||
LocalTime startTime = LocalTime.parse(reqVo.getStartTime());
|
||||
LocalTime endTime = LocalTime.parse(reqVo.getEndTime());
|
||||
|
||||
// 4. 验证时间是否合法
|
||||
if (startTime.isAfter(endTime)) {
|
||||
return R.failed("开始时间不能晚于结束时间");
|
||||
}
|
||||
|
||||
// 5. 验证是否在可用时间段内
|
||||
LocalTime availableStart = LocalTime.of(8, 0);
|
||||
LocalTime availableEnd = LocalTime.of(18, 0);
|
||||
if (startTime.isBefore(availableStart) || endTime.isAfter(availableEnd)) {
|
||||
return R.failed("预约时间必须在8:00-18:00之间");
|
||||
}
|
||||
|
||||
// 6. 验证是否在午休时间
|
||||
if ((startTime.isAfter(LocalTime.of(11, 59)) && startTime.isBefore(LocalTime.of(13, 0))) ||
|
||||
(endTime.isAfter(LocalTime.of(11, 59)) && endTime.isBefore(LocalTime.of(13, 0)))) {
|
||||
return R.failed("不能预约午休时间(12:00-13:00)");
|
||||
}
|
||||
|
||||
// 7. 检查时间段是否已被预约
|
||||
List<MeetingBookingEntity> existingBookings = meetingBookingService.list(
|
||||
Wrappers.<MeetingBookingEntity>lambdaQuery()
|
||||
.eq(MeetingBookingEntity::getRoomId, roomId)
|
||||
.eq(MeetingBookingEntity::getBookingDate, bookingDate)
|
||||
.eq(MeetingBookingEntity::getCheckStatus, TaskCheckStatusEnum.RESULT.getCode())
|
||||
);
|
||||
|
||||
for (MeetingBookingEntity booking : existingBookings) {
|
||||
LocalTime bookingStart = booking.getStartTime();
|
||||
LocalTime bookingEnd = booking.getEndTime();
|
||||
|
||||
// 修改判断逻辑:只要时间段有重叠就表示冲突
|
||||
if (!(endTime.isBefore(bookingStart) || startTime.isAfter(bookingEnd))) {
|
||||
return R.failed("该时间段已被预约");
|
||||
}
|
||||
}
|
||||
|
||||
// 8. 创建预约记录
|
||||
MeetingBookingEntity booking = new MeetingBookingEntity();
|
||||
booking.setTitle(reqVo.getTitle());
|
||||
booking.setDescription(reqVo.getDescription());
|
||||
booking.setRoomId(roomId);
|
||||
booking.setApplicantId(SecurityUtils.getUser().getId());
|
||||
booking.setDeptId(SecurityUtils.getUser().getDeptId());
|
||||
booking.setBookingDate(bookingDate);
|
||||
booking.setStartTime(startTime);
|
||||
booking.setEndTime(endTime);
|
||||
booking.setCheckStatus(TaskCheckStatusEnum.RESULT.getCode());
|
||||
|
||||
boolean success = meetingBookingService.save(booking);
|
||||
return R.ok(success);
|
||||
}
|
||||
|
||||
}
|
||||
+11
-3
@@ -6,7 +6,10 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import com.bsd.pjcloud.common.core.util.TenantTable;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
* 会议室预约
|
||||
@@ -51,7 +54,7 @@ public class MeetingBookingEntity extends Model<MeetingBookingEntity> {
|
||||
* 审批状态
|
||||
*/
|
||||
@Schema(description="审批状态")
|
||||
private String meetingStatus;
|
||||
private String checkStatus;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
@@ -75,13 +78,13 @@ public class MeetingBookingEntity extends Model<MeetingBookingEntity> {
|
||||
* 开始时间
|
||||
*/
|
||||
@Schema(description="开始时间")
|
||||
private LocalDateTime startTime;
|
||||
private LocalTime startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@Schema(description="结束时间")
|
||||
private LocalDateTime endTime;
|
||||
private LocalTime endTime;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
@@ -124,4 +127,9 @@ public class MeetingBookingEntity extends Model<MeetingBookingEntity> {
|
||||
*/
|
||||
@Schema(description="租户编号")
|
||||
private Long tenantId;
|
||||
|
||||
|
||||
@Schema(description = "预约日期")
|
||||
private LocalDate bookingDate;
|
||||
|
||||
}
|
||||
+2
-1
@@ -3,6 +3,7 @@ package com.bsd.pjcloud.integrated.mapper;
|
||||
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
|
||||
import com.bsd.pjcloud.integrated.entity.MeetingBookingEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
@@ -13,5 +14,5 @@ public interface MeetingBookingMapper extends PjcloudBaseMapper<MeetingBookingEn
|
||||
|
||||
|
||||
|
||||
List<MeetingBookingEntity> findByRoomIdAndDate(Long roomId, LocalDate date);
|
||||
List<MeetingBookingEntity> findByRoomIdAndDate(Long roomId, @Param("date") LocalDate date);
|
||||
}
|
||||
+3
-2
@@ -8,7 +8,7 @@
|
||||
<result property="title" column="title"/>
|
||||
<result property="roomId" column="room_id"/>
|
||||
<result property="description" column="description"/>
|
||||
<result property="meetingStatus" column="meeting_status"/>
|
||||
<result property="checkStatus" column="meeting_status"/>
|
||||
<result property="deptId" column="dept_id"/>
|
||||
<result property="applicantId" column="applicant_id"/>
|
||||
<result property="assigneeId" column="assignee_id"/>
|
||||
@@ -20,8 +20,9 @@
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="tenantId" column="tenant_id"/>
|
||||
<result property="bookingDate" column="booking_date"/>
|
||||
</resultMap>
|
||||
<select id="findByRoomIdAndDate" resultType="com.bsd.pjcloud.integrated.entity.MeetingBookingEntity">
|
||||
SELECT * FROM meeting_booking WHERE room_id = #{roomId} AND start_time >= #{startTime} AND start_time <= #{endTime}
|
||||
SELECT * FROM meeting_booking WHERE room_id = #{roomId} AND start_time >= #{date} AND start_time <= #{date}
|
||||
</select>
|
||||
</mapper>
|
||||
+1
-1
@@ -126,7 +126,7 @@ public class SmErpSpuServiceImpl extends ServiceImpl<SmErpSpuMapper, SmErpSpuEnt
|
||||
}
|
||||
List<SmErpUnitEntity> unitCollect = smErpUnitEntityList.stream().filter(smErpUnitEntity -> smErpUnitEntity.getPackageNum() <= 0).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(unitCollect)){
|
||||
return R.failed("包装类型内装数量不能小于等于0!");
|
||||
return R.failed("包装类型内装数.量不能小于等于0!");
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(smErpUnitEntityList)) {
|
||||
smErpUnitEntityList.forEach(supermarketUnitEntity -> supermarketUnitEntity.setSpuId(supermarketSpu.getId()));
|
||||
|
||||
Reference in new issue
Block a user