会议模块完善,修复共富商户筛选

This commit is contained in:
zjf committed 2025-09-10 17:00:55 +08:00
1 parent 7bfd882c83
commit bb31380671
20 files changed
+920 -11

No files matched your search

@@ -22,4 +22,10 @@ public class MeetingBookingSaveDto {
@Schema(description = "结束时间,格式HH:mm")
private String endTime;
@Schema(description = "是否需要会务服务(0=不需要 1=需要)")
private String needService;
@Schema(description = "桌子摆放形态")
private String deskLayout;
}
@@ -0,0 +1,29 @@
package com.bsd.pjcloud.integrated.vo.clean;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 保洁用户下拉列表VO
*
* @author zjf
* @date 2025-01-27
*/
@Data
@Schema(description = "保洁用户下拉列表")
public class CleanUserDropdownVo {
@Schema(description = "id")
private Long id;
@Schema(description = "姓名")
private String name;
@Schema(description = "手机号")
private String phone;
@Schema(description = "1保洁阿姨,2会务人员")
private String type;
}
@@ -49,4 +49,10 @@ public class MeetingBookingPageVo {
@Schema(description = "审核原因")
private String checkReason;
@Schema(description = "是否需要会务服务(0=不需要 1=需要)")
private String needService;
@Schema(description = "桌子摆放形态")
private String deskLayout;
}
@@ -0,0 +1,228 @@
# 会议室预约流程动态审批人实现示例
## 📋 概述
本文档展示如何在会议室预约的save方法中实现根据会议室管理员字段动态确定审批人的功能。
## 🔧 核心修改
### 1. 添加必要的依赖注入
```java
@RestController
@RequiredArgsConstructor
public class MeetingBookingController {
private final MeetingBookingService meetingBookingService;
private final MeetingRoomService meetingRoomService;
private final RemoteFlowApiFlowService remoteFlowApiFlowService;
private final RemoteUserService remoteUserService; // 新增:用于获取用户信息
}
```
### 2. 修改save方法中的流程启动部分
```java
@PostMapping
@Transactional
public R save(@RequestBody MeetingBookingSaveDto dto) {
// ... 前面的验证逻辑保持不变 ...
// 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);
// 🔥 关键:动态设置审批人 - 根据会议室管理员
List<NodeUser> approvers = determineApproversByRoomAdmin(room);
if (!approvers.isEmpty()) {
// 注意:这里的 "approval_node_1" 需要根据实际流程设计中的节点ID调整
stringObjectMap.put("approval_node_1_assignee_select", approvers);
}
ProcessInstanceParamDto processInstanceParamDto = new ProcessInstanceParamDto();
processInstanceParamDto.setFlowId(process.getFlowId());
processInstanceParamDto.setParamMap(stringObjectMap);
var stringR = remoteFlowApiFlowService.startProcessInstance(processInstanceParamDto);
// ... 后续逻辑保持不变 ...
}
```
### 3. 实现动态审批人确定方法
```java
/**
* 根据会议室管理员确定审批人
* @param room 会议室信息
* @return 审批人列表
*/
private List<NodeUser> determineApproversByRoomAdmin(MeetingRoomEntity room) {
List<NodeUser> approvers = new ArrayList<>();
// 1. 优先使用会议室指定的管理员
if (room.getAdminId() != null) {
try {
// 获取管理员用户信息
R<List<SysUser>> userResult = remoteUserService.getUserById(Arrays.asList(room.getAdminId()));
if (userResult.isOk() && !userResult.getData().isEmpty()) {
SysUser adminUser = userResult.getData().get(0);
NodeUser approver = NodeUser.builder()
.id(adminUser.getUserId())
.name(adminUser.getName())
.type("user")
.selected(true)
.avatar(adminUser.getAvatar())
.build();
approvers.add(approver);
}
} catch (Exception e) {
log.error("获取会议室管理员信息失败: {}", e.getMessage());
}
}
// 2. 如果会议室没有管理员,使用部门经理
if (approvers.isEmpty() && room.getDeptId() != null) {
approvers.addAll(getDeptManagerAsApprovers(room.getDeptId()));
}
// 3. 如果仍然没有审批人,使用默认审批人
if (approvers.isEmpty()) {
approvers.addAll(getDefaultApprovers());
}
return approvers;
}
/**
* 获取部门经理作为审批人
*/
private List<NodeUser> getDeptManagerAsApprovers(Long deptId) {
List<NodeUser> approvers = new ArrayList<>();
try {
// 这里需要根据实际的部门服务接口获取部门经理
// 示例:假设有部门服务可以获取部门经理
/*
R<SysDept> deptResult = remoteDeptService.getDeptById(deptId);
if (deptResult.isOk() && deptResult.getData() != null) {
SysDept dept = deptResult.getData();
Long managerId = dept.getManagerId();
if (managerId != null) {
R<List<SysUser>> userResult = remoteUserService.getUserById(Arrays.asList(managerId));
if (userResult.isOk() && !userResult.getData().isEmpty()) {
SysUser manager = userResult.getData().get(0);
NodeUser approver = NodeUser.builder()
.id(manager.getUserId())
.name(manager.getName())
.type("user")
.selected(true)
.avatar(manager.getAvatar())
.build();
approvers.add(approver);
}
}
}
*/
} catch (Exception e) {
log.error("获取部门经理信息失败: {}", e.getMessage());
}
return approvers;
}
/**
* 获取默认审批人
*/
private List<NodeUser> getDefaultApprovers() {
List<NodeUser> approvers = new ArrayList<>();
try {
// 设置系统管理员作为默认审批人
Long systemAdminId = 1L; // 需要替换为实际的系统管理员ID
NodeUser defaultApprover = NodeUser.builder()
.id(systemAdminId)
.name("系统管理员")
.type("user")
.selected(true)
.build();
approvers.add(defaultApprover);
} catch (Exception e) {
log.error("获取默认审批人失败: {}", e.getMessage());
}
return approvers;
}
```
## 🎯 关键要点
### 1. 流程节点ID配置
```java
// 这个key的格式是:{节点ID}_assignee_select
stringObjectMap.put("approval_node_1_assignee_select", approvers);
```
- `approval_node_1` 需要替换为实际流程设计中的审批节点ID
- 节点ID可以在流程设计器中查看
### 2. NodeUser对象构建
```java
NodeUser approver = NodeUser.builder()
.id(adminUser.getUserId()) // 用户ID
.name(adminUser.getName()) // 用户姓名
.type("user") // 用户类型,固定为"user"
.selected(true) // 是否选中
.avatar(adminUser.getAvatar()) // 用户头像(可选)
.build();
```
### 3. 审批人优先级
1. **会议室管理员** - 最高优先级
2. **部门经理** - 次优先级
3. **默认审批人** - 兜底方案
### 4. 错误处理
- 所有获取用户信息的操作都有异常处理
- 确保即使获取审批人失败,流程也能正常启动
- 使用日志记录错误信息,便于排查问题
## 🔄 流程设计配置
在流程设计器中,需要将审批节点配置为:
- **分配类型**: `SELF_SELECT` (发起人自选)
- **节点ID**: 与代码中的key保持一致
- **多实例模式**: 根据需要选择会签/或签/顺签
## 📝 使用示例
```java
// 会议室预约时,系统会自动:
// 1. 检查会议室是否有管理员
// 2. 如果有管理员,使用管理员作为审批人
// 3. 如果没有管理员,使用部门经理
// 4. 如果都没有,使用系统管理员
// 流程启动后,审批人会收到待办任务
// 审批人可以在流程中看到会议预约的详细信息
```
## ⚠️ 注意事项
1. **节点ID一致性**: 确保代码中的节点ID与流程设计中的节点ID一致
2. **用户服务可用性**: 确保用户服务接口可用,避免获取用户信息失败
3. **权限控制**: 确保选择的审批人有相应的审批权限
4. **测试验证**: 建议在测试环境先验证流程是否正常工作
## 🚀 扩展功能
可以根据业务需求进一步扩展:
1. **多级审批**: 根据会议室等级设置多级审批
2. **时间限制**: 根据预约时间长度确定审批人
3. **部门规则**: 根据部门特殊规则确定审批人
4. **用户角色**: 根据用户角色确定审批人
@@ -0,0 +1,135 @@
# 移动端摆放形式选择接口使用说明
## 📋 概述
本文档介绍移动端预约课程时选择摆放形式的接口使用方法。
## 🌐 接口信息
### 获取摆放形式列表接口
- **接口地址**: `GET /meetingDeskLayout/app/list`
- **请求方式**: GET
- **认证方式**: 无需认证(移动端公开接口)
- **数据格式**: JSON
## 📡 响应格式
### 成功响应
```json
{
"code": 0,
"msg": "操作成功",
"data": [
{
"id": 1,
"layoutName": "U型摆放",
"layoutImage": "https://example.com/images/u-layout.jpg",
"capacityMin": 8,
"capacityMax": 12,
"description": "适合小组讨论的U型摆放方式"
},
{
"id": 2,
"layoutName": "课桌式摆放",
"layoutImage": "https://example.com/images/classroom-layout.jpg",
"capacityMin": 20,
"capacityMax": 50,
"description": "传统课桌式摆放,适合培训课程"
},
{
"id": 3,
"layoutName": "圆桌式摆放",
"layoutImage": "https://example.com/images/round-table-layout.jpg",
"capacityMin": 6,
"capacityMax": 10,
"description": "圆桌式摆放,促进互动交流"
}
]
}
```
### 字段说明
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | Long | 摆放形式ID |
| layoutName | String | 摆放形式名称 |
| layoutImage | String | 摆放形式示意图URL |
| capacityMin | Integer | 最小容纳人数 |
| capacityMax | Integer | 最大容纳人数 |
| description | String | 摆放形式描述 |
## 🔍 业务逻辑说明
1. **数据过滤**: 只返回状态为"可用"(isAvailable = "0")的摆放形式
2. **排序规则**: 按照sortOrder字段升序排列
3. **数据精简**: 只返回移动端需要的核心字段,减少数据传输量
## 📱 使用示例
### JavaScript 调用示例
```javascript
fetch('/meetingDeskLayout/app/list', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.code === 0) {
// 处理摆放形式数据
const layouts = data.data;
layouts.forEach(layout => {
console.log(`摆放形式: ${layout.layoutName}, 容纳人数: ${layout.capacityMin}-${layout.capacityMax}人`);
});
}
})
.catch(error => {
console.error('获取摆放形式失败:', error);
});
```
### React Native 调用示例
```javascript
const fetchDeskLayouts = async () => {
try {
const response = await fetch('/meetingDeskLayout/app/list');
const result = await response.json();
if (result.code === 0) {
return result.data;
} else {
throw new Error(result.msg);
}
} catch (error) {
console.error('获取摆放形式失败:', error);
return [];
}
};
```
### cURL 调用示例
```bash
curl -X GET "http://your-domain/meetingDeskLayout/app/list" \
-H "Content-Type: application/json"
```
## 🎯 应用场景
1. **课程预约**: 用户在预约课程时选择适合的摆放形式
2. **会议室配置**: 根据参会人数推荐合适的摆放形式
3. **活动策划**: 根据活动类型选择合适的桌椅摆放方式
## ⚠️ 注意事项
1. **数据一致性**: 接口返回的数据与后台管理系统的摆放形式数据保持一致
2. **图片加载**: layoutImage字段可能为空,前端需要处理图片加载失败的情况
3. **容量限制**: 建议根据实际参会人数选择合适的摆放形式
4. **缓存策略**: 建议前端对摆放形式数据进行适当缓存,减少重复请求
## 🔄 版本更新
- **v1.0.0** (2025-01-27): 初始版本,提供基本的摆放形式选择功能
@@ -0,0 +1,75 @@
package com.bsd.pjcloud.integrated.constant;
/**
* 商城相关常量
*
* @author pjcloud
* @date 2025-01-27
*/
public interface IntegratedConstants {
/**
* 会议保洁/会务人员用户类型
*/
interface MeetingUserType {
/**
* 启用状态
*/
String BJ_USER = "1";
/**
* 禁用状态
*/
String HW_USER = "2";
}
/**
* 角色相关常量
*/
interface RoleCode {
/**
* 商户用户角色
*/
String MERCHANT_USER = "MALL_MCH";
/**
* 超市管理员角色
*/
String SUPERMARKET_ADMIN = "SUPERMARKET_ADMIN";
}
/**
* 商户相关常量
*/
interface Merchant {
/**
* 商户状态 - 正常
*/
String STATUS_NORMAL = "1";
/**
* 商户状态 - 停用
*/
String STATUS_DISABLED = "0";
}
/**
* 删除标记
*/
interface DelFlag {
/**
* 正常
*/
String NORMAL = "0";
/**
* 删除
*/
String DELETED = "1";
}
}
@@ -7,10 +7,12 @@ 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.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.core.util.BeanUtils;
import com.bsd.pjcloud.common.log.annotation.SysLog;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.integrated.entity.CleanUserEntity;
import com.bsd.pjcloud.integrated.service.CleanUserService;
import com.bsd.pjcloud.integrated.vo.clean.CleanUserDropdownVo;
import org.springframework.security.access.prepost.PreAuthorize;
import com.bsd.pjcloud.common.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
@@ -52,6 +54,7 @@ public class CleanUserController {
LambdaQueryWrapper<CleanUserEntity> wrapper = Wrappers.lambdaQuery();
wrapper.eq(StrUtil.isNotBlank(cleanUser.getName()),CleanUserEntity::getName,cleanUser.getName());
wrapper.eq(StrUtil.isNotBlank(cleanUser.getPhone()),CleanUserEntity::getPhone,cleanUser.getPhone());
wrapper.eq(CleanUserEntity::getType, cleanUser.getType());
return R.ok(cleanUserService.page(page, wrapper));
}
@@ -105,6 +108,15 @@ public class CleanUserController {
@DeleteMapping
@PreAuthorize("@pms.hasPermission('integrated_cleanUser_del')" )
public R removeById(@RequestBody Long[] ids) {
// 验证要删除的记录是否属于指定的type
LambdaQueryWrapper<CleanUserEntity> wrapper = Wrappers.lambdaQuery();
wrapper.in(CleanUserEntity::getId, CollUtil.toList(ids));
List<CleanUserEntity> validRecords = cleanUserService.list(wrapper);
if (validRecords.size() != ids.length) {
return R.failed("部分记录不属于指定类型,无法删除");
}
return R.ok(cleanUserService.removeBatchByIds(CollUtil.toList(ids)));
}
@@ -113,13 +125,18 @@ public class CleanUserController {
* 导出excel 表格
* @param cleanUser 查询条件
* @param ids 导出指定ID
* @param type 类型:1保洁阿姨,2会务人员
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('integrated_cleanUser_export')" )
public List<CleanUserEntity> export(CleanUserEntity cleanUser,Long[] ids) {
return cleanUserService.list(Wrappers.lambdaQuery(cleanUser).in(ArrayUtil.isNotEmpty(ids), CleanUserEntity::getId, ids));
public List<CleanUserEntity> export(CleanUserEntity cleanUser, Long[] ids,
@RequestParam(value = "type", required = false) String type) {
LambdaQueryWrapper<CleanUserEntity> wrapper = Wrappers.lambdaQuery(cleanUser);
wrapper.in(ArrayUtil.isNotEmpty(ids), CleanUserEntity::getId, ids);
wrapper.eq(StrUtil.isNotBlank(type), CleanUserEntity::getType, type);
return cleanUserService.list(wrapper);
}
@@ -130,12 +147,13 @@ public class CleanUserController {
@Operation(summary = "获取保洁/会务人员用户下拉列表", description = "获取保洁/会务人员用户下拉列表")
@GetMapping("/dropdown")
// @PreAuthorize("@pms.hasPermission('integrated_cleanUser_view')")
public R getCleanUserDropdown(@RequestParam("type")String type) {
public R<List<CleanUserDropdownVo>> getCleanUserDropdown(@RequestParam(value = "type",required = false)String type) {
LambdaQueryWrapper<CleanUserEntity> wrapper = Wrappers.lambdaQuery();
wrapper.eq(CleanUserEntity::getType, type);
wrapper.select(CleanUserEntity::getId, CleanUserEntity::getName, CleanUserEntity::getPhone);
wrapper.eq(type != null,CleanUserEntity::getType, type);
// wrapper.select(CleanUserEntity::getId, CleanUserEntity::getName, CleanUserEntity::getPhone);
wrapper.orderByAsc(CleanUserEntity::getName);
List<CleanUserEntity> list = cleanUserService.list(wrapper);
return R.ok(list);
List<CleanUserDropdownVo> voList = BeanUtils.toBean(list, CleanUserDropdownVo.class);
return R.ok(voList);
}
}
@@ -100,6 +100,8 @@ public class MeetingBookingController {
vo.setCreateTime(e.getCreateTime());
vo.setCreateBy(e.getCreateBy());
vo.setDescription(e.getDescription());
vo.setNeedService(e.getNeedService());
vo.setDeskLayout(e.getDeskLayout());
return vo;
}).toList();
@@ -140,6 +142,8 @@ public class MeetingBookingController {
meetingBooking.setBookingDate(LocalDate.parse(dto.getBookingDate()));
meetingBooking.setStartTime(LocalTime.parse(dto.getStartTime()));
meetingBooking.setEndTime(LocalTime.parse(dto.getEndTime()));
meetingBooking.setNeedService(dto.getNeedService());
meetingBooking.setDeskLayout(dto.getDeskLayout());
// 2. 验证会议室是否存在
MeetingRoomEntity room = meetingRoomService.getById(meetingBooking.getRoomId());
if (room == null) {
@@ -184,7 +188,8 @@ public class MeetingBookingController {
// 7. 发起流程
var processByBusinessKey = remoteFlowApiFlowService.getProcessByBusinessKey(IntegratedFlowConstant.INTEGRATED_MEETING_BOOKING);
if (!processByBusinessKey.isOk() || processByBusinessKey.getData() == null) {
throw new ServiceException("流程配置获取失败: " + processByBusinessKey.getMsg());
// throw new ServiceException("流程配置获取失败: " + processByBusinessKey.getMsg());
return R.failed("流程配置获取失败");
}
Process process = processByBusinessKey.getData();
MeetingFlowDto meetingFlowDto = new MeetingFlowDto();
@@ -0,0 +1,143 @@
package com.bsd.pjcloud.integrated.controller;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.collection.CollUtil;
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.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.log.annotation.SysLog;
import com.bsd.pjcloud.integrated.entity.MeetingDeskLayoutEntity;
import com.bsd.pjcloud.integrated.service.MeetingDeskLayoutService;
import com.bsd.pjcloud.integrated.vo.MeetingDeskLayoutAppVO;
import com.bsd.pjcloud.common.core.util.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import com.bsd.pjcloud.common.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
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 java.util.List;
import java.util.Objects;
/**
* 摆放形式
*
* @author zjf
* @date 2025-09-10 12:56:45
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/meetingDeskLayout" )
@Tag(description = "meetingDeskLayout" , name = "摆放形式管理" )
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class MeetingDeskLayoutController {
private final MeetingDeskLayoutService meetingDeskLayoutService;
/**
* 分页查询
* @param page 分页对象
* @param meetingDeskLayout 摆放形式
* @return
*/
@Operation(summary = "分页查询" , description = "分页查询" )
@GetMapping("/page" )
@PreAuthorize("@pms.hasPermission('integrated_meetingDeskLayout_view')" )
public R getMeetingDeskLayoutPage(@ParameterObject Page page, @ParameterObject MeetingDeskLayoutEntity meetingDeskLayout) {
LambdaQueryWrapper<MeetingDeskLayoutEntity> wrapper = Wrappers.lambdaQuery();
return R.ok(meetingDeskLayoutService.page(page, wrapper));
}
/**
* 通过id查询摆放形式
* @param id id
* @return R
*/
@Operation(summary = "通过id查询" , description = "通过id查询" )
@GetMapping("/{id}" )
@PreAuthorize("@pms.hasPermission('integrated_meetingDeskLayout_view')" )
public R getById(@PathVariable("id" ) Long id) {
return R.ok(meetingDeskLayoutService.getById(id));
}
/**
* 新增摆放形式
* @param meetingDeskLayout 摆放形式
* @return R
*/
@Operation(summary = "新增摆放形式" , description = "新增摆放形式" )
@SysLog("新增摆放形式" )
@PostMapping
@PreAuthorize("@pms.hasPermission('integrated_meetingDeskLayout_add')" )
public R save(@RequestBody MeetingDeskLayoutEntity meetingDeskLayout) {
return R.ok(meetingDeskLayoutService.save(meetingDeskLayout));
}
/**
* 修改摆放形式
* @param meetingDeskLayout 摆放形式
* @return R
*/
@Operation(summary = "修改摆放形式" , description = "修改摆放形式" )
@SysLog("修改摆放形式" )
@PutMapping
@PreAuthorize("@pms.hasPermission('integrated_meetingDeskLayout_edit')" )
public R updateById(@RequestBody MeetingDeskLayoutEntity meetingDeskLayout) {
return R.ok(meetingDeskLayoutService.updateById(meetingDeskLayout));
}
/**
* 通过id删除摆放形式
* @param ids id列表
* @return R
*/
@Operation(summary = "通过id删除摆放形式" , description = "通过id删除摆放形式" )
@SysLog("通过id删除摆放形式" )
@DeleteMapping
@PreAuthorize("@pms.hasPermission('integrated_meetingDeskLayout_del')" )
public R removeById(@RequestBody Long[] ids) {
return R.ok(meetingDeskLayoutService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 导出excel 表格
* @param meetingDeskLayout 查询条件
* @param ids 导出指定ID
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('integrated_meetingDeskLayout_export')" )
public List<MeetingDeskLayoutEntity> export(MeetingDeskLayoutEntity meetingDeskLayout,Long[] ids) {
return meetingDeskLayoutService.list(Wrappers.lambdaQuery(meetingDeskLayout).in(ArrayUtil.isNotEmpty(ids), MeetingDeskLayoutEntity::getId, ids));
}
//----------------------------------APP---------------------------------*/
/**
* 移动端获取可用的摆放形式列表
* @return R
*/
@Operation(summary = "移动端获取摆放形式列表", description = "移动端预约课程时选择摆放形式")
@GetMapping("/app/list")
public R<List<MeetingDeskLayoutAppVO>> getAppLayoutList() {
LambdaQueryWrapper<MeetingDeskLayoutEntity> wrapper = Wrappers.lambdaQuery();
// 只查询可用的摆放形式
wrapper.eq(MeetingDeskLayoutEntity::getIsAvailable, "0");
// 按排序字段排序
wrapper.orderByAsc(MeetingDeskLayoutEntity::getSortOrder);
List<MeetingDeskLayoutEntity> entityList = meetingDeskLayoutService.list(wrapper);
List<MeetingDeskLayoutAppVO> voList = BeanUtils.toBean(entityList, MeetingDeskLayoutAppVO.class);
return R.ok(voList);
}
}
@@ -320,7 +320,8 @@ public class MeetingRoomController {
//发起流程
R<Process> processByBusinessKey = remoteFlowApiFlowService.getProcessByBusinessKey(IntegratedFlowConstant.INTEGRATED_MEETING_BOOKING);
if (!processByBusinessKey.isOk() || processByBusinessKey.getData() == null) {
throw new ServiceException("流程配置获取失败: " + processByBusinessKey.getMsg());
// throw new ServiceException("流程配置获取失败: " + processByBusinessKey.getMsg());
return R.failed("流程配置获取失败");
}
Process process = processByBusinessKey.getData();
@@ -143,4 +143,16 @@ public class MeetingBookingEntity extends Model<MeetingBookingEntity> {
@Schema(description = "审批原因")
private String checkReason;
/**
* 是否需要会务服务(0=不需要 1=需要)
*/
@Schema(description = "是否需要会务服务(0=不需要 1=需要)")
private String needService;
/**
* 桌子摆放形态
*/
@Schema(description = "桌子摆放形态")
private String deskLayout;
}
@@ -0,0 +1,133 @@
package com.bsd.pjcloud.integrated.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
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.LocalDateTime;
/**
* 摆放形式
*
* @author zjf
* @date 2025-09-10 12:56:45
*/
@Data
@TenantTable
@TableName("meeting_desk_layout")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "摆放形式")
public class MeetingDeskLayoutEntity extends Model<MeetingDeskLayoutEntity> {
/**
* 编号
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description="编号")
private Long id;
/**
* 摆放形式名称
*/
@Schema(description="摆放形式名称")
private String layoutName;
/**
* 摆放形式编码
*/
@Schema(description="摆放形式编码")
private String layoutCode;
/**
* 摆放形式描述
*/
@Schema(description="摆放形式描述")
private String description;
/**
* 最小容纳人数
*/
@Schema(description="最小容纳人数")
private Integer capacityMin;
/**
* 最大容纳人数
*/
@Schema(description="最大容纳人数")
private Integer capacityMax;
/**
* 摆放形式示意图
*/
@Schema(description="摆放形式示意图")
private String layoutImage;
/**
* 布置所需时间(分钟)
*/
@Schema(description="布置所需时间(分钟)")
private Integer setupTime;
/**
* 是否可用(0=可用 1=不可用)
*/
@Schema(description="是否可用(0=可用 1=不可用)")
private String isAvailable;
/**
* 排序
*/
@Schema(description="排序")
private Integer sortOrder;
/**
* 备注
*/
@Schema(description="备注")
private String remark;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description="创建人")
private String createBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description="创建时间")
private LocalDateTime createTime;
/**
* 修改人
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
@Schema(description="修改人")
private String updateBy;
/**
* 修改时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
@Schema(description="修改时间")
private LocalDateTime updateTime;
/**
* 删除标记
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description="删除标记")
private String delFlag;
/**
* 租户ID
*/
@Schema(description="租户ID")
private Long tenantId;
}
@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
*/
@Data
@TenantTable
@TableName("meeting__room_equipment")
@TableName("meeting_room_equipment")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "设备会议室关联表")
public class MeetingRoomEquipmentEntity extends Model<MeetingRoomEquipmentEntity> {
@@ -0,0 +1,11 @@
package com.bsd.pjcloud.integrated.mapper;
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
import com.bsd.pjcloud.integrated.entity.MeetingDeskLayoutEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface MeetingDeskLayoutMapper extends PjcloudBaseMapper<MeetingDeskLayoutEntity> {
}
@@ -0,0 +1,8 @@
package com.bsd.pjcloud.integrated.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.integrated.entity.MeetingDeskLayoutEntity;
public interface MeetingDeskLayoutService extends IService<MeetingDeskLayoutEntity> {
}
@@ -0,0 +1,16 @@
package com.bsd.pjcloud.integrated.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.integrated.entity.MeetingDeskLayoutEntity;
import com.bsd.pjcloud.integrated.mapper.MeetingDeskLayoutMapper;
import com.bsd.pjcloud.integrated.service.MeetingDeskLayoutService;
import org.springframework.stereotype.Service;
/**
* 摆放形式
*
* @author zjf
* @date 2025-09-10 12:56:45
*/
@Service
public class MeetingDeskLayoutServiceImpl extends ServiceImpl<MeetingDeskLayoutMapper, MeetingDeskLayoutEntity> implements MeetingDeskLayoutService {
}
@@ -0,0 +1,56 @@
package com.bsd.pjcloud.integrated.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
* 移动端摆放形式选择VO
*
* @author zjf
* @date 2025-01-27
*/
@Data
@Schema(description = "移动端摆放形式选择VO")
public class MeetingDeskLayoutAppVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 编号
*/
@Schema(description = "编号")
private Long id;
/**
* 摆放形式名称
*/
@Schema(description = "摆放形式名称")
private String layoutName;
/**
* 摆放形式示意图
*/
@Schema(description = "摆放形式示意图")
private String layoutImage;
/**
* 最小容纳人数
*/
@Schema(description = "最小容纳人数")
private Integer capacityMin;
/**
* 最大容纳人数
*/
@Schema(description = "最大容纳人数")
private Integer capacityMax;
/**
* 摆放形式描述
*/
@Schema(description = "摆放形式描述")
private String description;
}
@@ -24,6 +24,8 @@
<result property="processInstanceId" column="process_instance_id"/>
<result property="checkReason" column="check_reason"/>
<result property="isConfirmEnd" column="is_confirm_end"/>
<result property="needService" column="need_service"/>
<result property="deskLayout" column="desk_layout"/>
</resultMap>
<select id="findByRoomIdAndDate" resultType="com.bsd.pjcloud.integrated.entity.MeetingBookingEntity">
SELECT * FROM meeting_booking WHERE room_id = #{roomId} AND start_time >= #{date} AND start_time &lt;= #{date}
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bsd.pjcloud.integrated.mapper.MeetingDeskLayoutMapper">
<resultMap id="meetingDeskLayoutMap" type="com.bsd.pjcloud.integrated.entity.MeetingDeskLayoutEntity">
<id property="id" column="id"/>
<result property="layoutName" column="layout_name"/>
<result property="layoutCode" column="layout_code"/>
<result property="description" column="description"/>
<result property="capacityMin" column="capacity_min"/>
<result property="capacityMax" column="capacity_max"/>
<result property="layoutImage" column="layout_image"/>
<result property="setupTime" column="setup_time"/>
<result property="isAvailable" column="is_available"/>
<result property="sortOrder" column="sort_order"/>
<result property="remark" column="remark"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="tenantId" column="tenant_id"/>
</resultMap>
</mapper>
@@ -232,12 +232,12 @@ public class MallAppController {
@ParameterObject Page page,
@RequestParam(required = false) Long categoryId,
@RequestParam(required = false) String keyword,
Long merchantId
@RequestParam Long merchantId
) {
LambdaQueryWrapper<MallProductEntity> wrapper = Wrappers.lambdaQuery();
wrapper.eq(categoryId != null, MallProductEntity::getCategoryId, categoryId);
wrapper.like(StrUtil.isNotBlank(keyword), MallProductEntity::getTitle, keyword);
wrapper.eq(merchantId != null, MallProductEntity::getMerchantId, merchantId);
wrapper.eq(MallProductEntity::getMerchantId, merchantId);
wrapper.eq(MallProductEntity::getStatus, MallConstants.Status.ENABLED); // 只查上架商品
IPage<MallProductEntity> productPage = mallProductService.page(page, wrapper);