Procházet zdrojové kódy

Merge remote-tracking branch 'origin/master'

jiuling před 4 dny
rodič
revize
129d910b00
86 změnil soubory, kde provedl 8978 přidání a 67 odebrání
  1. 5 2
      ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
  2. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/AlarmLogController.java
  3. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/DialogueLogController.java
  4. 106 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsAppointmentRecordController.java
  5. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsBroadcastContentController.java
  6. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsBroadcastTaskController.java
  7. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsFaqController.java
  8. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsFaqSimilarController.java
  9. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsMediaAssetController.java
  10. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsPlayPlanController.java
  11. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsScreenThemeConfigController.java
  12. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsSysLogController.java
  13. 105 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsVisitorRecordController.java
  14. 104 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsWhitelistController.java
  15. 191 51
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
  16. 1 1
      ruoyi-admin/src/main/resources/application.yml
  17. 10 3
      ruoyi-common/pom.xml
  18. 188 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/ThumbnailUtils.java
  19. 262 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/VideoUtils.java
  20. 29 10
      ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
  21. 223 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/AlarmLog.java
  22. 218 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/DialogueLog.java
  23. 165 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsAppointmentRecord.java
  24. 100 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsBroadcastContent.java
  25. 160 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsBroadcastTask.java
  26. 147 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsFaq.java
  27. 81 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsFaqSimilar.java
  28. 206 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsMediaAsset.java
  29. 120 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsPlayPlan.java
  30. 209 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsPlayPlanItem.java
  31. 177 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsScreenThemeConfig.java
  32. 193 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsSysLog.java
  33. 208 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsVisitorRecord.java
  34. 179 0
      ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsWhitelist.java
  35. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/AlarmLogMapper.java
  36. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/DialogueLogMapper.java
  37. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsAppointmentRecordMapper.java
  38. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsBroadcastContentMapper.java
  39. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsBroadcastTaskMapper.java
  40. 87 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsFaqMapper.java
  41. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsFaqSimilarMapper.java
  42. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsMediaAssetMapper.java
  43. 114 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsPlayPlanMapper.java
  44. 69 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsScreenThemeConfigMapper.java
  45. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsSysLogMapper.java
  46. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsVisitorRecordMapper.java
  47. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsWhitelistMapper.java
  48. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IAlarmLogService.java
  49. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IDialogueLogService.java
  50. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsAppointmentRecordService.java
  51. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsBroadcastContentService.java
  52. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsBroadcastTaskService.java
  53. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsFaqService.java
  54. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsFaqSimilarService.java
  55. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsMediaAssetService.java
  56. 68 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsPlayPlanService.java
  57. 69 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsScreenThemeConfigService.java
  58. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsSysLogService.java
  59. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsVisitorRecordService.java
  60. 61 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsWhitelistService.java
  61. 95 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/AlarmLogServiceImpl.java
  62. 95 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/DialogueLogServiceImpl.java
  63. 96 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsAppointmentRecordServiceImpl.java
  64. 96 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsBroadcastContentServiceImpl.java
  65. 96 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsBroadcastTaskServiceImpl.java
  66. 134 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsFaqServiceImpl.java
  67. 93 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsFaqSimilarServiceImpl.java
  68. 96 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsMediaAssetServiceImpl.java
  69. 169 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsPlayPlanServiceImpl.java
  70. 108 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsScreenThemeConfigServiceImpl.java
  71. 95 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsSysLogServiceImpl.java
  72. 96 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsVisitorRecordServiceImpl.java
  73. 96 0
      ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsWhitelistServiceImpl.java
  74. 119 0
      ruoyi-system/src/main/resources/mapper/base/AlarmLogMapper.xml
  75. 115 0
      ruoyi-system/src/main/resources/mapper/base/DialogueLogMapper.xml
  76. 109 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsAppointmentRecordMapper.xml
  77. 83 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsBroadcastContentMapper.xml
  78. 103 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsBroadcastTaskMapper.xml
  79. 138 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsFaqMapper.xml
  80. 74 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsFaqSimilarMapper.xml
  81. 126 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsMediaAssetMapper.xml
  82. 168 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsPlayPlanMapper.xml
  83. 122 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsScreenThemeConfigMapper.xml
  84. 109 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsSysLogMapper.xml
  85. 124 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsVisitorRecordMapper.xml
  86. 108 0
      ruoyi-system/src/main/resources/mapper/base/RobotOpsWhitelistMapper.xml

+ 5 - 2
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java

@@ -3,20 +3,23 @@ package com.ruoyi;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
 
 /**
  * 启动程序
  *
  * @author ruoyi
  */
-@SpringBootApplication
+
+@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }, scanBasePackages = { "com.ruoyi.*", "com.test.*" })
 @MapperScan("com.ruoyi.**.mapper")
 public class RuoYiApplication
 {
     public static void main(String[] args)
     {
         SpringApplication.run(RuoYiApplication.class, args);
-        System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)号楼  \n" +
+        System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)  \n" +
                 " .-------.       ____     __        \n" +
                 " |  _ _   \\      \\   \\   /  /    \n" +
                 " | ( ' )  |       \\  _. /  '       \n" +

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/AlarmLogController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.AlarmLog;
+import com.ruoyi.base.service.IAlarmLogService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 安防告警日志Controller
+ *
+ * @author ruoyi
+ * @date 2026-05-20
+ */
+@RestController
+@RequestMapping("/base/alarmLog")
+public class AlarmLogController extends BaseController
+{
+    @Autowired
+    private IAlarmLogService alarmLogService;
+
+    /**
+     * 查询安防告警日志列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:alarmLog:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(AlarmLog alarmLog)
+    {
+        startPage();
+        List<AlarmLog> list = alarmLogService.selectAlarmLogList(alarmLog);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出安防告警日志列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:alarmLog:export')")
+    @Log(title = "安防告警日志", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, AlarmLog alarmLog)
+    {
+        List<AlarmLog> list = alarmLogService.selectAlarmLogList(alarmLog);
+        ExcelUtil<AlarmLog> util = new ExcelUtil<AlarmLog>(AlarmLog.class);
+        util.exportExcel(response, list, "安防告警日志数据");
+    }
+
+    /**
+     * 获取安防告警日志详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:alarmLog:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(alarmLogService.selectAlarmLogById(id));
+    }
+
+    /**
+     * 新增安防告警日志
+     */
+    @PreAuthorize("@ss.hasPermi('base:alarmLog:add')")
+    @Log(title = "安防告警日志", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody AlarmLog alarmLog)
+    {
+        return toAjax(alarmLogService.insertAlarmLog(alarmLog));
+    }
+
+    /**
+     * 修改安防告警日志
+     */
+    @PreAuthorize("@ss.hasPermi('base:alarmLog:edit')")
+    @Log(title = "安防告警日志", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody AlarmLog alarmLog)
+    {
+        return toAjax(alarmLogService.updateAlarmLog(alarmLog));
+    }
+
+    /**
+     * 删除安防告警日志
+     */
+    @PreAuthorize("@ss.hasPermi('base:alarmLog:remove')")
+    @Log(title = "安防告警日志", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(alarmLogService.deleteAlarmLogByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/DialogueLogController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.DialogueLog;
+import com.ruoyi.base.service.IDialogueLogService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 对话日志Controller
+ *
+ * @author ruoyi
+ * @date 2026-05-19
+ */
+@RestController
+@RequestMapping("/base/dialogueLog")
+public class DialogueLogController extends BaseController
+{
+    @Autowired
+    private IDialogueLogService dialogueLogService;
+
+    /**
+     * 查询对话日志列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:dialogueLog:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(DialogueLog dialogueLog)
+    {
+        startPage();
+        List<DialogueLog> list = dialogueLogService.selectDialogueLogList(dialogueLog);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出对话日志列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:dialogueLog:export')")
+    @Log(title = "对话日志", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, DialogueLog dialogueLog)
+    {
+        List<DialogueLog> list = dialogueLogService.selectDialogueLogList(dialogueLog);
+        ExcelUtil<DialogueLog> util = new ExcelUtil<DialogueLog>(DialogueLog.class);
+        util.exportExcel(response, list, "对话日志数据");
+    }
+
+    /**
+     * 获取对话日志详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:dialogueLog:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(dialogueLogService.selectDialogueLogById(id));
+    }
+
+    /**
+     * 新增对话日志
+     */
+    @PreAuthorize("@ss.hasPermi('base:dialogueLog:add')")
+    @Log(title = "对话日志", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody DialogueLog dialogueLog)
+    {
+        return toAjax(dialogueLogService.insertDialogueLog(dialogueLog));
+    }
+
+    /**
+     * 修改对话日志
+     */
+    @PreAuthorize("@ss.hasPermi('base:dialogueLog:edit')")
+    @Log(title = "对话日志", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody DialogueLog dialogueLog)
+    {
+        return toAjax(dialogueLogService.updateDialogueLog(dialogueLog));
+    }
+
+    /**
+     * 删除对话日志
+     */
+    @PreAuthorize("@ss.hasPermi('base:dialogueLog:remove')")
+    @Log(title = "对话日志", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(dialogueLogService.deleteDialogueLogByIds(ids));
+    }
+}

+ 106 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsAppointmentRecordController.java

@@ -0,0 +1,106 @@
+package com.ruoyi.web.controller.base;
+
+import com.ruoyi.base.domain.RobotOpsAppointmentRecord;
+import com.ruoyi.base.service.IRobotOpsAppointmentRecordService;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 访客预约记录Controller
+ *
+ * @author ruoyi
+ * @date 2026-04-28
+ */
+@RestController
+@RequestMapping("/base/appointmentRecord")
+public class RobotOpsAppointmentRecordController extends BaseController
+{
+    @Autowired
+    private IRobotOpsAppointmentRecordService robotOpsAppointmentRecordService;
+
+    /**
+     * 查询访客预约记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:appointmentRecord:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsAppointmentRecord robotOpsAppointmentRecord,
+                              @RequestParam(required = false) String appointmentTimeStart,
+                              @RequestParam(required = false) String appointmentTimeEnd)
+    {
+        startPage();
+        if (appointmentTimeStart != null && !appointmentTimeStart.isEmpty()) {
+            robotOpsAppointmentRecord.getParams().put("beginTime", appointmentTimeStart);
+        }
+        if (appointmentTimeEnd != null && !appointmentTimeEnd.isEmpty()) {
+            robotOpsAppointmentRecord.getParams().put("endTime", appointmentTimeEnd);
+        }
+        List<RobotOpsAppointmentRecord> list = robotOpsAppointmentRecordService.selectRobotOpsAppointmentRecordList(robotOpsAppointmentRecord);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出访客预约记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:appointmentRecord:export')")
+    @Log(title = "访客预约记录", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsAppointmentRecord robotOpsAppointmentRecord)
+    {
+        List<RobotOpsAppointmentRecord> list = robotOpsAppointmentRecordService.selectRobotOpsAppointmentRecordList(robotOpsAppointmentRecord);
+        ExcelUtil<RobotOpsAppointmentRecord> util = new ExcelUtil<RobotOpsAppointmentRecord>(RobotOpsAppointmentRecord.class);
+        util.exportExcel(response, list, "访客预约记录数据");
+    }
+
+    /**
+     * 获取访客预约记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:appointmentRecord:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsAppointmentRecordService.selectRobotOpsAppointmentRecordById(id));
+    }
+
+    /**
+     * 新增访客预约记录
+     */
+    @PreAuthorize("@ss.hasPermi('base:appointmentRecord:add')")
+    @Log(title = "访客预约记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsAppointmentRecord robotOpsAppointmentRecord)
+    {
+        return toAjax(robotOpsAppointmentRecordService.insertRobotOpsAppointmentRecord(robotOpsAppointmentRecord));
+    }
+
+    /**
+     * 修改访客预约记录
+     */
+    @PreAuthorize("@ss.hasPermi('base:appointmentRecord:edit')")
+    @Log(title = "访客预约记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsAppointmentRecord robotOpsAppointmentRecord)
+    {
+        return toAjax(robotOpsAppointmentRecordService.updateRobotOpsAppointmentRecord(robotOpsAppointmentRecord));
+    }
+
+    /**
+     * 删除访客预约记录
+     */
+    @PreAuthorize("@ss.hasPermi('base:appointmentRecord:remove')")
+    @Log(title = "访客预约记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsAppointmentRecordService.deleteRobotOpsAppointmentRecordByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsBroadcastContentController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.RobotOpsBroadcastContent;
+import com.ruoyi.base.service.IRobotOpsBroadcastContentService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 播报内容Controller
+ *
+ * @author ruoyi
+ * @date 2026-04-27
+ */
+@RestController
+@RequestMapping("/base/broadcastContent")
+public class RobotOpsBroadcastContentController extends BaseController
+{
+    @Autowired
+    private IRobotOpsBroadcastContentService robotOpsBroadcastContentService;
+
+    /**
+     * 查询播报内容列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastContent:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsBroadcastContent robotOpsBroadcastContent)
+    {
+        startPage();
+        List<RobotOpsBroadcastContent> list = robotOpsBroadcastContentService.selectRobotOpsBroadcastContentList(robotOpsBroadcastContent);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出播报内容列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastContent:export')")
+    @Log(title = "播报内容", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsBroadcastContent robotOpsBroadcastContent)
+    {
+        List<RobotOpsBroadcastContent> list = robotOpsBroadcastContentService.selectRobotOpsBroadcastContentList(robotOpsBroadcastContent);
+        ExcelUtil<RobotOpsBroadcastContent> util = new ExcelUtil<RobotOpsBroadcastContent>(RobotOpsBroadcastContent.class);
+        util.exportExcel(response, list, "播报内容数据");
+    }
+
+    /**
+     * 获取播报内容详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastContent:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsBroadcastContentService.selectRobotOpsBroadcastContentById(id));
+    }
+
+    /**
+     * 新增播报内容
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastContent:add')")
+    @Log(title = "播报内容", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsBroadcastContent robotOpsBroadcastContent)
+    {
+        return toAjax(robotOpsBroadcastContentService.insertRobotOpsBroadcastContent(robotOpsBroadcastContent));
+    }
+
+    /**
+     * 修改播报内容
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastContent:edit')")
+    @Log(title = "播报内容", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsBroadcastContent robotOpsBroadcastContent)
+    {
+        return toAjax(robotOpsBroadcastContentService.updateRobotOpsBroadcastContent(robotOpsBroadcastContent));
+    }
+
+    /**
+     * 删除播报内容
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastContent:remove')")
+    @Log(title = "播报内容", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsBroadcastContentService.deleteRobotOpsBroadcastContentByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsBroadcastTaskController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.RobotOpsBroadcastTask;
+import com.ruoyi.base.service.IRobotOpsBroadcastTaskService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 播报任务Controller
+ *
+ * @author ruoyi
+ * @date 2026-04-27
+ */
+@RestController
+@RequestMapping("/base/broadcastTask")
+public class RobotOpsBroadcastTaskController extends BaseController
+{
+    @Autowired
+    private IRobotOpsBroadcastTaskService robotOpsBroadcastTaskService;
+
+    /**
+     * 查询播报任务列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastTask:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsBroadcastTask robotOpsBroadcastTask)
+    {
+        startPage();
+        List<RobotOpsBroadcastTask> list = robotOpsBroadcastTaskService.selectRobotOpsBroadcastTaskList(robotOpsBroadcastTask);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出播报任务列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastTask:export')")
+    @Log(title = "播报任务", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsBroadcastTask robotOpsBroadcastTask)
+    {
+        List<RobotOpsBroadcastTask> list = robotOpsBroadcastTaskService.selectRobotOpsBroadcastTaskList(robotOpsBroadcastTask);
+        ExcelUtil<RobotOpsBroadcastTask> util = new ExcelUtil<RobotOpsBroadcastTask>(RobotOpsBroadcastTask.class);
+        util.exportExcel(response, list, "播报任务数据");
+    }
+
+    /**
+     * 获取播报任务详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastTask:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsBroadcastTaskService.selectRobotOpsBroadcastTaskById(id));
+    }
+
+    /**
+     * 新增播报任务
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastTask:add')")
+    @Log(title = "播报任务", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsBroadcastTask robotOpsBroadcastTask)
+    {
+        return toAjax(robotOpsBroadcastTaskService.insertRobotOpsBroadcastTask(robotOpsBroadcastTask));
+    }
+
+    /**
+     * 修改播报任务
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastTask:edit')")
+    @Log(title = "播报任务", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsBroadcastTask robotOpsBroadcastTask)
+    {
+        return toAjax(robotOpsBroadcastTaskService.updateRobotOpsBroadcastTask(robotOpsBroadcastTask));
+    }
+
+    /**
+     * 删除播报任务
+     */
+    @PreAuthorize("@ss.hasPermi('base:broadcastTask:remove')")
+    @Log(title = "播报任务", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsBroadcastTaskService.deleteRobotOpsBroadcastTaskByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsFaqController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.RobotOpsFaq;
+import com.ruoyi.base.service.IRobotOpsFaqService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 问答库管理Controller
+ *
+ * @author ruoyi
+ * @date 2026-05-07
+ */
+@RestController
+@RequestMapping("/base/faq")
+public class RobotOpsFaqController extends BaseController
+{
+    @Autowired
+    private IRobotOpsFaqService robotOpsFaqService;
+
+    /**
+     * 查询问答库管理列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:faq:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsFaq robotOpsFaq)
+    {
+        startPage();
+        List<RobotOpsFaq> list = robotOpsFaqService.selectRobotOpsFaqList(robotOpsFaq);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出问答库管理列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:faq:export')")
+    @Log(title = "问答库管理", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsFaq robotOpsFaq)
+    {
+        List<RobotOpsFaq> list = robotOpsFaqService.selectRobotOpsFaqList(robotOpsFaq);
+        ExcelUtil<RobotOpsFaq> util = new ExcelUtil<RobotOpsFaq>(RobotOpsFaq.class);
+        util.exportExcel(response, list, "问答库管理数据");
+    }
+
+    /**
+     * 获取问答库管理详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:faq:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsFaqService.selectRobotOpsFaqById(id));
+    }
+
+    /**
+     * 新增问答库管理
+     */
+    @PreAuthorize("@ss.hasPermi('base:faq:add')")
+    @Log(title = "问答库管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsFaq robotOpsFaq)
+    {
+        return toAjax(robotOpsFaqService.insertRobotOpsFaq(robotOpsFaq));
+    }
+
+    /**
+     * 修改问答库管理
+     */
+    @PreAuthorize("@ss.hasPermi('base:faq:edit')")
+    @Log(title = "问答库管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsFaq robotOpsFaq)
+    {
+        return toAjax(robotOpsFaqService.updateRobotOpsFaq(robotOpsFaq));
+    }
+
+    /**
+     * 删除问答库管理
+     */
+    @PreAuthorize("@ss.hasPermi('base:faq:remove')")
+    @Log(title = "问答库管理", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsFaqService.deleteRobotOpsFaqByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsFaqSimilarController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.RobotOpsFaqSimilar;
+import com.ruoyi.base.service.IRobotOpsFaqSimilarService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 相似问答表Controller
+ *
+ * @author ruoyi
+ * @date 2026-05-07
+ */
+@RestController
+@RequestMapping("/base/similar")
+public class RobotOpsFaqSimilarController extends BaseController
+{
+    @Autowired
+    private IRobotOpsFaqSimilarService robotOpsFaqSimilarService;
+
+    /**
+     * 查询相似问答表列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:similar:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsFaqSimilar robotOpsFaqSimilar)
+    {
+        startPage();
+        List<RobotOpsFaqSimilar> list = robotOpsFaqSimilarService.selectRobotOpsFaqSimilarList(robotOpsFaqSimilar);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出相似问答表列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:similar:export')")
+    @Log(title = "相似问答表", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsFaqSimilar robotOpsFaqSimilar)
+    {
+        List<RobotOpsFaqSimilar> list = robotOpsFaqSimilarService.selectRobotOpsFaqSimilarList(robotOpsFaqSimilar);
+        ExcelUtil<RobotOpsFaqSimilar> util = new ExcelUtil<RobotOpsFaqSimilar>(RobotOpsFaqSimilar.class);
+        util.exportExcel(response, list, "相似问答表数据");
+    }
+
+    /**
+     * 获取相似问答表详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:similar:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsFaqSimilarService.selectRobotOpsFaqSimilarById(id));
+    }
+
+    /**
+     * 新增相似问答表
+     */
+    @PreAuthorize("@ss.hasPermi('base:similar:add')")
+    @Log(title = "相似问答表", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsFaqSimilar robotOpsFaqSimilar)
+    {
+        return toAjax(robotOpsFaqSimilarService.insertRobotOpsFaqSimilar(robotOpsFaqSimilar));
+    }
+
+    /**
+     * 修改相似问答表
+     */
+    @PreAuthorize("@ss.hasPermi('base:similar:edit')")
+    @Log(title = "相似问答表", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsFaqSimilar robotOpsFaqSimilar)
+    {
+        return toAjax(robotOpsFaqSimilarService.updateRobotOpsFaqSimilar(robotOpsFaqSimilar));
+    }
+
+    /**
+     * 删除相似问答表
+     */
+    @PreAuthorize("@ss.hasPermi('base:similar:remove')")
+    @Log(title = "相似问答表", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsFaqSimilarService.deleteRobotOpsFaqSimilarByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsMediaAssetController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.RobotOpsMediaAsset;
+import com.ruoyi.base.service.IRobotOpsMediaAssetService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 素材资源Controller
+ *
+ * @author ruoyi
+ * @date 2026-05-08
+ */
+@RestController
+@RequestMapping("/base/mediAasset")
+public class RobotOpsMediaAssetController extends BaseController
+{
+    @Autowired
+    private IRobotOpsMediaAssetService robotOpsMediaAssetService;
+
+    /**
+     * 查询素材资源列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:mediAasset:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsMediaAsset robotOpsMediaAsset)
+    {
+        startPage();
+        List<RobotOpsMediaAsset> list = robotOpsMediaAssetService.selectRobotOpsMediaAssetList(robotOpsMediaAsset);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出素材资源列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:mediAasset:export')")
+    @Log(title = "素材资源", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsMediaAsset robotOpsMediaAsset)
+    {
+        List<RobotOpsMediaAsset> list = robotOpsMediaAssetService.selectRobotOpsMediaAssetList(robotOpsMediaAsset);
+        ExcelUtil<RobotOpsMediaAsset> util = new ExcelUtil<RobotOpsMediaAsset>(RobotOpsMediaAsset.class);
+        util.exportExcel(response, list, "素材资源数据");
+    }
+
+    /**
+     * 获取素材资源详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:mediAasset:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsMediaAssetService.selectRobotOpsMediaAssetById(id));
+    }
+
+    /**
+     * 新增素材资源
+     */
+    @PreAuthorize("@ss.hasPermi('base:mediAasset:add')")
+    @Log(title = "素材资源", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsMediaAsset robotOpsMediaAsset)
+    {
+        return toAjax(robotOpsMediaAssetService.insertRobotOpsMediaAsset(robotOpsMediaAsset));
+    }
+
+    /**
+     * 修改素材资源
+     */
+    @PreAuthorize("@ss.hasPermi('base:mediAasset:edit')")
+    @Log(title = "素材资源", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsMediaAsset robotOpsMediaAsset)
+    {
+        return toAjax(robotOpsMediaAssetService.updateRobotOpsMediaAsset(robotOpsMediaAsset));
+    }
+
+    /**
+     * 删除素材资源
+     */
+    @PreAuthorize("@ss.hasPermi('base:mediAasset:remove')")
+    @Log(title = "素材资源", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsMediaAssetService.deleteRobotOpsMediaAssetByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsPlayPlanController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.RobotOpsPlayPlan;
+import com.ruoyi.base.service.IRobotOpsPlayPlanService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 播放方案Controller
+ *
+ * @author ruoyi
+ * @date 2026-05-11
+ */
+@RestController
+@RequestMapping("/base/plan")
+public class RobotOpsPlayPlanController extends BaseController
+{
+    @Autowired
+    private IRobotOpsPlayPlanService robotOpsPlayPlanService;
+
+    /**
+     * 查询播放方案列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:plan:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsPlayPlan robotOpsPlayPlan)
+    {
+        startPage();
+        List<RobotOpsPlayPlan> list = robotOpsPlayPlanService.selectRobotOpsPlayPlanList(robotOpsPlayPlan);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出播放方案列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:plan:export')")
+    @Log(title = "播放方案", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsPlayPlan robotOpsPlayPlan)
+    {
+        List<RobotOpsPlayPlan> list = robotOpsPlayPlanService.selectRobotOpsPlayPlanList(robotOpsPlayPlan);
+        ExcelUtil<RobotOpsPlayPlan> util = new ExcelUtil<RobotOpsPlayPlan>(RobotOpsPlayPlan.class);
+        util.exportExcel(response, list, "播放方案数据");
+    }
+
+    /**
+     * 获取播放方案详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:plan:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsPlayPlanService.selectRobotOpsPlayPlanById(id));
+    }
+
+    /**
+     * 新增播放方案
+     */
+    @PreAuthorize("@ss.hasPermi('base:plan:add')")
+    @Log(title = "播放方案", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsPlayPlan robotOpsPlayPlan)
+    {
+        return toAjax(robotOpsPlayPlanService.insertRobotOpsPlayPlan(robotOpsPlayPlan));
+    }
+
+    /**
+     * 修改播放方案
+     */
+    @PreAuthorize("@ss.hasPermi('base:plan:edit')")
+    @Log(title = "播放方案", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsPlayPlan robotOpsPlayPlan)
+    {
+        return toAjax(robotOpsPlayPlanService.updateRobotOpsPlayPlan(robotOpsPlayPlan));
+    }
+
+    /**
+     * 删除播放方案
+     */
+    @PreAuthorize("@ss.hasPermi('base:plan:remove')")
+    @Log(title = "播放方案", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsPlayPlanService.deleteRobotOpsPlayPlanByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsScreenThemeConfigController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.RobotOpsScreenThemeConfig;
+import com.ruoyi.base.service.IRobotOpsScreenThemeConfigService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 展示主题配置Controller
+ *
+ * @author ruoyi
+ * @date 2026-05-14
+ */
+@RestController
+@RequestMapping("/base/opsScreenThemeConfig")
+public class RobotOpsScreenThemeConfigController extends BaseController
+{
+    @Autowired
+    private IRobotOpsScreenThemeConfigService robotOpsScreenThemeConfigService;
+
+    /**
+     * 查询展示主题配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:opsScreenThemeConfig:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsScreenThemeConfig robotOpsScreenThemeConfig)
+    {
+        startPage();
+        List<RobotOpsScreenThemeConfig> list = robotOpsScreenThemeConfigService.selectRobotOpsScreenThemeConfigList(robotOpsScreenThemeConfig);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出展示主题配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:opsScreenThemeConfig:export')")
+    @Log(title = "展示主题配置", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsScreenThemeConfig robotOpsScreenThemeConfig)
+    {
+        List<RobotOpsScreenThemeConfig> list = robotOpsScreenThemeConfigService.selectRobotOpsScreenThemeConfigList(robotOpsScreenThemeConfig);
+        ExcelUtil<RobotOpsScreenThemeConfig> util = new ExcelUtil<RobotOpsScreenThemeConfig>(RobotOpsScreenThemeConfig.class);
+        util.exportExcel(response, list, "展示主题配置数据");
+    }
+
+    /**
+     * 获取展示主题配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:opsScreenThemeConfig:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsScreenThemeConfigService.selectRobotOpsScreenThemeConfigById(id));
+    }
+
+    /**
+     * 新增展示主题配置
+     */
+    @PreAuthorize("@ss.hasPermi('base:opsScreenThemeConfig:add')")
+    @Log(title = "展示主题配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsScreenThemeConfig robotOpsScreenThemeConfig)
+    {
+        return toAjax(robotOpsScreenThemeConfigService.insertRobotOpsScreenThemeConfig(robotOpsScreenThemeConfig));
+    }
+
+    /**
+     * 修改展示主题配置
+     */
+    @PreAuthorize("@ss.hasPermi('base:opsScreenThemeConfig:edit')")
+    @Log(title = "展示主题配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsScreenThemeConfig robotOpsScreenThemeConfig)
+    {
+        return toAjax(robotOpsScreenThemeConfigService.updateRobotOpsScreenThemeConfig(robotOpsScreenThemeConfig));
+    }
+
+    /**
+     * 删除展示主题配置
+     */
+    @PreAuthorize("@ss.hasPermi('base:opsScreenThemeConfig:remove')")
+    @Log(title = "展示主题配置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsScreenThemeConfigService.deleteRobotOpsScreenThemeConfigByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsSysLogController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.RobotOpsSysLog;
+import com.ruoyi.base.service.IRobotOpsSysLogService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 运行日志Controller
+ *
+ * @author ruoyi
+ * @date 2026-05-18
+ */
+@RestController
+@RequestMapping("/base/sysLog")
+public class RobotOpsSysLogController extends BaseController
+{
+    @Autowired
+    private IRobotOpsSysLogService robotOpsSysLogService;
+
+    /**
+     * 查询运行日志列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:sysLog:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsSysLog robotOpsSysLog)
+    {
+        startPage();
+        List<RobotOpsSysLog> list = robotOpsSysLogService.selectRobotOpsSysLogList(robotOpsSysLog);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出运行日志列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:sysLog:export')")
+    @Log(title = "运行日志", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsSysLog robotOpsSysLog)
+    {
+        List<RobotOpsSysLog> list = robotOpsSysLogService.selectRobotOpsSysLogList(robotOpsSysLog);
+        ExcelUtil<RobotOpsSysLog> util = new ExcelUtil<RobotOpsSysLog>(RobotOpsSysLog.class);
+        util.exportExcel(response, list, "运行日志数据");
+    }
+
+    /**
+     * 获取运行日志详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:sysLog:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsSysLogService.selectRobotOpsSysLogById(id));
+    }
+
+    /**
+     * 新增运行日志
+     */
+    @PreAuthorize("@ss.hasPermi('base:sysLog:add')")
+    @Log(title = "运行日志", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsSysLog robotOpsSysLog)
+    {
+        return toAjax(robotOpsSysLogService.insertRobotOpsSysLog(robotOpsSysLog));
+    }
+
+    /**
+     * 修改运行日志
+     */
+    @PreAuthorize("@ss.hasPermi('base:sysLog:edit')")
+    @Log(title = "运行日志", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsSysLog robotOpsSysLog)
+    {
+        return toAjax(robotOpsSysLogService.updateRobotOpsSysLog(robotOpsSysLog));
+    }
+
+    /**
+     * 删除运行日志
+     */
+    @PreAuthorize("@ss.hasPermi('base:sysLog:remove')")
+    @Log(title = "运行日志", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsSysLogService.deleteRobotOpsSysLogByIds(ids));
+    }
+}

+ 105 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsVisitorRecordController.java

@@ -0,0 +1,105 @@
+package com.ruoyi.web.controller.base;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.RobotOpsVisitorRecord;
+import com.ruoyi.base.service.IRobotOpsVisitorRecordService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 访客登记记录Controller
+ *
+ * @author ruoyi
+ * @date 2026-04-30
+ */
+@RestController
+@RequestMapping("/base/visitorRecord")
+public class RobotOpsVisitorRecordController extends BaseController
+{
+    @Autowired
+    private IRobotOpsVisitorRecordService robotOpsVisitorRecordService;
+
+    /**
+     * 查询访客登记记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:visitorRecord:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsVisitorRecord robotOpsVisitorRecord,
+                              @RequestParam(required = false) String visitTimeStart,
+                              @RequestParam(required = false) String visitTimeEnd)
+    {
+        startPage();
+        if (visitTimeStart != null && !visitTimeStart.isEmpty()) {
+            robotOpsVisitorRecord.getParams().put("beginTime", visitTimeStart);
+        }
+        if (visitTimeEnd != null && !visitTimeEnd.isEmpty()) {
+            robotOpsVisitorRecord.getParams().put("endTime", visitTimeEnd);
+        }
+        List<RobotOpsVisitorRecord> list = robotOpsVisitorRecordService.selectRobotOpsVisitorRecordList(robotOpsVisitorRecord);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出访客登记记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:visitorRecord:export')")
+    @Log(title = "访客登记记录", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsVisitorRecord robotOpsVisitorRecord)
+    {
+        List<RobotOpsVisitorRecord> list = robotOpsVisitorRecordService.selectRobotOpsVisitorRecordList(robotOpsVisitorRecord);
+        ExcelUtil<RobotOpsVisitorRecord> util = new ExcelUtil<RobotOpsVisitorRecord>(RobotOpsVisitorRecord.class);
+        util.exportExcel(response, list, "访客登记记录数据");
+    }
+
+    /**
+     * 获取访客登记记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:visitorRecord:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsVisitorRecordService.selectRobotOpsVisitorRecordById(id));
+    }
+
+    /**
+     * 新增访客登记记录
+     */
+    @PreAuthorize("@ss.hasPermi('base:visitorRecord:add')")
+    @Log(title = "访客登记记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsVisitorRecord robotOpsVisitorRecord)
+    {
+        return toAjax(robotOpsVisitorRecordService.insertRobotOpsVisitorRecord(robotOpsVisitorRecord));
+    }
+
+    /**
+     * 修改访客登记记录
+     */
+    @PreAuthorize("@ss.hasPermi('base:visitorRecord:edit')")
+    @Log(title = "访客登记记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsVisitorRecord robotOpsVisitorRecord)
+    {
+        return toAjax(robotOpsVisitorRecordService.updateRobotOpsVisitorRecord(robotOpsVisitorRecord));
+    }
+
+    /**
+     * 删除访客登记记录
+     */
+    @PreAuthorize("@ss.hasPermi('base:visitorRecord:remove')")
+    @Log(title = "访客登记记录", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsVisitorRecordService.deleteRobotOpsVisitorRecordByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/base/RobotOpsWhitelistController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.base.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.base.domain.RobotOpsWhitelist;
+import com.ruoyi.base.service.IRobotOpsWhitelistService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 访客白名单Controller
+ *
+ * @author ruoyi
+ * @date 2026-04-29
+ */
+@RestController
+@RequestMapping("/base/whitelist")
+public class RobotOpsWhitelistController extends BaseController
+{
+    @Autowired
+    private IRobotOpsWhitelistService robotOpsWhitelistService;
+
+    /**
+     * 查询访客白名单列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:whitelist:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(RobotOpsWhitelist robotOpsWhitelist)
+    {
+        startPage();
+        List<RobotOpsWhitelist> list = robotOpsWhitelistService.selectRobotOpsWhitelistList(robotOpsWhitelist);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出访客白名单列表
+     */
+    @PreAuthorize("@ss.hasPermi('base:whitelist:export')")
+    @Log(title = "访客白名单", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, RobotOpsWhitelist robotOpsWhitelist)
+    {
+        List<RobotOpsWhitelist> list = robotOpsWhitelistService.selectRobotOpsWhitelistList(robotOpsWhitelist);
+        ExcelUtil<RobotOpsWhitelist> util = new ExcelUtil<RobotOpsWhitelist>(RobotOpsWhitelist.class);
+        util.exportExcel(response, list, "访客白名单数据");
+    }
+
+    /**
+     * 获取访客白名单详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('base:whitelist:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(robotOpsWhitelistService.selectRobotOpsWhitelistById(id));
+    }
+
+    /**
+     * 新增访客白名单
+     */
+    @PreAuthorize("@ss.hasPermi('base:whitelist:add')")
+    @Log(title = "访客白名单", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody RobotOpsWhitelist robotOpsWhitelist)
+    {
+        return toAjax(robotOpsWhitelistService.insertRobotOpsWhitelist(robotOpsWhitelist));
+    }
+
+    /**
+     * 修改访客白名单
+     */
+    @PreAuthorize("@ss.hasPermi('base:whitelist:edit')")
+    @Log(title = "访客白名单", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody RobotOpsWhitelist robotOpsWhitelist)
+    {
+        return toAjax(robotOpsWhitelistService.updateRobotOpsWhitelist(robotOpsWhitelist));
+    }
+
+    /**
+     * 删除访客白名单
+     */
+    @PreAuthorize("@ss.hasPermi('base:whitelist:remove')")
+    @Log(title = "访客白名单", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(robotOpsWhitelistService.deleteRobotOpsWhitelistByIds(ids));
+    }
+}

+ 191 - 51
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java

@@ -2,8 +2,12 @@ package com.ruoyi.web.controller.common;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
+import com.ruoyi.common.utils.ThumbnailUtils;
+import com.ruoyi.common.utils.VideoUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -18,13 +22,13 @@ import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.file.FileUploadUtils;
 import com.ruoyi.common.utils.file.FileUtils;
+import com.ruoyi.common.utils.file.MimeTypeUtils;
 import com.ruoyi.framework.config.ServerConfig;
+import com.ruoyi.base.domain.RobotOpsMediaAsset;
+import com.ruoyi.base.service.IRobotOpsMediaAssetService;
+
+// ... existing code ...
 
-/**
- * 通用请求处理
- * 
- * @author ruoyi
- */
 @RestController
 @RequestMapping("/common")
 public class CommonController
@@ -34,66 +38,124 @@ public class CommonController
     @Autowired
     private ServerConfig serverConfig;
 
+    @Autowired
+    private IRobotOpsMediaAssetService robotOpsMediaAssetService;
+
     private static final String FILE_DELIMITER = ",";
 
+    // ... existing code ...
+
     /**
-     * 通用下载请求
-     * 
-     * @param fileName 文件名称
-     * @param delete 是否删除
+     * 通用上传请求(单个)
      */
-    @GetMapping("/download")
-    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
+    @PostMapping("/upload")
+    public AjaxResult uploadFile(MultipartFile file) throws Exception
     {
         try
         {
-            if (!FileUtils.checkAllowDownload(fileName))
-            {
-                throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
-            }
-            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
-            String filePath = RuoYiConfig.getDownloadPath() + fileName;
-
-            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
-            FileUtils.setAttachmentResponseHeader(response, realFileName);
-            FileUtils.writeBytes(filePath, response.getOutputStream());
-            if (delete)
-            {
-                FileUtils.deleteFile(filePath);
-            }
+            // 上传文件路径
+            String filePath = RuoYiConfig.getUploadPath();
+            // 上传并返回新文件名称
+            String fileName = FileUploadUtils.upload(filePath, file);
+            String url = serverConfig.getUrl() + fileName;
+            AjaxResult ajax = AjaxResult.success();
+            ajax.put("url", url);
+            ajax.put("fileName", fileName);
+            ajax.put("newFileName", FileUtils.getName(fileName));
+            ajax.put("originalFilename", file.getOriginalFilename());
+            return ajax;
         }
         catch (Exception e)
         {
-            log.error("下载文件失败", e);
+            return AjaxResult.error(e.getMessage());
         }
     }
 
     /**
-     * 通用上传请求(单个)
+     * 上传素材文件(单个)- 只上传文件,返回文件信息,不保存到数据库
      */
-    @PostMapping("/upload")
-    public AjaxResult uploadFile(MultipartFile file) throws Exception
+    @PostMapping("/uploadMediaFile")
+    public AjaxResult uploadMediaFile(MultipartFile file) throws Exception
     {
         try
         {
-            // 上传文件路径
+            // 1. 上传文件
             String filePath = RuoYiConfig.getUploadPath();
-            // 上传并返回新文件名称
             String fileName = FileUploadUtils.upload(filePath, file);
             String url = serverConfig.getUrl() + fileName;
-            AjaxResult ajax = AjaxResult.success();
-            ajax.put("url", url);
+
+            // 2. 构建返回数据
+            AjaxResult ajax = AjaxResult.success("上传成功");
+            ajax.put("fileUrl", url);
             ajax.put("fileName", fileName);
-            ajax.put("newFileName", FileUtils.getName(fileName));
             ajax.put("originalFilename", file.getOriginalFilename());
+            ajax.put("fileSize", file.getSize());
+            ajax.put("mimeType", file.getContentType());
+            ajax.put("fileFormat", FileUtils.getExtension(file));
+
+            // 3. 根据文件类型处理
+            String contentType = file.getContentType();
+
+            if (contentType != null && contentType.startsWith("image/"))
+            {
+                // 图片:生成缩略图和获取分辨率
+                String thumbnailUrl = ThumbnailUtils.generateThumbnail(file);
+                ajax.put("thumbnailUrl", thumbnailUrl);
+
+                try
+                {
+                    java.awt.image.BufferedImage image = javax.imageio.ImageIO.read(file.getInputStream());
+                    if (image != null)
+                    {
+                        String resolution = image.getWidth() + "x" + image.getHeight();
+                        ajax.put("resolution", resolution);
+                    }
+                }
+                catch (Exception e)
+                {
+                    log.warn("获取图片分辨率失败", e);
+                }
+            }
+            else if (contentType != null && contentType.startsWith("video/"))
+            {
+                // 视频:生成缩略图、获取时长和分辨率
+                try
+                {
+                    // 获取实际文件路径
+                    String realFilePath = RuoYiConfig.getProfile() + FileUtils.stripPrefix(url);
+
+                    // 生成视频缩略图(截取第1秒的画面)
+                    String thumbnailUrl = VideoUtils.generateVideoThumbnail(realFilePath, 1);
+                    ajax.put("thumbnailUrl", thumbnailUrl);
+
+                    // 获取视频信息(时长和分辨率)
+                    Map<String, Object> videoInfo = VideoUtils.getVideoInfo(realFilePath);
+                    if (videoInfo.containsKey("durationSeconds"))
+                    {
+                        ajax.put("durationSeconds", videoInfo.get("durationSeconds"));
+                    }
+                    if (videoInfo.containsKey("resolution"))
+                    {
+                        ajax.put("resolution", videoInfo.get("resolution"));
+                    }
+                }
+                catch (Exception e)
+                {
+                    log.warn("处理视频文件失败", e);
+                }
+            }
+
             return ajax;
         }
         catch (Exception e)
         {
-            return AjaxResult.error(e.getMessage());
+            log.error("上传素材文件失败", e);
+            return AjaxResult.error("上传失败: " + e.getMessage());
         }
     }
 
+    // ... existing code ...
+
     /**
      * 通用上传请求(多个)
      */
@@ -132,31 +194,109 @@ public class CommonController
     }
 
     /**
-     * 本地资源通用下载
+     * 批量上传素材文件 - 只上传文件,返回文件信息列表,不保存到数据库
      */
-    @GetMapping("/download/resource")
-    public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
-            throws Exception
+    @PostMapping("/uploadMediaFiles")
+    public AjaxResult uploadMediaFiles(List<MultipartFile> files) throws Exception
     {
+        List<AjaxResult> fileInfoList = new ArrayList<>();
+        int successCount = 0;
+        int failedCount = 0;
+
         try
         {
-            if (!FileUtils.checkAllowDownload(resource))
+            String filePath = RuoYiConfig.getUploadPath();
+
+            for (MultipartFile file : files)
             {
-                throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
+                try
+                {
+                    // 1. 上传文件
+                    String fileName = FileUploadUtils.upload(filePath, file);
+                    String url = serverConfig.getUrl() + fileName;
+
+                    // 2. 构建文件信息
+                    AjaxResult fileInfo = AjaxResult.success();
+                    fileInfo.put("fileUrl", url);
+                    fileInfo.put("fileName", fileName);
+                    fileInfo.put("originalFilename", file.getOriginalFilename());
+                    fileInfo.put("fileSize", file.getSize());
+                    fileInfo.put("mimeType", file.getContentType());
+                    fileInfo.put("fileFormat", FileUtils.getExtension(file));
+
+                    // 3. 根据文件类型处理
+                    String contentType = file.getContentType();
+
+                    if (contentType != null && contentType.startsWith("image/"))
+                    {
+                        // 图片处理
+                        String thumbnailUrl = ThumbnailUtils.generateThumbnail(file);
+                        fileInfo.put("thumbnailUrl", thumbnailUrl);
+
+                        try
+                        {
+                            java.awt.image.BufferedImage image = javax.imageio.ImageIO.read(file.getInputStream());
+                            if (image != null)
+                            {
+                                String resolution = image.getWidth() + "x" + image.getHeight();
+                                fileInfo.put("resolution", resolution);
+                            }
+                        }
+                        catch (Exception e)
+                        {
+                            log.warn("获取图片分辨率失败", e);
+                        }
+                    }
+                    else if (contentType != null && contentType.startsWith("video/"))
+                    {
+                        // 视频处理
+                        try
+                        {
+                            String realFilePath = RuoYiConfig.getProfile() + FileUtils.stripPrefix(url);
+
+                            // 生成视频缩略图
+                            String thumbnailUrl = VideoUtils.generateVideoThumbnail(realFilePath, 1);
+                            fileInfo.put("thumbnailUrl", thumbnailUrl);
+
+                            // 获取视频信息
+                            Map<String, Object> videoInfo = VideoUtils.getVideoInfo(realFilePath);
+                            if (videoInfo.containsKey("durationSeconds"))
+                            {
+                                fileInfo.put("durationSeconds", videoInfo.get("durationSeconds"));
+                            }
+                            if (videoInfo.containsKey("resolution"))
+                            {
+                                fileInfo.put("resolution", videoInfo.get("resolution"));
+                            }
+                        }
+                        catch (Exception e)
+                        {
+                            log.warn("处理视频文件失败", e);
+                        }
+                    }
+
+                    fileInfoList.add(fileInfo);
+                    successCount++;
+                }
+                catch (Exception e)
+                {
+                    log.error("上传文件失败: {}", file.getOriginalFilename(), e);
+                    failedCount++;
+                }
             }
-            // 本地资源路径
-            String localPath = RuoYiConfig.getProfile();
-            // 数据库资源地址
-            String downloadPath = localPath + FileUtils.stripPrefix(resource);
-            // 下载名称
-            String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
-            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
-            FileUtils.setAttachmentResponseHeader(response, downloadName);
-            FileUtils.writeBytes(downloadPath, response.getOutputStream());
+
+            AjaxResult ajax = AjaxResult.success();
+            ajax.put("files", fileInfoList);
+            ajax.put("successCount", successCount);
+            ajax.put("failedCount", failedCount);
+            return ajax;
         }
         catch (Exception e)
         {
-            log.error("下载文件失败", e);
+            log.error("批量上传素材文件失败", e);
+            return AjaxResult.error("批量上传失败: " + e.getMessage());
         }
     }
+
+    // ... existing code ...
 }

+ 1 - 1
ruoyi-admin/src/main/resources/application.yml

@@ -7,7 +7,7 @@ ruoyi:
   # 版权年份
   copyrightYear: 2026
   # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
-  profile: D:/ruoyi/uploadPath
+  profile: /opt/app/jiqiren/uploadPath
   # 获取ip地址开关
   addressEnabled: false
   # 验证码类型 math 数字计算 char 字符验证

+ 10 - 3
ruoyi-common/pom.xml

@@ -52,13 +52,13 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
-  
+
         <!-- JSON工具类 -->
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
         </dependency>
-        
+
         <!-- 阿里JSON解析器 -->
         <dependency>
             <groupId>com.alibaba.fastjson2</groupId>
@@ -119,6 +119,13 @@
             <scope>provided</scope>
         </dependency>
 
+        <!-- JavaCV 视频处理 -->
+        <dependency>
+            <groupId>org.bytedeco</groupId>
+            <artifactId>javacv-platform</artifactId>
+            <version>1.5.9</version>
+        </dependency>
+
     </dependencies>
 
-</project>
+</project>

+ 188 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/ThumbnailUtils.java

@@ -0,0 +1,188 @@
+package com.ruoyi.common.utils;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import javax.imageio.ImageIO;
+
+import com.ruoyi.common.utils.file.FileUploadUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.ruoyi.common.config.RuoYiConfig;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.uuid.IdUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 缩略图处理工具类(仅处理图片)
+ *
+ * @author ruoyi
+ */
+public class ThumbnailUtils
+{
+    private static final Logger log = LoggerFactory.getLogger(ThumbnailUtils.class);
+
+    /**
+     * 默认缩略图宽度
+     */
+    private static final int DEFAULT_THUMBNAIL_WIDTH = 200;
+
+    /**
+     * 默认缩略图高度
+     */
+    private static final int DEFAULT_THUMBNAIL_HEIGHT = 200;
+
+    /**
+     * 生成缩略图
+     *
+     * @param file 原始文件
+     * @return 缩略图文件路径,如果生成失败返回null
+     */
+    public static String generateThumbnail(MultipartFile file)
+    {
+        try
+        {
+            BufferedImage originalImage = ImageIO.read(file.getInputStream());
+            if (originalImage == null)
+            {
+                log.warn("无法读取图片文件: {}", file.getOriginalFilename());
+                return null;
+            }
+
+            return generateThumbnail(originalImage, file.getOriginalFilename(), DEFAULT_THUMBNAIL_WIDTH, DEFAULT_THUMBNAIL_HEIGHT);
+        }
+        catch (IOException e)
+        {
+            log.error("生成缩略图失败", e);
+            return null;
+        }
+    }
+
+    /**
+     * 生成缩略图
+     *
+     * @param file 原始文件
+     * @param width 缩略图宽度
+     * @param height 缩略图高度
+     * @return 缩略图文件路径,如果生成失败返回null
+     */
+    public static String generateThumbnail(MultipartFile file, int width, int height)
+    {
+        try
+        {
+            BufferedImage originalImage = ImageIO.read(file.getInputStream());
+            if (originalImage == null)
+            {
+                log.warn("无法读取图片文件: {}", file.getOriginalFilename());
+                return null;
+            }
+
+            return generateThumbnail(originalImage, file.getOriginalFilename(), width, height);
+        }
+        catch (IOException e)
+        {
+            log.error("生成缩略图失败", e);
+            return null;
+        }
+    }
+
+    /**
+     * 生成缩略图
+     *
+     * @param imagePath 原始图片路径
+     * @return 缩略图文件路径,如果生成失败返回null
+     */
+    public static String generateThumbnail(String imagePath)
+    {
+        try
+        {
+            File imageFile = new File(imagePath);
+            if (!imageFile.exists())
+            {
+                log.warn("图片文件不存在: {}", imagePath);
+                return null;
+            }
+
+            BufferedImage originalImage = ImageIO.read(imageFile);
+            if (originalImage == null)
+            {
+                log.warn("无法读取图片文件: {}", imagePath);
+                return null;
+            }
+
+            String fileName = imageFile.getName();
+            return generateThumbnail(originalImage, fileName, DEFAULT_THUMBNAIL_WIDTH, DEFAULT_THUMBNAIL_HEIGHT);
+        }
+        catch (IOException e)
+        {
+            log.error("生成缩略图失败: {}", imagePath, e);
+            return null;
+        }
+    }
+
+    /**
+     * 生成缩略图(内部方法)
+     */
+    private static String generateThumbnail(BufferedImage originalImage, String originalFileName, int width, int height)
+    {
+        try
+        {
+            int originalWidth = originalImage.getWidth();
+            int originalHeight = originalImage.getHeight();
+
+            // 计算缩放比例,保持宽高比
+            double scale = Math.min((double) width / originalWidth, (double) height / originalHeight);
+            int scaledWidth = (int) (originalWidth * scale);
+            int scaledHeight = (int) (originalHeight * scale);
+
+            // 创建缩略图
+            BufferedImage thumbnail = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
+            Graphics2D g2d = thumbnail.createGraphics();
+
+            // 设置图片平滑渲染
+            g2d.setRenderingHint(java.awt.RenderingHints.KEY_INTERPOLATION,
+                    java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+            g2d.drawImage(originalImage.getScaledInstance(scaledWidth, scaledHeight, Image.SCALE_SMOOTH), 0, 0, null);
+            g2d.dispose();
+
+            // 生成缩略图文件名
+            String extension = getFileExtension(originalFileName);
+            String thumbnailFileName = "thumb_" + IdUtils.fastSimpleUUID() + "." + extension;
+            String datePath = DateUtils.datePath();
+            String thumbnailPath = datePath + "/" + thumbnailFileName;
+
+            // 保存缩略图
+            String uploadDir = RuoYiConfig.getUploadPath();
+            File thumbnailFile = FileUploadUtils.getAbsoluteFile(uploadDir, thumbnailPath);
+            ImageIO.write(thumbnail, extension, thumbnailFile);
+
+            // 返回访问路径
+            return FileUploadUtils.getPathFileName(uploadDir, thumbnailPath);
+        }
+        catch (Exception e)
+        {
+            log.error("生成缩略图失败", e);
+            return null;
+        }
+    }
+
+    /**
+     * 获取文件扩展名
+     */
+    private static String getFileExtension(String fileName)
+    {
+        if (StringUtils.isEmpty(fileName))
+        {
+            return "jpg";
+        }
+        int lastDotIndex = fileName.lastIndexOf('.');
+        if (lastDotIndex > 0 && lastDotIndex < fileName.length() - 1)
+        {
+            return fileName.substring(lastDotIndex + 1).toLowerCase();
+        }
+        return "jpg";
+    }
+}

+ 262 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/VideoUtils.java

@@ -0,0 +1,262 @@
+package com.ruoyi.common.utils;
+
+
+
+import com.ruoyi.common.utils.file.FileUploadUtils;
+import org.bytedeco.javacv.FFmpegFrameGrabber;
+import org.bytedeco.javacv.Frame;
+import org.bytedeco.javacv.Java2DFrameConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 视频处理工具类(基于JavaCV)
+ *
+ * @author ruoyi
+ */
+public class VideoUtils
+{
+    private static final Logger log = LoggerFactory.getLogger(VideoUtils.class);
+
+    /**
+     * 获取视频信息
+     *
+     * @param videoPath 视频文件路径
+     * @return 视频信息Map,包含duration(时长秒)、width(宽度)、height(高度)
+     */
+    public static Map<String, Object> getVideoInfo(String videoPath)
+    {
+        Map<String, Object> videoInfo = new HashMap<>();
+        FFmpegFrameGrabber grabber = null;
+
+        try
+        {
+            grabber = new FFmpegFrameGrabber(videoPath);
+            grabber.start();
+
+            // 获取视频时长(微秒转换为秒)
+            long durationMicroseconds = grabber.getLengthInTime();
+            if (durationMicroseconds > 0)
+            {
+                long durationSeconds = durationMicroseconds / 1000000;
+                videoInfo.put("durationSeconds", durationSeconds);
+            }
+
+            // 获取视频帧数
+            int frameNumber = grabber.getLengthInFrames();
+
+            // 获取视频宽度和高度
+            int width = grabber.getImageWidth();
+            int height = grabber.getImageHeight();
+
+            if (width > 0 && height > 0)
+            {
+                videoInfo.put("resolution", width + "x" + height);
+                videoInfo.put("width", width);
+                videoInfo.put("height", height);
+            }
+
+            // 获取帧率
+            double frameRate = grabber.getFrameRate();
+            if (frameRate > 0)
+            {
+                videoInfo.put("frameRate", frameRate);
+            }
+        }
+        catch (Exception e)
+        {
+            log.error("获取视频信息失败: {}", videoPath, e);
+        }
+        finally
+        {
+            if (grabber != null)
+            {
+                try
+                {
+                    grabber.stop();
+                    grabber.release();
+                }
+                catch (Exception e)
+                {
+                    log.warn("释放视频资源失败", e);
+                }
+            }
+        }
+
+        return videoInfo;
+    }
+
+    /**
+     * 获取视频时长(秒)
+     *
+     * @param videoPath 视频文件路径
+     * @return 时长(秒),失败返回null
+     */
+    public static Long getVideoDuration(String videoPath)
+    {
+        Map<String, Object> videoInfo = getVideoInfo(videoPath);
+        return (Long) videoInfo.get("durationSeconds");
+    }
+
+    /**
+     * 获取视频分辨率
+     *
+     * @param videoPath 视频文件路径
+     * @return 分辨率(如1920x1080),失败返回null
+     */
+    public static String getVideoResolution(String videoPath)
+    {
+        Map<String, Object> videoInfo = getVideoInfo(videoPath);
+        return (String) videoInfo.get("resolution");
+    }
+
+    /**
+     * 从视频文件生成缩略图
+     *
+     * @param videoPath 视频文件路径
+     * @return 缩略图文件路径,如果生成失败返回null
+     */
+    public static String generateVideoThumbnail(String videoPath)
+    {
+        return generateVideoThumbnail(videoPath, 1);
+    }
+
+    /**
+     * 从视频文件生成缩略图
+     *
+     * @param videoPath 视频文件路径
+     * @param captureTime 截取时间点(秒)
+     * @return 缩略图文件路径,如果生成失败返回null
+     */
+    public static String generateVideoThumbnail(String videoPath, int captureTime)
+    {
+        return generateVideoThumbnail(videoPath, captureTime, 200, 200);
+    }
+
+    /**
+     * 从视频文件生成缩略图(自定义尺寸)
+     *
+     * @param videoPath 视频文件路径
+     * @param captureTime 截取时间点(秒)
+     * @param width 缩略图宽度
+     * @param height 缩略图高度
+     * @return 缩略图文件路径,如果生成失败返回null
+     */
+    public static String generateVideoThumbnail(String videoPath, int captureTime, int width, int height)
+    {
+        FFmpegFrameGrabber grabber = null;
+        Java2DFrameConverter converter = null;
+
+        try
+        {
+            grabber = new FFmpegFrameGrabber(videoPath);
+            grabber.start();
+
+            // 计算目标帧位置
+            int frameNumber = (int) (captureTime * grabber.getFrameRate());
+            if (frameNumber >= grabber.getLengthInFrames())
+            {
+                frameNumber = grabber.getLengthInFrames() - 1;
+            }
+
+            // 跳转到指定帧
+            grabber.setFrameNumber(frameNumber);
+            Frame frame = grabber.grabImage();
+
+            if (frame == null)
+            {
+                log.warn("无法抓取视频帧: {}", videoPath);
+                return null;
+            }
+
+            // 转换Frame为BufferedImage
+            converter = new Java2DFrameConverter();
+            BufferedImage bufferedImage = converter.convert(frame);
+
+            if (bufferedImage == null)
+            {
+                log.warn("转换视频帧失败: {}", videoPath);
+                return null;
+            }
+
+            // 缩放图片
+            BufferedImage thumbnail = resizeImage(bufferedImage, width, height);
+
+            // 生成缩略图文件名
+            String extension = "jpg";
+            String thumbnailFileName = "thumb_" + com.ruoyi.common.utils.uuid.IdUtils.fastSimpleUUID() + "." + extension;
+            String datePath = com.ruoyi.common.utils.DateUtils.datePath();
+            String thumbnailPath = datePath + "/" + thumbnailFileName;
+
+            // 保存缩略图
+            String uploadDir = com.ruoyi.common.config.RuoYiConfig.getUploadPath();
+            File thumbnailFile = FileUploadUtils.getAbsoluteFile(uploadDir, thumbnailPath);
+            ImageIO.write(thumbnail, extension, thumbnailFile);
+
+            // 返回访问路径
+            return FileUploadUtils.getPathFileName(uploadDir, thumbnailPath);
+        }
+        catch (Exception e)
+        {
+            log.error("生成视频缩略图失败: {}", videoPath, e);
+            return null;
+        }
+        finally
+        {
+            if (converter != null)
+            {
+                converter.close();
+            }
+            if (grabber != null)
+            {
+                try
+                {
+                    grabber.stop();
+                    grabber.release();
+                }
+                catch (Exception e)
+                {
+                    log.warn("释放视频资源失败", e);
+                }
+            }
+        }
+    }
+
+    /**
+     * 缩放图片(保持宽高比)
+     *
+     * @param original 原始图片
+     * @param targetWidth 目标宽度
+     * @param targetHeight 目标高度
+     * @return 缩放后的图片
+     */
+    private static BufferedImage resizeImage(BufferedImage original, int targetWidth, int targetHeight)
+    {
+        int originalWidth = original.getWidth();
+        int originalHeight = original.getHeight();
+
+        // 计算缩放比例,保持宽高比
+        double scale = Math.min((double) targetWidth / originalWidth, (double) targetHeight / originalHeight);
+        int scaledWidth = (int) (originalWidth * scale);
+        int scaledHeight = (int) (originalHeight * scale);
+
+        // 创建缩放后的图片
+        BufferedImage resized = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
+        java.awt.Graphics2D g2d = resized.createGraphics();
+
+        // 设置图片平滑渲染
+        g2d.setRenderingHint(java.awt.RenderingHints.KEY_INTERPOLATION,
+                java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+        g2d.drawImage(original.getScaledInstance(scaledWidth, scaledHeight, java.awt.Image.SCALE_SMOOTH),
+                0, 0, null);
+        g2d.dispose();
+
+        return resized;
+    }
+}

+ 29 - 10
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java

@@ -19,10 +19,11 @@ import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.uuid.IdUtils;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * 文件处理工具类
- * 
+ *
  * @author ruoyi
  */
 public class FileUtils
@@ -31,7 +32,7 @@ public class FileUtils
 
     /**
      * 输出指定文件的byte数组
-     * 
+     *
      * @param filePath 文件路径
      * @param os 输出流
      * @return
@@ -106,7 +107,7 @@ public class FileUtils
 
     /**
      * 移除路径中的请求前缀片段
-     * 
+     *
      * @param filePath 文件路径
      * @return 移除后的文件路径
      */
@@ -117,7 +118,7 @@ public class FileUtils
 
     /**
      * 删除文件
-     * 
+     *
      * @param filePath 文件
      * @return
      */
@@ -135,7 +136,7 @@ public class FileUtils
 
     /**
      * 文件名称验证
-     * 
+     *
      * @param filename 文件名称
      * @return true 正常 false 非法
      */
@@ -146,7 +147,7 @@ public class FileUtils
 
     /**
      * 检查文件是否可下载
-     * 
+     *
      * @param resource 需要下载的文件
      * @return true 正常 false 非法
      */
@@ -170,7 +171,7 @@ public class FileUtils
 
     /**
      * 下载文件名重新编码
-     * 
+     *
      * @param request 请求对象
      * @param fileName 文件名
      * @return 编码后的文件名
@@ -240,7 +241,7 @@ public class FileUtils
 
     /**
      * 获取图像后缀
-     * 
+     *
      * @param photoByte 图像数据
      * @return 后缀名
      */
@@ -269,7 +270,7 @@ public class FileUtils
 
     /**
      * 获取文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi.png
-     * 
+     *
      * @param fileName 路径名称
      * @return 没有文件路径的名称
      */
@@ -287,7 +288,7 @@ public class FileUtils
 
     /**
      * 获取不带后缀文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi
-     * 
+     *
      * @param fileName 路径名称
      * @return 没有文件路径和后缀的名称
      */
@@ -300,4 +301,22 @@ public class FileUtils
         String baseName = FilenameUtils.getBaseName(fileName);
         return baseName;
     }
+
+
+
+    /**
+     * 获取文件扩展名
+     *
+     * @param file 表单文件
+     * @return 扩展名
+     */
+    public static String getExtension(MultipartFile file)
+    {
+        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
+        if (StringUtils.isEmpty(extension))
+        {
+            extension = MimeTypeUtils.getExtension(file.getContentType());
+        }
+        return extension;
+    }
 }

+ 223 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/AlarmLog.java

@@ -0,0 +1,223 @@
+package com.ruoyi.base.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 安防告警日志对象 robot_ops_alarm_log
+ * 
+ * @author ruoyi
+ * @date 2026-05-20
+ */
+public class AlarmLog extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 告警时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "告警时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date alarmTime;
+
+    /** 告警类型 */
+    @Excel(name = "告警类型")
+    private String alarmType;
+
+    /** 告警级别 */
+    @Excel(name = "告警级别")
+    private String alarmLevel;
+
+    /** 告警来源 */
+    @Excel(name = "告警来源")
+    private String alarmSource;
+
+    /** 来源位置,如大厅入口、前台区域、走廊 */
+    @Excel(name = "来源位置,如大厅入口、前台区域、走廊")
+    private String sourcePosition;
+
+    /** 告警标题或摘要 */
+    @Excel(name = "告警标题或摘要")
+    private String alarmTitle;
+
+    /** 告警描述 */
+    @Excel(name = "告警描述")
+    private String description;
+
+    /** 抓拍图地址 */
+    @Excel(name = "抓拍图地址")
+    private String snapshotUrl;
+
+    /** 处理状态 */
+    @Excel(name = "处理状态")
+    private String handleStatus;
+
+    /** 处理人 */
+    @Excel(name = "处理人")
+    private String handleBy;
+
+    /** 处理时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "处理时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date handleTime;
+
+    /** 处理备注 */
+    @Excel(name = "处理备注")
+    private String handleRemark;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setAlarmTime(Date alarmTime) 
+    {
+        this.alarmTime = alarmTime;
+    }
+
+    public Date getAlarmTime() 
+    {
+        return alarmTime;
+    }
+
+    public void setAlarmType(String alarmType) 
+    {
+        this.alarmType = alarmType;
+    }
+
+    public String getAlarmType() 
+    {
+        return alarmType;
+    }
+
+    public void setAlarmLevel(String alarmLevel) 
+    {
+        this.alarmLevel = alarmLevel;
+    }
+
+    public String getAlarmLevel() 
+    {
+        return alarmLevel;
+    }
+
+    public void setAlarmSource(String alarmSource) 
+    {
+        this.alarmSource = alarmSource;
+    }
+
+    public String getAlarmSource() 
+    {
+        return alarmSource;
+    }
+
+    public void setSourcePosition(String sourcePosition) 
+    {
+        this.sourcePosition = sourcePosition;
+    }
+
+    public String getSourcePosition() 
+    {
+        return sourcePosition;
+    }
+
+    public void setAlarmTitle(String alarmTitle) 
+    {
+        this.alarmTitle = alarmTitle;
+    }
+
+    public String getAlarmTitle() 
+    {
+        return alarmTitle;
+    }
+
+    public void setDescription(String description) 
+    {
+        this.description = description;
+    }
+
+    public String getDescription() 
+    {
+        return description;
+    }
+
+    public void setSnapshotUrl(String snapshotUrl) 
+    {
+        this.snapshotUrl = snapshotUrl;
+    }
+
+    public String getSnapshotUrl() 
+    {
+        return snapshotUrl;
+    }
+
+    public void setHandleStatus(String handleStatus) 
+    {
+        this.handleStatus = handleStatus;
+    }
+
+    public String getHandleStatus() 
+    {
+        return handleStatus;
+    }
+
+    public void setHandleBy(String handleBy) 
+    {
+        this.handleBy = handleBy;
+    }
+
+    public String getHandleBy() 
+    {
+        return handleBy;
+    }
+
+    public void setHandleTime(Date handleTime) 
+    {
+        this.handleTime = handleTime;
+    }
+
+    public Date getHandleTime() 
+    {
+        return handleTime;
+    }
+
+    public void setHandleRemark(String handleRemark) 
+    {
+        this.handleRemark = handleRemark;
+    }
+
+    public String getHandleRemark() 
+    {
+        return handleRemark;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("alarmTime", getAlarmTime())
+            .append("alarmType", getAlarmType())
+            .append("alarmLevel", getAlarmLevel())
+            .append("alarmSource", getAlarmSource())
+            .append("sourcePosition", getSourcePosition())
+            .append("alarmTitle", getAlarmTitle())
+            .append("description", getDescription())
+            .append("snapshotUrl", getSnapshotUrl())
+            .append("handleStatus", getHandleStatus())
+            .append("handleBy", getHandleBy())
+            .append("handleTime", getHandleTime())
+            .append("handleRemark", getHandleRemark())
+            .append("remark", getRemark())
+            .append("createTime", getCreateTime())
+            .toString();
+    }
+}

+ 218 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/DialogueLog.java

@@ -0,0 +1,218 @@
+package com.ruoyi.base.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 对话日志对象 robot_ops_dialogue_log
+ * 
+ * @author ruoyi
+ * @date 2026-05-19
+ */
+public class DialogueLog extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 机器人编号,用于后续上传上位平台或多机器人汇聚识别 */
+    @Excel(name = "机器人编号,用于后续上传上位平台或多机器人汇聚识别")
+    private String robotCode;
+
+    /** 会话ID */
+    @Excel(name = "会话ID")
+    private String sessionId;
+
+    /** 提问时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "提问时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date askTime;
+
+    /** 用户问题 */
+    @Excel(name = "用户问题")
+    private String question;
+
+    /** 机器人回答 */
+    private String answer;
+
+    /** 回答摘要 */
+    @Excel(name = "回答摘要")
+    private String answerSummary;
+
+    /** 命中方式 */
+    @Excel(name = "命中方式")
+    private String hitType;
+
+    /** 来源场景 */
+    @Excel(name = "来源场景")
+    private String sceneType;
+
+    /** 结果状态 */
+    @Excel(name = "结果状态")
+    private String resultStatus;
+
+    /** 失败原因或错误信息 */
+    @Excel(name = "失败原因或错误信息")
+    private String errorMsg;
+
+    /** 原始请求 */
+    private String rawRequest;
+
+    /** 原始响应 */
+    private String rawResponse;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setRobotCode(String robotCode) 
+    {
+        this.robotCode = robotCode;
+    }
+
+    public String getRobotCode() 
+    {
+        return robotCode;
+    }
+
+    public void setSessionId(String sessionId) 
+    {
+        this.sessionId = sessionId;
+    }
+
+    public String getSessionId() 
+    {
+        return sessionId;
+    }
+
+    public void setAskTime(Date askTime) 
+    {
+        this.askTime = askTime;
+    }
+
+    public Date getAskTime() 
+    {
+        return askTime;
+    }
+
+    public void setQuestion(String question) 
+    {
+        this.question = question;
+    }
+
+    public String getQuestion() 
+    {
+        return question;
+    }
+
+    public void setAnswer(String answer) 
+    {
+        this.answer = answer;
+    }
+
+    public String getAnswer() 
+    {
+        return answer;
+    }
+
+    public void setAnswerSummary(String answerSummary) 
+    {
+        this.answerSummary = answerSummary;
+    }
+
+    public String getAnswerSummary() 
+    {
+        return answerSummary;
+    }
+
+    public void setHitType(String hitType) 
+    {
+        this.hitType = hitType;
+    }
+
+    public String getHitType() 
+    {
+        return hitType;
+    }
+
+    public void setSceneType(String sceneType) 
+    {
+        this.sceneType = sceneType;
+    }
+
+    public String getSceneType() 
+    {
+        return sceneType;
+    }
+
+    public void setResultStatus(String resultStatus) 
+    {
+        this.resultStatus = resultStatus;
+    }
+
+    public String getResultStatus() 
+    {
+        return resultStatus;
+    }
+
+    public void setErrorMsg(String errorMsg) 
+    {
+        this.errorMsg = errorMsg;
+    }
+
+    public String getErrorMsg() 
+    {
+        return errorMsg;
+    }
+
+    public void setRawRequest(String rawRequest) 
+    {
+        this.rawRequest = rawRequest;
+    }
+
+    public String getRawRequest() 
+    {
+        return rawRequest;
+    }
+
+    public void setRawResponse(String rawResponse) 
+    {
+        this.rawResponse = rawResponse;
+    }
+
+    public String getRawResponse() 
+    {
+        return rawResponse;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("robotCode", getRobotCode())
+            .append("sessionId", getSessionId())
+            .append("askTime", getAskTime())
+            .append("question", getQuestion())
+            .append("answer", getAnswer())
+            .append("answerSummary", getAnswerSummary())
+            .append("hitType", getHitType())
+            .append("sceneType", getSceneType())
+            .append("resultStatus", getResultStatus())
+            .append("errorMsg", getErrorMsg())
+            .append("rawRequest", getRawRequest())
+            .append("rawResponse", getRawResponse())
+            .append("createTime", getCreateTime())
+            .toString();
+    }
+}

+ 165 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsAppointmentRecord.java

@@ -0,0 +1,165 @@
+package com.ruoyi.base.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 访客预约记录对象 robot_ops_appointment_record
+ *
+ * @author ruoyi
+ * @date 2026-04-28
+ */
+
+public class RobotOpsAppointmentRecord extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 预约单号 */
+    @Excel(name = "预约单号")
+    private String appointmentNo;
+
+    /** 访客姓名 */
+    @Excel(name = "访客姓名")
+    private String visitorName;
+
+    /** 访客手机号 */
+    @Excel(name = "访客手机号")
+    private String mobile;
+
+    /** 被访人/被访对象 */
+    @Excel(name = "被访人/被访对象")
+    private String visitedPerson;
+
+    /** 预约到访时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "预约到访时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date appointmentTime;
+
+    /** 预约状态 */
+    @Excel(name = "预约状态")
+    private Long status;
+
+    /** 同步到本地时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "同步到本地时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date syncTime;
+
+    /** 来源平台 */
+    @Excel(name = "来源平台")
+    private String sourcePlatform;
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setAppointmentNo(String appointmentNo)
+    {
+        this.appointmentNo = appointmentNo;
+    }
+
+    public String getAppointmentNo()
+    {
+        return appointmentNo;
+    }
+
+    public void setVisitorName(String visitorName)
+    {
+        this.visitorName = visitorName;
+    }
+
+    public String getVisitorName()
+    {
+        return visitorName;
+    }
+
+    public void setMobile(String mobile)
+    {
+        this.mobile = mobile;
+    }
+
+    public String getMobile()
+    {
+        return mobile;
+    }
+
+    public void setVisitedPerson(String visitedPerson)
+    {
+        this.visitedPerson = visitedPerson;
+    }
+
+    public String getVisitedPerson()
+    {
+        return visitedPerson;
+    }
+
+    public void setAppointmentTime(Date appointmentTime)
+    {
+        this.appointmentTime = appointmentTime;
+    }
+
+    public Date getAppointmentTime()
+    {
+        return appointmentTime;
+    }
+
+    public void setStatus(Long status)
+    {
+        this.status = status;
+    }
+
+    public Long getStatus()
+    {
+        return status;
+    }
+
+    public void setSyncTime(Date syncTime)
+    {
+        this.syncTime = syncTime;
+    }
+
+    public Date getSyncTime()
+    {
+        return syncTime;
+    }
+
+    public void setSourcePlatform(String sourcePlatform)
+    {
+        this.sourcePlatform = sourcePlatform;
+    }
+
+    public String getSourcePlatform()
+    {
+        return sourcePlatform;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("appointmentNo", getAppointmentNo())
+            .append("visitorName", getVisitorName())
+            .append("mobile", getMobile())
+            .append("visitedPerson", getVisitedPerson())
+            .append("appointmentTime", getAppointmentTime())
+            .append("status", getStatus())
+            .append("syncTime", getSyncTime())
+            .append("sourcePlatform", getSourcePlatform())
+            .append("remark", getRemark())
+            .append("createTime", getCreateTime())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 100 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsBroadcastContent.java

@@ -0,0 +1,100 @@
+package com.ruoyi.base.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 播报内容对象 robot_ops_broadcast_content
+ * 
+ * @author ruoyi
+ * @date 2026-04-27
+ */
+public class RobotOpsBroadcastContent extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 播报内容名称 */
+    @Excel(name = "播报内容名称")
+    private String contentName;
+
+    /** 内容分类 */
+    @Excel(name = "内容分类")
+    private Long contentType;
+
+    /** 播报文本 */
+    @Excel(name = "播报文本")
+    private String broadcastText;
+
+    /** 启用状态:0停用,1启用 */
+    @Excel(name = "启用状态:0停用,1启用")
+    private String status;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setContentName(String contentName) 
+    {
+        this.contentName = contentName;
+    }
+
+    public String getContentName() 
+    {
+        return contentName;
+    }
+
+    public void setContentType(Long contentType) 
+    {
+        this.contentType = contentType;
+    }
+
+    public Long getContentType() 
+    {
+        return contentType;
+    }
+
+    public void setBroadcastText(String broadcastText) 
+    {
+        this.broadcastText = broadcastText;
+    }
+
+    public String getBroadcastText() 
+    {
+        return broadcastText;
+    }
+
+    public void setStatus(String status) 
+    {
+        this.status = status;
+    }
+
+    public String getStatus() 
+    {
+        return status;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("contentName", getContentName())
+            .append("contentType", getContentType())
+            .append("broadcastText", getBroadcastText())
+            .append("status", getStatus())
+            .append("remark", getRemark())
+            .append("createTime", getCreateTime())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 160 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsBroadcastTask.java

@@ -0,0 +1,160 @@
+package com.ruoyi.base.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 播报任务对象 robot_ops_broadcast_task
+ * 
+ * @author ruoyi
+ * @date 2026-04-27
+ */
+public class RobotOpsBroadcastTask extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 播报任务名称 */
+    @Excel(name = "播报任务名称")
+    private String taskName;
+
+    /** 播报内容ID,关联robot_ops_broadcast_content.id */
+    @Excel(name = "播报内容ID,关联robot_ops_broadcast_content.id")
+    private Long contentId;
+
+    /** 开始时间,格式HH:mm:ss */
+    @Excel(name = "开始时间,格式HH:mm:ss")
+    private String startTime;
+
+    /** 结束时间,格式HH:mm:ss */
+    @Excel(name = "结束时间,格式HH:mm:ss")
+    private String endTime;
+
+    /** 播报频率,单位分钟 */
+    @Excel(name = "播报频率,单位分钟")
+    private Long frequencyMinutes;
+
+    /** 循环类型  */
+    @Excel(name = "循环类型 ")
+    private Long cycleType;
+
+    /** 循环取值,指定日期或星期配置 */
+    @Excel(name = "循环取值,指定日期或星期配置")
+    private String cycleValue;
+
+    /** 启用状态:0停用,1启用 */
+    @Excel(name = "启用状态:0停用,1启用")
+    private String status;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setTaskName(String taskName) 
+    {
+        this.taskName = taskName;
+    }
+
+    public String getTaskName() 
+    {
+        return taskName;
+    }
+
+    public void setContentId(Long contentId) 
+    {
+        this.contentId = contentId;
+    }
+
+    public Long getContentId() 
+    {
+        return contentId;
+    }
+
+    public void setStartTime(String startTime) 
+    {
+        this.startTime = startTime;
+    }
+
+    public String getStartTime() 
+    {
+        return startTime;
+    }
+
+    public void setEndTime(String endTime) 
+    {
+        this.endTime = endTime;
+    }
+
+    public String getEndTime() 
+    {
+        return endTime;
+    }
+
+    public void setFrequencyMinutes(Long frequencyMinutes) 
+    {
+        this.frequencyMinutes = frequencyMinutes;
+    }
+
+    public Long getFrequencyMinutes() 
+    {
+        return frequencyMinutes;
+    }
+
+    public void setCycleType(Long cycleType) 
+    {
+        this.cycleType = cycleType;
+    }
+
+    public Long getCycleType() 
+    {
+        return cycleType;
+    }
+
+    public void setCycleValue(String cycleValue) 
+    {
+        this.cycleValue = cycleValue;
+    }
+
+    public String getCycleValue() 
+    {
+        return cycleValue;
+    }
+
+    public void setStatus(String status) 
+    {
+        this.status = status;
+    }
+
+    public String getStatus() 
+    {
+        return status;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("taskName", getTaskName())
+            .append("contentId", getContentId())
+            .append("startTime", getStartTime())
+            .append("endTime", getEndTime())
+            .append("frequencyMinutes", getFrequencyMinutes())
+            .append("cycleType", getCycleType())
+            .append("cycleValue", getCycleValue())
+            .append("status", getStatus())
+            .append("remark", getRemark())
+            .append("createTime", getCreateTime())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 147 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsFaq.java

@@ -0,0 +1,147 @@
+package com.ruoyi.base.domain;
+
+import java.util.List;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 问答库管理对象 robot_ops_faq
+ *
+ * @author ruoyi
+ * @date 2026-05-07
+ */
+public class RobotOpsFaq extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 问题分类字典值,字典类型:robot_faq_category */
+    @Excel(name = "问题分类字典值,字典类型:robot_faq_category")
+    private String categoryType;
+
+    /** 标准问题 */
+    @Excel(name = "标准问题")
+    private String question;
+
+    /** 答案内容 */
+    @Excel(name = "答案内容")
+    private String answer;
+
+    /** 排序号,数字越小越靠前 */
+    @Excel(name = "排序号,数字越小越靠前")
+    private Long sortNo;
+
+    /** 启用状态:0停用,1启用 */
+    @Excel(name = "启用状态:0停用,1启用")
+    private String status;
+
+    /** 相似问个数 */
+    @Excel(name = "相似问个数")
+    private Integer similarCount;
+
+    /** 问答相似问信息 */
+    private List<RobotOpsFaqSimilar> robotOpsFaqSimilarList;
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setCategoryType(String categoryType)
+    {
+        this.categoryType = categoryType;
+    }
+
+    public String getCategoryType()
+    {
+        return categoryType;
+    }
+
+    public void setQuestion(String question)
+    {
+        this.question = question;
+    }
+
+    public String getQuestion()
+    {
+        return question;
+    }
+
+    public void setAnswer(String answer)
+    {
+        this.answer = answer;
+    }
+
+    public String getAnswer()
+    {
+        return answer;
+    }
+
+    public void setSortNo(Long sortNo)
+    {
+        this.sortNo = sortNo;
+    }
+
+    public Long getSortNo()
+    {
+        return sortNo;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public List<RobotOpsFaqSimilar> getRobotOpsFaqSimilarList()
+    {
+        return robotOpsFaqSimilarList;
+    }
+
+    public void setSimilarCount(Integer similarCount)
+    {
+        this.similarCount = similarCount;
+    }
+
+    public Integer getSimilarCount()
+    {
+        return similarCount;
+    }
+
+    public void setRobotOpsFaqSimilarList(List<RobotOpsFaqSimilar> robotOpsFaqSimilarList)
+    {
+        this.robotOpsFaqSimilarList = robotOpsFaqSimilarList;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("categoryType", getCategoryType())
+                .append("question", getQuestion())
+                .append("answer", getAnswer())
+                .append("sortNo", getSortNo())
+                .append("status", getStatus())
+                .append("similarCount", getSimilarCount())
+                .append("remark", getRemark())
+                .append("createTime", getCreateTime())
+                .append("updateTime", getUpdateTime())
+                .append("createBy", getCreateBy())
+                .append("updateBy", getUpdateBy())
+                .append("robotOpsFaqSimilarList", getRobotOpsFaqSimilarList())
+                .toString();
+    }
+}

+ 81 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsFaqSimilar.java

@@ -0,0 +1,81 @@
+package com.ruoyi.base.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 问答相似问对象 robot_ops_faq_similar
+ * 
+ * @author ruoyi
+ * @date 2026-05-07
+ */
+public class RobotOpsFaqSimilar extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 问答ID,关联robot_ops_faq.id */
+    @Excel(name = "问答ID,关联robot_ops_faq.id")
+    private Long faqId;
+
+    /** 相似问文本 */
+    @Excel(name = "相似问文本")
+    private String similarQuestion;
+
+    /** 排序号,数字越小越靠前 */
+    @Excel(name = "排序号,数字越小越靠前")
+    private Long sortNo;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+    public void setFaqId(Long faqId) 
+    {
+        this.faqId = faqId;
+    }
+
+    public Long getFaqId() 
+    {
+        return faqId;
+    }
+    public void setSimilarQuestion(String similarQuestion) 
+    {
+        this.similarQuestion = similarQuestion;
+    }
+
+    public String getSimilarQuestion() 
+    {
+        return similarQuestion;
+    }
+    public void setSortNo(Long sortNo) 
+    {
+        this.sortNo = sortNo;
+    }
+
+    public Long getSortNo() 
+    {
+        return sortNo;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("faqId", getFaqId())
+            .append("similarQuestion", getSimilarQuestion())
+            .append("sortNo", getSortNo())
+            .append("createBy", getCreateBy())
+            .append("updateBy", getUpdateBy())
+            .toString();
+    }
+}

+ 206 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsMediaAsset.java

@@ -0,0 +1,206 @@
+package com.ruoyi.base.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 素材资源对象 robot_ops_media_asset
+ * 
+ * @author ruoyi
+ * @date 2026-05-08
+ */
+public class RobotOpsMediaAsset extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 素材名称 */
+    @Excel(name = "素材名称")
+    private String assetName;
+
+    /** 素材类型 */
+    @Excel(name = "素材类型")
+    private String assetType;
+
+    /** 素材文件地址 */
+    private String fileUrl;
+
+    /** 缩略图地址 */
+    @Excel(name = "缩略图地址")
+    private String thumbnailUrl;
+
+    /** 文件大小 */
+    @Excel(name = "文件大小")
+    private Long fileSize;
+
+    /** 文件格式 */
+    @Excel(name = "文件格式")
+    private String fileFormat;
+
+    /** 文件MIME类型,如image/jpeg、video/mp4 */
+    @Excel(name = "文件MIME类型,如image/jpeg、video/mp4")
+    private String mimeType;
+
+    /** 视频时长,单位秒;图片为空 */
+    @Excel(name = "视频时长,单位秒;图片为空")
+    private Long durationSeconds;
+
+    /** 分辨率,如1920x1080 */
+    @Excel(name = "分辨率,如1920x1080")
+    private String resolution;
+
+    /** 启用状态:0停用,1启用 */
+    @Excel(name = "启用状态:0停用,1启用")
+    private String status;
+
+    /** 是否被播放方案引用:0否,1是,由系统维护 */
+    @Excel(name = "是否被播放方案引用:0否,1是,由系统维护")
+    private String quotedFlag;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setAssetName(String assetName) 
+    {
+        this.assetName = assetName;
+    }
+
+    public String getAssetName() 
+    {
+        return assetName;
+    }
+
+    public void setAssetType(String assetType) 
+    {
+        this.assetType = assetType;
+    }
+
+    public String getAssetType() 
+    {
+        return assetType;
+    }
+
+    public void setFileUrl(String fileUrl) 
+    {
+        this.fileUrl = fileUrl;
+    }
+
+    public String getFileUrl() 
+    {
+        return fileUrl;
+    }
+
+    public void setThumbnailUrl(String thumbnailUrl) 
+    {
+        this.thumbnailUrl = thumbnailUrl;
+    }
+
+    public String getThumbnailUrl() 
+    {
+        return thumbnailUrl;
+    }
+
+    public void setFileSize(Long fileSize) 
+    {
+        this.fileSize = fileSize;
+    }
+
+    public Long getFileSize() 
+    {
+        return fileSize;
+    }
+
+    public void setFileFormat(String fileFormat) 
+    {
+        this.fileFormat = fileFormat;
+    }
+
+    public String getFileFormat() 
+    {
+        return fileFormat;
+    }
+
+    public void setMimeType(String mimeType) 
+    {
+        this.mimeType = mimeType;
+    }
+
+    public String getMimeType() 
+    {
+        return mimeType;
+    }
+
+    public void setDurationSeconds(Long durationSeconds) 
+    {
+        this.durationSeconds = durationSeconds;
+    }
+
+    public Long getDurationSeconds() 
+    {
+        return durationSeconds;
+    }
+
+    public void setResolution(String resolution) 
+    {
+        this.resolution = resolution;
+    }
+
+    public String getResolution() 
+    {
+        return resolution;
+    }
+
+    public void setStatus(String status) 
+    {
+        this.status = status;
+    }
+
+    public String getStatus() 
+    {
+        return status;
+    }
+
+    public void setQuotedFlag(String quotedFlag) 
+    {
+        this.quotedFlag = quotedFlag;
+    }
+
+    public String getQuotedFlag() 
+    {
+        return quotedFlag;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("assetName", getAssetName())
+            .append("assetType", getAssetType())
+            .append("fileUrl", getFileUrl())
+            .append("thumbnailUrl", getThumbnailUrl())
+            .append("fileSize", getFileSize())
+            .append("fileFormat", getFileFormat())
+            .append("mimeType", getMimeType())
+            .append("durationSeconds", getDurationSeconds())
+            .append("resolution", getResolution())
+            .append("status", getStatus())
+            .append("quotedFlag", getQuotedFlag())
+            .append("remark", getRemark())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 120 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsPlayPlan.java

@@ -0,0 +1,120 @@
+package com.ruoyi.base.domain;
+
+import java.util.List;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 播放方案对象 robot_ops_play_plan
+ *
+ * @author ruoyi
+ * @date 2026-05-11
+ */
+public class RobotOpsPlayPlan extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 播放方案名称 */
+    @Excel(name = "播放方案名称")
+    private String planName;
+
+    /** 循环方式:loop循环播放,once播放一次 */
+    @Excel(name = "循环方式:loop循环播放,once播放一次")
+    private String loopMode;
+
+
+    /** 素材数量 */
+    @Excel(name = "素材数量")
+    private Long assetCount;
+
+    /** 启用状态:0备用/停用,1当前播放*/
+    @Excel(name = "0备用/停用,1当前播放")
+    private String status;
+
+    /** 播放方案素材明细信息 */
+    private List<RobotOpsPlayPlanItem> robotOpsPlayPlanItemList;
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setPlanName(String planName)
+    {
+        this.planName = planName;
+    }
+
+    public String getPlanName()
+    {
+        return planName;
+    }
+
+    public void setLoopMode(String loopMode)
+    {
+        this.loopMode = loopMode;
+    }
+
+    public String getLoopMode()
+    {
+        return loopMode;
+    }
+
+
+
+    public void setAssetCount(Long assetCount)
+    {
+        this.assetCount = assetCount;
+    }
+
+    public Long getAssetCount()
+    {
+        return assetCount;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public List<RobotOpsPlayPlanItem> getRobotOpsPlayPlanItemList()
+    {
+        return robotOpsPlayPlanItemList;
+    }
+
+    public void setRobotOpsPlayPlanItemList(List<RobotOpsPlayPlanItem> robotOpsPlayPlanItemList)
+    {
+        this.robotOpsPlayPlanItemList = robotOpsPlayPlanItemList;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("planName", getPlanName())
+            .append("loopMode", getLoopMode())
+            .append("assetCount", getAssetCount())
+            .append("status", getStatus())
+            .append("remark", getRemark())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("robotOpsPlayPlanItemList", getRobotOpsPlayPlanItemList())
+            .toString();
+    }
+}

+ 209 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsPlayPlanItem.java

@@ -0,0 +1,209 @@
+package com.ruoyi.base.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 播放方案素材明细对象 robot_ops_play_plan_item
+ *
+ * @author ruoyi
+ * @date 2026-05-11
+ */
+public class RobotOpsPlayPlanItem extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 播放方案ID,关联robot_ops_play_plan.id */
+    @Excel(name = "播放方案ID,关联robot_ops_play_plan.id")
+    private Long planId;
+
+    /** 素材ID,关联robot_ops_media_asset.id */
+    @Excel(name = "素材ID,关联robot_ops_media_asset.id")
+    private Long assetId;
+
+    /** 播放顺序,数字越小越靠前 */
+    @Excel(name = "播放顺序,数字越小越靠前")
+    private Long playOrder;
+
+    /** 停留时长,图片必填,视频可为空 */
+    @Excel(name = "停留时长,图片必填,视频可为空")
+    private Long staySeconds;
+
+    /** 转场方式,预留字段:none无转场,fade淡入淡出 */
+    @Excel(name = "转场方式,预留字段:none无转场,fade淡入淡出")
+    private String transitionType;
+
+
+    /** 素材文件地址 */
+    @Excel(name = "素材文件地址")
+    private String fileUrl;
+
+    /** 素材类型:image图片,video视频 */
+    @Excel(name = "素材类型")
+    private String assetType;
+
+
+    /** 分辨率,如1920x1080 */
+    @Excel(name = "分辨率")
+    private String resolution;
+
+    /** 视频时长,单位秒;图片为空 */
+    @Excel(name = "视频时长")
+    private Long durationSeconds;
+
+
+    /** 素材名称 */
+    @Excel(name = "素材名称")
+    private String assetName;
+
+
+    /** 缩略图地址 */
+    @Excel(name = "缩略图地址")
+    private String thumbnailUrl;
+
+
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+    public void setPlanId(Long planId)
+    {
+        this.planId = planId;
+    }
+
+    public Long getPlanId()
+    {
+        return planId;
+    }
+    public void setAssetId(Long assetId)
+    {
+        this.assetId = assetId;
+    }
+
+    public Long getAssetId()
+    {
+        return assetId;
+    }
+    public void setPlayOrder(Long playOrder)
+    {
+        this.playOrder = playOrder;
+    }
+
+    public Long getPlayOrder()
+    {
+        return playOrder;
+    }
+    public void setStaySeconds(Long staySeconds)
+    {
+        this.staySeconds = staySeconds;
+    }
+
+    public Long getStaySeconds()
+    {
+        return staySeconds;
+    }
+    public void setTransitionType(String transitionType)
+    {
+        this.transitionType = transitionType;
+    }
+
+    public String getTransitionType()
+    {
+        return transitionType;
+    }
+
+    public void setFileUrl(String fileUrl)
+    {
+        this.fileUrl = fileUrl;
+    }
+
+    public String getFileUrl()
+    {
+        return fileUrl;
+    }
+
+    public void setAssetType(String assetType)
+    {
+        this.assetType = assetType;
+    }
+
+    public String getAssetType()
+    {
+        return assetType;
+    }
+
+    public void setResolution(String resolution)
+    {
+        this.resolution = resolution;
+    }
+
+    public String getResolution()
+    {
+        return resolution;
+    }
+
+    public void setDurationSeconds(Long durationSeconds)
+    {
+        this.durationSeconds = durationSeconds;
+    }
+
+    public Long getDurationSeconds()
+    {
+        return durationSeconds;
+    }
+
+    public void setAssetName(String assetName)
+    {
+        this.assetName = assetName;
+    }
+
+    public String getAssetName()
+    {
+        return assetName;
+    }
+
+
+    public void setThumbnailUrl(String thumbnailUrl)
+    {
+        this.thumbnailUrl = thumbnailUrl;
+    }
+
+    public String getThumbnailUrl()
+    {
+        return thumbnailUrl;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("planId", getPlanId())
+                .append("assetId", getAssetId())
+                .append("playOrder", getPlayOrder())
+                .append("staySeconds", getStaySeconds())
+                .append("transitionType", getTransitionType())
+                .append("fileUrl", getFileUrl())
+                .append("assetType", getAssetType())
+                .append("assetName", getAssetName())
+                .append("thumbnailUrl", getThumbnailUrl())
+                .append("resolution", getResolution())
+                .append("durationSeconds", getDurationSeconds())
+                .append("createBy", getCreateBy())
+                .append("createTime", getCreateTime())
+                .append("updateBy", getUpdateBy())
+                .append("updateTime", getUpdateTime())
+                .toString();
+    }
+
+}

+ 177 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsScreenThemeConfig.java

@@ -0,0 +1,177 @@
+package com.ruoyi.base.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 展示主题配置对象 robot_ops_screen_theme_config
+ * 
+ * @author ruoyi
+ * @date 2026-05-14
+ */
+public class RobotOpsScreenThemeConfig extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 配置标识,默认配置固定为default */
+    @Excel(name = "配置标识,默认配置固定为default")
+    private String configKey;
+
+    /** Logo图片地址 */
+    @Excel(name = "Logo图片地址")
+    private String logoUrl;
+
+    /** 品牌标题/机器人名称 */
+    @Excel(name = "品牌标题/机器人名称")
+    private String robotName;
+
+    /** 品牌副标题 */
+    @Excel(name = "品牌副标题")
+    private String brandSubtitle;
+
+    /** 待机页背景图地址 */
+    @Excel(name = "待机页背景图地址")
+    private String backgroundImage;
+
+    /** 欢迎主标题 */
+    @Excel(name = "欢迎主标题")
+    private String welcomeTitle;
+
+    /** 欢迎副标题 */
+    @Excel(name = "欢迎副标题")
+    private String welcomeSubtitle;
+
+    /** 主按钮文案 */
+    @Excel(name = "主按钮文案")
+    private String touchText;
+
+    /** 主按钮颜色 */
+    @Excel(name = "主按钮颜色")
+    private String buttonColor;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setConfigKey(String configKey) 
+    {
+        this.configKey = configKey;
+    }
+
+    public String getConfigKey() 
+    {
+        return configKey;
+    }
+
+    public void setLogoUrl(String logoUrl) 
+    {
+        this.logoUrl = logoUrl;
+    }
+
+    public String getLogoUrl() 
+    {
+        return logoUrl;
+    }
+
+    public void setRobotName(String robotName) 
+    {
+        this.robotName = robotName;
+    }
+
+    public String getRobotName() 
+    {
+        return robotName;
+    }
+
+    public void setBrandSubtitle(String brandSubtitle) 
+    {
+        this.brandSubtitle = brandSubtitle;
+    }
+
+    public String getBrandSubtitle() 
+    {
+        return brandSubtitle;
+    }
+
+    public void setBackgroundImage(String backgroundImage) 
+    {
+        this.backgroundImage = backgroundImage;
+    }
+
+    public String getBackgroundImage() 
+    {
+        return backgroundImage;
+    }
+
+    public void setWelcomeTitle(String welcomeTitle) 
+    {
+        this.welcomeTitle = welcomeTitle;
+    }
+
+    public String getWelcomeTitle() 
+    {
+        return welcomeTitle;
+    }
+
+    public void setWelcomeSubtitle(String welcomeSubtitle) 
+    {
+        this.welcomeSubtitle = welcomeSubtitle;
+    }
+
+    public String getWelcomeSubtitle() 
+    {
+        return welcomeSubtitle;
+    }
+
+    public void setTouchText(String touchText) 
+    {
+        this.touchText = touchText;
+    }
+
+    public String getTouchText() 
+    {
+        return touchText;
+    }
+
+    public void setButtonColor(String buttonColor) 
+    {
+        this.buttonColor = buttonColor;
+    }
+
+    public String getButtonColor() 
+    {
+        return buttonColor;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("configKey", getConfigKey())
+            .append("logoUrl", getLogoUrl())
+            .append("robotName", getRobotName())
+            .append("brandSubtitle", getBrandSubtitle())
+            .append("backgroundImage", getBackgroundImage())
+            .append("welcomeTitle", getWelcomeTitle())
+            .append("welcomeSubtitle", getWelcomeSubtitle())
+            .append("touchText", getTouchText())
+            .append("buttonColor", getButtonColor())
+            .append("remark", getRemark())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 193 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsSysLog.java

@@ -0,0 +1,193 @@
+package com.ruoyi.base.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 运行日志对象 robot_ops_sys_log
+ * 
+ * @author ruoyi
+ * @date 2026-05-18
+ */
+public class RobotOpsSysLog extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 机器人编号 */
+    @Excel(name = "机器人编号")
+    private String robotCode;
+
+    /** 日志时间,设备侧或服务侧日志发生时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "日志时间,设备侧或服务侧日志发生时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date logTime;
+
+    /** 日志接收时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "日志接收时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date receiveTime;
+
+    /** 日志类型 */
+    @Excel(name = "日志类型")
+    private String logType;
+
+    /** 日志级别 */
+    @Excel(name = "日志级别")
+    private String logLevel;
+
+    /** 模块名称,如 screen、audio、camera、network、ota */
+    @Excel(name = "模块名称,如 screen、audio、camera、network、ota")
+    private String moduleName;
+
+    /** 日志摘要 */
+    @Excel(name = "日志摘要")
+    private String contentSummary;
+
+    /** 日志内容 */
+    @Excel(name = "日志内容")
+    private String content;
+
+    /** 结果状态 */
+    @Excel(name = "结果状态")
+    private String resultStatus;
+
+    /** 链路追踪ID */
+    @Excel(name = "链路追踪ID")
+    private String traceId;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setRobotCode(String robotCode) 
+    {
+        this.robotCode = robotCode;
+    }
+
+    public String getRobotCode() 
+    {
+        return robotCode;
+    }
+
+    public void setLogTime(Date logTime) 
+    {
+        this.logTime = logTime;
+    }
+
+    public Date getLogTime() 
+    {
+        return logTime;
+    }
+
+    public void setReceiveTime(Date receiveTime) 
+    {
+        this.receiveTime = receiveTime;
+    }
+
+    public Date getReceiveTime() 
+    {
+        return receiveTime;
+    }
+
+    public void setLogType(String logType) 
+    {
+        this.logType = logType;
+    }
+
+    public String getLogType() 
+    {
+        return logType;
+    }
+
+    public void setLogLevel(String logLevel) 
+    {
+        this.logLevel = logLevel;
+    }
+
+    public String getLogLevel() 
+    {
+        return logLevel;
+    }
+
+    public void setModuleName(String moduleName) 
+    {
+        this.moduleName = moduleName;
+    }
+
+    public String getModuleName() 
+    {
+        return moduleName;
+    }
+
+    public void setContentSummary(String contentSummary) 
+    {
+        this.contentSummary = contentSummary;
+    }
+
+    public String getContentSummary() 
+    {
+        return contentSummary;
+    }
+
+    public void setContent(String content) 
+    {
+        this.content = content;
+    }
+
+    public String getContent() 
+    {
+        return content;
+    }
+
+    public void setResultStatus(String resultStatus) 
+    {
+        this.resultStatus = resultStatus;
+    }
+
+    public String getResultStatus() 
+    {
+        return resultStatus;
+    }
+
+    public void setTraceId(String traceId) 
+    {
+        this.traceId = traceId;
+    }
+
+    public String getTraceId() 
+    {
+        return traceId;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("robotCode", getRobotCode())
+            .append("logTime", getLogTime())
+            .append("receiveTime", getReceiveTime())
+            .append("logType", getLogType())
+            .append("logLevel", getLogLevel())
+            .append("moduleName", getModuleName())
+            .append("contentSummary", getContentSummary())
+            .append("content", getContent())
+            .append("resultStatus", getResultStatus())
+            .append("traceId", getTraceId())
+            .append("remark", getRemark())
+            .append("createTime", getCreateTime())
+            .toString();
+    }
+}

+ 208 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsVisitorRecord.java

@@ -0,0 +1,208 @@
+package com.ruoyi.base.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 访客登记记录对象 robot_ops_visitor_record
+ *
+ * @author ruoyi
+ * @date 2026-04-30
+ */
+public class RobotOpsVisitorRecord extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 访客姓名 */
+    @Excel(name = "访客姓名")
+    private String visitorName;
+
+    /** 访客手机号 */
+    @Excel(name = "访客手机号")
+    private String mobile;
+
+    /** 证件号码 */
+    @Excel(name = "证件号码")
+    private String idCardNo;
+
+    /** 到访类型 */
+    @Excel(name = "到访类型")
+    private String visitType;
+
+    /** 访客来源,如公司、单位、亲友、外卖、快递、供应商等 */
+    @Excel(name = "访客来源,如公司、单位、亲友、外卖、快递、供应商等")
+    private String visitorSource;
+
+    /** 来访事由,如业务接洽、走亲访友、酒店入住、配送、维修、参观等 */
+    @Excel(name = "来访事由,如业务接洽、走亲访友、酒店入住、配送、维修、参观等")
+    private String visitReason;
+
+    /** 访客照片地址 */
+    @Excel(name = "访客照片地址")
+    private String visitorPhoto;
+
+    /** 关联预约单号,现场登记可为空 */
+    @Excel(name = "关联预约单号,现场登记可为空")
+    private String appointmentNo;
+
+    /** 被访人/被访对象 */
+    @Excel(name = "被访人/被访对象")
+    private String visitedPerson;
+
+    /** 来访/登记时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "来访/登记时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date visitTime;
+
+    /** 登记方式 */
+    @Excel(name = "登记方式")
+    private String registerType;
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setVisitorName(String visitorName)
+    {
+        this.visitorName = visitorName;
+    }
+
+    public String getVisitorName()
+    {
+        return visitorName;
+    }
+
+    public void setMobile(String mobile)
+    {
+        this.mobile = mobile;
+    }
+
+    public String getMobile()
+    {
+        return mobile;
+    }
+
+    public void setIdCardNo(String idCardNo)
+    {
+        this.idCardNo = idCardNo;
+    }
+
+    public String getIdCardNo()
+    {
+        return idCardNo;
+    }
+
+    public void setVisitType(String visitType)
+    {
+        this.visitType = visitType;
+    }
+
+    public String getVisitType()
+    {
+        return visitType;
+    }
+
+    public void setVisitorSource(String visitorSource)
+    {
+        this.visitorSource = visitorSource;
+    }
+
+    public String getVisitorSource()
+    {
+        return visitorSource;
+    }
+
+    public void setVisitReason(String visitReason)
+    {
+        this.visitReason = visitReason;
+    }
+
+    public String getVisitReason()
+    {
+        return visitReason;
+    }
+
+    public void setVisitorPhoto(String visitorPhoto)
+    {
+        this.visitorPhoto = visitorPhoto;
+    }
+
+    public String getVisitorPhoto()
+    {
+        return visitorPhoto;
+    }
+
+    public void setAppointmentNo(String appointmentNo)
+    {
+        this.appointmentNo = appointmentNo;
+    }
+
+    public String getAppointmentNo()
+    {
+        return appointmentNo;
+    }
+
+    public void setVisitedPerson(String visitedPerson)
+    {
+        this.visitedPerson = visitedPerson;
+    }
+
+    public String getVisitedPerson()
+    {
+        return visitedPerson;
+    }
+
+    public void setVisitTime(Date visitTime)
+    {
+        this.visitTime = visitTime;
+    }
+
+    public Date getVisitTime()
+    {
+        return visitTime;
+    }
+
+    public void setRegisterType(String registerType)
+    {
+        this.registerType = registerType;
+    }
+
+    public String getRegisterType()
+    {
+        return registerType;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("visitorName", getVisitorName())
+                .append("mobile", getMobile())
+                .append("idCardNo", getIdCardNo())
+                .append("visitType", getVisitType())
+                .append("visitorSource", getVisitorSource())
+                .append("visitReason", getVisitReason())
+                .append("visitorPhoto", getVisitorPhoto())
+                .append("appointmentNo", getAppointmentNo())
+                .append("visitedPerson", getVisitedPerson())
+                .append("visitTime", getVisitTime())
+                .append("remark", getRemark())
+                .append("createTime", getCreateTime())
+                .append("updateTime", getUpdateTime())
+                .append("registerType", getRegisterType())
+                .toString();
+    }
+}

+ 179 - 0
ruoyi-system/src/main/java/com/ruoyi/base/domain/RobotOpsWhitelist.java

@@ -0,0 +1,179 @@
+package com.ruoyi.base.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 访客白名单对象 robot_ops_whitelist
+ *
+ * @author ruoyi
+ * @date 2026-04-29
+ */
+public class RobotOpsWhitelist extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键ID */
+    private Long id;
+
+    /** 姓名 */
+    @Excel(name = "姓名")
+    private String name;
+
+    /** 手机号 */
+    @Excel(name = "手机号")
+    private String mobile;
+
+    /** 身份证号 */
+    @Excel(name = "身份证号")
+    private String idCardNo;
+
+    /** 人脸照片地址,用于机器人侧照片比对 */
+    @Excel(name = "人脸照片地址,用于机器人侧照片比对")
+    private String faceImageUrl;
+
+    /** 有效开始时间,不填表示立即生效 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "有效开始时间,不填表示立即生效", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date validStartTime;
+
+    /** 有效结束时间,不填表示长期有效 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "有效结束时间,不填表示长期有效", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date validEndTime;
+
+    /** 启用状态:0停用,1启用 */
+    @Excel(name = "启用状态:0停用,1启用")
+    private String status;
+
+    /** 人员类型 */
+    @Excel(name = "人员类型")
+    private Long whitelistType;
+
+    /** 来源类型 */
+    @Excel(name = "来源类型")
+    private Long sourceType;
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setMobile(String mobile)
+    {
+        this.mobile = mobile;
+    }
+
+    public String getMobile()
+    {
+        return mobile;
+    }
+
+    public void setIdCardNo(String idCardNo)
+    {
+        this.idCardNo = idCardNo;
+    }
+
+    public String getIdCardNo()
+    {
+        return idCardNo;
+    }
+
+    public void setFaceImageUrl(String faceImageUrl)
+    {
+        this.faceImageUrl = faceImageUrl;
+    }
+
+    public String getFaceImageUrl()
+    {
+        return faceImageUrl;
+    }
+
+    public void setValidStartTime(Date validStartTime)
+    {
+        this.validStartTime = validStartTime;
+    }
+
+    public Date getValidStartTime()
+    {
+        return validStartTime;
+    }
+
+    public void setValidEndTime(Date validEndTime)
+    {
+        this.validEndTime = validEndTime;
+    }
+
+    public Date getValidEndTime()
+    {
+        return validEndTime;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public void setWhitelistType(Long whitelistType)
+    {
+        this.whitelistType = whitelistType;
+    }
+
+    public Long getWhitelistType()
+    {
+        return whitelistType;
+    }
+
+    public void setSourceType(Long sourceType)
+    {
+        this.sourceType = sourceType;
+    }
+
+    public Long getSourceType()
+    {
+        return sourceType;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("name", getName())
+                .append("mobile", getMobile())
+                .append("idCardNo", getIdCardNo())
+                .append("faceImageUrl", getFaceImageUrl())
+                .append("validStartTime", getValidStartTime())
+                .append("validEndTime", getValidEndTime())
+                .append("status", getStatus())
+                .append("remark", getRemark())
+                .append("createTime", getCreateTime())
+                .append("updateTime", getUpdateTime())
+                .append("whitelistType", getWhitelistType())
+                .append("sourceType", getSourceType())
+                .toString();
+    }
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/AlarmLogMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.AlarmLog;
+
+/**
+ * 安防告警日志Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-20
+ */
+public interface AlarmLogMapper 
+{
+    /**
+     * 查询安防告警日志
+     * 
+     * @param id 安防告警日志主键
+     * @return 安防告警日志
+     */
+    public AlarmLog selectAlarmLogById(Long id);
+
+    /**
+     * 查询安防告警日志列表
+     * 
+     * @param alarmLog 安防告警日志
+     * @return 安防告警日志集合
+     */
+    public List<AlarmLog> selectAlarmLogList(AlarmLog alarmLog);
+
+    /**
+     * 新增安防告警日志
+     * 
+     * @param alarmLog 安防告警日志
+     * @return 结果
+     */
+    public int insertAlarmLog(AlarmLog alarmLog);
+
+    /**
+     * 修改安防告警日志
+     * 
+     * @param alarmLog 安防告警日志
+     * @return 结果
+     */
+    public int updateAlarmLog(AlarmLog alarmLog);
+
+    /**
+     * 删除安防告警日志
+     * 
+     * @param id 安防告警日志主键
+     * @return 结果
+     */
+    public int deleteAlarmLogById(Long id);
+
+    /**
+     * 批量删除安防告警日志
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteAlarmLogByIds(Long[] ids);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/DialogueLogMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.DialogueLog;
+
+/**
+ * 对话日志Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-19
+ */
+public interface DialogueLogMapper 
+{
+    /**
+     * 查询对话日志
+     * 
+     * @param id 对话日志主键
+     * @return 对话日志
+     */
+    public DialogueLog selectDialogueLogById(Long id);
+
+    /**
+     * 查询对话日志列表
+     * 
+     * @param dialogueLog 对话日志
+     * @return 对话日志集合
+     */
+    public List<DialogueLog> selectDialogueLogList(DialogueLog dialogueLog);
+
+    /**
+     * 新增对话日志
+     * 
+     * @param dialogueLog 对话日志
+     * @return 结果
+     */
+    public int insertDialogueLog(DialogueLog dialogueLog);
+
+    /**
+     * 修改对话日志
+     * 
+     * @param dialogueLog 对话日志
+     * @return 结果
+     */
+    public int updateDialogueLog(DialogueLog dialogueLog);
+
+    /**
+     * 删除对话日志
+     * 
+     * @param id 对话日志主键
+     * @return 结果
+     */
+    public int deleteDialogueLogById(Long id);
+
+    /**
+     * 批量删除对话日志
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteDialogueLogByIds(Long[] ids);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsAppointmentRecordMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsAppointmentRecord;
+
+/**
+ * 访客预约记录Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2026-04-28
+ */
+public interface RobotOpsAppointmentRecordMapper 
+{
+    /**
+     * 查询访客预约记录
+     * 
+     * @param id 访客预约记录主键
+     * @return 访客预约记录
+     */
+    public RobotOpsAppointmentRecord selectRobotOpsAppointmentRecordById(Long id);
+
+    /**
+     * 查询访客预约记录列表
+     * 
+     * @param robotOpsAppointmentRecord 访客预约记录
+     * @return 访客预约记录集合
+     */
+    public List<RobotOpsAppointmentRecord> selectRobotOpsAppointmentRecordList(RobotOpsAppointmentRecord robotOpsAppointmentRecord);
+
+    /**
+     * 新增访客预约记录
+     * 
+     * @param robotOpsAppointmentRecord 访客预约记录
+     * @return 结果
+     */
+    public int insertRobotOpsAppointmentRecord(RobotOpsAppointmentRecord robotOpsAppointmentRecord);
+
+    /**
+     * 修改访客预约记录
+     * 
+     * @param robotOpsAppointmentRecord 访客预约记录
+     * @return 结果
+     */
+    public int updateRobotOpsAppointmentRecord(RobotOpsAppointmentRecord robotOpsAppointmentRecord);
+
+    /**
+     * 删除访客预约记录
+     * 
+     * @param id 访客预约记录主键
+     * @return 结果
+     */
+    public int deleteRobotOpsAppointmentRecordById(Long id);
+
+    /**
+     * 批量删除访客预约记录
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsAppointmentRecordByIds(Long[] ids);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsBroadcastContentMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsBroadcastContent;
+
+/**
+ * 播报内容Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2026-04-27
+ */
+public interface RobotOpsBroadcastContentMapper 
+{
+    /**
+     * 查询播报内容
+     * 
+     * @param id 播报内容主键
+     * @return 播报内容
+     */
+    public RobotOpsBroadcastContent selectRobotOpsBroadcastContentById(Long id);
+
+    /**
+     * 查询播报内容列表
+     * 
+     * @param robotOpsBroadcastContent 播报内容
+     * @return 播报内容集合
+     */
+    public List<RobotOpsBroadcastContent> selectRobotOpsBroadcastContentList(RobotOpsBroadcastContent robotOpsBroadcastContent);
+
+    /**
+     * 新增播报内容
+     * 
+     * @param robotOpsBroadcastContent 播报内容
+     * @return 结果
+     */
+    public int insertRobotOpsBroadcastContent(RobotOpsBroadcastContent robotOpsBroadcastContent);
+
+    /**
+     * 修改播报内容
+     * 
+     * @param robotOpsBroadcastContent 播报内容
+     * @return 结果
+     */
+    public int updateRobotOpsBroadcastContent(RobotOpsBroadcastContent robotOpsBroadcastContent);
+
+    /**
+     * 删除播报内容
+     * 
+     * @param id 播报内容主键
+     * @return 结果
+     */
+    public int deleteRobotOpsBroadcastContentById(Long id);
+
+    /**
+     * 批量删除播报内容
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsBroadcastContentByIds(Long[] ids);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsBroadcastTaskMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsBroadcastTask;
+
+/**
+ * 播报任务Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2026-04-27
+ */
+public interface RobotOpsBroadcastTaskMapper 
+{
+    /**
+     * 查询播报任务
+     * 
+     * @param id 播报任务主键
+     * @return 播报任务
+     */
+    public RobotOpsBroadcastTask selectRobotOpsBroadcastTaskById(Long id);
+
+    /**
+     * 查询播报任务列表
+     * 
+     * @param robotOpsBroadcastTask 播报任务
+     * @return 播报任务集合
+     */
+    public List<RobotOpsBroadcastTask> selectRobotOpsBroadcastTaskList(RobotOpsBroadcastTask robotOpsBroadcastTask);
+
+    /**
+     * 新增播报任务
+     * 
+     * @param robotOpsBroadcastTask 播报任务
+     * @return 结果
+     */
+    public int insertRobotOpsBroadcastTask(RobotOpsBroadcastTask robotOpsBroadcastTask);
+
+    /**
+     * 修改播报任务
+     * 
+     * @param robotOpsBroadcastTask 播报任务
+     * @return 结果
+     */
+    public int updateRobotOpsBroadcastTask(RobotOpsBroadcastTask robotOpsBroadcastTask);
+
+    /**
+     * 删除播报任务
+     * 
+     * @param id 播报任务主键
+     * @return 结果
+     */
+    public int deleteRobotOpsBroadcastTaskById(Long id);
+
+    /**
+     * 批量删除播报任务
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsBroadcastTaskByIds(Long[] ids);
+}

+ 87 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsFaqMapper.java

@@ -0,0 +1,87 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsFaq;
+import com.ruoyi.base.domain.RobotOpsFaqSimilar;
+
+/**
+ * 问答库管理Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-07
+ */
+public interface RobotOpsFaqMapper 
+{
+    /**
+     * 查询问答库管理
+     * 
+     * @param id 问答库管理主键
+     * @return 问答库管理
+     */
+    public RobotOpsFaq selectRobotOpsFaqById(Long id);
+
+    /**
+     * 查询问答库管理列表
+     * 
+     * @param robotOpsFaq 问答库管理
+     * @return 问答库管理集合
+     */
+    public List<RobotOpsFaq> selectRobotOpsFaqList(RobotOpsFaq robotOpsFaq);
+
+    /**
+     * 新增问答库管理
+     * 
+     * @param robotOpsFaq 问答库管理
+     * @return 结果
+     */
+    public int insertRobotOpsFaq(RobotOpsFaq robotOpsFaq);
+
+    /**
+     * 修改问答库管理
+     * 
+     * @param robotOpsFaq 问答库管理
+     * @return 结果
+     */
+    public int updateRobotOpsFaq(RobotOpsFaq robotOpsFaq);
+
+    /**
+     * 删除问答库管理
+     * 
+     * @param id 问答库管理主键
+     * @return 结果
+     */
+    public int deleteRobotOpsFaqById(Long id);
+
+    /**
+     * 批量删除问答库管理
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsFaqByIds(Long[] ids);
+
+    /**
+     * 批量删除问答相似问
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsFaqSimilarByFaqIds(Long[] ids);
+    
+    /**
+     * 批量新增问答相似问
+     * 
+     * @param robotOpsFaqSimilarList 问答相似问列表
+     * @return 结果
+     */
+    public int batchRobotOpsFaqSimilar(List<RobotOpsFaqSimilar> robotOpsFaqSimilarList);
+    
+
+    /**
+     * 通过问答库管理主键删除问答相似问信息
+     * 
+     * @param id 问答库管理ID
+     * @return 结果
+     */
+    public int deleteRobotOpsFaqSimilarByFaqId(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsFaqSimilarMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsFaqSimilar;
+
+/**
+ * 相似问答表Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-07
+ */
+public interface RobotOpsFaqSimilarMapper 
+{
+    /**
+     * 查询相似问答表
+     * 
+     * @param id 相似问答表主键
+     * @return 相似问答表
+     */
+    public RobotOpsFaqSimilar selectRobotOpsFaqSimilarById(Long id);
+
+    /**
+     * 查询相似问答表列表
+     * 
+     * @param robotOpsFaqSimilar 相似问答表
+     * @return 相似问答表集合
+     */
+    public List<RobotOpsFaqSimilar> selectRobotOpsFaqSimilarList(RobotOpsFaqSimilar robotOpsFaqSimilar);
+
+    /**
+     * 新增相似问答表
+     * 
+     * @param robotOpsFaqSimilar 相似问答表
+     * @return 结果
+     */
+    public int insertRobotOpsFaqSimilar(RobotOpsFaqSimilar robotOpsFaqSimilar);
+
+    /**
+     * 修改相似问答表
+     * 
+     * @param robotOpsFaqSimilar 相似问答表
+     * @return 结果
+     */
+    public int updateRobotOpsFaqSimilar(RobotOpsFaqSimilar robotOpsFaqSimilar);
+
+    /**
+     * 删除相似问答表
+     * 
+     * @param id 相似问答表主键
+     * @return 结果
+     */
+    public int deleteRobotOpsFaqSimilarById(Long id);
+
+    /**
+     * 批量删除相似问答表
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsFaqSimilarByIds(Long[] ids);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsMediaAssetMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsMediaAsset;
+
+/**
+ * 素材资源Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-08
+ */
+public interface RobotOpsMediaAssetMapper 
+{
+    /**
+     * 查询素材资源
+     * 
+     * @param id 素材资源主键
+     * @return 素材资源
+     */
+    public RobotOpsMediaAsset selectRobotOpsMediaAssetById(Long id);
+
+    /**
+     * 查询素材资源列表
+     * 
+     * @param robotOpsMediaAsset 素材资源
+     * @return 素材资源集合
+     */
+    public List<RobotOpsMediaAsset> selectRobotOpsMediaAssetList(RobotOpsMediaAsset robotOpsMediaAsset);
+
+    /**
+     * 新增素材资源
+     * 
+     * @param robotOpsMediaAsset 素材资源
+     * @return 结果
+     */
+    public int insertRobotOpsMediaAsset(RobotOpsMediaAsset robotOpsMediaAsset);
+
+    /**
+     * 修改素材资源
+     * 
+     * @param robotOpsMediaAsset 素材资源
+     * @return 结果
+     */
+    public int updateRobotOpsMediaAsset(RobotOpsMediaAsset robotOpsMediaAsset);
+
+    /**
+     * 删除素材资源
+     * 
+     * @param id 素材资源主键
+     * @return 结果
+     */
+    public int deleteRobotOpsMediaAssetById(Long id);
+
+    /**
+     * 批量删除素材资源
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsMediaAssetByIds(Long[] ids);
+}

+ 114 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsPlayPlanMapper.java

@@ -0,0 +1,114 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsPlayPlan;
+import com.ruoyi.base.domain.RobotOpsPlayPlanItem;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 播放方案Mapper接口
+ *
+ * @author ruoyi
+ * @date 2026-05-11
+ */
+public interface RobotOpsPlayPlanMapper
+{
+    /**
+     * 查询播放方案
+     *
+     * @param id 播放方案主键
+     * @return 播放方案
+     */
+    public RobotOpsPlayPlan selectRobotOpsPlayPlanById(Long id);
+
+    /**
+     * 查询播放方案列表
+     *
+     * @param robotOpsPlayPlan 播放方案
+     * @return 播放方案集合
+     */
+    public List<RobotOpsPlayPlan> selectRobotOpsPlayPlanList(RobotOpsPlayPlan robotOpsPlayPlan);
+
+    /**
+     * 新增播放方案
+     *
+     * @param robotOpsPlayPlan 播放方案
+     * @return 结果
+     */
+    public int insertRobotOpsPlayPlan(RobotOpsPlayPlan robotOpsPlayPlan);
+
+    /**
+     * 修改播放方案
+     *
+     * @param robotOpsPlayPlan 播放方案
+     * @return 结果
+     */
+    public int updateRobotOpsPlayPlan(RobotOpsPlayPlan robotOpsPlayPlan);
+
+    /**
+     * 删除播放方案
+     *
+     * @param id 播放方案主键
+     * @return 结果
+     */
+    public int deleteRobotOpsPlayPlanById(Long id);
+
+    /**
+     * 批量删除播放方案
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsPlayPlanByIds(Long[] ids);
+
+    /**
+     * 批量删除播放方案素材明细
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsPlayPlanItemByPlanIds(Long[] ids);
+
+    /**
+     * 批量新增播放方案素材明细
+     *
+     * @param robotOpsPlayPlanItemList 播放方案素材明细列表
+     * @return 结果
+     */
+    public int batchRobotOpsPlayPlanItem(List<RobotOpsPlayPlanItem> robotOpsPlayPlanItemList);
+
+
+    /**
+     * 通过播放方案主键删除播放方案素材明细信息
+     *
+     * @param id 播放方案ID
+     * @return 结果
+     */
+    public int deleteRobotOpsPlayPlanItemByPlanId(Long id);
+
+
+    /**
+     * 查询当前正在播放的方案
+     *
+     * @return 播放方案
+     */
+    public RobotOpsPlayPlan selectCurrentPlayingPlan();
+
+    /**
+     * 根据方案ID查询素材明细列表
+     *
+     * @param planId 播放方案ID
+     * @return 素材明细列表
+     */
+    public List<RobotOpsPlayPlanItem> selectRobotOpsPlayPlanItemListByPlanId(Long planId);
+
+    /**
+     * 更新播放方案状态
+     *
+     * @param id 播放方案ID
+     * @param status 状态
+     * @return 结果
+     */
+    public int updatePlayPlanStatus(@Param("id") Long id, @Param("status") String status);
+
+}

+ 69 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsScreenThemeConfigMapper.java

@@ -0,0 +1,69 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsScreenThemeConfig;
+
+/**
+ * 展示主题配置Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-14
+ */
+public interface RobotOpsScreenThemeConfigMapper 
+{
+    /**
+     * 查询展示主题配置
+     *
+     * @param id 展示主题配置主键
+     * @return 展示主题配置
+     */
+    public RobotOpsScreenThemeConfig selectRobotOpsScreenThemeConfigById(Long id);
+
+    /**
+     * 根据配置标识查询展示主题配置
+     *
+     * @param configKey 配置标识
+     * @return 展示主题配置
+     */
+    public RobotOpsScreenThemeConfig selectRobotOpsScreenThemeConfigByConfigKey(String configKey);
+
+    /**
+     * 查询展示主题配置列表
+     * 
+     * @param robotOpsScreenThemeConfig 展示主题配置
+     * @return 展示主题配置集合
+     */
+    public List<RobotOpsScreenThemeConfig> selectRobotOpsScreenThemeConfigList(RobotOpsScreenThemeConfig robotOpsScreenThemeConfig);
+
+    /**
+     * 新增展示主题配置
+     * 
+     * @param robotOpsScreenThemeConfig 展示主题配置
+     * @return 结果
+     */
+    public int insertRobotOpsScreenThemeConfig(RobotOpsScreenThemeConfig robotOpsScreenThemeConfig);
+
+    /**
+     * 修改展示主题配置
+     * 
+     * @param robotOpsScreenThemeConfig 展示主题配置
+     * @return 结果
+     */
+    public int updateRobotOpsScreenThemeConfig(RobotOpsScreenThemeConfig robotOpsScreenThemeConfig);
+
+    /**
+     * 删除展示主题配置
+     * 
+     * @param id 展示主题配置主键
+     * @return 结果
+     */
+    public int deleteRobotOpsScreenThemeConfigById(Long id);
+
+    /**
+     * 批量删除展示主题配置
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsScreenThemeConfigByIds(Long[] ids);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsSysLogMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsSysLog;
+
+/**
+ * 运行日志Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-18
+ */
+public interface RobotOpsSysLogMapper 
+{
+    /**
+     * 查询运行日志
+     * 
+     * @param id 运行日志主键
+     * @return 运行日志
+     */
+    public RobotOpsSysLog selectRobotOpsSysLogById(Long id);
+
+    /**
+     * 查询运行日志列表
+     * 
+     * @param robotOpsSysLog 运行日志
+     * @return 运行日志集合
+     */
+    public List<RobotOpsSysLog> selectRobotOpsSysLogList(RobotOpsSysLog robotOpsSysLog);
+
+    /**
+     * 新增运行日志
+     * 
+     * @param robotOpsSysLog 运行日志
+     * @return 结果
+     */
+    public int insertRobotOpsSysLog(RobotOpsSysLog robotOpsSysLog);
+
+    /**
+     * 修改运行日志
+     * 
+     * @param robotOpsSysLog 运行日志
+     * @return 结果
+     */
+    public int updateRobotOpsSysLog(RobotOpsSysLog robotOpsSysLog);
+
+    /**
+     * 删除运行日志
+     * 
+     * @param id 运行日志主键
+     * @return 结果
+     */
+    public int deleteRobotOpsSysLogById(Long id);
+
+    /**
+     * 批量删除运行日志
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsSysLogByIds(Long[] ids);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsVisitorRecordMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsVisitorRecord;
+
+/**
+ * 访客登记记录Mapper接口
+ *
+ * @author ruoyi
+ * @date 2026-04-30
+ */
+public interface RobotOpsVisitorRecordMapper
+{
+    /**
+     * 查询访客登记记录
+     *
+     * @param id 访客登记记录主键
+     * @return 访客登记记录
+     */
+    public RobotOpsVisitorRecord selectRobotOpsVisitorRecordById(Long id);
+
+    /**
+     * 查询访客登记记录列表
+     *
+     * @param robotOpsVisitorRecord 访客登记记录
+     * @return 访客登记记录集合
+     */
+    public List<RobotOpsVisitorRecord> selectRobotOpsVisitorRecordList(RobotOpsVisitorRecord robotOpsVisitorRecord);
+
+    /**
+     * 新增访客登记记录
+     *
+     * @param robotOpsVisitorRecord 访客登记记录
+     * @return 结果
+     */
+    public int insertRobotOpsVisitorRecord(RobotOpsVisitorRecord robotOpsVisitorRecord);
+
+    /**
+     * 修改访客登记记录
+     *
+     * @param robotOpsVisitorRecord 访客登记记录
+     * @return 结果
+     */
+    public int updateRobotOpsVisitorRecord(RobotOpsVisitorRecord robotOpsVisitorRecord);
+
+    /**
+     * 删除访客登记记录
+     *
+     * @param id 访客登记记录主键
+     * @return 结果
+     */
+    public int deleteRobotOpsVisitorRecordById(Long id);
+
+    /**
+     * 批量删除访客登记记录
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsVisitorRecordByIds(Long[] ids);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/mapper/RobotOpsWhitelistMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.mapper;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsWhitelist;
+
+/**
+ * 访客白名单Mapper接口
+ *
+ * @author ruoyi
+ * @date 2026-04-29
+ */
+public interface RobotOpsWhitelistMapper
+{
+    /**
+     * 查询访客白名单
+     *
+     * @param id 访客白名单主键
+     * @return 访客白名单
+     */
+    public RobotOpsWhitelist selectRobotOpsWhitelistById(Long id);
+
+    /**
+     * 查询访客白名单列表
+     *
+     * @param robotOpsWhitelist 访客白名单
+     * @return 访客白名单集合
+     */
+    public List<RobotOpsWhitelist> selectRobotOpsWhitelistList(RobotOpsWhitelist robotOpsWhitelist);
+
+    /**
+     * 新增访客白名单
+     *
+     * @param robotOpsWhitelist 访客白名单
+     * @return 结果
+     */
+    public int insertRobotOpsWhitelist(RobotOpsWhitelist robotOpsWhitelist);
+
+    /**
+     * 修改访客白名单
+     *
+     * @param robotOpsWhitelist 访客白名单
+     * @return 结果
+     */
+    public int updateRobotOpsWhitelist(RobotOpsWhitelist robotOpsWhitelist);
+
+    /**
+     * 删除访客白名单
+     *
+     * @param id 访客白名单主键
+     * @return 结果
+     */
+    public int deleteRobotOpsWhitelistById(Long id);
+
+    /**
+     * 批量删除访客白名单
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsWhitelistByIds(Long[] ids);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IAlarmLogService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.AlarmLog;
+
+/**
+ * 安防告警日志Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-20
+ */
+public interface IAlarmLogService 
+{
+    /**
+     * 查询安防告警日志
+     * 
+     * @param id 安防告警日志主键
+     * @return 安防告警日志
+     */
+    public AlarmLog selectAlarmLogById(Long id);
+
+    /**
+     * 查询安防告警日志列表
+     * 
+     * @param alarmLog 安防告警日志
+     * @return 安防告警日志集合
+     */
+    public List<AlarmLog> selectAlarmLogList(AlarmLog alarmLog);
+
+    /**
+     * 新增安防告警日志
+     * 
+     * @param alarmLog 安防告警日志
+     * @return 结果
+     */
+    public int insertAlarmLog(AlarmLog alarmLog);
+
+    /**
+     * 修改安防告警日志
+     * 
+     * @param alarmLog 安防告警日志
+     * @return 结果
+     */
+    public int updateAlarmLog(AlarmLog alarmLog);
+
+    /**
+     * 批量删除安防告警日志
+     * 
+     * @param ids 需要删除的安防告警日志主键集合
+     * @return 结果
+     */
+    public int deleteAlarmLogByIds(Long[] ids);
+
+    /**
+     * 删除安防告警日志信息
+     * 
+     * @param id 安防告警日志主键
+     * @return 结果
+     */
+    public int deleteAlarmLogById(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IDialogueLogService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.DialogueLog;
+
+/**
+ * 对话日志Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-19
+ */
+public interface IDialogueLogService 
+{
+    /**
+     * 查询对话日志
+     * 
+     * @param id 对话日志主键
+     * @return 对话日志
+     */
+    public DialogueLog selectDialogueLogById(Long id);
+
+    /**
+     * 查询对话日志列表
+     * 
+     * @param dialogueLog 对话日志
+     * @return 对话日志集合
+     */
+    public List<DialogueLog> selectDialogueLogList(DialogueLog dialogueLog);
+
+    /**
+     * 新增对话日志
+     * 
+     * @param dialogueLog 对话日志
+     * @return 结果
+     */
+    public int insertDialogueLog(DialogueLog dialogueLog);
+
+    /**
+     * 修改对话日志
+     * 
+     * @param dialogueLog 对话日志
+     * @return 结果
+     */
+    public int updateDialogueLog(DialogueLog dialogueLog);
+
+    /**
+     * 批量删除对话日志
+     * 
+     * @param ids 需要删除的对话日志主键集合
+     * @return 结果
+     */
+    public int deleteDialogueLogByIds(Long[] ids);
+
+    /**
+     * 删除对话日志信息
+     * 
+     * @param id 对话日志主键
+     * @return 结果
+     */
+    public int deleteDialogueLogById(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsAppointmentRecordService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsAppointmentRecord;
+
+/**
+ * 访客预约记录Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-04-28
+ */
+public interface IRobotOpsAppointmentRecordService 
+{
+    /**
+     * 查询访客预约记录
+     * 
+     * @param id 访客预约记录主键
+     * @return 访客预约记录
+     */
+    public RobotOpsAppointmentRecord selectRobotOpsAppointmentRecordById(Long id);
+
+    /**
+     * 查询访客预约记录列表
+     * 
+     * @param robotOpsAppointmentRecord 访客预约记录
+     * @return 访客预约记录集合
+     */
+    public List<RobotOpsAppointmentRecord> selectRobotOpsAppointmentRecordList(RobotOpsAppointmentRecord robotOpsAppointmentRecord);
+
+    /**
+     * 新增访客预约记录
+     * 
+     * @param robotOpsAppointmentRecord 访客预约记录
+     * @return 结果
+     */
+    public int insertRobotOpsAppointmentRecord(RobotOpsAppointmentRecord robotOpsAppointmentRecord);
+
+    /**
+     * 修改访客预约记录
+     * 
+     * @param robotOpsAppointmentRecord 访客预约记录
+     * @return 结果
+     */
+    public int updateRobotOpsAppointmentRecord(RobotOpsAppointmentRecord robotOpsAppointmentRecord);
+
+    /**
+     * 批量删除访客预约记录
+     * 
+     * @param ids 需要删除的访客预约记录主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsAppointmentRecordByIds(Long[] ids);
+
+    /**
+     * 删除访客预约记录信息
+     * 
+     * @param id 访客预约记录主键
+     * @return 结果
+     */
+    public int deleteRobotOpsAppointmentRecordById(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsBroadcastContentService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsBroadcastContent;
+
+/**
+ * 播报内容Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-04-27
+ */
+public interface IRobotOpsBroadcastContentService 
+{
+    /**
+     * 查询播报内容
+     * 
+     * @param id 播报内容主键
+     * @return 播报内容
+     */
+    public RobotOpsBroadcastContent selectRobotOpsBroadcastContentById(Long id);
+
+    /**
+     * 查询播报内容列表
+     * 
+     * @param robotOpsBroadcastContent 播报内容
+     * @return 播报内容集合
+     */
+    public List<RobotOpsBroadcastContent> selectRobotOpsBroadcastContentList(RobotOpsBroadcastContent robotOpsBroadcastContent);
+
+    /**
+     * 新增播报内容
+     * 
+     * @param robotOpsBroadcastContent 播报内容
+     * @return 结果
+     */
+    public int insertRobotOpsBroadcastContent(RobotOpsBroadcastContent robotOpsBroadcastContent);
+
+    /**
+     * 修改播报内容
+     * 
+     * @param robotOpsBroadcastContent 播报内容
+     * @return 结果
+     */
+    public int updateRobotOpsBroadcastContent(RobotOpsBroadcastContent robotOpsBroadcastContent);
+
+    /**
+     * 批量删除播报内容
+     * 
+     * @param ids 需要删除的播报内容主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsBroadcastContentByIds(Long[] ids);
+
+    /**
+     * 删除播报内容信息
+     * 
+     * @param id 播报内容主键
+     * @return 结果
+     */
+    public int deleteRobotOpsBroadcastContentById(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsBroadcastTaskService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsBroadcastTask;
+
+/**
+ * 播报任务Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-04-27
+ */
+public interface IRobotOpsBroadcastTaskService 
+{
+    /**
+     * 查询播报任务
+     * 
+     * @param id 播报任务主键
+     * @return 播报任务
+     */
+    public RobotOpsBroadcastTask selectRobotOpsBroadcastTaskById(Long id);
+
+    /**
+     * 查询播报任务列表
+     * 
+     * @param robotOpsBroadcastTask 播报任务
+     * @return 播报任务集合
+     */
+    public List<RobotOpsBroadcastTask> selectRobotOpsBroadcastTaskList(RobotOpsBroadcastTask robotOpsBroadcastTask);
+
+    /**
+     * 新增播报任务
+     * 
+     * @param robotOpsBroadcastTask 播报任务
+     * @return 结果
+     */
+    public int insertRobotOpsBroadcastTask(RobotOpsBroadcastTask robotOpsBroadcastTask);
+
+    /**
+     * 修改播报任务
+     * 
+     * @param robotOpsBroadcastTask 播报任务
+     * @return 结果
+     */
+    public int updateRobotOpsBroadcastTask(RobotOpsBroadcastTask robotOpsBroadcastTask);
+
+    /**
+     * 批量删除播报任务
+     * 
+     * @param ids 需要删除的播报任务主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsBroadcastTaskByIds(Long[] ids);
+
+    /**
+     * 删除播报任务信息
+     * 
+     * @param id 播报任务主键
+     * @return 结果
+     */
+    public int deleteRobotOpsBroadcastTaskById(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsFaqService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsFaq;
+
+/**
+ * 问答库管理Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-07
+ */
+public interface IRobotOpsFaqService 
+{
+    /**
+     * 查询问答库管理
+     * 
+     * @param id 问答库管理主键
+     * @return 问答库管理
+     */
+    public RobotOpsFaq selectRobotOpsFaqById(Long id);
+
+    /**
+     * 查询问答库管理列表
+     * 
+     * @param robotOpsFaq 问答库管理
+     * @return 问答库管理集合
+     */
+    public List<RobotOpsFaq> selectRobotOpsFaqList(RobotOpsFaq robotOpsFaq);
+
+    /**
+     * 新增问答库管理
+     * 
+     * @param robotOpsFaq 问答库管理
+     * @return 结果
+     */
+    public int insertRobotOpsFaq(RobotOpsFaq robotOpsFaq);
+
+    /**
+     * 修改问答库管理
+     * 
+     * @param robotOpsFaq 问答库管理
+     * @return 结果
+     */
+    public int updateRobotOpsFaq(RobotOpsFaq robotOpsFaq);
+
+    /**
+     * 批量删除问答库管理
+     * 
+     * @param ids 需要删除的问答库管理主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsFaqByIds(Long[] ids);
+
+    /**
+     * 删除问答库管理信息
+     * 
+     * @param id 问答库管理主键
+     * @return 结果
+     */
+    public int deleteRobotOpsFaqById(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsFaqSimilarService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsFaqSimilar;
+
+/**
+ * 相似问答表Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-07
+ */
+public interface IRobotOpsFaqSimilarService 
+{
+    /**
+     * 查询相似问答表
+     * 
+     * @param id 相似问答表主键
+     * @return 相似问答表
+     */
+    public RobotOpsFaqSimilar selectRobotOpsFaqSimilarById(Long id);
+
+    /**
+     * 查询相似问答表列表
+     * 
+     * @param robotOpsFaqSimilar 相似问答表
+     * @return 相似问答表集合
+     */
+    public List<RobotOpsFaqSimilar> selectRobotOpsFaqSimilarList(RobotOpsFaqSimilar robotOpsFaqSimilar);
+
+    /**
+     * 新增相似问答表
+     * 
+     * @param robotOpsFaqSimilar 相似问答表
+     * @return 结果
+     */
+    public int insertRobotOpsFaqSimilar(RobotOpsFaqSimilar robotOpsFaqSimilar);
+
+    /**
+     * 修改相似问答表
+     * 
+     * @param robotOpsFaqSimilar 相似问答表
+     * @return 结果
+     */
+    public int updateRobotOpsFaqSimilar(RobotOpsFaqSimilar robotOpsFaqSimilar);
+
+    /**
+     * 批量删除相似问答表
+     * 
+     * @param ids 需要删除的相似问答表主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsFaqSimilarByIds(Long[] ids);
+
+    /**
+     * 删除相似问答表信息
+     * 
+     * @param id 相似问答表主键
+     * @return 结果
+     */
+    public int deleteRobotOpsFaqSimilarById(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsMediaAssetService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsMediaAsset;
+
+/**
+ * 素材资源Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-08
+ */
+public interface IRobotOpsMediaAssetService 
+{
+    /**
+     * 查询素材资源
+     * 
+     * @param id 素材资源主键
+     * @return 素材资源
+     */
+    public RobotOpsMediaAsset selectRobotOpsMediaAssetById(Long id);
+
+    /**
+     * 查询素材资源列表
+     * 
+     * @param robotOpsMediaAsset 素材资源
+     * @return 素材资源集合
+     */
+    public List<RobotOpsMediaAsset> selectRobotOpsMediaAssetList(RobotOpsMediaAsset robotOpsMediaAsset);
+
+    /**
+     * 新增素材资源
+     * 
+     * @param robotOpsMediaAsset 素材资源
+     * @return 结果
+     */
+    public int insertRobotOpsMediaAsset(RobotOpsMediaAsset robotOpsMediaAsset);
+
+    /**
+     * 修改素材资源
+     * 
+     * @param robotOpsMediaAsset 素材资源
+     * @return 结果
+     */
+    public int updateRobotOpsMediaAsset(RobotOpsMediaAsset robotOpsMediaAsset);
+
+    /**
+     * 批量删除素材资源
+     * 
+     * @param ids 需要删除的素材资源主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsMediaAssetByIds(Long[] ids);
+
+    /**
+     * 删除素材资源信息
+     * 
+     * @param id 素材资源主键
+     * @return 结果
+     */
+    public int deleteRobotOpsMediaAssetById(Long id);
+}

+ 68 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsPlayPlanService.java

@@ -0,0 +1,68 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsPlayPlan;
+
+/**
+ * 播放方案Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-11
+ */
+public interface IRobotOpsPlayPlanService 
+{
+    /**
+     * 查询播放方案
+     * 
+     * @param id 播放方案主键
+     * @return 播放方案
+     */
+    public RobotOpsPlayPlan selectRobotOpsPlayPlanById(Long id);
+
+    /**
+     * 查询播放方案列表
+     * 
+     * @param robotOpsPlayPlan 播放方案
+     * @return 播放方案集合
+     */
+    public List<RobotOpsPlayPlan> selectRobotOpsPlayPlanList(RobotOpsPlayPlan robotOpsPlayPlan);
+
+    /**
+     * 新增播放方案
+     * 
+     * @param robotOpsPlayPlan 播放方案
+     * @return 结果
+     */
+    public int insertRobotOpsPlayPlan(RobotOpsPlayPlan robotOpsPlayPlan);
+
+    /**
+     * 修改播放方案
+     * 
+     * @param robotOpsPlayPlan 播放方案
+     * @return 结果
+     */
+    public int updateRobotOpsPlayPlan(RobotOpsPlayPlan robotOpsPlayPlan);
+
+    /**
+     * 批量删除播放方案
+     * 
+     * @param ids 需要删除的播放方案主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsPlayPlanByIds(Long[] ids);
+
+    /**
+     * 删除播放方案信息
+     * 
+     * @param id 播放方案主键
+     * @return 结果
+     */
+    public int deleteRobotOpsPlayPlanById(Long id);
+
+    /**
+     * 查询当前正在播放的方案(包含素材项)
+     * 
+     * @return 播放方案
+     */
+    public RobotOpsPlayPlan selectCurrentPlayingPlanWithItems();
+}

+ 69 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsScreenThemeConfigService.java

@@ -0,0 +1,69 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsScreenThemeConfig;
+
+/**
+ * 展示主题配置Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-14
+ */
+public interface IRobotOpsScreenThemeConfigService 
+{
+    /**
+     * 查询展示主题配置
+     *
+     * @param id 展示主题配置主键
+     * @return 展示主题配置
+     */
+    public RobotOpsScreenThemeConfig selectRobotOpsScreenThemeConfigById(Long id);
+
+    /**
+     * 根据配置标识查询展示主题配置
+     *
+     * @param configKey 配置标识
+     * @return 展示主题配置
+     */
+    public RobotOpsScreenThemeConfig selectRobotOpsScreenThemeConfigByConfigKey(String configKey);
+
+    /**
+     * 查询展示主题配置列表
+     * 
+     * @param robotOpsScreenThemeConfig 展示主题配置
+     * @return 展示主题配置集合
+     */
+    public List<RobotOpsScreenThemeConfig> selectRobotOpsScreenThemeConfigList(RobotOpsScreenThemeConfig robotOpsScreenThemeConfig);
+
+    /**
+     * 新增展示主题配置
+     * 
+     * @param robotOpsScreenThemeConfig 展示主题配置
+     * @return 结果
+     */
+    public int insertRobotOpsScreenThemeConfig(RobotOpsScreenThemeConfig robotOpsScreenThemeConfig);
+
+    /**
+     * 修改展示主题配置
+     * 
+     * @param robotOpsScreenThemeConfig 展示主题配置
+     * @return 结果
+     */
+    public int updateRobotOpsScreenThemeConfig(RobotOpsScreenThemeConfig robotOpsScreenThemeConfig);
+
+    /**
+     * 批量删除展示主题配置
+     * 
+     * @param ids 需要删除的展示主题配置主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsScreenThemeConfigByIds(Long[] ids);
+
+    /**
+     * 删除展示主题配置信息
+     * 
+     * @param id 展示主题配置主键
+     * @return 结果
+     */
+    public int deleteRobotOpsScreenThemeConfigById(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsSysLogService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsSysLog;
+
+/**
+ * 运行日志Service接口
+ * 
+ * @author ruoyi
+ * @date 2026-05-18
+ */
+public interface IRobotOpsSysLogService 
+{
+    /**
+     * 查询运行日志
+     * 
+     * @param id 运行日志主键
+     * @return 运行日志
+     */
+    public RobotOpsSysLog selectRobotOpsSysLogById(Long id);
+
+    /**
+     * 查询运行日志列表
+     * 
+     * @param robotOpsSysLog 运行日志
+     * @return 运行日志集合
+     */
+    public List<RobotOpsSysLog> selectRobotOpsSysLogList(RobotOpsSysLog robotOpsSysLog);
+
+    /**
+     * 新增运行日志
+     * 
+     * @param robotOpsSysLog 运行日志
+     * @return 结果
+     */
+    public int insertRobotOpsSysLog(RobotOpsSysLog robotOpsSysLog);
+
+    /**
+     * 修改运行日志
+     * 
+     * @param robotOpsSysLog 运行日志
+     * @return 结果
+     */
+    public int updateRobotOpsSysLog(RobotOpsSysLog robotOpsSysLog);
+
+    /**
+     * 批量删除运行日志
+     * 
+     * @param ids 需要删除的运行日志主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsSysLogByIds(Long[] ids);
+
+    /**
+     * 删除运行日志信息
+     * 
+     * @param id 运行日志主键
+     * @return 结果
+     */
+    public int deleteRobotOpsSysLogById(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsVisitorRecordService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsVisitorRecord;
+
+/**
+ * 访客登记记录Service接口
+ *
+ * @author ruoyi
+ * @date 2026-04-30
+ */
+public interface IRobotOpsVisitorRecordService
+{
+    /**
+     * 查询访客登记记录
+     *
+     * @param id 访客登记记录主键
+     * @return 访客登记记录
+     */
+    public RobotOpsVisitorRecord selectRobotOpsVisitorRecordById(Long id);
+
+    /**
+     * 查询访客登记记录列表
+     *
+     * @param robotOpsVisitorRecord 访客登记记录
+     * @return 访客登记记录集合
+     */
+    public List<RobotOpsVisitorRecord> selectRobotOpsVisitorRecordList(RobotOpsVisitorRecord robotOpsVisitorRecord);
+
+    /**
+     * 新增访客登记记录
+     *
+     * @param robotOpsVisitorRecord 访客登记记录
+     * @return 结果
+     */
+    public int insertRobotOpsVisitorRecord(RobotOpsVisitorRecord robotOpsVisitorRecord);
+
+    /**
+     * 修改访客登记记录
+     *
+     * @param robotOpsVisitorRecord 访客登记记录
+     * @return 结果
+     */
+    public int updateRobotOpsVisitorRecord(RobotOpsVisitorRecord robotOpsVisitorRecord);
+
+    /**
+     * 批量删除访客登记记录
+     *
+     * @param ids 需要删除的访客登记记录主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsVisitorRecordByIds(Long[] ids);
+
+    /**
+     * 删除访客登记记录信息
+     *
+     * @param id 访客登记记录主键
+     * @return 结果
+     */
+    public int deleteRobotOpsVisitorRecordById(Long id);
+}

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/IRobotOpsWhitelistService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.base.service;
+
+import java.util.List;
+import com.ruoyi.base.domain.RobotOpsWhitelist;
+
+/**
+ * 访客白名单Service接口
+ *
+ * @author ruoyi
+ * @date 2026-04-29
+ */
+public interface IRobotOpsWhitelistService
+{
+    /**
+     * 查询访客白名单
+     *
+     * @param id 访客白名单主键
+     * @return 访客白名单
+     */
+    public RobotOpsWhitelist selectRobotOpsWhitelistById(Long id);
+
+    /**
+     * 查询访客白名单列表
+     *
+     * @param robotOpsWhitelist 访客白名单
+     * @return 访客白名单集合
+     */
+    public List<RobotOpsWhitelist> selectRobotOpsWhitelistList(RobotOpsWhitelist robotOpsWhitelist);
+
+    /**
+     * 新增访客白名单
+     *
+     * @param robotOpsWhitelist 访客白名单
+     * @return 结果
+     */
+    public int insertRobotOpsWhitelist(RobotOpsWhitelist robotOpsWhitelist);
+
+    /**
+     * 修改访客白名单
+     *
+     * @param robotOpsWhitelist 访客白名单
+     * @return 结果
+     */
+    public int updateRobotOpsWhitelist(RobotOpsWhitelist robotOpsWhitelist);
+
+    /**
+     * 批量删除访客白名单
+     *
+     * @param ids 需要删除的访客白名单主键集合
+     * @return 结果
+     */
+    public int deleteRobotOpsWhitelistByIds(Long[] ids);
+
+    /**
+     * 删除访客白名单信息
+     *
+     * @param id 访客白名单主键
+     * @return 结果
+     */
+    public int deleteRobotOpsWhitelistById(Long id);
+}

+ 95 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/AlarmLogServiceImpl.java

@@ -0,0 +1,95 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.AlarmLogMapper;
+import com.ruoyi.base.domain.AlarmLog;
+import com.ruoyi.base.service.IAlarmLogService;
+
+/**
+ * 安防告警日志Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2026-05-20
+ */
+@Service
+public class AlarmLogServiceImpl implements IAlarmLogService 
+{
+    @Autowired
+    private AlarmLogMapper alarmLogMapper;
+
+    /**
+     * 查询安防告警日志
+     * 
+     * @param id 安防告警日志主键
+     * @return 安防告警日志
+     */
+    @Override
+    public AlarmLog selectAlarmLogById(Long id)
+    {
+        return alarmLogMapper.selectAlarmLogById(id);
+    }
+
+    /**
+     * 查询安防告警日志列表
+     * 
+     * @param alarmLog 安防告警日志
+     * @return 安防告警日志
+     */
+    @Override
+    public List<AlarmLog> selectAlarmLogList(AlarmLog alarmLog)
+    {
+        return alarmLogMapper.selectAlarmLogList(alarmLog);
+    }
+
+    /**
+     * 新增安防告警日志
+     * 
+     * @param alarmLog 安防告警日志
+     * @return 结果
+     */
+    @Override
+    public int insertAlarmLog(AlarmLog alarmLog)
+    {
+        alarmLog.setCreateTime(DateUtils.getNowDate());
+        return alarmLogMapper.insertAlarmLog(alarmLog);
+    }
+
+    /**
+     * 修改安防告警日志
+     * 
+     * @param alarmLog 安防告警日志
+     * @return 结果
+     */
+    @Override
+    public int updateAlarmLog(AlarmLog alarmLog)
+    {
+        return alarmLogMapper.updateAlarmLog(alarmLog);
+    }
+
+    /**
+     * 批量删除安防告警日志
+     * 
+     * @param ids 需要删除的安防告警日志主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlarmLogByIds(Long[] ids)
+    {
+        return alarmLogMapper.deleteAlarmLogByIds(ids);
+    }
+
+    /**
+     * 删除安防告警日志信息
+     * 
+     * @param id 安防告警日志主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlarmLogById(Long id)
+    {
+        return alarmLogMapper.deleteAlarmLogById(id);
+    }
+}

+ 95 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/DialogueLogServiceImpl.java

@@ -0,0 +1,95 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.DialogueLogMapper;
+import com.ruoyi.base.domain.DialogueLog;
+import com.ruoyi.base.service.IDialogueLogService;
+
+/**
+ * 对话日志Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2026-05-19
+ */
+@Service
+public class DialogueLogServiceImpl implements IDialogueLogService 
+{
+    @Autowired
+    private DialogueLogMapper dialogueLogMapper;
+
+    /**
+     * 查询对话日志
+     * 
+     * @param id 对话日志主键
+     * @return 对话日志
+     */
+    @Override
+    public DialogueLog selectDialogueLogById(Long id)
+    {
+        return dialogueLogMapper.selectDialogueLogById(id);
+    }
+
+    /**
+     * 查询对话日志列表
+     * 
+     * @param dialogueLog 对话日志
+     * @return 对话日志
+     */
+    @Override
+    public List<DialogueLog> selectDialogueLogList(DialogueLog dialogueLog)
+    {
+        return dialogueLogMapper.selectDialogueLogList(dialogueLog);
+    }
+
+    /**
+     * 新增对话日志
+     * 
+     * @param dialogueLog 对话日志
+     * @return 结果
+     */
+    @Override
+    public int insertDialogueLog(DialogueLog dialogueLog)
+    {
+        dialogueLog.setCreateTime(DateUtils.getNowDate());
+        return dialogueLogMapper.insertDialogueLog(dialogueLog);
+    }
+
+    /**
+     * 修改对话日志
+     * 
+     * @param dialogueLog 对话日志
+     * @return 结果
+     */
+    @Override
+    public int updateDialogueLog(DialogueLog dialogueLog)
+    {
+        return dialogueLogMapper.updateDialogueLog(dialogueLog);
+    }
+
+    /**
+     * 批量删除对话日志
+     * 
+     * @param ids 需要删除的对话日志主键
+     * @return 结果
+     */
+    @Override
+    public int deleteDialogueLogByIds(Long[] ids)
+    {
+        return dialogueLogMapper.deleteDialogueLogByIds(ids);
+    }
+
+    /**
+     * 删除对话日志信息
+     * 
+     * @param id 对话日志主键
+     * @return 结果
+     */
+    @Override
+    public int deleteDialogueLogById(Long id)
+    {
+        return dialogueLogMapper.deleteDialogueLogById(id);
+    }
+}

+ 96 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsAppointmentRecordServiceImpl.java

@@ -0,0 +1,96 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.RobotOpsAppointmentRecordMapper;
+import com.ruoyi.base.domain.RobotOpsAppointmentRecord;
+import com.ruoyi.base.service.IRobotOpsAppointmentRecordService;
+
+/**
+ * 访客预约记录Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2026-04-28
+ */
+@Service
+public class RobotOpsAppointmentRecordServiceImpl implements IRobotOpsAppointmentRecordService 
+{
+    @Autowired
+    private RobotOpsAppointmentRecordMapper robotOpsAppointmentRecordMapper;
+
+    /**
+     * 查询访客预约记录
+     * 
+     * @param id 访客预约记录主键
+     * @return 访客预约记录
+     */
+    @Override
+    public RobotOpsAppointmentRecord selectRobotOpsAppointmentRecordById(Long id)
+    {
+        return robotOpsAppointmentRecordMapper.selectRobotOpsAppointmentRecordById(id);
+    }
+
+    /**
+     * 查询访客预约记录列表
+     * 
+     * @param robotOpsAppointmentRecord 访客预约记录
+     * @return 访客预约记录
+     */
+    @Override
+    public List<RobotOpsAppointmentRecord> selectRobotOpsAppointmentRecordList(RobotOpsAppointmentRecord robotOpsAppointmentRecord)
+    {
+        return robotOpsAppointmentRecordMapper.selectRobotOpsAppointmentRecordList(robotOpsAppointmentRecord);
+    }
+
+    /**
+     * 新增访客预约记录
+     * 
+     * @param robotOpsAppointmentRecord 访客预约记录
+     * @return 结果
+     */
+    @Override
+    public int insertRobotOpsAppointmentRecord(RobotOpsAppointmentRecord robotOpsAppointmentRecord)
+    {
+        robotOpsAppointmentRecord.setCreateTime(DateUtils.getNowDate());
+        return robotOpsAppointmentRecordMapper.insertRobotOpsAppointmentRecord(robotOpsAppointmentRecord);
+    }
+
+    /**
+     * 修改访客预约记录
+     * 
+     * @param robotOpsAppointmentRecord 访客预约记录
+     * @return 结果
+     */
+    @Override
+    public int updateRobotOpsAppointmentRecord(RobotOpsAppointmentRecord robotOpsAppointmentRecord)
+    {
+        robotOpsAppointmentRecord.setUpdateTime(DateUtils.getNowDate());
+        return robotOpsAppointmentRecordMapper.updateRobotOpsAppointmentRecord(robotOpsAppointmentRecord);
+    }
+
+    /**
+     * 批量删除访客预约记录
+     * 
+     * @param ids 需要删除的访客预约记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsAppointmentRecordByIds(Long[] ids)
+    {
+        return robotOpsAppointmentRecordMapper.deleteRobotOpsAppointmentRecordByIds(ids);
+    }
+
+    /**
+     * 删除访客预约记录信息
+     * 
+     * @param id 访客预约记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsAppointmentRecordById(Long id)
+    {
+        return robotOpsAppointmentRecordMapper.deleteRobotOpsAppointmentRecordById(id);
+    }
+}

+ 96 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsBroadcastContentServiceImpl.java

@@ -0,0 +1,96 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.RobotOpsBroadcastContentMapper;
+import com.ruoyi.base.domain.RobotOpsBroadcastContent;
+import com.ruoyi.base.service.IRobotOpsBroadcastContentService;
+
+/**
+ * 播报内容Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2026-04-27
+ */
+@Service
+public class RobotOpsBroadcastContentServiceImpl implements IRobotOpsBroadcastContentService 
+{
+    @Autowired
+    private RobotOpsBroadcastContentMapper robotOpsBroadcastContentMapper;
+
+    /**
+     * 查询播报内容
+     * 
+     * @param id 播报内容主键
+     * @return 播报内容
+     */
+    @Override
+    public RobotOpsBroadcastContent selectRobotOpsBroadcastContentById(Long id)
+    {
+        return robotOpsBroadcastContentMapper.selectRobotOpsBroadcastContentById(id);
+    }
+
+    /**
+     * 查询播报内容列表
+     * 
+     * @param robotOpsBroadcastContent 播报内容
+     * @return 播报内容
+     */
+    @Override
+    public List<RobotOpsBroadcastContent> selectRobotOpsBroadcastContentList(RobotOpsBroadcastContent robotOpsBroadcastContent)
+    {
+        return robotOpsBroadcastContentMapper.selectRobotOpsBroadcastContentList(robotOpsBroadcastContent);
+    }
+
+    /**
+     * 新增播报内容
+     * 
+     * @param robotOpsBroadcastContent 播报内容
+     * @return 结果
+     */
+    @Override
+    public int insertRobotOpsBroadcastContent(RobotOpsBroadcastContent robotOpsBroadcastContent)
+    {
+        robotOpsBroadcastContent.setCreateTime(DateUtils.getNowDate());
+        return robotOpsBroadcastContentMapper.insertRobotOpsBroadcastContent(robotOpsBroadcastContent);
+    }
+
+    /**
+     * 修改播报内容
+     * 
+     * @param robotOpsBroadcastContent 播报内容
+     * @return 结果
+     */
+    @Override
+    public int updateRobotOpsBroadcastContent(RobotOpsBroadcastContent robotOpsBroadcastContent)
+    {
+        robotOpsBroadcastContent.setUpdateTime(DateUtils.getNowDate());
+        return robotOpsBroadcastContentMapper.updateRobotOpsBroadcastContent(robotOpsBroadcastContent);
+    }
+
+    /**
+     * 批量删除播报内容
+     * 
+     * @param ids 需要删除的播报内容主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsBroadcastContentByIds(Long[] ids)
+    {
+        return robotOpsBroadcastContentMapper.deleteRobotOpsBroadcastContentByIds(ids);
+    }
+
+    /**
+     * 删除播报内容信息
+     * 
+     * @param id 播报内容主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsBroadcastContentById(Long id)
+    {
+        return robotOpsBroadcastContentMapper.deleteRobotOpsBroadcastContentById(id);
+    }
+}

+ 96 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsBroadcastTaskServiceImpl.java

@@ -0,0 +1,96 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.RobotOpsBroadcastTaskMapper;
+import com.ruoyi.base.domain.RobotOpsBroadcastTask;
+import com.ruoyi.base.service.IRobotOpsBroadcastTaskService;
+
+/**
+ * 播报任务Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2026-04-27
+ */
+@Service
+public class RobotOpsBroadcastTaskServiceImpl implements IRobotOpsBroadcastTaskService 
+{
+    @Autowired
+    private RobotOpsBroadcastTaskMapper robotOpsBroadcastTaskMapper;
+
+    /**
+     * 查询播报任务
+     * 
+     * @param id 播报任务主键
+     * @return 播报任务
+     */
+    @Override
+    public RobotOpsBroadcastTask selectRobotOpsBroadcastTaskById(Long id)
+    {
+        return robotOpsBroadcastTaskMapper.selectRobotOpsBroadcastTaskById(id);
+    }
+
+    /**
+     * 查询播报任务列表
+     * 
+     * @param robotOpsBroadcastTask 播报任务
+     * @return 播报任务
+     */
+    @Override
+    public List<RobotOpsBroadcastTask> selectRobotOpsBroadcastTaskList(RobotOpsBroadcastTask robotOpsBroadcastTask)
+    {
+        return robotOpsBroadcastTaskMapper.selectRobotOpsBroadcastTaskList(robotOpsBroadcastTask);
+    }
+
+    /**
+     * 新增播报任务
+     * 
+     * @param robotOpsBroadcastTask 播报任务
+     * @return 结果
+     */
+    @Override
+    public int insertRobotOpsBroadcastTask(RobotOpsBroadcastTask robotOpsBroadcastTask)
+    {
+        robotOpsBroadcastTask.setCreateTime(DateUtils.getNowDate());
+        return robotOpsBroadcastTaskMapper.insertRobotOpsBroadcastTask(robotOpsBroadcastTask);
+    }
+
+    /**
+     * 修改播报任务
+     * 
+     * @param robotOpsBroadcastTask 播报任务
+     * @return 结果
+     */
+    @Override
+    public int updateRobotOpsBroadcastTask(RobotOpsBroadcastTask robotOpsBroadcastTask)
+    {
+        robotOpsBroadcastTask.setUpdateTime(DateUtils.getNowDate());
+        return robotOpsBroadcastTaskMapper.updateRobotOpsBroadcastTask(robotOpsBroadcastTask);
+    }
+
+    /**
+     * 批量删除播报任务
+     * 
+     * @param ids 需要删除的播报任务主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsBroadcastTaskByIds(Long[] ids)
+    {
+        return robotOpsBroadcastTaskMapper.deleteRobotOpsBroadcastTaskByIds(ids);
+    }
+
+    /**
+     * 删除播报任务信息
+     * 
+     * @param id 播报任务主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsBroadcastTaskById(Long id)
+    {
+        return robotOpsBroadcastTaskMapper.deleteRobotOpsBroadcastTaskById(id);
+    }
+}

+ 134 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsFaqServiceImpl.java

@@ -0,0 +1,134 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.ArrayList;
+import com.ruoyi.common.utils.StringUtils;
+import org.springframework.transaction.annotation.Transactional;
+import com.ruoyi.base.domain.RobotOpsFaqSimilar;
+import com.ruoyi.base.mapper.RobotOpsFaqMapper;
+import com.ruoyi.base.domain.RobotOpsFaq;
+import com.ruoyi.base.service.IRobotOpsFaqService;
+
+/**
+ * 问答库管理Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2026-05-07
+ */
+@Service
+public class RobotOpsFaqServiceImpl implements IRobotOpsFaqService 
+{
+    @Autowired
+    private RobotOpsFaqMapper robotOpsFaqMapper;
+
+    /**
+     * 查询问答库管理
+     * 
+     * @param id 问答库管理主键
+     * @return 问答库管理
+     */
+    @Override
+    public RobotOpsFaq selectRobotOpsFaqById(Long id)
+    {
+        return robotOpsFaqMapper.selectRobotOpsFaqById(id);
+    }
+
+    /**
+     * 查询问答库管理列表
+     * 
+     * @param robotOpsFaq 问答库管理
+     * @return 问答库管理
+     */
+    @Override
+    public List<RobotOpsFaq> selectRobotOpsFaqList(RobotOpsFaq robotOpsFaq)
+    {
+        return robotOpsFaqMapper.selectRobotOpsFaqList(robotOpsFaq);
+    }
+
+    /**
+     * 新增问答库管理
+     * 
+     * @param robotOpsFaq 问答库管理
+     * @return 结果
+     */
+    @Transactional
+    @Override
+    public int insertRobotOpsFaq(RobotOpsFaq robotOpsFaq)
+    {
+        robotOpsFaq.setCreateTime(DateUtils.getNowDate());
+        int rows = robotOpsFaqMapper.insertRobotOpsFaq(robotOpsFaq);
+        insertRobotOpsFaqSimilar(robotOpsFaq);
+        return rows;
+    }
+
+    /**
+     * 修改问答库管理
+     * 
+     * @param robotOpsFaq 问答库管理
+     * @return 结果
+     */
+    @Transactional
+    @Override
+    public int updateRobotOpsFaq(RobotOpsFaq robotOpsFaq)
+    {
+        robotOpsFaq.setUpdateTime(DateUtils.getNowDate());
+        robotOpsFaqMapper.deleteRobotOpsFaqSimilarByFaqId(robotOpsFaq.getId());
+        insertRobotOpsFaqSimilar(robotOpsFaq);
+        return robotOpsFaqMapper.updateRobotOpsFaq(robotOpsFaq);
+    }
+
+    /**
+     * 批量删除问答库管理
+     * 
+     * @param ids 需要删除的问答库管理主键
+     * @return 结果
+     */
+    @Transactional
+    @Override
+    public int deleteRobotOpsFaqByIds(Long[] ids)
+    {
+        robotOpsFaqMapper.deleteRobotOpsFaqSimilarByFaqIds(ids);
+        return robotOpsFaqMapper.deleteRobotOpsFaqByIds(ids);
+    }
+
+    /**
+     * 删除问答库管理信息
+     * 
+     * @param id 问答库管理主键
+     * @return 结果
+     */
+    @Transactional
+    @Override
+    public int deleteRobotOpsFaqById(Long id)
+    {
+        robotOpsFaqMapper.deleteRobotOpsFaqSimilarByFaqId(id);
+        return robotOpsFaqMapper.deleteRobotOpsFaqById(id);
+    }
+
+    /**
+     * 新增问答相似问信息
+     * 
+     * @param robotOpsFaq 问答库管理对象
+     */
+    public void insertRobotOpsFaqSimilar(RobotOpsFaq robotOpsFaq)
+    {
+        List<RobotOpsFaqSimilar> robotOpsFaqSimilarList = robotOpsFaq.getRobotOpsFaqSimilarList();
+        Long id = robotOpsFaq.getId();
+        if (StringUtils.isNotNull(robotOpsFaqSimilarList))
+        {
+            List<RobotOpsFaqSimilar> list = new ArrayList<RobotOpsFaqSimilar>();
+            for (RobotOpsFaqSimilar robotOpsFaqSimilar : robotOpsFaqSimilarList)
+            {
+                robotOpsFaqSimilar.setFaqId(id);
+                list.add(robotOpsFaqSimilar);
+            }
+            if (list.size() > 0)
+            {
+                robotOpsFaqMapper.batchRobotOpsFaqSimilar(list);
+            }
+        }
+    }
+}

+ 93 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsFaqSimilarServiceImpl.java

@@ -0,0 +1,93 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.RobotOpsFaqSimilarMapper;
+import com.ruoyi.base.domain.RobotOpsFaqSimilar;
+import com.ruoyi.base.service.IRobotOpsFaqSimilarService;
+
+/**
+ * 相似问答表Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2026-05-07
+ */
+@Service
+public class RobotOpsFaqSimilarServiceImpl implements IRobotOpsFaqSimilarService 
+{
+    @Autowired
+    private RobotOpsFaqSimilarMapper robotOpsFaqSimilarMapper;
+
+    /**
+     * 查询相似问答表
+     * 
+     * @param id 相似问答表主键
+     * @return 相似问答表
+     */
+    @Override
+    public RobotOpsFaqSimilar selectRobotOpsFaqSimilarById(Long id)
+    {
+        return robotOpsFaqSimilarMapper.selectRobotOpsFaqSimilarById(id);
+    }
+
+    /**
+     * 查询相似问答表列表
+     * 
+     * @param robotOpsFaqSimilar 相似问答表
+     * @return 相似问答表
+     */
+    @Override
+    public List<RobotOpsFaqSimilar> selectRobotOpsFaqSimilarList(RobotOpsFaqSimilar robotOpsFaqSimilar)
+    {
+        return robotOpsFaqSimilarMapper.selectRobotOpsFaqSimilarList(robotOpsFaqSimilar);
+    }
+
+    /**
+     * 新增相似问答表
+     * 
+     * @param robotOpsFaqSimilar 相似问答表
+     * @return 结果
+     */
+    @Override
+    public int insertRobotOpsFaqSimilar(RobotOpsFaqSimilar robotOpsFaqSimilar)
+    {
+        return robotOpsFaqSimilarMapper.insertRobotOpsFaqSimilar(robotOpsFaqSimilar);
+    }
+
+    /**
+     * 修改相似问答表
+     * 
+     * @param robotOpsFaqSimilar 相似问答表
+     * @return 结果
+     */
+    @Override
+    public int updateRobotOpsFaqSimilar(RobotOpsFaqSimilar robotOpsFaqSimilar)
+    {
+        return robotOpsFaqSimilarMapper.updateRobotOpsFaqSimilar(robotOpsFaqSimilar);
+    }
+
+    /**
+     * 批量删除相似问答表
+     * 
+     * @param ids 需要删除的相似问答表主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsFaqSimilarByIds(Long[] ids)
+    {
+        return robotOpsFaqSimilarMapper.deleteRobotOpsFaqSimilarByIds(ids);
+    }
+
+    /**
+     * 删除相似问答表信息
+     * 
+     * @param id 相似问答表主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsFaqSimilarById(Long id)
+    {
+        return robotOpsFaqSimilarMapper.deleteRobotOpsFaqSimilarById(id);
+    }
+}

+ 96 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsMediaAssetServiceImpl.java

@@ -0,0 +1,96 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.RobotOpsMediaAssetMapper;
+import com.ruoyi.base.domain.RobotOpsMediaAsset;
+import com.ruoyi.base.service.IRobotOpsMediaAssetService;
+
+/**
+ * 素材资源Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2026-05-08
+ */
+@Service
+public class RobotOpsMediaAssetServiceImpl implements IRobotOpsMediaAssetService 
+{
+    @Autowired
+    private RobotOpsMediaAssetMapper robotOpsMediaAssetMapper;
+
+    /**
+     * 查询素材资源
+     * 
+     * @param id 素材资源主键
+     * @return 素材资源
+     */
+    @Override
+    public RobotOpsMediaAsset selectRobotOpsMediaAssetById(Long id)
+    {
+        return robotOpsMediaAssetMapper.selectRobotOpsMediaAssetById(id);
+    }
+
+    /**
+     * 查询素材资源列表
+     * 
+     * @param robotOpsMediaAsset 素材资源
+     * @return 素材资源
+     */
+    @Override
+    public List<RobotOpsMediaAsset> selectRobotOpsMediaAssetList(RobotOpsMediaAsset robotOpsMediaAsset)
+    {
+        return robotOpsMediaAssetMapper.selectRobotOpsMediaAssetList(robotOpsMediaAsset);
+    }
+
+    /**
+     * 新增素材资源
+     * 
+     * @param robotOpsMediaAsset 素材资源
+     * @return 结果
+     */
+    @Override
+    public int insertRobotOpsMediaAsset(RobotOpsMediaAsset robotOpsMediaAsset)
+    {
+        robotOpsMediaAsset.setCreateTime(DateUtils.getNowDate());
+        return robotOpsMediaAssetMapper.insertRobotOpsMediaAsset(robotOpsMediaAsset);
+    }
+
+    /**
+     * 修改素材资源
+     * 
+     * @param robotOpsMediaAsset 素材资源
+     * @return 结果
+     */
+    @Override
+    public int updateRobotOpsMediaAsset(RobotOpsMediaAsset robotOpsMediaAsset)
+    {
+        robotOpsMediaAsset.setUpdateTime(DateUtils.getNowDate());
+        return robotOpsMediaAssetMapper.updateRobotOpsMediaAsset(robotOpsMediaAsset);
+    }
+
+    /**
+     * 批量删除素材资源
+     * 
+     * @param ids 需要删除的素材资源主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsMediaAssetByIds(Long[] ids)
+    {
+        return robotOpsMediaAssetMapper.deleteRobotOpsMediaAssetByIds(ids);
+    }
+
+    /**
+     * 删除素材资源信息
+     * 
+     * @param id 素材资源主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsMediaAssetById(Long id)
+    {
+        return robotOpsMediaAssetMapper.deleteRobotOpsMediaAssetById(id);
+    }
+}

+ 169 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsPlayPlanServiceImpl.java

@@ -0,0 +1,169 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.ArrayList;
+import com.ruoyi.common.utils.StringUtils;
+import org.springframework.transaction.annotation.Transactional;
+import com.ruoyi.base.domain.RobotOpsPlayPlanItem;
+import com.ruoyi.base.mapper.RobotOpsPlayPlanMapper;
+import com.ruoyi.base.domain.RobotOpsPlayPlan;
+import com.ruoyi.base.service.IRobotOpsPlayPlanService;
+
+/**
+ * 播放方案Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2026-05-11
+ */
+@Service
+public class RobotOpsPlayPlanServiceImpl implements IRobotOpsPlayPlanService
+{
+    @Autowired
+    private RobotOpsPlayPlanMapper robotOpsPlayPlanMapper;
+
+    /**
+     * 查询播放方案
+     *
+     * @param id 播放方案主键
+     * @return 播放方案
+     */
+    @Override
+    public RobotOpsPlayPlan selectRobotOpsPlayPlanById(Long id)
+    {
+        return robotOpsPlayPlanMapper.selectRobotOpsPlayPlanById(id);
+    }
+
+    /**
+     * 查询播放方案列表
+     *
+     * @param robotOpsPlayPlan 播放方案
+     * @return 播放方案
+     */
+    @Override
+    public List<RobotOpsPlayPlan> selectRobotOpsPlayPlanList(RobotOpsPlayPlan robotOpsPlayPlan)
+    {
+        return robotOpsPlayPlanMapper.selectRobotOpsPlayPlanList(robotOpsPlayPlan);
+    }
+
+    /**
+     * 新增播放方案
+     *
+     * @param robotOpsPlayPlan 播放方案
+     * @return 结果
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public int insertRobotOpsPlayPlan(RobotOpsPlayPlan robotOpsPlayPlan)
+    {
+        robotOpsPlayPlan.setCreateTime(DateUtils.getNowDate());
+        if ("1".equals(robotOpsPlayPlan.getStatus()))
+        {
+            RobotOpsPlayPlan currentPlayingPlan = robotOpsPlayPlanMapper.selectCurrentPlayingPlan();
+            if (currentPlayingPlan != null)
+            {
+                robotOpsPlayPlanMapper.updatePlayPlanStatus(currentPlayingPlan.getId(), "0");
+            }
+        }
+        int rows = robotOpsPlayPlanMapper.insertRobotOpsPlayPlan(robotOpsPlayPlan);
+        insertRobotOpsPlayPlanItem(robotOpsPlayPlan);
+        return rows;
+    }
+
+    /**
+     * 修改播放方案
+     *
+     * @param robotOpsPlayPlan 播放方案
+     * @return 结果
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public int updateRobotOpsPlayPlan(RobotOpsPlayPlan robotOpsPlayPlan)
+    {
+        robotOpsPlayPlan.setUpdateTime(DateUtils.getNowDate());
+
+        if ("1".equals(robotOpsPlayPlan.getStatus()))
+        {
+            RobotOpsPlayPlan currentPlayingPlan = robotOpsPlayPlanMapper.selectCurrentPlayingPlan();
+            if (currentPlayingPlan != null && !currentPlayingPlan.getId().equals(robotOpsPlayPlan.getId()))
+            {
+                robotOpsPlayPlanMapper.updatePlayPlanStatus(currentPlayingPlan.getId(), "0");
+            }
+        }
+
+        robotOpsPlayPlanMapper.deleteRobotOpsPlayPlanItemByPlanId(robotOpsPlayPlan.getId());
+        insertRobotOpsPlayPlanItem(robotOpsPlayPlan);
+        return robotOpsPlayPlanMapper.updateRobotOpsPlayPlan(robotOpsPlayPlan);
+    }
+
+
+    /**
+     * 批量删除播放方案
+     *
+     * @param ids 需要删除的播放方案主键
+     * @return 结果
+     */
+    @Transactional
+    @Override
+    public int deleteRobotOpsPlayPlanByIds(Long[] ids)
+    {
+        robotOpsPlayPlanMapper.deleteRobotOpsPlayPlanItemByPlanIds(ids);
+        return robotOpsPlayPlanMapper.deleteRobotOpsPlayPlanByIds(ids);
+    }
+
+    /**
+     * 删除播放方案信息
+     *
+     * @param id 播放方案主键
+     * @return 结果
+     */
+    @Transactional
+    @Override
+    public int deleteRobotOpsPlayPlanById(Long id)
+    {
+        robotOpsPlayPlanMapper.deleteRobotOpsPlayPlanItemByPlanId(id);
+        return robotOpsPlayPlanMapper.deleteRobotOpsPlayPlanById(id);
+    }
+
+    /**
+     * 查询当前正在播放的方案(包含素材项)
+     *
+     * @return 播放方案
+     */
+    @Override
+    public RobotOpsPlayPlan selectCurrentPlayingPlanWithItems()
+    {
+        RobotOpsPlayPlan plan = robotOpsPlayPlanMapper.selectCurrentPlayingPlan();
+        if (plan != null) {
+            List<RobotOpsPlayPlanItem> items = robotOpsPlayPlanMapper.selectRobotOpsPlayPlanItemListByPlanId(plan.getId());
+            plan.setRobotOpsPlayPlanItemList(items);
+        }
+        return plan;
+    }
+
+    /**
+     * 新增播放方案素材明细信息
+     *
+     * @param robotOpsPlayPlan 播放方案对象
+     */
+    public void insertRobotOpsPlayPlanItem(RobotOpsPlayPlan robotOpsPlayPlan)
+    {
+        List<RobotOpsPlayPlanItem> robotOpsPlayPlanItemList = robotOpsPlayPlan.getRobotOpsPlayPlanItemList();
+        Long id = robotOpsPlayPlan.getId();
+        if (StringUtils.isNotNull(robotOpsPlayPlanItemList))
+        {
+            List<RobotOpsPlayPlanItem> list = new ArrayList<RobotOpsPlayPlanItem>();
+            for (RobotOpsPlayPlanItem robotOpsPlayPlanItem : robotOpsPlayPlanItemList)
+            {
+                robotOpsPlayPlanItem.setPlanId(id);
+                list.add(robotOpsPlayPlanItem);
+            }
+            if (list.size() > 0)
+            {
+                robotOpsPlayPlanMapper.batchRobotOpsPlayPlanItem(list);
+            }
+        }
+    }
+}

+ 108 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsScreenThemeConfigServiceImpl.java

@@ -0,0 +1,108 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.RobotOpsScreenThemeConfigMapper;
+import com.ruoyi.base.domain.RobotOpsScreenThemeConfig;
+import com.ruoyi.base.service.IRobotOpsScreenThemeConfigService;
+
+/**
+ * 展示主题配置Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2026-05-14
+ */
+@Service
+public class RobotOpsScreenThemeConfigServiceImpl implements IRobotOpsScreenThemeConfigService 
+{
+    @Autowired
+    private RobotOpsScreenThemeConfigMapper robotOpsScreenThemeConfigMapper;
+
+    /**
+     * 查询展示主题配置
+     *
+     * @param id 展示主题配置主键
+     * @return 展示主题配置
+     */
+    @Override
+    public RobotOpsScreenThemeConfig selectRobotOpsScreenThemeConfigById(Long id)
+    {
+        return robotOpsScreenThemeConfigMapper.selectRobotOpsScreenThemeConfigById(id);
+    }
+
+    /**
+     * 根据配置标识查询展示主题配置
+     *
+     * @param configKey 配置标识
+     * @return 展示主题配置
+     */
+    @Override
+    public RobotOpsScreenThemeConfig selectRobotOpsScreenThemeConfigByConfigKey(String configKey)
+    {
+        return robotOpsScreenThemeConfigMapper.selectRobotOpsScreenThemeConfigByConfigKey(configKey);
+    }
+
+    /**
+     * 查询展示主题配置列表
+     * 
+     * @param robotOpsScreenThemeConfig 展示主题配置
+     * @return 展示主题配置
+     */
+    @Override
+    public List<RobotOpsScreenThemeConfig> selectRobotOpsScreenThemeConfigList(RobotOpsScreenThemeConfig robotOpsScreenThemeConfig)
+    {
+        return robotOpsScreenThemeConfigMapper.selectRobotOpsScreenThemeConfigList(robotOpsScreenThemeConfig);
+    }
+
+    /**
+     * 新增展示主题配置
+     * 
+     * @param robotOpsScreenThemeConfig 展示主题配置
+     * @return 结果
+     */
+    @Override
+    public int insertRobotOpsScreenThemeConfig(RobotOpsScreenThemeConfig robotOpsScreenThemeConfig)
+    {
+        robotOpsScreenThemeConfig.setCreateTime(DateUtils.getNowDate());
+        return robotOpsScreenThemeConfigMapper.insertRobotOpsScreenThemeConfig(robotOpsScreenThemeConfig);
+    }
+
+    /**
+     * 修改展示主题配置
+     * 
+     * @param robotOpsScreenThemeConfig 展示主题配置
+     * @return 结果
+     */
+    @Override
+    public int updateRobotOpsScreenThemeConfig(RobotOpsScreenThemeConfig robotOpsScreenThemeConfig)
+    {
+        robotOpsScreenThemeConfig.setUpdateTime(DateUtils.getNowDate());
+        return robotOpsScreenThemeConfigMapper.updateRobotOpsScreenThemeConfig(robotOpsScreenThemeConfig);
+    }
+
+    /**
+     * 批量删除展示主题配置
+     * 
+     * @param ids 需要删除的展示主题配置主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsScreenThemeConfigByIds(Long[] ids)
+    {
+        return robotOpsScreenThemeConfigMapper.deleteRobotOpsScreenThemeConfigByIds(ids);
+    }
+
+    /**
+     * 删除展示主题配置信息
+     * 
+     * @param id 展示主题配置主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsScreenThemeConfigById(Long id)
+    {
+        return robotOpsScreenThemeConfigMapper.deleteRobotOpsScreenThemeConfigById(id);
+    }
+}

+ 95 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsSysLogServiceImpl.java

@@ -0,0 +1,95 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.RobotOpsSysLogMapper;
+import com.ruoyi.base.domain.RobotOpsSysLog;
+import com.ruoyi.base.service.IRobotOpsSysLogService;
+
+/**
+ * 运行日志Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2026-05-18
+ */
+@Service
+public class RobotOpsSysLogServiceImpl implements IRobotOpsSysLogService 
+{
+    @Autowired
+    private RobotOpsSysLogMapper robotOpsSysLogMapper;
+
+    /**
+     * 查询运行日志
+     * 
+     * @param id 运行日志主键
+     * @return 运行日志
+     */
+    @Override
+    public RobotOpsSysLog selectRobotOpsSysLogById(Long id)
+    {
+        return robotOpsSysLogMapper.selectRobotOpsSysLogById(id);
+    }
+
+    /**
+     * 查询运行日志列表
+     * 
+     * @param robotOpsSysLog 运行日志
+     * @return 运行日志
+     */
+    @Override
+    public List<RobotOpsSysLog> selectRobotOpsSysLogList(RobotOpsSysLog robotOpsSysLog)
+    {
+        return robotOpsSysLogMapper.selectRobotOpsSysLogList(robotOpsSysLog);
+    }
+
+    /**
+     * 新增运行日志
+     * 
+     * @param robotOpsSysLog 运行日志
+     * @return 结果
+     */
+    @Override
+    public int insertRobotOpsSysLog(RobotOpsSysLog robotOpsSysLog)
+    {
+        robotOpsSysLog.setCreateTime(DateUtils.getNowDate());
+        return robotOpsSysLogMapper.insertRobotOpsSysLog(robotOpsSysLog);
+    }
+
+    /**
+     * 修改运行日志
+     * 
+     * @param robotOpsSysLog 运行日志
+     * @return 结果
+     */
+    @Override
+    public int updateRobotOpsSysLog(RobotOpsSysLog robotOpsSysLog)
+    {
+        return robotOpsSysLogMapper.updateRobotOpsSysLog(robotOpsSysLog);
+    }
+
+    /**
+     * 批量删除运行日志
+     * 
+     * @param ids 需要删除的运行日志主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsSysLogByIds(Long[] ids)
+    {
+        return robotOpsSysLogMapper.deleteRobotOpsSysLogByIds(ids);
+    }
+
+    /**
+     * 删除运行日志信息
+     * 
+     * @param id 运行日志主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsSysLogById(Long id)
+    {
+        return robotOpsSysLogMapper.deleteRobotOpsSysLogById(id);
+    }
+}

+ 96 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsVisitorRecordServiceImpl.java

@@ -0,0 +1,96 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.RobotOpsVisitorRecordMapper;
+import com.ruoyi.base.domain.RobotOpsVisitorRecord;
+import com.ruoyi.base.service.IRobotOpsVisitorRecordService;
+
+/**
+ * 访客登记记录Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2026-04-30
+ */
+@Service
+public class RobotOpsVisitorRecordServiceImpl implements IRobotOpsVisitorRecordService
+{
+    @Autowired
+    private RobotOpsVisitorRecordMapper robotOpsVisitorRecordMapper;
+
+    /**
+     * 查询访客登记记录
+     *
+     * @param id 访客登记记录主键
+     * @return 访客登记记录
+     */
+    @Override
+    public RobotOpsVisitorRecord selectRobotOpsVisitorRecordById(Long id)
+    {
+        return robotOpsVisitorRecordMapper.selectRobotOpsVisitorRecordById(id);
+    }
+
+    /**
+     * 查询访客登记记录列表
+     *
+     * @param robotOpsVisitorRecord 访客登记记录
+     * @return 访客登记记录
+     */
+    @Override
+    public List<RobotOpsVisitorRecord> selectRobotOpsVisitorRecordList(RobotOpsVisitorRecord robotOpsVisitorRecord)
+    {
+        return robotOpsVisitorRecordMapper.selectRobotOpsVisitorRecordList(robotOpsVisitorRecord);
+    }
+
+    /**
+     * 新增访客登记记录
+     *
+     * @param robotOpsVisitorRecord 访客登记记录
+     * @return 结果
+     */
+    @Override
+    public int insertRobotOpsVisitorRecord(RobotOpsVisitorRecord robotOpsVisitorRecord)
+    {
+        robotOpsVisitorRecord.setCreateTime(DateUtils.getNowDate());
+        return robotOpsVisitorRecordMapper.insertRobotOpsVisitorRecord(robotOpsVisitorRecord);
+    }
+
+    /**
+     * 修改访客登记记录
+     *
+     * @param robotOpsVisitorRecord 访客登记记录
+     * @return 结果
+     */
+    @Override
+    public int updateRobotOpsVisitorRecord(RobotOpsVisitorRecord robotOpsVisitorRecord)
+    {
+        robotOpsVisitorRecord.setUpdateTime(DateUtils.getNowDate());
+        return robotOpsVisitorRecordMapper.updateRobotOpsVisitorRecord(robotOpsVisitorRecord);
+    }
+
+    /**
+     * 批量删除访客登记记录
+     *
+     * @param ids 需要删除的访客登记记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsVisitorRecordByIds(Long[] ids)
+    {
+        return robotOpsVisitorRecordMapper.deleteRobotOpsVisitorRecordByIds(ids);
+    }
+
+    /**
+     * 删除访客登记记录信息
+     *
+     * @param id 访客登记记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsVisitorRecordById(Long id)
+    {
+        return robotOpsVisitorRecordMapper.deleteRobotOpsVisitorRecordById(id);
+    }
+}

+ 96 - 0
ruoyi-system/src/main/java/com/ruoyi/base/service/impl/RobotOpsWhitelistServiceImpl.java

@@ -0,0 +1,96 @@
+package com.ruoyi.base.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.base.mapper.RobotOpsWhitelistMapper;
+import com.ruoyi.base.domain.RobotOpsWhitelist;
+import com.ruoyi.base.service.IRobotOpsWhitelistService;
+
+/**
+ * 访客白名单Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2026-04-29
+ */
+@Service
+public class RobotOpsWhitelistServiceImpl implements IRobotOpsWhitelistService
+{
+    @Autowired
+    private RobotOpsWhitelistMapper robotOpsWhitelistMapper;
+
+    /**
+     * 查询访客白名单
+     *
+     * @param id 访客白名单主键
+     * @return 访客白名单
+     */
+    @Override
+    public RobotOpsWhitelist selectRobotOpsWhitelistById(Long id)
+    {
+        return robotOpsWhitelistMapper.selectRobotOpsWhitelistById(id);
+    }
+
+    /**
+     * 查询访客白名单列表
+     *
+     * @param robotOpsWhitelist 访客白名单
+     * @return 访客白名单
+     */
+    @Override
+    public List<RobotOpsWhitelist> selectRobotOpsWhitelistList(RobotOpsWhitelist robotOpsWhitelist)
+    {
+        return robotOpsWhitelistMapper.selectRobotOpsWhitelistList(robotOpsWhitelist);
+    }
+
+    /**
+     * 新增访客白名单
+     *
+     * @param robotOpsWhitelist 访客白名单
+     * @return 结果
+     */
+    @Override
+    public int insertRobotOpsWhitelist(RobotOpsWhitelist robotOpsWhitelist)
+    {
+        robotOpsWhitelist.setCreateTime(DateUtils.getNowDate());
+        return robotOpsWhitelistMapper.insertRobotOpsWhitelist(robotOpsWhitelist);
+    }
+
+    /**
+     * 修改访客白名单
+     *
+     * @param robotOpsWhitelist 访客白名单
+     * @return 结果
+     */
+    @Override
+    public int updateRobotOpsWhitelist(RobotOpsWhitelist robotOpsWhitelist)
+    {
+        robotOpsWhitelist.setUpdateTime(DateUtils.getNowDate());
+        return robotOpsWhitelistMapper.updateRobotOpsWhitelist(robotOpsWhitelist);
+    }
+
+    /**
+     * 批量删除访客白名单
+     *
+     * @param ids 需要删除的访客白名单主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsWhitelistByIds(Long[] ids)
+    {
+        return robotOpsWhitelistMapper.deleteRobotOpsWhitelistByIds(ids);
+    }
+
+    /**
+     * 删除访客白名单信息
+     *
+     * @param id 访客白名单主键
+     * @return 结果
+     */
+    @Override
+    public int deleteRobotOpsWhitelistById(Long id)
+    {
+        return robotOpsWhitelistMapper.deleteRobotOpsWhitelistById(id);
+    }
+}

+ 119 - 0
ruoyi-system/src/main/resources/mapper/base/AlarmLogMapper.xml

@@ -0,0 +1,119 @@
+<?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.ruoyi.base.mapper.AlarmLogMapper">
+    
+    <resultMap type="AlarmLog" id="AlarmLogResult">
+        <result property="id"    column="id"    />
+        <result property="alarmTime"    column="alarm_time"    />
+        <result property="alarmType"    column="alarm_type"    />
+        <result property="alarmLevel"    column="alarm_level"    />
+        <result property="alarmSource"    column="alarm_source"    />
+        <result property="sourcePosition"    column="source_position"    />
+        <result property="alarmTitle"    column="alarm_title"    />
+        <result property="description"    column="description"    />
+        <result property="snapshotUrl"    column="snapshot_url"    />
+        <result property="handleStatus"    column="handle_status"    />
+        <result property="handleBy"    column="handle_by"    />
+        <result property="handleTime"    column="handle_time"    />
+        <result property="handleRemark"    column="handle_remark"    />
+        <result property="remark"    column="remark"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectAlarmLogVo">
+        select id, alarm_time, alarm_type, alarm_level, alarm_source, source_position, alarm_title, description, snapshot_url, handle_status, handle_by, handle_time, handle_remark, remark, create_time from robot_ops_alarm_log
+    </sql>
+
+    <select id="selectAlarmLogList" parameterType="AlarmLog" resultMap="AlarmLogResult">
+        <include refid="selectAlarmLogVo"/>
+        <where>  
+            <if test="alarmTime != null "> and alarm_time = #{alarmTime}</if>
+            <if test="alarmType != null  and alarmType != ''"> and alarm_type = #{alarmType}</if>
+            <if test="alarmLevel != null  and alarmLevel != ''"> and alarm_level = #{alarmLevel}</if>
+            <if test="alarmSource != null  and alarmSource != ''"> and alarm_source = #{alarmSource}</if>
+            <if test="sourcePosition != null  and sourcePosition != ''"> and source_position = #{sourcePosition}</if>
+            <if test="alarmTitle != null  and alarmTitle != ''"> and alarm_title = #{alarmTitle}</if>
+            <if test="description != null  and description != ''"> and description = #{description}</if>
+            <if test="snapshotUrl != null  and snapshotUrl != ''"> and snapshot_url = #{snapshotUrl}</if>
+            <if test="handleStatus != null  and handleStatus != ''"> and handle_status = #{handleStatus}</if>
+            <if test="handleBy != null  and handleBy != ''"> and handle_by = #{handleBy}</if>
+            <if test="handleTime != null "> and handle_time = #{handleTime}</if>
+            <if test="handleRemark != null  and handleRemark != ''"> and handle_remark = #{handleRemark}</if>
+        </where>
+    </select>
+    
+    <select id="selectAlarmLogById" parameterType="Long" resultMap="AlarmLogResult">
+        <include refid="selectAlarmLogVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertAlarmLog" parameterType="AlarmLog" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_alarm_log
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="alarmTime != null">alarm_time,</if>
+            <if test="alarmType != null">alarm_type,</if>
+            <if test="alarmLevel != null">alarm_level,</if>
+            <if test="alarmSource != null">alarm_source,</if>
+            <if test="sourcePosition != null">source_position,</if>
+            <if test="alarmTitle != null">alarm_title,</if>
+            <if test="description != null">description,</if>
+            <if test="snapshotUrl != null">snapshot_url,</if>
+            <if test="handleStatus != null">handle_status,</if>
+            <if test="handleBy != null">handle_by,</if>
+            <if test="handleTime != null">handle_time,</if>
+            <if test="handleRemark != null">handle_remark,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createTime != null">create_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="alarmTime != null">#{alarmTime},</if>
+            <if test="alarmType != null">#{alarmType},</if>
+            <if test="alarmLevel != null">#{alarmLevel},</if>
+            <if test="alarmSource != null">#{alarmSource},</if>
+            <if test="sourcePosition != null">#{sourcePosition},</if>
+            <if test="alarmTitle != null">#{alarmTitle},</if>
+            <if test="description != null">#{description},</if>
+            <if test="snapshotUrl != null">#{snapshotUrl},</if>
+            <if test="handleStatus != null">#{handleStatus},</if>
+            <if test="handleBy != null">#{handleBy},</if>
+            <if test="handleTime != null">#{handleTime},</if>
+            <if test="handleRemark != null">#{handleRemark},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateAlarmLog" parameterType="AlarmLog">
+        update robot_ops_alarm_log
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="alarmTime != null">alarm_time = #{alarmTime},</if>
+            <if test="alarmType != null">alarm_type = #{alarmType},</if>
+            <if test="alarmLevel != null">alarm_level = #{alarmLevel},</if>
+            <if test="alarmSource != null">alarm_source = #{alarmSource},</if>
+            <if test="sourcePosition != null">source_position = #{sourcePosition},</if>
+            <if test="alarmTitle != null">alarm_title = #{alarmTitle},</if>
+            <if test="description != null">description = #{description},</if>
+            <if test="snapshotUrl != null">snapshot_url = #{snapshotUrl},</if>
+            <if test="handleStatus != null">handle_status = #{handleStatus},</if>
+            <if test="handleBy != null">handle_by = #{handleBy},</if>
+            <if test="handleTime != null">handle_time = #{handleTime},</if>
+            <if test="handleRemark != null">handle_remark = #{handleRemark},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteAlarmLogById" parameterType="Long">
+        delete from robot_ops_alarm_log where id = #{id}
+    </delete>
+
+    <delete id="deleteAlarmLogByIds" parameterType="String">
+        delete from robot_ops_alarm_log where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 115 - 0
ruoyi-system/src/main/resources/mapper/base/DialogueLogMapper.xml

@@ -0,0 +1,115 @@
+<?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.ruoyi.base.mapper.DialogueLogMapper">
+    
+    <resultMap type="DialogueLog" id="DialogueLogResult">
+        <result property="id"    column="id"    />
+        <result property="robotCode"    column="robot_code"    />
+        <result property="sessionId"    column="session_id"    />
+        <result property="askTime"    column="ask_time"    />
+        <result property="question"    column="question"    />
+        <result property="answer"    column="answer"    />
+        <result property="answerSummary"    column="answer_summary"    />
+        <result property="hitType"    column="hit_type"    />
+        <result property="sceneType"    column="scene_type"    />
+        <result property="resultStatus"    column="result_status"    />
+        <result property="errorMsg"    column="error_msg"    />
+        <result property="rawRequest"    column="raw_request"    />
+        <result property="rawResponse"    column="raw_response"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectDialogueLogVo">
+        select id, robot_code, session_id, ask_time, question, answer, answer_summary, hit_type, scene_type, result_status, error_msg, raw_request, raw_response, create_time from robot_ops_dialogue_log
+    </sql>
+
+    <select id="selectDialogueLogList" parameterType="DialogueLog" resultMap="DialogueLogResult">
+        <include refid="selectDialogueLogVo"/>
+        <where>  
+            <if test="robotCode != null  and robotCode != ''"> and robot_code = #{robotCode}</if>
+            <if test="sessionId != null  and sessionId != ''"> and session_id = #{sessionId}</if>
+            <if test="askTime != null "> and ask_time = #{askTime}</if>
+            <if test="question != null  and question != ''"> and question = #{question}</if>
+            <if test="answer != null  and answer != ''"> and answer = #{answer}</if>
+            <if test="answerSummary != null  and answerSummary != ''"> and answer_summary = #{answerSummary}</if>
+            <if test="hitType != null  and hitType != ''"> and hit_type = #{hitType}</if>
+            <if test="sceneType != null  and sceneType != ''"> and scene_type = #{sceneType}</if>
+            <if test="resultStatus != null  and resultStatus != ''"> and result_status = #{resultStatus}</if>
+            <if test="errorMsg != null  and errorMsg != ''"> and error_msg = #{errorMsg}</if>
+            <if test="rawRequest != null  and rawRequest != ''"> and raw_request = #{rawRequest}</if>
+            <if test="rawResponse != null  and rawResponse != ''"> and raw_response = #{rawResponse}</if>
+        </where>
+    </select>
+    
+    <select id="selectDialogueLogById" parameterType="Long" resultMap="DialogueLogResult">
+        <include refid="selectDialogueLogVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertDialogueLog" parameterType="DialogueLog" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_dialogue_log
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="robotCode != null">robot_code,</if>
+            <if test="sessionId != null">session_id,</if>
+            <if test="askTime != null">ask_time,</if>
+            <if test="question != null">question,</if>
+            <if test="answer != null">answer,</if>
+            <if test="answerSummary != null">answer_summary,</if>
+            <if test="hitType != null">hit_type,</if>
+            <if test="sceneType != null">scene_type,</if>
+            <if test="resultStatus != null">result_status,</if>
+            <if test="errorMsg != null">error_msg,</if>
+            <if test="rawRequest != null">raw_request,</if>
+            <if test="rawResponse != null">raw_response,</if>
+            <if test="createTime != null">create_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="robotCode != null">#{robotCode},</if>
+            <if test="sessionId != null">#{sessionId},</if>
+            <if test="askTime != null">#{askTime},</if>
+            <if test="question != null">#{question},</if>
+            <if test="answer != null">#{answer},</if>
+            <if test="answerSummary != null">#{answerSummary},</if>
+            <if test="hitType != null">#{hitType},</if>
+            <if test="sceneType != null">#{sceneType},</if>
+            <if test="resultStatus != null">#{resultStatus},</if>
+            <if test="errorMsg != null">#{errorMsg},</if>
+            <if test="rawRequest != null">#{rawRequest},</if>
+            <if test="rawResponse != null">#{rawResponse},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateDialogueLog" parameterType="DialogueLog">
+        update robot_ops_dialogue_log
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="robotCode != null">robot_code = #{robotCode},</if>
+            <if test="sessionId != null">session_id = #{sessionId},</if>
+            <if test="askTime != null">ask_time = #{askTime},</if>
+            <if test="question != null">question = #{question},</if>
+            <if test="answer != null">answer = #{answer},</if>
+            <if test="answerSummary != null">answer_summary = #{answerSummary},</if>
+            <if test="hitType != null">hit_type = #{hitType},</if>
+            <if test="sceneType != null">scene_type = #{sceneType},</if>
+            <if test="resultStatus != null">result_status = #{resultStatus},</if>
+            <if test="errorMsg != null">error_msg = #{errorMsg},</if>
+            <if test="rawRequest != null">raw_request = #{rawRequest},</if>
+            <if test="rawResponse != null">raw_response = #{rawResponse},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteDialogueLogById" parameterType="Long">
+        delete from robot_ops_dialogue_log where id = #{id}
+    </delete>
+
+    <delete id="deleteDialogueLogByIds" parameterType="String">
+        delete from robot_ops_dialogue_log where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 109 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsAppointmentRecordMapper.xml

@@ -0,0 +1,109 @@
+<?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.ruoyi.base.mapper.RobotOpsAppointmentRecordMapper">
+
+    <resultMap type="RobotOpsAppointmentRecord" id="RobotOpsAppointmentRecordResult">
+        <result property="id"    column="id"    />
+        <result property="appointmentNo"    column="appointment_no"    />
+        <result property="visitorName"    column="visitor_name"    />
+        <result property="mobile"    column="mobile"    />
+        <result property="visitedPerson"    column="visited_person"    />
+        <result property="appointmentTime"    column="appointment_time"    />
+        <result property="status"    column="status"    />
+        <result property="syncTime"    column="sync_time"    />
+        <result property="sourcePlatform"    column="source_platform"    />
+        <result property="remark"    column="remark"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsAppointmentRecordVo">
+        select id, appointment_no, visitor_name, mobile, visited_person, appointment_time, status, sync_time, source_platform, remark, create_time, update_time from robot_ops_appointment_record
+    </sql>
+
+    <select id="selectRobotOpsAppointmentRecordList" parameterType="RobotOpsAppointmentRecord" resultMap="RobotOpsAppointmentRecordResult">
+        <include refid="selectRobotOpsAppointmentRecordVo"/>
+        <where>
+            <if test="appointmentNo != null  and appointmentNo != ''"> and appointment_no = #{appointmentNo}</if>
+            <if test="visitorName != null  and visitorName != ''"> and visitor_name like concat('%', #{visitorName}, '%')</if>
+            <if test="mobile != null  and mobile != ''"> and mobile = #{mobile}</if>
+            <if test="visitedPerson != null  and visitedPerson != ''"> and visited_person like concat('%', #{visitedPerson}, '%')</if>
+            <if test="appointmentTime != null "> and appointment_time = #{appointmentTime}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="syncTime != null "> and sync_time = #{syncTime}</if>
+            <if test="sourcePlatform != null  and sourcePlatform != ''"> and source_platform = #{sourcePlatform}</if>
+            <if test="params.beginTime != null and params.beginTime != ''">
+                and date_format(appointment_time,'%Y%m%d') &gt;= date_format(#{params.beginTime},'%Y%m%d')
+            </if>
+            <if test="params.endTime != null and params.endTime != ''">
+                and date_format(appointment_time,'%Y%m%d') &lt;= date_format(#{params.endTime},'%Y%m%d')
+            </if>
+        </where>
+    </select>
+
+    <select id="selectRobotOpsAppointmentRecordById" parameterType="Long" resultMap="RobotOpsAppointmentRecordResult">
+        <include refid="selectRobotOpsAppointmentRecordVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertRobotOpsAppointmentRecord" parameterType="RobotOpsAppointmentRecord" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_appointment_record
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="appointmentNo != null and appointmentNo != ''">appointment_no,</if>
+            <if test="visitorName != null">visitor_name,</if>
+            <if test="mobile != null">mobile,</if>
+            <if test="visitedPerson != null">visited_person,</if>
+            <if test="appointmentTime != null">appointment_time,</if>
+            <if test="status != null">status,</if>
+            <if test="syncTime != null">sync_time,</if>
+            <if test="sourcePlatform != null">source_platform,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="appointmentNo != null and appointmentNo != ''">#{appointmentNo},</if>
+            <if test="visitorName != null">#{visitorName},</if>
+            <if test="mobile != null">#{mobile},</if>
+            <if test="visitedPerson != null">#{visitedPerson},</if>
+            <if test="appointmentTime != null">#{appointmentTime},</if>
+            <if test="status != null">#{status},</if>
+            <if test="syncTime != null">#{syncTime},</if>
+            <if test="sourcePlatform != null">#{sourcePlatform},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateRobotOpsAppointmentRecord" parameterType="RobotOpsAppointmentRecord">
+        update robot_ops_appointment_record
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="appointmentNo != null and appointmentNo != ''">appointment_no = #{appointmentNo},</if>
+            <if test="visitorName != null">visitor_name = #{visitorName},</if>
+            <if test="mobile != null">mobile = #{mobile},</if>
+            <if test="visitedPerson != null">visited_person = #{visitedPerson},</if>
+            <if test="appointmentTime != null">appointment_time = #{appointmentTime},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="syncTime != null">sync_time = #{syncTime},</if>
+            <if test="sourcePlatform != null">source_platform = #{sourcePlatform},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsAppointmentRecordById" parameterType="Long">
+        delete from robot_ops_appointment_record where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsAppointmentRecordByIds" parameterType="String">
+        delete from robot_ops_appointment_record where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 83 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsBroadcastContentMapper.xml

@@ -0,0 +1,83 @@
+<?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.ruoyi.base.mapper.RobotOpsBroadcastContentMapper">
+    
+    <resultMap type="RobotOpsBroadcastContent" id="RobotOpsBroadcastContentResult">
+        <result property="id"    column="id"    />
+        <result property="contentName"    column="content_name"    />
+        <result property="contentType"    column="content_type"    />
+        <result property="broadcastText"    column="broadcast_text"    />
+        <result property="status"    column="status"    />
+        <result property="remark"    column="remark"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsBroadcastContentVo">
+        select id, content_name, content_type, broadcast_text, status, remark, create_time, update_time from robot_ops_broadcast_content
+    </sql>
+
+    <select id="selectRobotOpsBroadcastContentList" parameterType="RobotOpsBroadcastContent" resultMap="RobotOpsBroadcastContentResult">
+        <include refid="selectRobotOpsBroadcastContentVo"/>
+        <where>  
+            <if test="contentName != null  and contentName != ''"> and content_name like concat('%', #{contentName}, '%')</if>
+            <if test="contentType != null "> and content_type = #{contentType}</if>
+            <if test="broadcastText != null  and broadcastText != ''"> and broadcast_text = #{broadcastText}</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+        </where>
+    </select>
+    
+    <select id="selectRobotOpsBroadcastContentById" parameterType="Long" resultMap="RobotOpsBroadcastContentResult">
+        <include refid="selectRobotOpsBroadcastContentVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertRobotOpsBroadcastContent" parameterType="RobotOpsBroadcastContent" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_broadcast_content
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="contentName != null and contentName != ''">content_name,</if>
+            <if test="contentType != null">content_type,</if>
+            <if test="broadcastText != null and broadcastText != ''">broadcast_text,</if>
+            <if test="status != null and status != ''">status,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="contentName != null and contentName != ''">#{contentName},</if>
+            <if test="contentType != null">#{contentType},</if>
+            <if test="broadcastText != null and broadcastText != ''">#{broadcastText},</if>
+            <if test="status != null and status != ''">#{status},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateRobotOpsBroadcastContent" parameterType="RobotOpsBroadcastContent">
+        update robot_ops_broadcast_content
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="contentName != null and contentName != ''">content_name = #{contentName},</if>
+            <if test="contentType != null">content_type = #{contentType},</if>
+            <if test="broadcastText != null and broadcastText != ''">broadcast_text = #{broadcastText},</if>
+            <if test="status != null and status != ''">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsBroadcastContentById" parameterType="Long">
+        delete from robot_ops_broadcast_content where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsBroadcastContentByIds" parameterType="String">
+        delete from robot_ops_broadcast_content where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 103 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsBroadcastTaskMapper.xml

@@ -0,0 +1,103 @@
+<?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.ruoyi.base.mapper.RobotOpsBroadcastTaskMapper">
+    
+    <resultMap type="RobotOpsBroadcastTask" id="RobotOpsBroadcastTaskResult">
+        <result property="id"    column="id"    />
+        <result property="taskName"    column="task_name"    />
+        <result property="contentId"    column="content_id"    />
+        <result property="startTime"    column="start_time"    />
+        <result property="endTime"    column="end_time"    />
+        <result property="frequencyMinutes"    column="frequency_minutes"    />
+        <result property="cycleType"    column="cycle_type"    />
+        <result property="cycleValue"    column="cycle_value"    />
+        <result property="status"    column="status"    />
+        <result property="remark"    column="remark"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsBroadcastTaskVo">
+        select id, task_name, content_id, start_time, end_time, frequency_minutes, cycle_type, cycle_value, status, remark, create_time, update_time from robot_ops_broadcast_task
+    </sql>
+
+    <select id="selectRobotOpsBroadcastTaskList" parameterType="RobotOpsBroadcastTask" resultMap="RobotOpsBroadcastTaskResult">
+        <include refid="selectRobotOpsBroadcastTaskVo"/>
+        <where>  
+            <if test="taskName != null  and taskName != ''"> and task_name like concat('%', #{taskName}, '%')</if>
+            <if test="contentId != null "> and content_id = #{contentId}</if>
+            <if test="startTime != null  and startTime != ''"> and start_time = #{startTime}</if>
+            <if test="endTime != null  and endTime != ''"> and end_time = #{endTime}</if>
+            <if test="frequencyMinutes != null "> and frequency_minutes = #{frequencyMinutes}</if>
+            <if test="cycleType != null "> and cycle_type = #{cycleType}</if>
+            <if test="cycleValue != null  and cycleValue != ''"> and cycle_value = #{cycleValue}</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+        </where>
+    </select>
+    
+    <select id="selectRobotOpsBroadcastTaskById" parameterType="Long" resultMap="RobotOpsBroadcastTaskResult">
+        <include refid="selectRobotOpsBroadcastTaskVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertRobotOpsBroadcastTask" parameterType="RobotOpsBroadcastTask" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_broadcast_task
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="taskName != null and taskName != ''">task_name,</if>
+            <if test="contentId != null">content_id,</if>
+            <if test="startTime != null">start_time,</if>
+            <if test="endTime != null">end_time,</if>
+            <if test="frequencyMinutes != null">frequency_minutes,</if>
+            <if test="cycleType != null">cycle_type,</if>
+            <if test="cycleValue != null">cycle_value,</if>
+            <if test="status != null and status != ''">status,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="taskName != null and taskName != ''">#{taskName},</if>
+            <if test="contentId != null">#{contentId},</if>
+            <if test="startTime != null">#{startTime},</if>
+            <if test="endTime != null">#{endTime},</if>
+            <if test="frequencyMinutes != null">#{frequencyMinutes},</if>
+            <if test="cycleType != null">#{cycleType},</if>
+            <if test="cycleValue != null">#{cycleValue},</if>
+            <if test="status != null and status != ''">#{status},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateRobotOpsBroadcastTask" parameterType="RobotOpsBroadcastTask">
+        update robot_ops_broadcast_task
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="taskName != null and taskName != ''">task_name = #{taskName},</if>
+            <if test="contentId != null">content_id = #{contentId},</if>
+            <if test="startTime != null">start_time = #{startTime},</if>
+            <if test="endTime != null">end_time = #{endTime},</if>
+            <if test="frequencyMinutes != null">frequency_minutes = #{frequencyMinutes},</if>
+            <if test="cycleType != null">cycle_type = #{cycleType},</if>
+            <if test="cycleValue != null">cycle_value = #{cycleValue},</if>
+            <if test="status != null and status != ''">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsBroadcastTaskById" parameterType="Long">
+        delete from robot_ops_broadcast_task where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsBroadcastTaskByIds" parameterType="String">
+        delete from robot_ops_broadcast_task where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 138 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsFaqMapper.xml

@@ -0,0 +1,138 @@
+<?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.ruoyi.base.mapper.RobotOpsFaqMapper">
+
+    <resultMap type="RobotOpsFaq" id="RobotOpsFaqResult">
+        <result property="id"    column="id"    />
+        <result property="categoryType"    column="category_type"    />
+        <result property="question"    column="question"    />
+        <result property="answer"    column="answer"    />
+        <result property="sortNo"    column="sort_no"    />
+        <result property="status"    column="status"    />
+        <result property="similarCount"    column="similar_count"    />
+        <result property="remark"    column="remark"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="updateBy"    column="update_by"    />
+    </resultMap>
+
+    <resultMap id="RobotOpsFaqRobotOpsFaqSimilarResult" type="RobotOpsFaq" extends="RobotOpsFaqResult">
+        <collection property="robotOpsFaqSimilarList" ofType="RobotOpsFaqSimilar" column="id" select="selectRobotOpsFaqSimilarList" />
+    </resultMap>
+
+    <resultMap type="RobotOpsFaqSimilar" id="RobotOpsFaqSimilarResult">
+        <result property="id"    column="id"    />
+        <result property="faqId"    column="faq_id"    />
+        <result property="similarQuestion"    column="similar_question"    />
+        <result property="sortNo"    column="sort_no"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="updateBy"    column="update_by"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsFaqVo">
+        select f.id, f.category_type, f.question, f.answer, f.sort_no, f.status, f.remark, f.create_time, f.update_time, f.create_by, f.update_by,
+               (select count(*) from robot_ops_faq_similar s where s.faq_id = f.id) as similar_count
+        from robot_ops_faq f
+    </sql>
+
+    <select id="selectRobotOpsFaqList" parameterType="RobotOpsFaq" resultMap="RobotOpsFaqResult">
+        <include refid="selectRobotOpsFaqVo"/>
+        <where>
+            <if test="categoryType != null  and categoryType != ''"> and category_type = #{categoryType}</if>
+            <if test="question != null  and question != ''"> and question like concat('%', #{question}, '%')</if>
+            <if test="answer != null  and answer != ''"> and answer = #{answer}</if>
+            <if test="sortNo != null "> and sort_no = #{sortNo}</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+        </where>
+    </select>
+
+    <select id="selectRobotOpsFaqById" parameterType="Long" resultMap="RobotOpsFaqRobotOpsFaqSimilarResult">
+        select f.id, f.category_type, f.question, f.answer, f.sort_no, f.status, f.remark, f.create_time, f.update_time, f.create_by, f.update_by,
+               (select count(*) from robot_ops_faq_similar s where s.faq_id = f.id) as similar_count
+        from robot_ops_faq f
+        where f.id = #{id}
+    </select>
+
+    <select id="selectRobotOpsFaqSimilarList" resultMap="RobotOpsFaqSimilarResult">
+        select id, faq_id, similar_question, sort_no, create_by, update_by
+        from robot_ops_faq_similar
+        where faq_id = #{faq_id}
+    </select>
+
+    <insert id="insertRobotOpsFaq" parameterType="RobotOpsFaq" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_faq
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="categoryType != null">category_type,</if>
+            <if test="question != null and question != ''">question,</if>
+            <if test="answer != null and answer != ''">answer,</if>
+            <if test="sortNo != null">sort_no,</if>
+            <if test="status != null and status != ''">status,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="updateBy != null">update_by,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="categoryType != null">#{categoryType},</if>
+            <if test="question != null and question != ''">#{question},</if>
+            <if test="answer != null and answer != ''">#{answer},</if>
+            <if test="sortNo != null">#{sortNo},</if>
+            <if test="status != null and status != ''">#{status},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+         </trim>
+    </insert>
+
+    <update id="updateRobotOpsFaq" parameterType="RobotOpsFaq">
+        update robot_ops_faq
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="categoryType != null">category_type = #{categoryType},</if>
+            <if test="question != null and question != ''">question = #{question},</if>
+            <if test="answer != null and answer != ''">answer = #{answer},</if>
+            <if test="sortNo != null">sort_no = #{sortNo},</if>
+            <if test="status != null and status != ''">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsFaqById" parameterType="Long">
+        delete from robot_ops_faq where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsFaqByIds" parameterType="String">
+        delete from robot_ops_faq where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <delete id="deleteRobotOpsFaqSimilarByFaqIds" parameterType="String">
+        delete from robot_ops_faq_similar where faq_id in
+        <foreach item="faqId" collection="array" open="(" separator="," close=")">
+            #{faqId}
+        </foreach>
+    </delete>
+
+    <delete id="deleteRobotOpsFaqSimilarByFaqId" parameterType="Long">
+        delete from robot_ops_faq_similar where faq_id = #{faqId}
+    </delete>
+
+    <insert id="batchRobotOpsFaqSimilar">
+        insert into robot_ops_faq_similar( id, faq_id, similar_question, sort_no, create_by, update_by) values
+        <foreach item="item" index="index" collection="list" separator=",">
+            ( #{item.id}, #{item.faqId}, #{item.similarQuestion}, #{item.sortNo}, #{item.createBy}, #{item.updateBy})
+        </foreach>
+    </insert>
+</mapper>

+ 74 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsFaqSimilarMapper.xml

@@ -0,0 +1,74 @@
+<?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.ruoyi.base.mapper.RobotOpsFaqSimilarMapper">
+    
+    <resultMap type="RobotOpsFaqSimilar" id="RobotOpsFaqSimilarResult">
+        <result property="id"    column="id"    />
+        <result property="faqId"    column="faq_id"    />
+        <result property="similarQuestion"    column="similar_question"    />
+        <result property="sortNo"    column="sort_no"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="updateBy"    column="update_by"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsFaqSimilarVo">
+        select id, faq_id, similar_question, sort_no, create_by, update_by from robot_ops_faq_similar
+    </sql>
+
+    <select id="selectRobotOpsFaqSimilarList" parameterType="RobotOpsFaqSimilar" resultMap="RobotOpsFaqSimilarResult">
+        <include refid="selectRobotOpsFaqSimilarVo"/>
+        <where>  
+            <if test="faqId != null "> and faq_id = #{faqId}</if>
+            <if test="similarQuestion != null  and similarQuestion != ''"> and similar_question = #{similarQuestion}</if>
+            <if test="sortNo != null "> and sort_no = #{sortNo}</if>
+        </where>
+    </select>
+    
+    <select id="selectRobotOpsFaqSimilarById" parameterType="Long" resultMap="RobotOpsFaqSimilarResult">
+        <include refid="selectRobotOpsFaqSimilarVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertRobotOpsFaqSimilar" parameterType="RobotOpsFaqSimilar" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_faq_similar
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="faqId != null">faq_id,</if>
+            <if test="similarQuestion != null and similarQuestion != ''">similar_question,</if>
+            <if test="sortNo != null">sort_no,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="updateBy != null">update_by,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="faqId != null">#{faqId},</if>
+            <if test="similarQuestion != null and similarQuestion != ''">#{similarQuestion},</if>
+            <if test="sortNo != null">#{sortNo},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+         </trim>
+    </insert>
+
+    <update id="updateRobotOpsFaqSimilar" parameterType="RobotOpsFaqSimilar">
+        update robot_ops_faq_similar
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="faqId != null">faq_id = #{faqId},</if>
+            <if test="similarQuestion != null and similarQuestion != ''">similar_question = #{similarQuestion},</if>
+            <if test="sortNo != null">sort_no = #{sortNo},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsFaqSimilarById" parameterType="Long">
+        delete from robot_ops_faq_similar where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsFaqSimilarByIds" parameterType="String">
+        delete from robot_ops_faq_similar where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 126 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsMediaAssetMapper.xml

@@ -0,0 +1,126 @@
+<?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.ruoyi.base.mapper.RobotOpsMediaAssetMapper">
+
+    <resultMap type="RobotOpsMediaAsset" id="RobotOpsMediaAssetResult">
+        <result property="id"    column="id"    />
+        <result property="assetName"    column="asset_name"    />
+        <result property="assetType"    column="asset_type"    />
+        <result property="fileUrl"    column="file_url"    />
+        <result property="thumbnailUrl"    column="thumbnail_url"    />
+        <result property="fileSize"    column="file_size"    />
+        <result property="fileFormat"    column="file_format"    />
+        <result property="mimeType"    column="mime_type"    />
+        <result property="durationSeconds"    column="duration_seconds"    />
+        <result property="resolution"    column="resolution"    />
+        <result property="status"    column="status"    />
+        <result property="quotedFlag"    column="quoted_flag"    />
+        <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"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsMediaAssetVo">
+        select id, asset_name, asset_type, file_url, thumbnail_url, file_size, file_format, mime_type, duration_seconds, resolution, status, quoted_flag, remark, create_by, create_time, update_by, update_time from robot_ops_media_asset
+    </sql>
+
+    <select id="selectRobotOpsMediaAssetList" parameterType="RobotOpsMediaAsset" resultMap="RobotOpsMediaAssetResult">
+        <include refid="selectRobotOpsMediaAssetVo"/>
+        <where>
+            <if test="assetName != null  and assetName != ''"> and asset_name like concat('%', #{assetName}, '%')</if>
+            <if test="assetType != null  and assetType != ''"> and asset_type = #{assetType}</if>
+            <if test="mimeType != null  and mimeType != ''"> and mime_type = #{mimeType}</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+            <if test="quotedFlag != null  and quotedFlag != ''"> and quoted_flag = #{quotedFlag}</if>
+            <if test="params.beginCreateTime != null and params.beginCreateTime != ''">
+                and date_format(create_time,'%Y%m%d') &gt;= date_format(#{params.beginCreateTime},'%Y%m%d')
+            </if>
+            <if test="params.endCreateTime != null and params.endCreateTime != ''">
+                and date_format(create_time,'%Y%m%d') &lt;= date_format(#{params.endCreateTime},'%Y%m%d')
+            </if>
+        </where>
+    </select>
+
+    <select id="selectRobotOpsMediaAssetById" parameterType="Long" resultMap="RobotOpsMediaAssetResult">
+        <include refid="selectRobotOpsMediaAssetVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertRobotOpsMediaAsset" parameterType="RobotOpsMediaAsset" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_media_asset
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="assetName != null and assetName != ''">asset_name,</if>
+            <if test="assetType != null and assetType != ''">asset_type,</if>
+            <if test="fileUrl != null and fileUrl != ''">file_url,</if>
+            <if test="thumbnailUrl != null">thumbnail_url,</if>
+            <if test="fileSize != null">file_size,</if>
+            <if test="fileFormat != null">file_format,</if>
+            <if test="mimeType != null">mime_type,</if>
+            <if test="durationSeconds != null">duration_seconds,</if>
+            <if test="resolution != null">resolution,</if>
+            <if test="status != null and status != ''">status,</if>
+            <if test="quotedFlag != null and quotedFlag != ''">quoted_flag,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="assetName != null and assetName != ''">#{assetName},</if>
+            <if test="assetType != null and assetType != ''">#{assetType},</if>
+            <if test="fileUrl != null and fileUrl != ''">#{fileUrl},</if>
+            <if test="thumbnailUrl != null">#{thumbnailUrl},</if>
+            <if test="fileSize != null">#{fileSize},</if>
+            <if test="fileFormat != null">#{fileFormat},</if>
+            <if test="mimeType != null">#{mimeType},</if>
+            <if test="durationSeconds != null">#{durationSeconds},</if>
+            <if test="resolution != null">#{resolution},</if>
+            <if test="status != null and status != ''">#{status},</if>
+            <if test="quotedFlag != null and quotedFlag != ''">#{quotedFlag},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateRobotOpsMediaAsset" parameterType="RobotOpsMediaAsset">
+        update robot_ops_media_asset
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="assetName != null and assetName != ''">asset_name = #{assetName},</if>
+            <if test="assetType != null and assetType != ''">asset_type = #{assetType},</if>
+            <if test="fileUrl != null and fileUrl != ''">file_url = #{fileUrl},</if>
+            <if test="thumbnailUrl != null">thumbnail_url = #{thumbnailUrl},</if>
+            <if test="fileSize != null">file_size = #{fileSize},</if>
+            <if test="fileFormat != null">file_format = #{fileFormat},</if>
+            <if test="mimeType != null">mime_type = #{mimeType},</if>
+            <if test="durationSeconds != null">duration_seconds = #{durationSeconds},</if>
+            <if test="resolution != null">resolution = #{resolution},</if>
+            <if test="status != null and status != ''">status = #{status},</if>
+            <if test="quotedFlag != null and quotedFlag != ''">quoted_flag = #{quotedFlag},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsMediaAssetById" parameterType="Long">
+        delete from robot_ops_media_asset where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsMediaAssetByIds" parameterType="String">
+        delete from robot_ops_media_asset where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 168 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsPlayPlanMapper.xml

@@ -0,0 +1,168 @@
+<?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.ruoyi.base.mapper.RobotOpsPlayPlanMapper">
+
+    <resultMap type="RobotOpsPlayPlan" id="RobotOpsPlayPlanResult">
+        <result property="id"    column="id"    />
+        <result property="planName"    column="plan_name"    />
+        <result property="loopMode"    column="loop_mode"    />
+        <result property="assetCount"    column="asset_count"    />
+        <result property="status"    column="status"    />
+        <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"    />
+    </resultMap>
+
+    <resultMap id="RobotOpsPlayPlanRobotOpsPlayPlanItemResult" type="RobotOpsPlayPlan" extends="RobotOpsPlayPlanResult">
+        <collection property="robotOpsPlayPlanItemList" ofType="RobotOpsPlayPlanItem" column="id" select="selectRobotOpsPlayPlanItemList" />
+    </resultMap>
+
+    <resultMap type="RobotOpsPlayPlanItem" id="RobotOpsPlayPlanItemResult">
+        <result property="id"    column="id"    />
+        <result property="planId"    column="plan_id"    />
+        <result property="assetId"    column="asset_id"    />
+        <result property="playOrder"    column="play_order"    />
+        <result property="staySeconds"    column="stay_seconds"    />
+        <result property="transitionType"    column="transition_type"    />
+        <result property="fileUrl"    column="file_url"    />
+        <result property="assetType"    column="asset_type"    />
+        <result property="assetName"    column="asset_name"    />
+        <result property="thumbnailUrl"    column="thumbnail_url"    />
+        <result property="resolution"    column="resolution"    />
+        <result property="durationSeconds"    column="duration_seconds"/>
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsPlayPlanVo">
+        select p.id, p.plan_name, p.loop_mode, p.asset_count, p.status, p.remark, p.create_by, p.create_time, p.update_by, p.update_time, count(i.id) as asset_count
+        from robot_ops_play_plan p
+                 left join robot_ops_play_plan_item i on p.id = i.plan_id
+        group by p.id
+    </sql>
+
+    <select id="selectRobotOpsPlayPlanList" parameterType="RobotOpsPlayPlan" resultMap="RobotOpsPlayPlanResult">
+        select p.id, p.plan_name, p.loop_mode, p.status, p.remark, p.create_by, p.create_time, p.update_by, p.update_time, count(i.id) as asset_count
+        from robot_ops_play_plan p
+        left join robot_ops_play_plan_item i on p.id = i.plan_id
+        <where>
+            <if test="planName != null  and planName != ''"> and p.plan_name like concat('%', #{planName}, '%')</if>
+            <if test="loopMode != null  and loopMode != ''"> and p.loop_mode = #{loopMode}</if>
+            <if test="status != null  and status != ''"> and p.status = #{status}</if>
+        </where>
+        group by p.id, p.plan_name, p.loop_mode, p.status, p.remark, p.create_by, p.create_time, p.update_by, p.update_time
+    </select>
+
+    <select id="selectRobotOpsPlayPlanById" parameterType="Long" resultMap="RobotOpsPlayPlanRobotOpsPlayPlanItemResult">
+        select id, plan_name, loop_mode, asset_count, status, remark, create_by, create_time, update_by, update_time
+        from robot_ops_play_plan
+        where id = #{id}
+    </select>
+
+    <select id="selectRobotOpsPlayPlanItemList" resultMap="RobotOpsPlayPlanItemResult">
+        select i.id, i.plan_id, i.asset_id, i.play_order, i.stay_seconds, i.transition_type, a.file_url, a.asset_type, a.asset_name, a.thumbnail_url, a.resolution, a.duration_seconds, i.create_by, i.create_time, i.update_by, i.update_time
+        from robot_ops_play_plan_item i
+                 left join robot_ops_media_asset a on i.asset_id = a.id
+        where i.plan_id = #{plan_id}
+    </select>
+
+    <insert id="insertRobotOpsPlayPlan" parameterType="RobotOpsPlayPlan" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_play_plan
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="planName != null and planName != ''">plan_name,</if>
+            <if test="loopMode != null and loopMode != ''">loop_mode,</if>
+            <if test="assetCount != null">asset_count,</if>
+            <if test="status != null and status != ''">status,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="planName != null and planName != ''">#{planName},</if>
+            <if test="loopMode != null and loopMode != ''">#{loopMode},</if>
+            <if test="assetCount != null">#{assetCount},</if>
+            <if test="status != null and status != ''">#{status},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateRobotOpsPlayPlan" parameterType="RobotOpsPlayPlan">
+        update robot_ops_play_plan
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="planName != null and planName != ''">plan_name = #{planName},</if>
+            <if test="loopMode != null and loopMode != ''">loop_mode = #{loopMode},</if>
+            <if test="assetCount != null">asset_count = #{assetCount},</if>
+            <if test="status != null and status != ''">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsPlayPlanById" parameterType="Long">
+        delete from robot_ops_play_plan where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsPlayPlanByIds" parameterType="String">
+        delete from robot_ops_play_plan where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <delete id="deleteRobotOpsPlayPlanItemByPlanIds" parameterType="String">
+        delete from robot_ops_play_plan_item where plan_id in
+        <foreach item="planId" collection="array" open="(" separator="," close=")">
+            #{planId}
+        </foreach>
+    </delete>
+
+    <delete id="deleteRobotOpsPlayPlanItemByPlanId" parameterType="Long">
+        delete from robot_ops_play_plan_item where plan_id = #{planId}
+    </delete>
+
+
+    <select id="selectCurrentPlayingPlan" resultMap="RobotOpsPlayPlanResult">
+        select id, plan_name, loop_mode, asset_count, status, remark, create_by, create_time, update_by, update_time
+        from robot_ops_play_plan
+        where status = '1'
+            limit 1
+    </select>
+
+    <select id="selectRobotOpsPlayPlanItemListByPlanId" parameterType="Long" resultMap="RobotOpsPlayPlanItemResult">
+        select i.id, i.plan_id, i.asset_id, i.play_order, i.stay_seconds, i.transition_type,
+               a.file_url, a.asset_type, a.asset_name, a.thumbnail_url, a.resolution, a.duration_seconds,
+               i.create_by, i.create_time, i.update_by, i.update_time
+        from robot_ops_play_plan_item i
+        left join robot_ops_media_asset a on i.asset_id = a.id
+        where i.plan_id = #{planId}
+    </select>
+
+    <update id="updatePlayPlanStatus">
+        update robot_ops_play_plan
+        set status = #{status}, update_time = sysdate()
+        where id = #{id}
+    </update>
+
+    <insert id="batchRobotOpsPlayPlanItem">
+        insert into robot_ops_play_plan_item( id, plan_id, asset_id, play_order, stay_seconds, transition_type, create_by, create_time, update_by, update_time) values
+        <foreach item="item" index="index" collection="list" separator=",">
+            ( #{item.id}, #{item.planId}, #{item.assetId}, #{item.playOrder}, #{item.staySeconds}, #{item.transitionType}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime})
+        </foreach>
+    </insert>
+</mapper>

+ 122 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsScreenThemeConfigMapper.xml

@@ -0,0 +1,122 @@
+<?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.ruoyi.base.mapper.RobotOpsScreenThemeConfigMapper">
+    
+    <resultMap type="RobotOpsScreenThemeConfig" id="RobotOpsScreenThemeConfigResult">
+        <result property="id"    column="id"    />
+        <result property="configKey"    column="config_key"    />
+        <result property="logoUrl"    column="logo_url"    />
+        <result property="robotName"    column="robot_name"    />
+        <result property="brandSubtitle"    column="brand_subtitle"    />
+        <result property="backgroundImage"    column="background_image"    />
+        <result property="welcomeTitle"    column="welcome_title"    />
+        <result property="welcomeSubtitle"    column="welcome_subtitle"    />
+        <result property="touchText"    column="touch_text"    />
+        <result property="buttonColor"    column="button_color"    />
+        <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"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsScreenThemeConfigVo">
+        select id, config_key, logo_url, robot_name, brand_subtitle, background_image, welcome_title, welcome_subtitle, touch_text, button_color, remark, create_by, create_time, update_by, update_time from robot_ops_screen_theme_config
+    </sql>
+
+    <select id="selectRobotOpsScreenThemeConfigList" parameterType="RobotOpsScreenThemeConfig" resultMap="RobotOpsScreenThemeConfigResult">
+        <include refid="selectRobotOpsScreenThemeConfigVo"/>
+        <where>  
+            <if test="configKey != null  and configKey != ''"> and config_key = #{configKey}</if>
+            <if test="logoUrl != null  and logoUrl != ''"> and logo_url = #{logoUrl}</if>
+            <if test="robotName != null  and robotName != ''"> and robot_name like concat('%', #{robotName}, '%')</if>
+            <if test="brandSubtitle != null  and brandSubtitle != ''"> and brand_subtitle = #{brandSubtitle}</if>
+            <if test="backgroundImage != null  and backgroundImage != ''"> and background_image = #{backgroundImage}</if>
+            <if test="welcomeTitle != null  and welcomeTitle != ''"> and welcome_title = #{welcomeTitle}</if>
+            <if test="welcomeSubtitle != null  and welcomeSubtitle != ''"> and welcome_subtitle = #{welcomeSubtitle}</if>
+            <if test="touchText != null  and touchText != ''"> and touch_text = #{touchText}</if>
+            <if test="buttonColor != null  and buttonColor != ''"> and button_color = #{buttonColor}</if>
+        </where>
+    </select>
+    
+    <select id="selectRobotOpsScreenThemeConfigById" parameterType="Long" resultMap="RobotOpsScreenThemeConfigResult">
+        <include refid="selectRobotOpsScreenThemeConfigVo"/>
+        where id = #{id}
+    </select>
+
+    <select id="selectRobotOpsScreenThemeConfigByConfigKey" parameterType="String" resultMap="RobotOpsScreenThemeConfigResult">
+        <include refid="selectRobotOpsScreenThemeConfigVo"/>
+        where config_key = #{configKey}
+        limit 1
+    </select>
+
+    <insert id="insertRobotOpsScreenThemeConfig" parameterType="RobotOpsScreenThemeConfig" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_screen_theme_config
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="configKey != null and configKey != ''">config_key,</if>
+            <if test="logoUrl != null">logo_url,</if>
+            <if test="robotName != null">robot_name,</if>
+            <if test="brandSubtitle != null">brand_subtitle,</if>
+            <if test="backgroundImage != null">background_image,</if>
+            <if test="welcomeTitle != null">welcome_title,</if>
+            <if test="welcomeSubtitle != null">welcome_subtitle,</if>
+            <if test="touchText != null">touch_text,</if>
+            <if test="buttonColor != null">button_color,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="configKey != null and configKey != ''">#{configKey},</if>
+            <if test="logoUrl != null">#{logoUrl},</if>
+            <if test="robotName != null">#{robotName},</if>
+            <if test="brandSubtitle != null">#{brandSubtitle},</if>
+            <if test="backgroundImage != null">#{backgroundImage},</if>
+            <if test="welcomeTitle != null">#{welcomeTitle},</if>
+            <if test="welcomeSubtitle != null">#{welcomeSubtitle},</if>
+            <if test="touchText != null">#{touchText},</if>
+            <if test="buttonColor != null">#{buttonColor},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateRobotOpsScreenThemeConfig" parameterType="RobotOpsScreenThemeConfig">
+        update robot_ops_screen_theme_config
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="configKey != null and configKey != ''">config_key = #{configKey},</if>
+            <if test="logoUrl != null">logo_url = #{logoUrl},</if>
+            <if test="robotName != null">robot_name = #{robotName},</if>
+            <if test="brandSubtitle != null">brand_subtitle = #{brandSubtitle},</if>
+            <if test="backgroundImage != null">background_image = #{backgroundImage},</if>
+            <if test="welcomeTitle != null">welcome_title = #{welcomeTitle},</if>
+            <if test="welcomeSubtitle != null">welcome_subtitle = #{welcomeSubtitle},</if>
+            <if test="touchText != null">touch_text = #{touchText},</if>
+            <if test="buttonColor != null">button_color = #{buttonColor},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsScreenThemeConfigById" parameterType="Long">
+        delete from robot_ops_screen_theme_config where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsScreenThemeConfigByIds" parameterType="String">
+        delete from robot_ops_screen_theme_config where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 109 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsSysLogMapper.xml

@@ -0,0 +1,109 @@
+<?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.ruoyi.base.mapper.RobotOpsSysLogMapper">
+    
+    <resultMap type="RobotOpsSysLog" id="RobotOpsSysLogResult">
+        <result property="id"    column="id"    />
+        <result property="robotCode"    column="robot_code"    />
+        <result property="logTime"    column="log_time"    />
+        <result property="receiveTime"    column="receive_time"    />
+        <result property="logType"    column="log_type"    />
+        <result property="logLevel"    column="log_level"    />
+        <result property="moduleName"    column="module_name"    />
+        <result property="contentSummary"    column="content_summary"    />
+        <result property="content"    column="content"    />
+        <result property="resultStatus"    column="result_status"    />
+        <result property="traceId"    column="trace_id"    />
+        <result property="remark"    column="remark"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsSysLogVo">
+        select id, robot_code, log_time, receive_time, log_type, log_level, module_name, content_summary, content, result_status, trace_id, remark, create_time from robot_ops_sys_log
+    </sql>
+
+    <select id="selectRobotOpsSysLogList" parameterType="RobotOpsSysLog" resultMap="RobotOpsSysLogResult">
+        <include refid="selectRobotOpsSysLogVo"/>
+        <where>  
+            <if test="robotCode != null  and robotCode != ''"> and robot_code = #{robotCode}</if>
+            <if test="logTime != null "> and log_time = #{logTime}</if>
+            <if test="receiveTime != null "> and receive_time = #{receiveTime}</if>
+            <if test="logType != null  and logType != ''"> and log_type = #{logType}</if>
+            <if test="logLevel != null  and logLevel != ''"> and log_level = #{logLevel}</if>
+            <if test="moduleName != null  and moduleName != ''"> and module_name like concat('%', #{moduleName}, '%')</if>
+            <if test="contentSummary != null  and contentSummary != ''"> and content_summary = #{contentSummary}</if>
+            <if test="content != null  and content != ''"> and content = #{content}</if>
+            <if test="resultStatus != null  and resultStatus != ''"> and result_status = #{resultStatus}</if>
+            <if test="traceId != null  and traceId != ''"> and trace_id = #{traceId}</if>
+        </where>
+    </select>
+    
+    <select id="selectRobotOpsSysLogById" parameterType="Long" resultMap="RobotOpsSysLogResult">
+        <include refid="selectRobotOpsSysLogVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertRobotOpsSysLog" parameterType="RobotOpsSysLog" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_sys_log
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="robotCode != null">robot_code,</if>
+            <if test="logTime != null">log_time,</if>
+            <if test="receiveTime != null">receive_time,</if>
+            <if test="logType != null">log_type,</if>
+            <if test="logLevel != null">log_level,</if>
+            <if test="moduleName != null">module_name,</if>
+            <if test="contentSummary != null">content_summary,</if>
+            <if test="content != null">content,</if>
+            <if test="resultStatus != null">result_status,</if>
+            <if test="traceId != null">trace_id,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createTime != null">create_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="robotCode != null">#{robotCode},</if>
+            <if test="logTime != null">#{logTime},</if>
+            <if test="receiveTime != null">#{receiveTime},</if>
+            <if test="logType != null">#{logType},</if>
+            <if test="logLevel != null">#{logLevel},</if>
+            <if test="moduleName != null">#{moduleName},</if>
+            <if test="contentSummary != null">#{contentSummary},</if>
+            <if test="content != null">#{content},</if>
+            <if test="resultStatus != null">#{resultStatus},</if>
+            <if test="traceId != null">#{traceId},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateRobotOpsSysLog" parameterType="RobotOpsSysLog">
+        update robot_ops_sys_log
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="robotCode != null">robot_code = #{robotCode},</if>
+            <if test="logTime != null">log_time = #{logTime},</if>
+            <if test="receiveTime != null">receive_time = #{receiveTime},</if>
+            <if test="logType != null">log_type = #{logType},</if>
+            <if test="logLevel != null">log_level = #{logLevel},</if>
+            <if test="moduleName != null">module_name = #{moduleName},</if>
+            <if test="contentSummary != null">content_summary = #{contentSummary},</if>
+            <if test="content != null">content = #{content},</if>
+            <if test="resultStatus != null">result_status = #{resultStatus},</if>
+            <if test="traceId != null">trace_id = #{traceId},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsSysLogById" parameterType="Long">
+        delete from robot_ops_sys_log where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsSysLogByIds" parameterType="String">
+        delete from robot_ops_sys_log where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 124 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsVisitorRecordMapper.xml

@@ -0,0 +1,124 @@
+<?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.ruoyi.base.mapper.RobotOpsVisitorRecordMapper">
+
+    <resultMap type="RobotOpsVisitorRecord" id="RobotOpsVisitorRecordResult">
+        <result property="id"    column="id"    />
+        <result property="visitorName"    column="visitor_name"    />
+        <result property="mobile"    column="mobile"    />
+        <result property="idCardNo"    column="id_card_no"    />
+        <result property="visitType"    column="visit_type"    />
+        <result property="visitorSource"    column="visitor_source"    />
+        <result property="visitReason"    column="visit_reason"    />
+        <result property="visitorPhoto"    column="visitor_photo"    />
+        <result property="appointmentNo"    column="appointment_no"    />
+        <result property="visitedPerson"    column="visited_person"    />
+        <result property="visitTime"    column="visit_time"    />
+        <result property="remark"    column="remark"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="registerType"    column="register_type"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsVisitorRecordVo">
+        select id, visitor_name, mobile, id_card_no, visit_type, visitor_source, visit_reason, visitor_photo, appointment_no, visited_person, visit_time, remark, create_time, update_time, register_type from robot_ops_visitor_record
+    </sql>
+
+    <select id="selectRobotOpsVisitorRecordList" parameterType="RobotOpsVisitorRecord" resultMap="RobotOpsVisitorRecordResult">
+        <include refid="selectRobotOpsVisitorRecordVo"/>
+        <where>
+            <if test="visitorName != null  and visitorName != ''"> and visitor_name like concat('%', #{visitorName}, '%')</if>
+            <if test="mobile != null  and mobile != ''"> and mobile = #{mobile}</if>
+            <if test="idCardNo != null  and idCardNo != ''"> and id_card_no = #{idCardNo}</if>
+            <if test="visitType != null  and visitType != ''"> and visit_type = #{visitType}</if>
+            <if test="visitorSource != null  and visitorSource != ''"> and visitor_source = #{visitorSource}</if>
+            <if test="visitReason != null  and visitReason != ''"> and visit_reason = #{visitReason}</if>
+            <if test="visitorPhoto != null  and visitorPhoto != ''"> and visitor_photo = #{visitorPhoto}</if>
+            <if test="appointmentNo != null  and appointmentNo != ''"> and appointment_no = #{appointmentNo}</if>
+            <if test="visitedPerson != null  and visitedPerson != ''"> and visited_person like concat('%', #{visitedPerson}, '%')</if>
+            <if test="visitTime != null "> and visit_time = #{visitTime}</if>
+            <if test="registerType != null  and registerType != ''"> and register_type = #{registerType}</if>
+            <if test="params.beginTime != null and params.beginTime != ''">
+                and date_format(visit_time,'%Y%m%d') &gt;= date_format(#{params.beginTime},'%Y%m%d')
+            </if>
+            <if test="params.endTime != null and params.endTime != ''">
+                and date_format(visit_time,'%Y%m%d') &lt;= date_format(#{params.endTime},'%Y%m%d')
+            </if>
+        </where>
+    </select>
+
+    <select id="selectRobotOpsVisitorRecordById" parameterType="Long" resultMap="RobotOpsVisitorRecordResult">
+        <include refid="selectRobotOpsVisitorRecordVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertRobotOpsVisitorRecord" parameterType="RobotOpsVisitorRecord" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_visitor_record
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="visitorName != null">visitor_name,</if>
+            <if test="mobile != null">mobile,</if>
+            <if test="idCardNo != null">id_card_no,</if>
+            <if test="visitType != null and visitType != ''">visit_type,</if>
+            <if test="visitorSource != null">visitor_source,</if>
+            <if test="visitReason != null">visit_reason,</if>
+            <if test="visitorPhoto != null">visitor_photo,</if>
+            <if test="appointmentNo != null">appointment_no,</if>
+            <if test="visitedPerson != null">visited_person,</if>
+            <if test="visitTime != null">visit_time,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="registerType != null and registerType != ''">register_type,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="visitorName != null">#{visitorName},</if>
+            <if test="mobile != null">#{mobile},</if>
+            <if test="idCardNo != null">#{idCardNo},</if>
+            <if test="visitType != null and visitType != ''">#{visitType},</if>
+            <if test="visitorSource != null">#{visitorSource},</if>
+            <if test="visitReason != null">#{visitReason},</if>
+            <if test="visitorPhoto != null">#{visitorPhoto},</if>
+            <if test="appointmentNo != null">#{appointmentNo},</if>
+            <if test="visitedPerson != null">#{visitedPerson},</if>
+            <if test="visitTime != null">#{visitTime},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="registerType != null and registerType != ''">#{registerType},</if>
+        </trim>
+    </insert>
+
+    <update id="updateRobotOpsVisitorRecord" parameterType="RobotOpsVisitorRecord">
+        update robot_ops_visitor_record
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="visitorName != null">visitor_name = #{visitorName},</if>
+            <if test="mobile != null">mobile = #{mobile},</if>
+            <if test="idCardNo != null">id_card_no = #{idCardNo},</if>
+            <if test="visitType != null and visitType != ''">visit_type = #{visitType},</if>
+            <if test="visitorSource != null">visitor_source = #{visitorSource},</if>
+            <if test="visitReason != null">visit_reason = #{visitReason},</if>
+            <if test="visitorPhoto != null">visitor_photo = #{visitorPhoto},</if>
+            <if test="appointmentNo != null">appointment_no = #{appointmentNo},</if>
+            <if test="visitedPerson != null">visited_person = #{visitedPerson},</if>
+            <if test="visitTime != null">visit_time = #{visitTime},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="registerType != null and registerType != ''">register_type = #{registerType},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsVisitorRecordById" parameterType="Long">
+        delete from robot_ops_visitor_record where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsVisitorRecordByIds" parameterType="String">
+        delete from robot_ops_visitor_record where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 108 - 0
ruoyi-system/src/main/resources/mapper/base/RobotOpsWhitelistMapper.xml

@@ -0,0 +1,108 @@
+<?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.ruoyi.base.mapper.RobotOpsWhitelistMapper">
+
+    <resultMap type="RobotOpsWhitelist" id="RobotOpsWhitelistResult">
+        <result property="id"    column="id"    />
+        <result property="name"    column="name"    />
+        <result property="mobile"    column="mobile"    />
+        <result property="idCardNo"    column="id_card_no"    />
+        <result property="faceImageUrl"    column="face_image_url"    />
+        <result property="validStartTime"    column="valid_start_time"    />
+        <result property="validEndTime"    column="valid_end_time"    />
+        <result property="status"    column="status"    />
+        <result property="remark"    column="remark"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="whitelistType"    column="whitelist_type"    />
+        <result property="sourceType"    column="source_type"    />
+    </resultMap>
+
+    <sql id="selectRobotOpsWhitelistVo">
+        select id, name, mobile, id_card_no, face_image_url, valid_start_time, valid_end_time, status, remark, create_time, update_time, whitelist_type, source_type from robot_ops_whitelist
+    </sql>
+
+    <select id="selectRobotOpsWhitelistList" parameterType="RobotOpsWhitelist" resultMap="RobotOpsWhitelistResult">
+        <include refid="selectRobotOpsWhitelistVo"/>
+        <where>
+            <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
+            <if test="mobile != null  and mobile != ''"> and mobile = #{mobile}</if>
+            <if test="idCardNo != null  and idCardNo != ''"> and id_card_no = #{idCardNo}</if>
+            <if test="faceImageUrl != null  and faceImageUrl != ''"> and face_image_url = #{faceImageUrl}</if>
+            <if test="validStartTime != null "> and valid_start_time = #{validStartTime}</if>
+            <if test="validEndTime != null "> and valid_end_time = #{validEndTime}</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+            <if test="whitelistType != null "> and whitelist_type = #{whitelistType}</if>
+            <if test="sourceType != null "> and source_type = #{sourceType}</if>
+        </where>
+    </select>
+
+    <select id="selectRobotOpsWhitelistById" parameterType="Long" resultMap="RobotOpsWhitelistResult">
+        <include refid="selectRobotOpsWhitelistVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertRobotOpsWhitelist" parameterType="RobotOpsWhitelist" useGeneratedKeys="true" keyProperty="id">
+        insert into robot_ops_whitelist
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="name != null and name != ''">name,</if>
+            <if test="mobile != null">mobile,</if>
+            <if test="idCardNo != null">id_card_no,</if>
+            <if test="faceImageUrl != null">face_image_url,</if>
+            <if test="validStartTime != null">valid_start_time,</if>
+            <if test="validEndTime != null">valid_end_time,</if>
+            <if test="status != null and status != ''">status,</if>
+            <if test="remark != null">remark,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="whitelistType != null">whitelist_type,</if>
+            <if test="sourceType != null">source_type,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="name != null and name != ''">#{name},</if>
+            <if test="mobile != null">#{mobile},</if>
+            <if test="idCardNo != null">#{idCardNo},</if>
+            <if test="faceImageUrl != null">#{faceImageUrl},</if>
+            <if test="validStartTime != null">#{validStartTime},</if>
+            <if test="validEndTime != null">#{validEndTime},</if>
+            <if test="status != null and status != ''">#{status},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="whitelistType != null">#{whitelistType},</if>
+            <if test="sourceType != null">#{sourceType},</if>
+        </trim>
+    </insert>
+
+    <update id="updateRobotOpsWhitelist" parameterType="RobotOpsWhitelist">
+        update robot_ops_whitelist
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="name != null and name != ''">name = #{name},</if>
+            <if test="mobile != null">mobile = #{mobile},</if>
+            <if test="idCardNo != null">id_card_no = #{idCardNo},</if>
+            <if test="faceImageUrl != null">face_image_url = #{faceImageUrl},</if>
+            <if test="validStartTime != null">valid_start_time = #{validStartTime},</if>
+            <if test="validEndTime != null">valid_end_time = #{validEndTime},</if>
+            <if test="status != null and status != ''">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="whitelistType != null">whitelist_type = #{whitelistType},</if>
+            <if test="sourceType != null">source_type = #{sourceType},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteRobotOpsWhitelistById" parameterType="Long">
+        delete from robot_ops_whitelist where id = #{id}
+    </delete>
+
+    <delete id="deleteRobotOpsWhitelistByIds" parameterType="String">
+        delete from robot_ops_whitelist where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>