feat: 实现子任务deadline后端计算和存储功能
- 添加task_item表的deadline字段(数据库迁移V13) - 在TaskItem实体类中添加deadline字段 - 更新TaskItemMapper.grabItem()方法支持deadline参数 - 在TaskItemService.grabItem()中使用WorkHoursCalculator计算deadline - 更新前端TaskItem接口添加deadline字段 - 修改前端getSubTaskDeadline函数直接使用后端返回的deadline
This commit is contained in:
parent
124e18ab78
commit
7390289f1a
@ -66,6 +66,11 @@ public class TaskItem implements Serializable {
|
||||
*/
|
||||
private BigDecimal estimatedHours;
|
||||
|
||||
/**
|
||||
* 截止时间(接单时计算)
|
||||
*/
|
||||
private LocalDateTime deadline;
|
||||
|
||||
/**
|
||||
* 接单人ID
|
||||
*/
|
||||
|
||||
@ -268,6 +268,7 @@ public interface TaskItemMapper extends BaseMapper<TaskItem> {
|
||||
"receiver_name = #{receiverName}, " +
|
||||
"receiver_dept_id = #{receiverDeptId}, " +
|
||||
"status = 'in_progress', " +
|
||||
"deadline = CASE WHEN #{deadline} IS NOT NULL THEN #{deadline} ELSE deadline END, " +
|
||||
"update_time = NOW() " +
|
||||
"WHERE id = #{itemId} " +
|
||||
"AND status = 'pending' " +
|
||||
@ -276,7 +277,8 @@ public interface TaskItemMapper extends BaseMapper<TaskItem> {
|
||||
int grabItem(@Param("itemId") Long itemId,
|
||||
@Param("receiverId") Long receiverId,
|
||||
@Param("receiverName") String receiverName,
|
||||
@Param("receiverDeptId") Long receiverDeptId);
|
||||
@Param("receiverDeptId") Long receiverDeptId,
|
||||
@Param("deadline") LocalDateTime deadline);
|
||||
|
||||
/**
|
||||
* 解锁子任务
|
||||
|
||||
@ -272,8 +272,17 @@ public class TaskItemService {
|
||||
throw new BusinessException(ResultCode.TASK_ALREADY_TAKEN, "该子任务已被接单");
|
||||
}
|
||||
|
||||
// 乐观锁抢单(同时设置接单部门ID)
|
||||
int result = taskItemMapper.grabItem(itemId, userId, user.getRealName(), user.getDeptId());
|
||||
// 计算deadline
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime deadline = null;
|
||||
if (item.getEstimatedHours() != null && item.getEstimatedHours().compareTo(java.math.BigDecimal.ZERO) > 0) {
|
||||
deadline = workHoursCalculator.calculateDeadline(now, item.getEstimatedHours());
|
||||
log.info("子任务deadline已计算:从接单时间 {} 开始,预估 {} 小时,截止时间 {}",
|
||||
now, item.getEstimatedHours(), deadline);
|
||||
}
|
||||
|
||||
// 乐观锁抢单(同时设置接单部门ID和deadline)
|
||||
int result = taskItemMapper.grabItem(itemId, userId, user.getRealName(), user.getDeptId(), deadline);
|
||||
if (result == 0) {
|
||||
throw new BusinessException(ResultCode.TASK_ALREADY_TAKEN, "抢单失败,该子任务可能已被他人接单");
|
||||
}
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
-- V13__add_task_item_deadline.sql
|
||||
|
||||
-- 添加子任务截止时间字段
|
||||
ALTER TABLE `task_item`
|
||||
ADD COLUMN `deadline` DATETIME NULL COMMENT '截止时间(接单时计算)' AFTER `estimated_hours`;
|
||||
@ -85,6 +85,7 @@ export interface TaskItem {
|
||||
unitScore: number
|
||||
totalScore: number
|
||||
estimatedHours?: number
|
||||
deadline?: string // 截止时间(接单时计算)
|
||||
receiverId?: number
|
||||
receiverName?: string
|
||||
status: string // locked/pending/in_progress/completed/rejected
|
||||
|
||||
@ -167,6 +167,7 @@ interface TaskItem {
|
||||
status: string
|
||||
createTime?: string
|
||||
estimatedHours?: number
|
||||
deadline?: string // 截止时间(接单时计算)
|
||||
}
|
||||
|
||||
interface Task {
|
||||
@ -340,18 +341,15 @@ const getSubTaskStatusClass = (status: string) => {
|
||||
return classMap[status] || ''
|
||||
}
|
||||
|
||||
// 计算子任务完成截止日期(从接单开始计算+预计完成需要的时间)
|
||||
// 获取子任务完成截止日期(使用后端返回的deadline字段)
|
||||
// 只有已接单或进行中的子任务才显示截止时间
|
||||
const getSubTaskDeadline = (subTask: TaskItem) => {
|
||||
// 只有进行中或已完成的子任务才显示截止时间
|
||||
if (subTask.status !== 'in_progress' && subTask.status !== 'completed') return null
|
||||
if (!subTask.createTime || !subTask.estimatedHours) return null
|
||||
// 从创建时间(接单时间)开始计算
|
||||
const startTime = dayjs(subTask.createTime)
|
||||
// 计算截止时间:创建时间 + 预计工时
|
||||
const deadline = startTime.add(subTask.estimatedHours, 'hour')
|
||||
// 格式化为"XX月XX日XX时"
|
||||
return deadline.format('MM月DD日HH时')
|
||||
// 直接使用后端返回的deadline字段
|
||||
if (!subTask.deadline) return null
|
||||
// 格式化为"XX月XX日HH时"
|
||||
return dayjs(subTask.deadline).format('MM月DD日HH时')
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -988,21 +988,16 @@ const estimatedTotalHours = computed(() => {
|
||||
return totalHours
|
||||
})
|
||||
|
||||
// 格式化时效显示
|
||||
// 格式化时效显示(基于工作时间配置)
|
||||
const formattedEstimatedTime = computed(() => {
|
||||
const hours = estimatedTotalHours.value
|
||||
if (hours === 0) return '--'
|
||||
|
||||
if (hours < 1) {
|
||||
return `${Math.round(hours * 60)}分钟`
|
||||
} else if (hours < 24) {
|
||||
const h = Math.floor(hours)
|
||||
const m = Math.round((hours - h) * 60)
|
||||
return m > 0 ? `${h}小时${m}分钟` : `${h}小时`
|
||||
} else {
|
||||
const days = Math.floor(hours / 24)
|
||||
const remainHours = Math.round(hours % 24)
|
||||
return remainHours > 0 ? `${days}天${remainHours}小时` : `${days}天`
|
||||
// 使用formatWorkHours函数来格式化(基于工作时间配置)
|
||||
return formatWorkHours(hours)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@ -2913,18 +2913,15 @@ const getSubTaskStatusText = (status: string | undefined) => {
|
||||
return statusMap[status || ''] || status || '未知'
|
||||
}
|
||||
|
||||
// 计算子任务完成截止日期(从接单开始计算+预计完成需要的时间)
|
||||
// 获取子任务完成截止日期(使用后端返回的deadline字段)
|
||||
// 只有已接单或进行中的子任务才显示截止时间
|
||||
const getSubTaskDeadline = (subTask: any) => {
|
||||
// 只有进行中或已完成的子任务才显示截止时间
|
||||
if (subTask.status !== 'in_progress' && subTask.status !== 'completed') return null
|
||||
if (!subTask.createTime || !subTask.estimatedHours) return null
|
||||
// 从创建时间(接单时间)开始计算
|
||||
const startTime = dayjs(subTask.createTime)
|
||||
// 计算截止时间:创建时间 + 预计工时
|
||||
const deadline = startTime.add(subTask.estimatedHours, 'hour')
|
||||
// 直接使用后端返回的deadline字段
|
||||
if (!subTask.deadline) return null
|
||||
// 格式化为"XX月XX日HH时"
|
||||
return deadline.format('MM月DD日HH时')
|
||||
return dayjs(subTask.deadline).format('MM月DD日HH时')
|
||||
}
|
||||
|
||||
// 展开/折叠任务子任务详情
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user