|
|
@ -18,9 +18,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
import org.dromara.productManagement.domain.*; |
|
|
|
import org.dromara.productManagement.domain.vo.RequirementEntityVo; |
|
|
|
import org.dromara.productManagement.mapper.ContractualInfoMapper; |
|
|
|
import org.dromara.productManagement.mapper.DocumentTaskResultsMapper; |
|
|
|
import org.dromara.productManagement.mapper.DocumentTasksMapper; |
|
|
|
import org.dromara.productManagement.mapper.*; |
|
|
|
import org.dromara.productManagement.utils.CompressedFileUtils; |
|
|
|
import org.dromara.productManagement.utils.MyHttpUtils; |
|
|
|
import org.dromara.productManagement.utils.MyTimeUtils; |
|
|
@ -31,8 +29,8 @@ import org.springframework.beans.factory.annotation.Value; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.dromara.productManagement.domain.bo.JyjContractualTaskBatchBo; |
|
|
|
import org.dromara.productManagement.domain.vo.JyjContractualTaskBatchVo; |
|
|
|
import org.dromara.productManagement.mapper.JyjContractualTaskBatchMapper; |
|
|
|
import org.dromara.productManagement.service.IJyjContractualTaskBatchService; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
import org.springframework.web.multipart.MultipartFile; |
|
|
|
|
|
|
|
import java.io.*; |
|
|
@ -50,12 +48,14 @@ import java.util.*; |
|
|
|
@RequiredArgsConstructor |
|
|
|
@Service |
|
|
|
@Slf4j |
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBatchService { |
|
|
|
|
|
|
|
private final JyjContractualTaskBatchMapper baseMapper; |
|
|
|
protected final ISysOssService ossService; |
|
|
|
private final DocumentTasksMapper documentTasksMapper; |
|
|
|
private final DocumentTaskResultsMapper documentTaskResultsMapper; |
|
|
|
private final ContractualProductInfoMapper contractualProductInfoMapper; |
|
|
|
private final ContractualInfoMapper contractualInfoMapper; |
|
|
|
@Value("${chat.chatUrl}") |
|
|
|
protected String chatUrl; |
|
|
@ -81,20 +81,79 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa |
|
|
|
public TableDataInfo<JyjContractualTaskBatchVo> queryPageList(JyjContractualTaskBatchBo bo, PageQuery pageQuery) { |
|
|
|
LambdaQueryWrapper<JyjContractualTaskBatch> lqw = buildQueryWrapper(bo); |
|
|
|
Page<JyjContractualTaskBatchVo> result = baseMapper.getBatchStatistics(pageQuery.build(), bo); |
|
|
|
|
|
|
|
// 处理处理时间
|
|
|
|
result.getRecords().forEach(vo -> { |
|
|
|
//获取文件路径
|
|
|
|
List<JyjContractualTaskBatchVo> childrenList = vo.getChildren(); |
|
|
|
if (childrenList != null && !childrenList.isEmpty()) { |
|
|
|
// 存储所有子记录的处理时间,用于比较
|
|
|
|
List<String> childTimeDifferences = new ArrayList<>(); |
|
|
|
|
|
|
|
for (JyjContractualTaskBatchVo child : childrenList) { |
|
|
|
Long childId = child.getId(); |
|
|
|
LambdaQueryWrapper<DocumentTasks> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(DocumentTasks::getGroupId, childId); |
|
|
|
List<DocumentTasks> documentTasksList = documentTasksMapper.selectList(wrapper); |
|
|
|
if (documentTasksList.size() > 0) { |
|
|
|
// 获取最早的更新时间
|
|
|
|
Date minUpdateTime = documentTasksList.stream() |
|
|
|
.min(Comparator.comparing(DocumentTasks::getUpdateTime)) |
|
|
|
.get() |
|
|
|
.getUpdateTime(); |
|
|
|
|
|
|
|
// 获取最晚的更新时间
|
|
|
|
Date maxUpdateTime = documentTasksList.stream() |
|
|
|
.max(Comparator.comparing(DocumentTasks::getUpdateTime)) |
|
|
|
.get() |
|
|
|
.getUpdateTime(); |
|
|
|
|
|
|
|
// 计算最早更新时间和最晚更新时间之间的差值
|
|
|
|
String timeDifference = MyTimeUtils.formatTimeDifference(minUpdateTime, maxUpdateTime); |
|
|
|
child.setProcessingTime(timeDifference); |
|
|
|
childTimeDifferences.add(timeDifference); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 找出处理时间最长的子记录时间
|
|
|
|
if (!childTimeDifferences.isEmpty()) { |
|
|
|
// 根据实际时间长度排序,而不是字符串长度
|
|
|
|
String longestTimeDifference = childTimeDifferences.stream() |
|
|
|
.max((time1, time2) -> { |
|
|
|
// 提取时间值的小时和分钟
|
|
|
|
long minutes1 = extractTotalMinutes(time1); |
|
|
|
long minutes2 = extractTotalMinutes(time2); |
|
|
|
// 比较总分钟数
|
|
|
|
return Long.compare(minutes1, minutes2); |
|
|
|
}) |
|
|
|
.orElse(""); |
|
|
|
vo.setProcessingTime(longestTimeDifference); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 如果没有子记录,直接计算父记录的处理时间
|
|
|
|
Long id = vo.getId(); |
|
|
|
LambdaQueryWrapper<DocumentTasks> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(DocumentTasks::getGroupId, id); |
|
|
|
List<DocumentTasks> documentTasksList = documentTasksMapper.selectList(wrapper); |
|
|
|
if(documentTasksList.size() > 0){ |
|
|
|
//获取documentTasksList中最大的updateTime
|
|
|
|
Date maxUpdateTime = documentTasksList.stream().max(Comparator.comparing(DocumentTasks::getCreateTime)).get().getCreateTime(); |
|
|
|
String timeDifference = MyTimeUtils.formatTimeDifference(vo.getLatestTime(), maxUpdateTime); |
|
|
|
if (documentTasksList.size() > 0) { |
|
|
|
// 获取最早的更新时间
|
|
|
|
Date minUpdateTime = documentTasksList.stream() |
|
|
|
.min(Comparator.comparing(DocumentTasks::getUpdateTime)) |
|
|
|
.get() |
|
|
|
.getUpdateTime(); |
|
|
|
|
|
|
|
// 获取最晚的更新时间
|
|
|
|
Date maxUpdateTime = documentTasksList.stream() |
|
|
|
.max(Comparator.comparing(DocumentTasks::getUpdateTime)) |
|
|
|
.get() |
|
|
|
.getUpdateTime(); |
|
|
|
|
|
|
|
// 计算最早更新时间和最晚更新时间之间的差值
|
|
|
|
String timeDifference = MyTimeUtils.formatTimeDifference(minUpdateTime, maxUpdateTime); |
|
|
|
vo.setProcessingTime(timeDifference); |
|
|
|
} |
|
|
|
//获取documentTasksList中最大的updateTime对应的documentTaskResults
|
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
return TableDataInfo.build(result); |
|
|
|
} |
|
|
|
|
|
|
@ -134,13 +193,34 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa |
|
|
|
String fileName = fileInfo.getOriginalName(); |
|
|
|
|
|
|
|
CompressedFileUtils.FileValidationResult fileValidationResult = CompressedFileUtils.processCompressedFileFromMinio(fileInfo); |
|
|
|
int size = fileValidationResult.getValidFiles().size(); |
|
|
|
add.setDocumentName(fileName); |
|
|
|
add.setTotalContracts(Long.valueOf(size)); |
|
|
|
CompressedFileUtils.FolderStructure folderStructure = fileValidationResult.getFolderStructure(); |
|
|
|
|
|
|
|
// 检查是否有子目录
|
|
|
|
List<File> childFolders = folderStructure.getChildFolders(); |
|
|
|
if (childFolders == null || childFolders.isEmpty()) { |
|
|
|
throw new ServiceException("压缩包中未找到有效的子目录"); |
|
|
|
} |
|
|
|
|
|
|
|
// 计算所有子文件夹中的文件总数
|
|
|
|
long totalFileCount = 0; |
|
|
|
for (File childFolder : childFolders) { |
|
|
|
File[] files = childFolder.listFiles((dir, name) -> |
|
|
|
name.toLowerCase().endsWith(".pdf") || name.toLowerCase().endsWith(".ofd")); |
|
|
|
totalFileCount += (files != null ? files.length : 0); |
|
|
|
} |
|
|
|
|
|
|
|
// 检查是否有有效的文件
|
|
|
|
if (totalFileCount == 0) { |
|
|
|
throw new ServiceException("压缩包中未找到有效的PDF或OFD文件"); |
|
|
|
} |
|
|
|
|
|
|
|
// 保存父记录
|
|
|
|
add.setDocumentName(folderStructure.getParentName()); |
|
|
|
add.setTotalContracts(totalFileCount); |
|
|
|
|
|
|
|
//批次名称未填.系统填写
|
|
|
|
if(!StringUtils.isNotBlank(add.getBatchName())){ |
|
|
|
//查询当天的上传记录次数
|
|
|
|
// 使用数据库的日期函数进行比较(这里以MySQL为例)
|
|
|
|
LambdaQueryWrapper<JyjContractualTaskBatch> lqw = Wrappers.lambdaQuery(); |
|
|
|
lqw.apply("DATE(create_time) = CURRENT_DATE()"); |
|
|
|
|
|
|
@ -150,27 +230,52 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa |
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日第"); |
|
|
|
String batchName = sdf.format(new Date()) + count + "批"; |
|
|
|
add.setBatchName(batchName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 保存父记录
|
|
|
|
boolean flag = baseMapper.insert(add) > 0; |
|
|
|
|
|
|
|
for(File file : fileValidationResult.getValidFiles()){ |
|
|
|
//每个文件起一个任务
|
|
|
|
if (flag) { |
|
|
|
// 保存子记录
|
|
|
|
List<String> childNames = folderStructure.getChildNames(); |
|
|
|
|
|
|
|
for (int i = 0; i < childNames.size(); i++) { |
|
|
|
// 保存子文件夹记录
|
|
|
|
JyjContractualTaskBatch child = new JyjContractualTaskBatch(); |
|
|
|
child.setDocumentName(childNames.get(i)); |
|
|
|
child.setParentId(add.getId()); |
|
|
|
child.setBatchName(add.getBatchName()); |
|
|
|
child.setTaskName(bo.getTaskName()); |
|
|
|
child.setTaskType(bo.getTaskType()); |
|
|
|
|
|
|
|
// 计算子文件夹中的文件数量
|
|
|
|
File childFolder = childFolders.get(i); |
|
|
|
File[] files = childFolder.listFiles((dir, name) -> |
|
|
|
name.toLowerCase().endsWith(".pdf") || name.toLowerCase().endsWith(".ofd")); |
|
|
|
child.setTotalContracts(Long.valueOf(files != null ? files.length : 0)); |
|
|
|
|
|
|
|
baseMapper.insert(child); |
|
|
|
|
|
|
|
// 为子文件夹中的每个文件创建任务
|
|
|
|
if (files != null) { |
|
|
|
for (File file : files) { |
|
|
|
DocumentTasks documentTasks = new DocumentTasks(); |
|
|
|
documentTasks.setTaskName(bo.getTaskName()); |
|
|
|
documentTasks.setDocumentName(file.getName()); |
|
|
|
documentTasks.setProgressStatus("PENDING"); |
|
|
|
documentTasks.setTaskType(bo.getTaskType()); |
|
|
|
documentTasks.setGroupId(add.getId()); |
|
|
|
documentTasks.setGroupId(child.getId()); // 使用子记录的ID作为GroupId
|
|
|
|
documentTasks.setBatchName(add.getBatchName()); |
|
|
|
documentTasks.setRequirementType(bo.getRequirementType()); |
|
|
|
// 在插入数据库前调用扩展点
|
|
|
|
documentTasksMapper.insert(documentTasks); |
|
|
|
// 在发送消息前调用扩展点
|
|
|
|
|
|
|
|
// 发送任务开始消息
|
|
|
|
Long priority = 1L; |
|
|
|
MyHttpUtils.sendTaskStartMessage(chatUrl + "/back/taskStart", |
|
|
|
documentTasks.getId(), bo.getTaskName(), file.getAbsolutePath(), priority); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (flag) { |
|
|
@ -211,7 +316,46 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa |
|
|
|
if(isValid){ |
|
|
|
//TODO 做一些业务上的校验,判断是否需要校验
|
|
|
|
} |
|
|
|
return baseMapper.deleteByIds(ids) > 0; |
|
|
|
ArrayList<Long> longs = new ArrayList<>(); |
|
|
|
longs.addAll(ids); |
|
|
|
for (Long id : ids) { |
|
|
|
LambdaQueryWrapper<JyjContractualTaskBatch> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(JyjContractualTaskBatch::getParentId, id); |
|
|
|
List<JyjContractualTaskBatch> childList = baseMapper.selectList(wrapper); |
|
|
|
if (childList.size() > 0) { |
|
|
|
for (JyjContractualTaskBatch child : childList) { |
|
|
|
deleteDocTasks(child.getId()); |
|
|
|
longs.add(child.getId()); |
|
|
|
} |
|
|
|
}else{ |
|
|
|
deleteDocTasks(id); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 根据documentTasksList 删除documentTasks
|
|
|
|
return baseMapper.deleteByIds(longs)>0; |
|
|
|
} |
|
|
|
private void deleteDocTasks(Long id) { |
|
|
|
//根据id 查询documentTasks
|
|
|
|
LambdaQueryWrapper<DocumentTasks> wrapper = new LambdaQueryWrapper<>(); // 构建查询条件
|
|
|
|
wrapper.eq(DocumentTasks::getGroupId, id); |
|
|
|
List<DocumentTasks> documentTasksList = documentTasksMapper.selectList(wrapper); |
|
|
|
for (DocumentTasks documentTasks : documentTasksList){ |
|
|
|
Long documentTaskId = documentTasks.getId(); |
|
|
|
LambdaQueryWrapper<DocumentTaskResults> resultsWrapper = new LambdaQueryWrapper<>(); |
|
|
|
resultsWrapper.eq(DocumentTaskResults::getDocumentTaskId, documentTaskId); |
|
|
|
documentTaskResultsMapper.delete(resultsWrapper); |
|
|
|
documentTasksMapper.deleteById(documentTaskId); |
|
|
|
// 删除合同信息
|
|
|
|
LambdaQueryWrapper<ContractualInfo> contractualInfoWrapper = new LambdaQueryWrapper<>(); |
|
|
|
contractualInfoWrapper.eq(ContractualInfo::getTaskId, documentTaskId); |
|
|
|
contractualInfoMapper.delete(contractualInfoWrapper); |
|
|
|
// 删除合同产品信息
|
|
|
|
LambdaQueryWrapper<ContractualProductInfo> contractualProductInfoWrapper = new LambdaQueryWrapper<>(); |
|
|
|
contractualProductInfoWrapper.eq(ContractualProductInfo::getTaskId, documentTaskId); |
|
|
|
contractualProductInfoMapper.delete(contractualProductInfoWrapper); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
@Override |
|
|
|
public HashMap<String,String> uploadFile(MultipartFile file) throws IOException { |
|
|
@ -231,7 +375,7 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public ContractualRes getContractulResultById(Long id) throws JsonProcessingException { |
|
|
|
public Map<String, Object> getContractulResultById(Long id) throws JsonProcessingException { |
|
|
|
LambdaQueryWrapper<DocumentTaskResults> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(DocumentTaskResults::getDocumentTaskId, id); |
|
|
|
DocumentTaskResults documentTaskResults = documentTaskResultsMapper.selectOne(wrapper); |
|
|
@ -239,7 +383,34 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa |
|
|
|
//json 字符串转ContractualRes
|
|
|
|
ObjectMapper mapper = new ObjectMapper(); |
|
|
|
ContractualRes response = mapper.readValue(result, new TypeReference<ContractualRes>() {}); |
|
|
|
return response; |
|
|
|
String resultJson = documentTaskResults.getResultJson(); |
|
|
|
|
|
|
|
// 创建包含当前记录和历史记录的Map
|
|
|
|
Map<String, Object> resultMap = new HashMap<>(); |
|
|
|
resultMap.put("result", response); |
|
|
|
if (resultJson != null && !resultJson.isEmpty()) { |
|
|
|
try { |
|
|
|
// 尝试解析为列表
|
|
|
|
List<Map<String, Object>> resultList = mapper.readValue(resultJson, new TypeReference<List<Map<String, Object>>>() {}); |
|
|
|
resultMap.put("historyresultList", resultList); |
|
|
|
} catch (JsonProcessingException e) { |
|
|
|
// 如果解析为列表失败,尝试解析为单个对象
|
|
|
|
try { |
|
|
|
Map<String, Object> resultObject = mapper.readValue(resultJson, new TypeReference<Map<String, Object>>() {}); |
|
|
|
List<Map<String, Object>> resultList = new ArrayList<>(); |
|
|
|
resultList.add(resultObject); |
|
|
|
resultMap.put("historyresultList", resultList); |
|
|
|
} catch (JsonProcessingException ex) { |
|
|
|
// 如果两种解析都失败,返回空列表
|
|
|
|
resultMap.put("historyresultList", new ArrayList<>()); |
|
|
|
log.error("解析resultJson失败: {}", ex.getMessage()); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
resultMap.put("historyresultList", new ArrayList<>()); |
|
|
|
} |
|
|
|
|
|
|
|
return resultMap; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
@ -320,6 +491,9 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa |
|
|
|
LambdaQueryWrapper<ContractualInfo> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(ContractualInfo::getTaskId, id); |
|
|
|
ContractualInfo contractualInfo = contractualInfoMapper.selectOne(wrapper); |
|
|
|
if (contractualInfo == null) { |
|
|
|
return "获取合同文本内容失败"; |
|
|
|
} |
|
|
|
String text = contractualInfo.getText(); |
|
|
|
return text; |
|
|
|
} |
|
|
@ -365,4 +539,127 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa |
|
|
|
throw new ServiceException("导出Excel失败,请联系管理员"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 合并批次 |
|
|
|
* |
|
|
|
* @param bo 包含要合并的批次信息 |
|
|
|
* @return 是否合并成功 |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public Boolean mergeBatches(JyjContractualTaskBatchBo bo) { |
|
|
|
if (bo.getIds() == null || bo.getIds().length < 2) { |
|
|
|
throw new ServiceException("请至少选择两个批次进行合并"); |
|
|
|
} |
|
|
|
|
|
|
|
// 检查所选批次的状态
|
|
|
|
List<JyjContractualTaskBatch> batches = baseMapper.selectBatchIds(Arrays.asList(bo.getIds())); |
|
|
|
for (JyjContractualTaskBatch batch : batches) { |
|
|
|
if (batch.getParentId() != null) { |
|
|
|
throw new ServiceException("只能合并父级批次"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 创建新的父批次记录
|
|
|
|
JyjContractualTaskBatch newParent = new JyjContractualTaskBatch(); |
|
|
|
newParent.setDocumentName(bo.getDocumentName()); |
|
|
|
newParent.setBatchName(bo.getBatchName()); |
|
|
|
|
|
|
|
// 计算合并后的总数
|
|
|
|
long totalContracts = batches.stream() |
|
|
|
.mapToLong(JyjContractualTaskBatch::getTotalContracts) |
|
|
|
.sum(); |
|
|
|
newParent.setTotalContracts(totalContracts); |
|
|
|
|
|
|
|
// 保存新的父批次
|
|
|
|
boolean flag = baseMapper.insert(newParent) > 0; |
|
|
|
if (!flag) { |
|
|
|
throw new ServiceException("创建合并批次失败"); |
|
|
|
} |
|
|
|
|
|
|
|
// 更新所有批次
|
|
|
|
for (JyjContractualTaskBatch batch : batches) { |
|
|
|
// 查找原批次的所有子批次
|
|
|
|
LambdaQueryWrapper<JyjContractualTaskBatch> childWrapper = new LambdaQueryWrapper<>(); |
|
|
|
childWrapper.eq(JyjContractualTaskBatch::getParentId, batch.getId()); |
|
|
|
List<JyjContractualTaskBatch> children = baseMapper.selectList(childWrapper); |
|
|
|
|
|
|
|
if (children != null && !children.isEmpty()) { |
|
|
|
// 如果有子批次,更新子批次的父ID和批次名称
|
|
|
|
for (JyjContractualTaskBatch child : children) { |
|
|
|
child.setParentId(newParent.getId()); |
|
|
|
child.setBatchName(newParent.getBatchName()); |
|
|
|
baseMapper.updateById(child); |
|
|
|
|
|
|
|
// 更新关联的任务记录
|
|
|
|
updateTasksBatchName(child.getId(), newParent.getBatchName()); |
|
|
|
} |
|
|
|
// 删除原批次
|
|
|
|
baseMapper.deleteById(batch.getId()); |
|
|
|
} else { |
|
|
|
// 如果没有子批次,将当前批次作为子批次
|
|
|
|
batch.setParentId(newParent.getId()); |
|
|
|
batch.setBatchName(newParent.getBatchName()); |
|
|
|
baseMapper.updateById(batch); |
|
|
|
|
|
|
|
// 更新关联的任务记录
|
|
|
|
updateTasksBatchName(batch.getId(), newParent.getBatchName()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 更新任务的批次名称 |
|
|
|
* |
|
|
|
* @param groupId 组ID |
|
|
|
* @param batchName 新的批次名称 |
|
|
|
*/ |
|
|
|
private void updateTasksBatchName(Long groupId, String batchName) { |
|
|
|
LambdaQueryWrapper<DocumentTasks> taskWrapper = new LambdaQueryWrapper<>(); |
|
|
|
taskWrapper.eq(DocumentTasks::getGroupId, groupId); |
|
|
|
List<DocumentTasks> tasks = documentTasksMapper.selectList(taskWrapper); |
|
|
|
for (DocumentTasks task : tasks) { |
|
|
|
task.setBatchName(batchName); |
|
|
|
documentTasksMapper.updateById(task); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 从时间字符串中提取总分钟数 |
|
|
|
* 支持两种格式:"XX小时XX分钟" 和 "XX分钟" |
|
|
|
* |
|
|
|
* @param time 时间字符串,如 "2小时30分钟" 或 "45分钟" |
|
|
|
* @return 总分钟数 |
|
|
|
*/ |
|
|
|
private long extractTotalMinutes(String time) { |
|
|
|
if (time == null || time.isEmpty()) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
long hours = 0; |
|
|
|
long minutes = 0; |
|
|
|
|
|
|
|
// 处理包含"小时"的情况
|
|
|
|
if (time.contains("小时")) { |
|
|
|
String[] hourParts = time.split("小时"); |
|
|
|
hours = Long.parseLong(hourParts[0]); |
|
|
|
|
|
|
|
// 如果还有分钟部分
|
|
|
|
if (hourParts.length > 1 && hourParts[1].contains("分钟")) { |
|
|
|
String minuteStr = hourParts[1].replace("分钟", "").trim(); |
|
|
|
if (!minuteStr.isEmpty()) { |
|
|
|
minutes = Long.parseLong(minuteStr); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// 处理只有"分钟"的情况
|
|
|
|
else if (time.contains("分钟")) { |
|
|
|
String minuteStr = time.replace("分钟", "").trim(); |
|
|
|
minutes = Long.parseLong(minuteStr); |
|
|
|
} |
|
|
|
|
|
|
|
return hours * 60 + minutes; |
|
|
|
} |
|
|
|
} |
|
|
|