会议后台接口
This commit is contained in:
1 parent
236a4278fd
commit
8f554e933c
7 files changed
+167
-26
No files matched your search
+3
-2
@@ -7,6 +7,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
* 包厢预约记录表
|
||||
@@ -38,13 +39,13 @@ public class BoxesBookingEntity extends Model<BoxesBookingEntity> {
|
||||
* 开始时间
|
||||
*/
|
||||
@Schema(description="开始时间")
|
||||
private Object startTime;
|
||||
private LocalTime startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@Schema(description="结束时间")
|
||||
private Object endTime;
|
||||
private LocalTime endTime;
|
||||
|
||||
/**
|
||||
* 审核人id
|
||||
|
||||
+134
-13
@@ -20,9 +20,27 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.bsd.pjcloud.integrated.entity.MeetingRoomEntity;
|
||||
import com.bsd.pjcloud.integrated.service.MeetingRoomService;
|
||||
import com.bsd.pjcloud.flow.task.api.feign.RemoteFlowApiFlowService;
|
||||
import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum;
|
||||
import com.bsd.pjcloud.flow.task.dto.ProcessInstanceParamDto;
|
||||
import com.bsd.pjcloud.flow.task.entity.Process;
|
||||
import com.bsd.pjcloud.integrated.constant.IntegratedFlowConstant;
|
||||
import com.bsd.pjcloud.integrated.dto.flow.MeetingFlowDto;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
|
||||
import com.bsd.pjcloud.common.core.exception.ServiceException;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import com.bsd.pjcloud.integrated.dto.meeting.MeetingBookingSaveDto;
|
||||
import com.bsd.pjcloud.integrated.vo.meeting.MeetingBookingPageVo;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 会议室预约
|
||||
@@ -38,6 +56,8 @@ import java.util.Objects;
|
||||
public class MeetingBookingController {
|
||||
|
||||
private final MeetingBookingService meetingBookingService;
|
||||
private final MeetingRoomService meetingRoomService;
|
||||
private final RemoteFlowApiFlowService remoteFlowApiFlowService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
@@ -45,13 +65,47 @@ public class MeetingBookingController {
|
||||
* @param meetingBooking 会议室预约
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "分页查询" , description = "分页查询" )
|
||||
@GetMapping("/page" )
|
||||
@PreAuthorize("@pms.hasPermission('integrated_meetingBooking_view')" )
|
||||
public R getMeetingBookingPage(@ParameterObject Page page, @ParameterObject MeetingBookingEntity meetingBooking) {
|
||||
@Operation(summary = "分页查询", description = "分页查询")
|
||||
@GetMapping("/page")
|
||||
@PreAuthorize("@pms.hasPermission('integrated_meetingBooking_view')")
|
||||
public R<Page<MeetingBookingPageVo>> getMeetingBookingPage(@ParameterObject Page page, @ParameterObject MeetingBookingEntity meetingBooking) {
|
||||
LambdaQueryWrapper<MeetingBookingEntity> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(StrUtil.isNotBlank(meetingBooking.getTitle()),MeetingBookingEntity::getTitle,meetingBooking.getTitle());
|
||||
return R.ok(meetingBookingService.pageScope(page, wrapper));
|
||||
wrapper.eq(StrUtil.isNotBlank(meetingBooking.getTitle()), MeetingBookingEntity::getTitle, meetingBooking.getTitle());
|
||||
Page<MeetingBookingEntity> entityPage = meetingBookingService.pageScope(page, wrapper);
|
||||
|
||||
// 批量查会议室名称,避免N+1
|
||||
List<Long> roomIds = entityPage.getRecords().stream().map(MeetingBookingEntity::getRoomId).distinct().toList();
|
||||
Map<Long, String> roomNameMap = new HashMap<>();
|
||||
if (!roomIds.isEmpty()) {
|
||||
List<MeetingRoomEntity> rooms = meetingRoomService.listByIds(roomIds);
|
||||
for (MeetingRoomEntity room : rooms) {
|
||||
roomNameMap.put(room.getId(), room.getRoomName());
|
||||
}
|
||||
}
|
||||
|
||||
// 转VO
|
||||
List<MeetingBookingPageVo> voList = entityPage.getRecords().stream().map(e -> {
|
||||
MeetingBookingPageVo vo = new MeetingBookingPageVo();
|
||||
vo.setId(e.getId());
|
||||
vo.setTitle(e.getTitle());
|
||||
vo.setRoomId(e.getRoomId());
|
||||
vo.setRoomName(roomNameMap.get(e.getRoomId()));
|
||||
vo.setBookingDate(e.getBookingDate());
|
||||
vo.setStartTime(e.getStartTime());
|
||||
vo.setEndTime(e.getEndTime());
|
||||
vo.setApplicantId(e.getApplicantId());
|
||||
vo.setAssigneeName(e.getAssigneeName());
|
||||
vo.setCheckStatus(e.getCheckStatus());
|
||||
vo.setCheckReason(e.getCheckReason());
|
||||
vo.setCreateTime(e.getCreateTime());
|
||||
vo.setCreateBy(e.getCreateBy());
|
||||
vo.setDescription(e.getDescription());
|
||||
return vo;
|
||||
}).toList();
|
||||
|
||||
Page<MeetingBookingPageVo> voPage = new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal());
|
||||
voPage.setRecords(voList);
|
||||
return R.ok(voPage);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,17 +122,84 @@ public class MeetingBookingController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增会议室预约
|
||||
* @param meetingBooking 会议室预约
|
||||
* 新增会议室预约(PC端,逻辑与手机端一致)
|
||||
* @param dto 预约参数
|
||||
* @return R
|
||||
*/
|
||||
@Operation(summary = "新增会议室预约" , description = "新增会议室预约" )
|
||||
@SysLog("新增会议室预约" )
|
||||
@Operation(summary = "新增会议室预约", description = "新增会议室预约")
|
||||
@SysLog("新增会议室预约")
|
||||
@PostMapping
|
||||
@PreAuthorize("@pms.hasPermission('integrated_meetingBooking_add')" )
|
||||
public R save(@RequestBody MeetingBookingEntity meetingBooking) {
|
||||
@PreAuthorize("@pms.hasPermission('integrated_meetingBooking_add')")
|
||||
@Transactional
|
||||
public R save(@RequestBody MeetingBookingSaveDto dto) {
|
||||
// 1. 参数转换
|
||||
MeetingBookingEntity meetingBooking = new MeetingBookingEntity();
|
||||
meetingBooking.setTitle(dto.getTitle());
|
||||
meetingBooking.setRoomId(dto.getRoomId());
|
||||
meetingBooking.setDescription(dto.getDescription());
|
||||
meetingBooking.setBookingDate(LocalDate.parse(dto.getBookingDate()));
|
||||
meetingBooking.setStartTime(LocalTime.parse(dto.getStartTime()));
|
||||
meetingBooking.setEndTime(LocalTime.parse(dto.getEndTime()));
|
||||
// 2. 验证会议室是否存在
|
||||
MeetingRoomEntity room = meetingRoomService.getById(meetingBooking.getRoomId());
|
||||
if (room == null) {
|
||||
return R.failed("会议室不存在");
|
||||
}
|
||||
// 3. 验证会议室状态
|
||||
if (!YesNoEnum.NO.getCode().equals(room.getStatus())) {
|
||||
return R.failed("会议室当前不可用");
|
||||
}
|
||||
// 4. 校验时间
|
||||
LocalDate bookingDate = meetingBooking.getBookingDate();
|
||||
LocalTime startTime = meetingBooking.getStartTime();
|
||||
LocalTime endTime = meetingBooking.getEndTime();
|
||||
if (startTime == null || endTime == null || bookingDate == null) {
|
||||
return R.failed("预约日期和时间不能为空");
|
||||
}
|
||||
if (startTime.isAfter(endTime)) {
|
||||
return R.failed("开始时间不能晚于结束时间");
|
||||
}
|
||||
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之间");
|
||||
}
|
||||
// 5. 检查时间段是否已被预约
|
||||
var existingBookings = meetingBookingService.list(
|
||||
Wrappers.<MeetingBookingEntity>lambdaQuery()
|
||||
.eq(MeetingBookingEntity::getRoomId, meetingBooking.getRoomId())
|
||||
.eq(MeetingBookingEntity::getBookingDate, bookingDate)
|
||||
.eq(MeetingBookingEntity::getCheckStatus, TaskCheckStatusEnum.RESULT.getCode())
|
||||
);
|
||||
for (MeetingBookingEntity booking : existingBookings) {
|
||||
LocalTime bookingStart = booking.getStartTime();
|
||||
LocalTime bookingEnd = booking.getEndTime();
|
||||
if (!(endTime.compareTo(bookingStart) <= 0 || startTime.compareTo(bookingEnd) >= 0)) {
|
||||
return R.failed("该时间段已被预约");
|
||||
}
|
||||
}
|
||||
// 6. 设置预约人、部门
|
||||
meetingBooking.setApplicantId(SecurityUtils.getUser().getId());
|
||||
meetingBooking.setDeptId(SecurityUtils.getUser().getDeptId());
|
||||
return R.ok(meetingBookingService.save(meetingBooking));
|
||||
// 7. 发起流程
|
||||
var processByBusinessKey = remoteFlowApiFlowService.getProcessByBusinessKey(IntegratedFlowConstant.INTEGRATED_MEETING_BOOKING);
|
||||
if (!processByBusinessKey.isOk() || processByBusinessKey.getData() == null) {
|
||||
throw new ServiceException("流程配置获取失败: " + processByBusinessKey.getMsg());
|
||||
}
|
||||
Process process = processByBusinessKey.getData();
|
||||
MeetingFlowDto meetingFlowDto = new MeetingFlowDto();
|
||||
meetingFlowDto.setRoomName(room.getRoomName());
|
||||
meetingFlowDto.setApplicantName(SecurityUtils.getUser().getUsername());
|
||||
meetingFlowDto.setMeetingTime(bookingDate + " " + startTime + "-" + endTime);
|
||||
Map<String, Object> stringObjectMap = BeanUtil.beanToMap(meetingFlowDto);
|
||||
ProcessInstanceParamDto processInstanceParamDto = new ProcessInstanceParamDto();
|
||||
processInstanceParamDto.setFlowId(process.getFlowId());
|
||||
processInstanceParamDto.setParamMap(stringObjectMap);
|
||||
var stringR = remoteFlowApiFlowService.startProcessInstance(processInstanceParamDto);
|
||||
meetingBooking.setCheckStatus(TaskCheckStatusEnum.PADDING.getCode());
|
||||
meetingBooking.setProcessInstanceId(stringR.getData());
|
||||
boolean success = meetingBookingService.save(meetingBooking);
|
||||
return R.ok(success);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+22
-3
@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
|
||||
import com.bsd.pjcloud.common.core.exception.ServiceException;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.idempotent.annotation.Idempotent;
|
||||
import com.bsd.pjcloud.common.log.annotation.SysLog;
|
||||
import com.bsd.pjcloud.common.security.annotation.Inner;
|
||||
import com.bsd.pjcloud.common.security.util.SecurityUtils;
|
||||
@@ -50,6 +51,7 @@ import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 会议室信息表
|
||||
@@ -211,7 +213,7 @@ public class MeetingRoomController {
|
||||
Wrappers.<MeetingBookingEntity>lambdaQuery()
|
||||
.eq(MeetingBookingEntity::getRoomId, roomId)
|
||||
.eq(MeetingBookingEntity::getBookingDate, bookingDate)
|
||||
.eq(MeetingBookingEntity::getCheckStatus, TaskCheckStatusEnum.RESULT.getCode()) // 已通过的预约
|
||||
// .eq(MeetingBookingEntity::getCheckStatus, TaskCheckStatusEnum.RESULT.getCode()) // 已通过的预约
|
||||
);
|
||||
|
||||
// 标记已预约的时间段
|
||||
@@ -250,6 +252,7 @@ public class MeetingRoomController {
|
||||
@PostMapping("/{roomId}/book")
|
||||
@Operation(summary = "预约会议室", description = "预约会议室")
|
||||
@Transactional
|
||||
@Idempotent(expireTime = 5, info = "请勿重复预约")
|
||||
public R<Boolean> bookMeetingRoom(@PathVariable("roomId") Long roomId, @RequestBody MeetingBookingReqVo reqVo) {
|
||||
// 1. 验证会议室是否存在
|
||||
MeetingRoomEntity room = meetingRoomService.getById(roomId);
|
||||
@@ -413,8 +416,24 @@ public class MeetingRoomController {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 会议室下拉选择(仅返回可用会议室id和名称)
|
||||
*/
|
||||
@GetMapping("/app/select")
|
||||
public R<List<Map<String, Object>>> selectMeetingRooms() {
|
||||
LambdaQueryWrapper<MeetingRoomEntity> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(MeetingRoomEntity::getStatus, YesNoEnum.NO.getCode()); // 只查可用
|
||||
wrapper.select(MeetingRoomEntity::getId, MeetingRoomEntity::getRoomName);
|
||||
List<MeetingRoomEntity> list = meetingRoomService.list(wrapper);
|
||||
|
||||
|
||||
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
for (MeetingRoomEntity room : list) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("id", room.getId());
|
||||
map.put("name", room.getRoomName());
|
||||
result.add(map);
|
||||
}
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
}
|
||||
+5
-5
@@ -63,16 +63,16 @@ public class MeetingBookingEntity extends Model<MeetingBookingEntity> {
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 申请人id
|
||||
* 申请人
|
||||
*/
|
||||
@Schema(description="申请人id")
|
||||
@Schema(description="申请人")
|
||||
private Long applicantId;
|
||||
|
||||
/**
|
||||
* 会议负责人id
|
||||
* 会议负责人
|
||||
*/
|
||||
@Schema(description="会议负责人id")
|
||||
private Long assigneeId;
|
||||
@Schema(description="会议负责人")
|
||||
private String assigneeName;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
|
||||
+1
-1
@@ -14,5 +14,5 @@ public interface MeetingBookingService extends IService<MeetingBookingEntity> {
|
||||
* @param wrapper
|
||||
* @return
|
||||
*/
|
||||
Object pageScope(Page page, LambdaQueryWrapper<MeetingBookingEntity> wrapper);
|
||||
Page pageScope(Page page, LambdaQueryWrapper<MeetingBookingEntity> wrapper);
|
||||
}
|
||||
+1
-1
@@ -17,7 +17,7 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class MeetingBookingServiceImpl extends ServiceImpl<MeetingBookingMapper, MeetingBookingEntity> implements MeetingBookingService {
|
||||
@Override
|
||||
public Object pageScope(Page page, LambdaQueryWrapper<MeetingBookingEntity> wrapper) {
|
||||
public Page pageScope(Page page, LambdaQueryWrapper<MeetingBookingEntity> wrapper) {
|
||||
return baseMapper.selectPageByScope(page, wrapper, DataScope.of());
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
<result property="checkStatus" column="meeting_status"/>
|
||||
<result property="deptId" column="dept_id"/>
|
||||
<result property="applicantId" column="applicant_id"/>
|
||||
<result property="assigneeId" column="assignee_id"/>
|
||||
<result property="assigneeName" column="assignee_name"/>
|
||||
<result property="startTime" column="start_time"/>
|
||||
<result property="endTime" column="end_time"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
|
||||
Reference in new issue
Block a user