总数据导出优化
This commit is contained in:
parent
944f0e54d6
commit
9e7acd05eb
|
@ -75,6 +75,30 @@ public class JeecgController<T, S extends IService<T>> {
|
|||
mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
|
||||
return mv;
|
||||
}
|
||||
/**
|
||||
* 根据传入数据列表导出 Excel
|
||||
*
|
||||
* @param dataList 导出的数据列表
|
||||
* @param clazz 导出类的 Class
|
||||
* @param title 导出标题
|
||||
*/
|
||||
protected ModelAndView exportXlsByList(List<T> dataList, Class<T> clazz, String title) {
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, title);
|
||||
mv.addObject(NormalExcelConstants.CLASS, clazz);
|
||||
|
||||
ExportParams exportParams = new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title);
|
||||
exportParams.setImageBasePath(jeecgBaseConfig.getPath().getUpload());
|
||||
|
||||
mv.addObject(NormalExcelConstants.PARAMS, exportParams);
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, dataList);
|
||||
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据每页sheet数量导出多sheet
|
||||
*
|
||||
|
|
|
@ -17,8 +17,10 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.modules.entity.CetGroup;
|
||||
import org.jeecg.modules.entity.CetInvigilateData;
|
||||
import org.jeecg.modules.entity.ClassRoom;
|
||||
import org.jeecg.modules.service.ICetGroupService;
|
||||
import org.jeecg.modules.service.ICetInvigilateDataService;
|
||||
import org.jeecg.modules.service.IClassRoomService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
@ -42,6 +44,8 @@ public class CetGroupController extends JeecgController<CetGroup, ICetGroupServi
|
|||
private ICetGroupService cetGroupService;
|
||||
@Autowired
|
||||
private ICetInvigilateDataService cetInvigilateDataService;
|
||||
@Autowired
|
||||
private IClassRoomService classRoomService;
|
||||
|
||||
/**
|
||||
* @param webData
|
||||
|
@ -66,44 +70,63 @@ public class CetGroupController extends JeecgController<CetGroup, ICetGroupServi
|
|||
@ApiOperation(value="分组数据表-分页列表查询", notes="分组数据表-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<CetGroup>> queryPageList(CetGroup cetGroup,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
QueryWrapper<CetGroup> queryWrapper = QueryGenerator.initQueryWrapper(cetGroup, req.getParameterMap());
|
||||
Page<CetGroup> page = new Page<>(pageNo, pageSize);
|
||||
IPage<CetGroup> pageList = cetGroupService.page(page, queryWrapper);
|
||||
|
||||
// 取分页内所有分组id,类型保持一致(假设是Long)
|
||||
Set<String> groupIds = pageList.getRecords().stream()
|
||||
.map(CetGroup::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
// 获取当前页中所有 groupId 和 roomId
|
||||
Set<String> groupIds = new HashSet<>();
|
||||
Set<String> roomIds = new HashSet<>();
|
||||
|
||||
if(!groupIds.isEmpty()){
|
||||
// 批量查询所有这些分组下的用户
|
||||
for (CetGroup group : pageList.getRecords()) {
|
||||
if (group.getId() != null) {
|
||||
groupIds.add(group.getId());
|
||||
}
|
||||
if (group.getRoomId() != null) {
|
||||
roomIds.add(group.getRoomId());
|
||||
}
|
||||
}
|
||||
|
||||
// 查询 invigilator 用户信息
|
||||
if (!groupIds.isEmpty()) {
|
||||
List<CetInvigilateData> userList = cetInvigilateDataService.list(
|
||||
new QueryWrapper<CetInvigilateData>().in("group_id", groupIds)
|
||||
);
|
||||
|
||||
// 按groupId分组用户名称列表,groupId类型保持一致
|
||||
Map<String, List<String>> groupIdToUserNames = userList.stream()
|
||||
.collect(Collectors.groupingBy(CetInvigilateData::getGroupId,
|
||||
Collectors.mapping(CetInvigilateData::getName, Collectors.toList())));
|
||||
|
||||
// 设置每个分组的userNames字段
|
||||
pageList.getRecords().forEach(group -> {
|
||||
// 查询 roomId -> roomName 映射
|
||||
Map<String, String> roomIdToName = new HashMap<>();
|
||||
if (!roomIds.isEmpty()) {
|
||||
List<ClassRoom> rooms = classRoomService.list(
|
||||
new QueryWrapper<ClassRoom>().in("id", roomIds)
|
||||
);
|
||||
roomIdToName = rooms.stream()
|
||||
.collect(Collectors.toMap(
|
||||
room -> String.valueOf(room.getId()),
|
||||
ClassRoom::getFullName // 或 .getName()
|
||||
));
|
||||
}
|
||||
|
||||
// 设置每条记录的 userNames 和 roomName
|
||||
for (CetGroup group : pageList.getRecords()) {
|
||||
String groupIdStr = String.valueOf(group.getId());
|
||||
List<String> names = groupIdToUserNames.get(groupIdStr);
|
||||
// 拼接为字符串,例如用逗号分隔
|
||||
String userNamesStr = (names != null && !names.isEmpty()) ? String.join(", ", names) : "";
|
||||
group.setRowUser(userNamesStr);
|
||||
});
|
||||
group.setRowUser((names != null && !names.isEmpty()) ? String.join(", ", names) : "");
|
||||
|
||||
String roomName = roomIdToName.get(String.valueOf(group.getRoomId()));
|
||||
group.setRoomName(roomName != null ? roomName : "");
|
||||
}
|
||||
}
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
|
@ -147,12 +170,16 @@ public class CetGroupController extends JeecgController<CetGroup, ICetGroupServi
|
|||
public Result<String> delete(@RequestParam(name="id", required=true) String id) {
|
||||
// 删除分组表中的分组
|
||||
cetGroupService.removeById(id);
|
||||
|
||||
// 将数据总表对应groupId置空
|
||||
UpdateWrapper<CetInvigilateData> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.eq("group_id", id).set("group_id", null);
|
||||
cetInvigilateDataService.update(updateWrapper);
|
||||
|
||||
// 清空 ClassRoom 中的 group_id,并将状态设为 0(空闲)
|
||||
UpdateWrapper<ClassRoom> roomUpdateWrapper = new UpdateWrapper<>();
|
||||
roomUpdateWrapper.eq("group_id", id)
|
||||
.set("group_id", null)
|
||||
.set("status", 0);
|
||||
classRoomService.update(roomUpdateWrapper);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
|
@ -176,7 +203,12 @@ public class CetGroupController extends JeecgController<CetGroup, ICetGroupServi
|
|||
UpdateWrapper<CetInvigilateData> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.in("group_id", idList).set("group_id", null);
|
||||
cetInvigilateDataService.update(updateWrapper);
|
||||
|
||||
// 清空 ClassRoom 中的 group_id,并将状态设为 0(空闲)
|
||||
UpdateWrapper<ClassRoom> roomUpdateWrapper = new UpdateWrapper<>();
|
||||
roomUpdateWrapper.in("group_id", idList)
|
||||
.set("group_id", null)
|
||||
.set("status", 0);
|
||||
classRoomService.update(roomUpdateWrapper);
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ public class CetInvigilateDataController extends JeecgController<CetInvigilateDa
|
|||
private ICetNoTeachersService cetNoTeachersService;
|
||||
@Autowired
|
||||
private ICetGroupService cetGroupService;
|
||||
@Autowired
|
||||
private IClassRoomService classRoomService;
|
||||
|
||||
|
||||
|
||||
|
@ -276,7 +278,50 @@ public class CetInvigilateDataController extends JeecgController<CetInvigilateDa
|
|||
@RequiresPermissions("cet:cet_invigilate_data:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, CetInvigilateData cetInvigilateData) {
|
||||
return super.exportXls(request, cetInvigilateData, CetInvigilateData.class, "数据总表");
|
||||
// 1. 获取查询参数后的数据列表
|
||||
List<CetInvigilateData> dataList = cetInvigilateDataService.list(
|
||||
QueryGenerator.initQueryWrapper(cetInvigilateData, request.getParameterMap())
|
||||
);
|
||||
|
||||
// 2. 获取所有涉及的 groupId
|
||||
Set<String> groupIds = dataList.stream()
|
||||
.map(CetInvigilateData::getGroupId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 3. 查询所有 groupId -> roomId 的映射
|
||||
Map<String, String> groupIdToRoomId = new HashMap<>();
|
||||
if (!groupIds.isEmpty()) {
|
||||
List<CetGroup> groups = cetGroupService.list(
|
||||
new QueryWrapper<CetGroup>().in("id", groupIds)
|
||||
);
|
||||
groupIdToRoomId = groups.stream()
|
||||
.filter(g -> g.getRoomId() != null)
|
||||
.collect(Collectors.toMap(CetGroup::getId, CetGroup::getRoomId));
|
||||
}
|
||||
|
||||
// 4. 查询所有 roomId -> roomName 的映射
|
||||
Set<String> roomIds = new HashSet<>(groupIdToRoomId.values());
|
||||
Map<String, String> roomIdToName = new HashMap<>();
|
||||
if (!roomIds.isEmpty()) {
|
||||
List<ClassRoom> rooms = classRoomService.list(
|
||||
new QueryWrapper<ClassRoom>().in("id", roomIds)
|
||||
);
|
||||
roomIdToName = rooms.stream()
|
||||
.collect(Collectors.toMap(ClassRoom::getId, ClassRoom::getFullName));
|
||||
}
|
||||
|
||||
// 5. 给每条数据填充 roomName 字段
|
||||
for (CetInvigilateData item : dataList) {
|
||||
String groupId = item.getGroupId();
|
||||
String roomId = groupIdToRoomId.get(groupId);
|
||||
String roomName = roomIdToName.get(roomId);
|
||||
item.setRoomName(roomName != null ? roomName : "");
|
||||
}
|
||||
|
||||
// 6. 执行导出(手动指定导出数据)
|
||||
return super.exportXlsByList(dataList, CetInvigilateData.class, "数据总表");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,6 +41,11 @@ public class CetGroup implements Serializable {
|
|||
@ApiModelProperty(value = "分组名称")
|
||||
@TableField(exist = false)
|
||||
private String rowUser;
|
||||
/**分组名称*/
|
||||
@Excel(name = "教室名称", width = 15)
|
||||
@ApiModelProperty(value = "教室名称")
|
||||
@TableField(exist = false)
|
||||
private String roomName;
|
||||
/**教室ID*/
|
||||
@Excel(name = "教室ID", width = 15)
|
||||
@ApiModelProperty(value = "教室ID")
|
||||
|
|
|
@ -59,7 +59,7 @@ public class CetInvigilateData implements Serializable {
|
|||
@ApiModelProperty(value = "学院")
|
||||
private String college;
|
||||
/**照片地址*/
|
||||
@Excel(name = "照片地址", width = 15)
|
||||
// @Excel(name = "照片地址", width = 15)
|
||||
@ApiModelProperty(value = "照片地址")
|
||||
private String photoAddress;
|
||||
/**创建人*/
|
||||
|
@ -89,9 +89,14 @@ public class CetInvigilateData implements Serializable {
|
|||
// @Excel(name = "分组", width = 15)
|
||||
@ApiModelProperty(value = "分组")
|
||||
private String groupId;
|
||||
/**类型*/
|
||||
@Excel(name = "分组", width = 15)
|
||||
/**分组*/
|
||||
// @Excel(name = "分组", width = 15)
|
||||
@ApiModelProperty(value = "分组")
|
||||
@TableField(exist = false)
|
||||
private String groupName;
|
||||
/**教室*/
|
||||
@Excel(name = "教室", width = 15)
|
||||
@ApiModelProperty(value = "教室")
|
||||
@TableField(exist = false)
|
||||
private String roomName;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,10 @@ import org.springframework.stereotype.Service;
|
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description: 分组数据表
|
||||
|
@ -39,6 +41,7 @@ public class CetGroupServiceImpl extends ServiceImpl<CetGroupMapper, CetGroup> i
|
|||
if (!(idsObj instanceof List)) {
|
||||
return Result.error("参数错误:未找到班级 ID 列表");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> groupIds = (List<String>) idsObj;
|
||||
|
||||
|
@ -51,29 +54,33 @@ public class CetGroupServiceImpl extends ServiceImpl<CetGroupMapper, CetGroup> i
|
|||
new LambdaQueryWrapper<ClassRoom>().eq(ClassRoom::getStatus, 0)
|
||||
);
|
||||
|
||||
if (freeRooms.size() < groupIds.size()) {
|
||||
return Result.error("空闲教室数量不足,请减少分配数量或释放教室");
|
||||
}
|
||||
// 查询所有分组名称,构造 Map<groupId, groupName>
|
||||
List<CetGroup> groups = cetGroupMapper.selectBatchIds(groupIds);
|
||||
Map<String, String> groupIdNameMap = groups.stream()
|
||||
.collect(Collectors.toMap(CetGroup::getId, CetGroup::getGroupName));
|
||||
|
||||
for (int i = 0; i < groupIds.size(); i++) {
|
||||
List<String> failedGroupIds = new ArrayList<>();
|
||||
|
||||
int minSize = Math.min(groupIds.size(), freeRooms.size());
|
||||
|
||||
for (int i = 0; i < minSize; i++) {
|
||||
String groupId = groupIds.get(i);
|
||||
ClassRoom room = freeRooms.get(i);
|
||||
|
||||
// 使用 LambdaUpdateWrapper 更新教室状态和绑定班级
|
||||
boolean updated = classRoomMapper.update(
|
||||
null,
|
||||
new LambdaUpdateWrapper<ClassRoom>()
|
||||
.eq(ClassRoom::getId, room.getId())
|
||||
.eq(ClassRoom::getStatus, 0) // 乐观锁保证未被其他线程占用
|
||||
.eq(ClassRoom::getStatus, 0)
|
||||
.set(ClassRoom::getGroupId, groupId)
|
||||
.set(ClassRoom::getStatus, 1)
|
||||
) > 0;
|
||||
|
||||
if (!updated) {
|
||||
throw new RuntimeException("教室 " + room.getFullName() + " 被占用,请稍后重试");
|
||||
failedGroupIds.add(groupId);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 更新班级的教室字段(假设 classMapper 是使用 MyBatis Plus 的)
|
||||
cetGroupMapper.update(
|
||||
null,
|
||||
new LambdaUpdateWrapper<CetGroup>()
|
||||
|
@ -82,7 +89,25 @@ public class CetGroupServiceImpl extends ServiceImpl<CetGroupMapper, CetGroup> i
|
|||
);
|
||||
}
|
||||
|
||||
return Result.ok("成功为 " + groupIds.size() + " 个班级分配教室");
|
||||
// 如果教室不够,则剩下的也视为失败
|
||||
if (groupIds.size() > freeRooms.size()) {
|
||||
for (int i = freeRooms.size(); i < groupIds.size(); i++) {
|
||||
failedGroupIds.add(groupIds.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
// 构造返回消息
|
||||
String message = "成功为 " + (groupIds.size() - failedGroupIds.size()) + " 个分组分配教室。";
|
||||
if (!failedGroupIds.isEmpty()) {
|
||||
List<String> failedGroupNames = failedGroupIds.stream()
|
||||
.map(id -> groupIdNameMap.getOrDefault(id, "未知分组(ID=" + id + ")"))
|
||||
.collect(Collectors.toList());
|
||||
message += " 以下分组未分配到教室:" + String.join(", ", failedGroupNames);
|
||||
}
|
||||
|
||||
return Result.ok(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -153,12 +153,13 @@ public class CetInvigilateDataServiceImpl extends ServiceImpl<CetInvigilateDataM
|
|||
|
||||
int index = 1;
|
||||
for (List<CetInvigilateData> group : groups) {
|
||||
// 创建组
|
||||
String groupName = "第" + index + "组";
|
||||
// 中文数字组名
|
||||
String groupName = "第" + toChineseNumber(index) + "组";
|
||||
|
||||
CetGroup cetGroup = new CetGroup()
|
||||
.setGroupName(groupName)
|
||||
.setRoomId("") // 可选
|
||||
.setCreateBy("system") // 建议改为当前用户
|
||||
.setCreateBy("system") // 建议替换为当前用户
|
||||
.setCreateTime(new Date())
|
||||
.setSysOrgCode("default");
|
||||
|
||||
|
@ -167,7 +168,7 @@ public class CetInvigilateDataServiceImpl extends ServiceImpl<CetInvigilateDataM
|
|||
|
||||
// 设置组ID并更新每位成员
|
||||
for (CetInvigilateData member : group) {
|
||||
member.setGroupId(groupId); // 确保 entity 中有 groupId 字段
|
||||
member.setGroupId(groupId);
|
||||
cetInvigilateDataMapper.updateById(member);
|
||||
}
|
||||
|
||||
|
@ -179,6 +180,34 @@ public class CetInvigilateDataServiceImpl extends ServiceImpl<CetInvigilateDataM
|
|||
return Result.ok("共成功组队:" + successCount + " 组,失败:" + (total - successCount) + " 组");
|
||||
}
|
||||
|
||||
private String toChineseNumber(int num) {
|
||||
String[] numChinese = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
|
||||
String[] units = {"", "十", "百", "千"};
|
||||
if (num <= 0) return "";
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
String numStr = String.valueOf(num);
|
||||
int length = numStr.length();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
int digit = numStr.charAt(i) - '0';
|
||||
int position = length - i - 1;
|
||||
|
||||
if (digit != 0) {
|
||||
if (!(digit == 1 && position == 1 && result.length() == 0)) {
|
||||
result.append(numChinese[digit]);
|
||||
}
|
||||
result.append(units[position]);
|
||||
} else {
|
||||
// Append "零" only if next digit is non-zero and not at the end
|
||||
if (i < length - 1 && numStr.charAt(i + 1) != '0') {
|
||||
result.append("零");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue