diff --git a/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsRequest.java b/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsRequest.java index e460f49827..eb1aa6f807 100644 --- a/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsRequest.java +++ b/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsRequest.java @@ -62,6 +62,16 @@ public class AgentSettingsRequest extends BaseSettingsRequest { */ private MessageLeaveSettingsRequest messageLeaveSettings; + /** + * Published worktime setting uid + */ + private String worktimeSettingUid; + + /** + * Draft worktime setting uid + */ + private String draftWorktimeSettingUid; + /** * Auto-reply settings (Agent-specific) */ diff --git a/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsResponse.java b/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsResponse.java index 98a943f565..f610ad5fe5 100644 --- a/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsResponse.java +++ b/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsResponse.java @@ -19,6 +19,7 @@ import com.bytedesk.kbase.settings_ratedown.RatedownSettingsResponse; import com.bytedesk.service.agent_status.settings.AgentStatusSettingResponse; import com.bytedesk.service.message_leave_settings.MessageLeaveSettingsResponse; import com.bytedesk.service.queue_settings.QueueSettingsResponse; +import com.bytedesk.service.worktime_settings.WorktimeSettingResponse; import lombok.AllArgsConstructor; import lombok.Data; @@ -66,6 +67,15 @@ public class AgentSettingsResponse extends BaseSettingsResponse { */ private MessageLeaveSettingsResponse draftMessageLeaveSettings; + /** + * Worktime settings reference (Agent-specific) + */ + private WorktimeSettingResponse worktimeSettings; + /** + * Draft worktime settings reference (Agent-specific) + */ + private WorktimeSettingResponse draftWorktimeSettings; + /** * Auto-reply settings (Agent-specific) */ diff --git a/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsRestService.java b/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsRestService.java index e6bd5b2126..912157bf36 100644 --- a/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsRestService.java +++ b/modules/service/src/main/java/com/bytedesk/service/agent_settings/AgentSettingsRestService.java @@ -28,6 +28,8 @@ import com.bytedesk.service.queue_settings.QueueSettingsEntity; import com.bytedesk.service.agent_status.settings.AgentStatusSettingEntity; import com.bytedesk.service.message_leave_settings.MessageLeaveSettingsEntity; import com.bytedesk.service.message_leave_settings.MessageLeaveSettingsHelper; +import com.bytedesk.service.worktime_settings.WorktimeSettingEntity; +import com.bytedesk.service.worktime_settings.WorktimeSettingRepository; import com.bytedesk.service.agent.AgentRepository; import lombok.AllArgsConstructor; @@ -53,6 +55,8 @@ public class AgentSettingsRestService private final MessageLeaveSettingsHelper messageLeaveSettingsHelper; + private final WorktimeSettingRepository worktimeSettingRepository; + @Cacheable(value = "agentSettings", key = "#uid", unless = "#result == null") @Override public Optional findByUid(String uid) { @@ -107,19 +111,20 @@ public class AgentSettingsRestService MessageLeaveSettingsEntity mls = MessageLeaveSettingsEntity.fromRequest(request.getMessageLeaveSettings(), modelMapper); mls.setUid(uidUtils.getUid()); - // 处理 MessageLeaveSettings 关联(工作时间段) - if (request.getMessageLeaveSettings() != null) { - messageLeaveSettingsHelper.updateWorktimesIfPresent(mls, request.getMessageLeaveSettings()); - } entity.setMessageLeaveSettings(mls); MessageLeaveSettingsEntity mlsDraft = MessageLeaveSettingsEntity.fromRequest(request.getMessageLeaveSettings(), modelMapper); mlsDraft.setUid(uidUtils.getUid()); - if (request.getMessageLeaveSettings() != null) { - messageLeaveSettingsHelper.updateWorktimesIfPresent(mlsDraft, request.getMessageLeaveSettings()); - } entity.setDraftMessageLeaveSettings(mlsDraft); + WorktimeSettingEntity publishedWorktime = resolveWorktimeSetting(request.getWorktimeSettingUid()); + entity.setWorktimeSettings(publishedWorktime); + WorktimeSettingEntity draftWorktime = resolveWorktimeSetting(request.getDraftWorktimeSettingUid()); + if (draftWorktime == null) { + draftWorktime = publishedWorktime; + } + entity.setDraftWorktimeSettings(draftWorktime); + AutoReplySettingsEntity ars = AutoReplySettingsEntity.fromRequest(request.getAutoReplySettings(), modelMapper); ars.setUid(uidUtils.getUid()); entity.setAutoReplySettings(ars); @@ -199,8 +204,15 @@ public class AgentSettingsRestService modelMapper.map(request.getMessageLeaveSettings(), draft); draft.setUid(originalUid); } - // 根据 request 中的 worktime uids 映射关联 - messageLeaveSettingsHelper.updateWorktimesIfPresent(draft, request.getMessageLeaveSettings()); + entity.setHasUnpublishedChanges(true); + } + + if (request.getWorktimeSettingUid() != null) { + entity.setWorktimeSettings(resolveWorktimeSetting(request.getWorktimeSettingUid())); + } + + if (request.getDraftWorktimeSettingUid() != null) { + entity.setDraftWorktimeSettings(resolveWorktimeSetting(request.getDraftWorktimeSettingUid())); entity.setHasUnpublishedChanges(true); } @@ -519,6 +531,10 @@ public class AgentSettingsRestService entity.setMessageLeaveSettings(newPublished); } } + + if (entity.getDraftWorktimeSettings() != null || entity.getWorktimeSettings() != entity.getDraftWorktimeSettings()) { + entity.setWorktimeSettings(entity.getDraftWorktimeSettings()); + } if (entity.getDraftAutoReplySettings() != null) { AutoReplySettingsEntity published = entity.getAutoReplySettings(); @@ -614,4 +630,13 @@ public class AgentSettingsRestService } else { messageLeaveSettingsHelper.copyPropertiesExcludingIds(source, target); } - }} + } + + private WorktimeSettingEntity resolveWorktimeSetting(String uid) { + if (uid == null || uid.isBlank()) { + return null; + } + return worktimeSettingRepository.findByUid(uid) + .orElseThrow(() -> new RuntimeException("WorktimeSetting not found by uid: " + uid)); + } +} diff --git a/modules/service/src/main/java/com/bytedesk/service/message_leave_settings/MessageLeaveSettingsEntity.java b/modules/service/src/main/java/com/bytedesk/service/message_leave_settings/MessageLeaveSettingsEntity.java index 82f5d423ee..48d6565281 100644 --- a/modules/service/src/main/java/com/bytedesk/service/message_leave_settings/MessageLeaveSettingsEntity.java +++ b/modules/service/src/main/java/com/bytedesk/service/message_leave_settings/MessageLeaveSettingsEntity.java @@ -44,7 +44,6 @@ import lombok.NoArgsConstructor; @NoArgsConstructor public class MessageLeaveSettingsEntity extends BaseEntity { - // 留言开关 @Builder.Default @Column(name = "is_leave_msg_enabled") private Boolean messageLeaveEnabled = true; diff --git a/modules/service/src/main/java/com/bytedesk/service/routing_strategy/WorkgroupThreadRoutingStrategy.java b/modules/service/src/main/java/com/bytedesk/service/routing_strategy/WorkgroupThreadRoutingStrategy.java index 26e77e86af..1b4a54a985 100644 --- a/modules/service/src/main/java/com/bytedesk/service/routing_strategy/WorkgroupThreadRoutingStrategy.java +++ b/modules/service/src/main/java/com/bytedesk/service/routing_strategy/WorkgroupThreadRoutingStrategy.java @@ -53,6 +53,7 @@ import com.bytedesk.service.utils.ServiceConvertUtils; import com.bytedesk.service.utils.ThreadMessageUtil; import com.bytedesk.service.visitor.VisitorRequest; import com.bytedesk.service.visitor_thread.VisitorThreadService; +import com.bytedesk.service.worktime_settings.WorktimeSettingEntity; import com.bytedesk.service.workgroup.WorkgroupEntity; import com.bytedesk.service.workgroup.WorkgroupRepository; import com.bytedesk.service.workgroup.WorkgroupRestService; @@ -326,10 +327,7 @@ public class WorkgroupThreadRoutingStrategy extends AbstractThreadRoutingStrateg // 检查机器人配置和服务时间 boolean isOffline = !presenceFacadeService.isWorkgroupOnline(workgroup); - boolean isInServiceTime = workgroup.getSettings() != null - && workgroup.getSettings().getMessageLeaveSettings() != null - ? workgroup.getSettings().getMessageLeaveSettings().isInServiceTime() - : true; + boolean isInServiceTime = resolveIsInServiceTime(workgroup); log.debug("路由决策参数 - 工作组离线状态: {}, 在服务时间内: {}", isOffline, isInServiceTime); @@ -384,10 +382,7 @@ public class WorkgroupThreadRoutingStrategy extends AbstractThreadRoutingStrateg thread.getUid(), workgroup.getUid()); // 检查是否在工作时间内 - boolean isInServiceTime = workgroup.getSettings() != null - && workgroup.getSettings().getMessageLeaveSettings() != null - ? workgroup.getSettings().getMessageLeaveSettings().isInServiceTime() - : true; + boolean isInServiceTime = resolveIsInServiceTime(workgroup); log.debug("服务时间检查 - 是否在服务时间内: {}", isInServiceTime); if (!isInServiceTime) { @@ -853,4 +848,19 @@ public class WorkgroupThreadRoutingStrategy extends AbstractThreadRoutingStrateg int maxThreadCount = agent.getMaxThreadCount(); return maxThreadCount > 0 ? maxThreadCount : 1; } + + private boolean resolveIsInServiceTime(WorkgroupEntity workgroup) { + if (workgroup == null || workgroup.getSettings() == null) { + return true; + } + WorktimeSettingEntity published = workgroup.getSettings().getWorktimeSettings(); + if (published != null) { + return Boolean.TRUE.equals(published.isInWorktime()); + } + WorktimeSettingEntity draft = workgroup.getSettings().getDraftWorktimeSettings(); + if (draft != null) { + return Boolean.TRUE.equals(draft.isInWorktime()); + } + return true; + } } diff --git a/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsRequest.java b/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsRequest.java index 2fbd2b71e7..cdc0957042 100644 --- a/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsRequest.java +++ b/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsRequest.java @@ -45,6 +45,16 @@ public class WorkgroupSettingsRequest extends BaseSettingsRequest { */ private MessageLeaveSettingsRequest messageLeaveSettings; + /** + * Published worktime setting uid + */ + private String worktimeSettingUid; + + /** + * Draft worktime setting uid + */ + private String draftWorktimeSettingUid; + /** * Robot routing settings (Workgroup-specific) */ diff --git a/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsResponse.java b/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsResponse.java index 6b8b842333..7e41dfec5c 100644 --- a/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsResponse.java +++ b/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsResponse.java @@ -17,6 +17,7 @@ import com.bytedesk.ai.robot.settings.RobotRoutingSettingsResponse; import com.bytedesk.kbase.settings.BaseSettingsResponse; import com.bytedesk.service.message_leave_settings.MessageLeaveSettingsResponse; import com.bytedesk.service.queue_settings.QueueSettingsResponse; +import com.bytedesk.service.worktime_settings.WorktimeSettingResponse; import lombok.AllArgsConstructor; import lombok.Data; @@ -49,6 +50,15 @@ public class WorkgroupSettingsResponse extends BaseSettingsResponse { */ private MessageLeaveSettingsResponse draftMessageLeaveSettings; + /** + * Worktime settings reference (Workgroup-specific) + */ + private WorktimeSettingResponse worktimeSettings; + /** + * Draft worktime settings reference (Workgroup-specific) + */ + private WorktimeSettingResponse draftWorktimeSettings; + /** * Robot routing settings (Workgroup-specific) */ diff --git a/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsRestService.java b/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsRestService.java index a219fe08af..e7d450be0c 100644 --- a/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsRestService.java +++ b/modules/service/src/main/java/com/bytedesk/service/workgroup_settings/WorkgroupSettingsRestService.java @@ -26,6 +26,8 @@ import com.bytedesk.kbase.settings_intention.IntentionSettingsEntity; import com.bytedesk.service.message_leave_settings.MessageLeaveSettingsEntity; import com.bytedesk.service.message_leave_settings.MessageLeaveSettingsHelper; import com.bytedesk.service.queue_settings.QueueSettingsEntity; +import com.bytedesk.service.worktime_settings.WorktimeSettingEntity; +import com.bytedesk.service.worktime_settings.WorktimeSettingRepository; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -48,6 +50,8 @@ public class WorkgroupSettingsRestService private final RobotRepository robotRepository; + private final WorktimeSettingRepository worktimeSettingRepository; + @Cacheable(value = "workgroupSettings", key = "#uid", unless = "#result == null") @Override public Optional findByUid(String uid) { @@ -94,6 +98,14 @@ public class WorkgroupSettingsRestService mlsDraft.setUid(uidUtils.getUid()); entity.setDraftMessageLeaveSettings(mlsDraft); + WorktimeSettingEntity publishedWorktime = resolveWorktimeSetting(request.getWorktimeSettingUid()); + entity.setWorktimeSettings(publishedWorktime); + WorktimeSettingEntity draftWorktime = resolveWorktimeSetting(request.getDraftWorktimeSettingUid()); + if (draftWorktime == null) { + draftWorktime = publishedWorktime; + } + entity.setDraftWorktimeSettings(draftWorktime); + // create 场景:不将 robotUid 解析成 RobotEntity,统一使用 Entity.fromRequest 风格 RobotRoutingSettingsEntity rrs = RobotRoutingSettingsEntity.fromRequest(request.getRobotRoutingSettings()); rrs.setUid(uidUtils.getUid()); @@ -199,6 +211,15 @@ public class WorkgroupSettingsRestService entity.setHasUnpublishedChanges(true); } + if (request.getWorktimeSettingUid() != null) { + entity.setWorktimeSettings(resolveWorktimeSetting(request.getWorktimeSettingUid())); + } + + if (request.getDraftWorktimeSettingUid() != null) { + entity.setDraftWorktimeSettings(resolveWorktimeSetting(request.getDraftWorktimeSettingUid())); + entity.setHasUnpublishedChanges(true); + } + if (request.getRobotRoutingSettings() != null) { RobotRoutingSettingsEntity draft = entity.getDraftRobotSettings(); if (draft == null) { @@ -403,6 +424,10 @@ public class WorkgroupSettingsRestService } } + if (entity.getDraftWorktimeSettings() != null || entity.getWorktimeSettings() != entity.getDraftWorktimeSettings()) { + entity.setWorktimeSettings(entity.getDraftWorktimeSettings()); + } + if (entity.getDraftRobotSettings() != null) { RobotRoutingSettingsEntity published = entity.getRobotSettings(); if (published != null) { @@ -490,6 +515,14 @@ public class WorkgroupSettingsRestService target.setRobot(robot); } + private WorktimeSettingEntity resolveWorktimeSetting(String uid) { + if (uid == null || uid.isBlank()) { + return null; + } + return worktimeSettingRepository.findByUid(uid) + .orElseThrow(() -> new RuntimeException("WorktimeSetting not found by uid: " + uid)); + } + @Override public WorkgroupSettingsResponse convertToResponse(WorkgroupSettingsEntity entity) { // 注意:Entity 与 Response 的字段命名不一致: diff --git a/modules/service/src/main/java/com/bytedesk/service/worktime_settings/WorktimeSettingEntity.java b/modules/service/src/main/java/com/bytedesk/service/worktime_settings/WorktimeSettingEntity.java index bb5bcf1e12..181f346358 100644 --- a/modules/service/src/main/java/com/bytedesk/service/worktime_settings/WorktimeSettingEntity.java +++ b/modules/service/src/main/java/com/bytedesk/service/worktime_settings/WorktimeSettingEntity.java @@ -17,8 +17,6 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import com.bytedesk.core.base.BaseEntity; -import com.bytedesk.core.constant.BytedeskConsts; -import com.bytedesk.core.constant.I18Consts; import com.bytedesk.service.worktime.WorktimeEntity; import jakarta.persistence.CascadeType; @@ -48,11 +46,6 @@ public class WorktimeSettingEntity extends BaseEntity { private static final long serialVersionUID = 1L; - private String name; - - @Builder.Default - private String description = I18Consts.I18N_DESCRIPTION; - // 工作时间设置是否启用 @Builder.Default private Boolean enabled = true; @@ -72,26 +65,6 @@ public class WorktimeSettingEntity extends BaseEntity { @Column(columnDefinition = "text") private String holidays = "{}"; - // 非工作时间是否启用机器人 - @Builder.Default - private Boolean nonWorktimeRobotEnabled = true; - - // 非工作时间是否启用留言功能 - @Builder.Default - private Boolean nonWorktimeLeaveMessageEnabled = true; - - // 工作时间通知设置 - @Builder.Default - private Boolean worktimeNotificationEnabled = false; - - // 工作时间通知方式(邮件、短信、企业微信等) - @Builder.Default - private String worktimeNotificationType = "EMAIL"; - - // 工作时间通知接收人 - @Builder.Default - private String worktimeNotificationRecipients = BytedeskConsts.EMPTY_STRING; - /** * 检查当前时间是否在工作时间内 * diff --git a/modules/service/src/main/java/com/bytedesk/service/worktime_settings/WorktimeSettingRestService.java b/modules/service/src/main/java/com/bytedesk/service/worktime_settings/WorktimeSettingRestService.java index 374c1f71fd..88b465905f 100644 --- a/modules/service/src/main/java/com/bytedesk/service/worktime_settings/WorktimeSettingRestService.java +++ b/modules/service/src/main/java/com/bytedesk/service/worktime_settings/WorktimeSettingRestService.java @@ -107,7 +107,7 @@ public class WorktimeSettingRestService extends BaseRestServiceWithExport