Sfoglia il codice sorgente

1、blockly编程游戏管理

liyanbo 8 mesi fa
parent
commit
9b2eb5b4ba
14 ha cambiato i file con 620 aggiunte e 14 eliminazioni
  1. 104 0
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/controller/admin/mapgame/MapGameController.java
  2. 61 0
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/controller/admin/mapgame/vo/MapGamePageReqVO.java
  3. 75 0
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/controller/admin/mapgame/vo/MapGameRespVO.java
  4. 53 0
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/controller/admin/mapgame/vo/MapGameSaveReqVO.java
  5. 84 0
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/dal/dataobject/mapgame/MapGameDO.java
  6. 39 0
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/dal/mysql/mapgame/MapGameMapper.java
  7. 3 0
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/enums/ErrorCodeConstants.java
  8. 2 1
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/service/chat/AiChatMessageServiceImpl.java
  9. 62 0
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/service/mapgame/MapGameService.java
  10. 92 0
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/service/mapgame/MapGameServiceImpl.java
  11. 1 1
      byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/service/video/AiVideoServiceImpl.java
  12. 7 0
      byzs-module-ai/src/main/resources/mapper/mapgame/MapGameMapper.xml
  13. 35 11
      byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/ai/WebAiController.java
  14. 2 1
      byzs-web/src/main/java/cn/iocoder/byzs/module/web/service/ai/WebAiServiceImpl.java

+ 104 - 0
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/controller/admin/mapgame/MapGameController.java

@@ -0,0 +1,104 @@
+package cn.iocoder.byzs.module.ai.controller.admin.mapgame;
+
+import org.springframework.web.bind.annotation.*;
+import jakarta.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Operation;
+
+import jakarta.validation.constraints.*;
+import jakarta.validation.*;
+import jakarta.servlet.http.*;
+import java.util.*;
+import java.io.IOException;
+
+import cn.iocoder.byzs.framework.common.pojo.PageParam;
+import cn.iocoder.byzs.framework.common.pojo.PageResult;
+import cn.iocoder.byzs.framework.common.pojo.CommonResult;
+import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
+import static cn.iocoder.byzs.framework.common.pojo.CommonResult.success;
+
+import cn.iocoder.byzs.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.byzs.framework.apilog.core.annotation.ApiAccessLog;
+import static cn.iocoder.byzs.framework.apilog.core.enums.OperateTypeEnum.*;
+
+import cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo.*;
+import cn.iocoder.byzs.module.ai.dal.dataobject.mapgame.MapGameDO;
+import cn.iocoder.byzs.module.ai.service.mapgame.MapGameService;
+
+@Tag(name = "管理后台 - AI-blockly地图编程游戏")
+@RestController
+@RequestMapping("/ai/map-game")
+@Validated
+public class MapGameController {
+
+    @Resource
+    private MapGameService mapGameService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建AI-blockly地图编程游戏")
+    @PreAuthorize("@ss.hasPermission('ai:map-game:create')")
+    public CommonResult<Integer> createMapGame(@Valid @RequestBody MapGameSaveReqVO createReqVO) {
+        return success(mapGameService.createMapGame(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新AI-blockly地图编程游戏")
+    @PreAuthorize("@ss.hasPermission('ai:map-game:update')")
+    public CommonResult<Boolean> updateMapGame(@Valid @RequestBody MapGameSaveReqVO updateReqVO) {
+        mapGameService.updateMapGame(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除AI-blockly地图编程游戏")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('ai:map-game:delete')")
+    public CommonResult<Boolean> deleteMapGame(@RequestParam("id") Integer id) {
+        mapGameService.deleteMapGame(id);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete-list")
+    @Parameter(name = "ids", description = "编号", required = true)
+    @Operation(summary = "批量删除AI-blockly地图编程游戏")
+                @PreAuthorize("@ss.hasPermission('ai:map-game:delete')")
+    public CommonResult<Boolean> deleteMapGameList(@RequestParam("ids") List<Integer> ids) {
+        mapGameService.deleteMapGameListByIds(ids);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得AI-blockly地图编程游戏")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('ai:map-game:query')")
+    public CommonResult<MapGameRespVO> getMapGame(@RequestParam("id") Integer id) {
+        MapGameDO mapGame = mapGameService.getMapGame(id);
+        return success(BeanUtils.toBean(mapGame, MapGameRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得AI-blockly地图编程游戏分页")
+    @PreAuthorize("@ss.hasPermission('ai:map-game:query')")
+    public CommonResult<PageResult<MapGameRespVO>> getMapGamePage(@Valid MapGamePageReqVO pageReqVO) {
+        PageResult<MapGameDO> pageResult = mapGameService.getMapGamePage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, MapGameRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出AI-blockly地图编程游戏 Excel")
+    @PreAuthorize("@ss.hasPermission('ai:map-game:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportMapGameExcel(@Valid MapGamePageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<MapGameDO> list = mapGameService.getMapGamePage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "AI-blockly地图编程游戏.xls", "数据", MapGameRespVO.class,
+                        BeanUtils.toBean(list, MapGameRespVO.class));
+    }
+
+}

+ 61 - 0
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/controller/admin/mapgame/vo/MapGamePageReqVO.java

@@ -0,0 +1,61 @@
+package cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.*;
+import java.util.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import cn.iocoder.byzs.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.byzs.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - AI-blockly地图编程游戏分页 Request VO")
+@Data
+public class MapGamePageReqVO extends PageParam {
+
+    @Schema(description = "名称")
+    private String name;
+
+    @Schema(description = "简介")
+    private String info;
+
+    @Schema(description = "人物图标")
+    private String userImage;
+
+    @Schema(description = "人物初始坐标")
+    private String userPosition;
+
+    @Schema(description = "地图背景图")
+    @ExcelProperty("地图背景图")
+    private String mapBackground;
+
+    @Schema(description = "地图方格尺寸")
+    private Double mapTileSize;
+
+    @Schema(description = "地图开始坐标")
+    private String mapStartPoint;
+
+    @Schema(description = "地图结束坐标")
+    private String mapEndPoint;
+
+    @Schema(description = "地图可行走坐标")
+    private String mapWalkablePoints;
+
+    @Schema(description = "json数据")
+    private String jsonData;
+
+    @Schema(description = "排序")
+    private Integer sort;
+
+    @Schema(description = "状态")
+    private Integer status;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+    @Schema(description = "租户编号")
+    private Long tenantId;
+
+}

+ 75 - 0
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/controller/admin/mapgame/vo/MapGameRespVO.java

@@ -0,0 +1,75 @@
+package cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+@Schema(description = "管理后台 - AI-blockly地图编程游戏 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MapGameRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("主键")
+    private Integer id;
+
+    @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("名称")
+    private String name;
+
+    @Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("简介")
+    private String info;
+
+    @Schema(description = "人物图标")
+    @ExcelProperty("人物图标")
+    private String userImage;
+
+    @Schema(description = "人物初始坐标")
+    @ExcelProperty("人物初始坐标")
+    private String userPosition;
+
+    @Schema(description = "地图方格尺寸")
+    @ExcelProperty("地图方格尺寸")
+    private Double mapTileSize;
+
+    @Schema(description = "地图开始坐标")
+    @ExcelProperty("地图开始坐标")
+    private String mapStartPoint;
+
+    @Schema(description = "地图背景图")
+    @ExcelProperty("地图背景图")
+    private String mapBackground;
+
+    @Schema(description = "地图结束坐标")
+    @ExcelProperty("地图结束坐标")
+    private String mapEndPoint;
+
+    @Schema(description = "地图可行走坐标")
+    @ExcelProperty("地图可行走坐标")
+    private String mapWalkablePoints;
+
+    @Schema(description = "json数据")
+    @ExcelProperty("json数据")
+    private String jsonData;
+
+    @Schema(description = "排序")
+    @ExcelProperty("排序")
+    private Integer sort;
+
+    @Schema(description = "状态")
+    @ExcelProperty("状态")
+    private Integer status;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @Schema(description = "租户编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("租户编号")
+    private Long tenantId;
+
+}

+ 53 - 0
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/controller/admin/mapgame/vo/MapGameSaveReqVO.java

@@ -0,0 +1,53 @@
+package cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import jakarta.validation.constraints.*;
+
+@Schema(description = "管理后台 - AI-blockly地图编程游戏新增/修改 Request VO")
+@Data
+public class MapGameSaveReqVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED)
+    private Integer id;
+
+    @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "名称不能为空")
+    private String name;
+
+    @Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "简介不能为空")
+    private String info;
+
+    @Schema(description = "人物图标")
+    private String userImage;
+
+    @Schema(description = "人物初始坐标")
+    private String userPosition;
+
+    @Schema(description = "地图方格尺寸")
+    private Double mapTileSize;
+
+    @Schema(description = "地图开始坐标")
+    private String mapStartPoint;
+
+    @Schema(description = "地图背景图")
+    private String mapBackground;
+
+    @Schema(description = "地图结束坐标")
+    private String mapEndPoint;
+
+    @Schema(description = "地图可行走坐标")
+    private String mapWalkablePoints;
+
+    @Schema(description = "json数据")
+    private String jsonData;
+
+    @Schema(description = "排序")
+    private Integer sort;
+
+    @Schema(description = "状态")
+    private Integer status;
+
+}

+ 84 - 0
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/dal/dataobject/mapgame/MapGameDO.java

@@ -0,0 +1,84 @@
+package cn.iocoder.byzs.module.ai.dal.dataobject.mapgame;
+
+import lombok.*;
+import java.util.*;
+import java.time.LocalDateTime;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.byzs.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * AI-blockly地图编程游戏 DO
+ *
+ * @author lyb
+ */
+@TableName("ai_map_game")
+@KeySequence("ai_map_game_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MapGameDO extends BaseDO {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Integer id;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * 简介
+     */
+    private String info;
+    /**
+     * 人物图标
+     */
+    private String userImage;
+    /**
+     * 人物初始坐标
+     */
+    private String userPosition;
+    /**
+     * 地图方格大小
+     */
+    private Double mapTileSize;
+    /**
+     * 地图背景图
+     */
+    private String mapBackground;
+    /**
+     * 地图开始坐标
+     */
+    private String mapStartPoint;
+    /**
+     * 地图结束坐标
+     */
+    private String mapEndPoint;
+    /**
+     * 地图可行走坐标
+     */
+    private String mapWalkablePoints;
+    /**
+     * json数据
+     */
+    private String jsonData;
+    /**
+     * 排序
+     */
+    private Integer sort;
+    /**
+     * 状态
+     */
+    private Integer status;
+
+    /**
+     * 租户id
+     */
+    private Long tenantId;
+
+}

+ 39 - 0
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/dal/mysql/mapgame/MapGameMapper.java

@@ -0,0 +1,39 @@
+package cn.iocoder.byzs.module.ai.dal.mysql.mapgame;
+
+import java.util.*;
+
+import cn.iocoder.byzs.framework.common.pojo.PageResult;
+import cn.iocoder.byzs.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.byzs.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.byzs.module.ai.dal.dataobject.mapgame.MapGameDO;
+import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo.*;
+
+/**
+ * AI-blockly地图编程游戏 Mapper
+ *
+ * @author lyb
+ */
+@Mapper
+public interface MapGameMapper extends BaseMapperX<MapGameDO> {
+
+    default PageResult<MapGameDO> selectPage(MapGamePageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<MapGameDO>()
+                .likeIfPresent(MapGameDO::getName, reqVO.getName())
+                .eqIfPresent(MapGameDO::getInfo, reqVO.getInfo())
+                .eqIfPresent(MapGameDO::getUserImage, reqVO.getUserImage())
+                .eqIfPresent(MapGameDO::getUserPosition, reqVO.getUserPosition())
+                .eqIfPresent(MapGameDO::getMapTileSize, reqVO.getMapTileSize())
+                .eqIfPresent(MapGameDO::getMapStartPoint, reqVO.getMapStartPoint())
+                .eqIfPresent(MapGameDO::getMapBackground, reqVO.getMapBackground())
+                .eqIfPresent(MapGameDO::getMapEndPoint, reqVO.getMapEndPoint())
+                .eqIfPresent(MapGameDO::getMapWalkablePoints, reqVO.getMapWalkablePoints())
+                .eqIfPresent(MapGameDO::getJsonData, reqVO.getJsonData())
+                .eqIfPresent(MapGameDO::getSort, reqVO.getSort())
+                .eqIfPresent(MapGameDO::getStatus, reqVO.getStatus())
+                .betweenIfPresent(MapGameDO::getCreateTime, reqVO.getCreateTime())
+                .eqIfPresent(MapGameDO::getTenantId, reqVO.getTenantId())
+                .orderByDesc(MapGameDO::getId));
+    }
+
+}

+ 3 - 0
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/enums/ErrorCodeConstants.java

@@ -75,4 +75,7 @@ public interface ErrorCodeConstants {
      // ========== API 虚拟实验室 1-050-013-000 ==========
     ErrorCode VIRTUAL_DEVICE_NOT_EXISTS = new ErrorCode(1_050_001_000, "虚拟实验室不存在!");
 
+    // ========== API 地图游戏 1_060_001_000 ==========
+    ErrorCode MAP_GAME_NOT_EXISTS = new ErrorCode(1_060_001_000, "地图游戏不存在!");
+
 }

+ 2 - 1
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/service/chat/AiChatMessageServiceImpl.java

@@ -32,6 +32,7 @@ import cn.iocoder.byzs.module.ai.service.model.AiChatRoleService;
 import cn.iocoder.byzs.module.ai.service.model.AiModelService;
 import cn.iocoder.byzs.module.ai.service.model.AiToolService;
 import cn.iocoder.byzs.module.ai.util.tts.WavHeader;
+import com.alibaba.nls.client.protocol.SampleRateEnum;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.ai.chat.messages.Message;
@@ -324,7 +325,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
                         byte[] processedAudio;
                         if (isFirstChunk.getAndSet(false)) {
                             // 仅首包添加WAV头
-                            processedAudio = WavHeader.addWavHeader(audioBytes, 16000, 16, 1);
+                            processedAudio = WavHeader.addWavHeader(audioBytes, SampleRateEnum.SAMPLE_RATE_16K.value, 16, 1);
                             log.info("首包音频带WAV头,长度={} bytes", processedAudio.length);
                         } else {
                             // 后续包直接使用原始PCM数据

+ 62 - 0
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/service/mapgame/MapGameService.java

@@ -0,0 +1,62 @@
+package cn.iocoder.byzs.module.ai.service.mapgame;
+
+import java.util.*;
+import jakarta.validation.*;
+import cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo.*;
+import cn.iocoder.byzs.module.ai.dal.dataobject.mapgame.MapGameDO;
+import cn.iocoder.byzs.framework.common.pojo.PageResult;
+import cn.iocoder.byzs.framework.common.pojo.PageParam;
+
+/**
+ * AI-blockly地图编程游戏 Service 接口
+ *
+ * @author lyb
+ */
+public interface MapGameService {
+
+    /**
+     * 创建AI-blockly地图编程游戏
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Integer createMapGame(@Valid MapGameSaveReqVO createReqVO);
+
+    /**
+     * 更新AI-blockly地图编程游戏
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateMapGame(@Valid MapGameSaveReqVO updateReqVO);
+
+    /**
+     * 删除AI-blockly地图编程游戏
+     *
+     * @param id 编号
+     */
+    void deleteMapGame(Integer id);
+
+    /**
+    * 批量删除AI-blockly地图编程游戏
+    *
+    * @param ids 编号
+    */
+    void deleteMapGameListByIds(List<Integer> ids);
+
+    /**
+     * 获得AI-blockly地图编程游戏
+     *
+     * @param id 编号
+     * @return AI-blockly地图编程游戏
+     */
+    MapGameDO getMapGame(Integer id);
+
+    /**
+     * 获得AI-blockly地图编程游戏分页
+     *
+     * @param pageReqVO 分页查询
+     * @return AI-blockly地图编程游戏分页
+     */
+    PageResult<MapGameDO> getMapGamePage(MapGamePageReqVO pageReqVO);
+
+}

+ 92 - 0
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/service/mapgame/MapGameServiceImpl.java

@@ -0,0 +1,92 @@
+package cn.iocoder.byzs.module.ai.service.mapgame;
+
+import cn.hutool.core.collection.CollUtil;
+import org.springframework.stereotype.Service;
+import jakarta.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo.*;
+import cn.iocoder.byzs.module.ai.dal.dataobject.mapgame.MapGameDO;
+import cn.iocoder.byzs.framework.common.pojo.PageResult;
+import cn.iocoder.byzs.framework.common.pojo.PageParam;
+import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
+
+import cn.iocoder.byzs.module.ai.dal.mysql.mapgame.MapGameMapper;
+
+import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.byzs.framework.common.util.collection.CollectionUtils.convertList;
+import static cn.iocoder.byzs.framework.common.util.collection.CollectionUtils.diffList;
+import static cn.iocoder.byzs.module.ai.enums.ErrorCodeConstants.*;
+
+/**
+ * AI-blockly地图编程游戏 Service 实现类
+ *
+ * @author lyb
+ */
+@Service
+@Validated
+public class MapGameServiceImpl implements MapGameService {
+
+    @Resource
+    private MapGameMapper mapGameMapper;
+
+    @Override
+    public Integer createMapGame(MapGameSaveReqVO createReqVO) {
+        // 插入
+        MapGameDO mapGame = BeanUtils.toBean(createReqVO, MapGameDO.class);
+        mapGameMapper.insert(mapGame);
+        // 返回
+        return mapGame.getId();
+    }
+
+    @Override
+    public void updateMapGame(MapGameSaveReqVO updateReqVO) {
+        // 校验存在
+        validateMapGameExists(updateReqVO.getId());
+        // 更新
+        MapGameDO updateObj = BeanUtils.toBean(updateReqVO, MapGameDO.class);
+        mapGameMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteMapGame(Integer id) {
+        // 校验存在
+        validateMapGameExists(id);
+        // 删除
+        mapGameMapper.deleteById(id);
+    }
+
+    @Override
+        public void deleteMapGameListByIds(List<Integer> ids) {
+        // 校验存在
+        validateMapGameExists(ids);
+        // 删除
+        mapGameMapper.deleteByIds(ids);
+        }
+
+    private void validateMapGameExists(List<Integer> ids) {
+        List<MapGameDO> list = mapGameMapper.selectByIds(ids);
+        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
+            throw exception(MAP_GAME_NOT_EXISTS);
+        }
+    }
+
+    private void validateMapGameExists(Integer id) {
+        if (mapGameMapper.selectById(id) == null) {
+            throw exception(MAP_GAME_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public MapGameDO getMapGame(Integer id) {
+        return mapGameMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<MapGameDO> getMapGamePage(MapGamePageReqVO pageReqVO) {
+        return mapGameMapper.selectPage(pageReqVO);
+    }
+
+}

+ 1 - 1
byzs-module-ai/src/main/java/cn/iocoder/byzs/module/ai/service/video/AiVideoServiceImpl.java

@@ -135,7 +135,7 @@ public class AiVideoServiceImpl implements AiVideoService {
             //是否固定相机位置
             boolean cameraFixed = false;
             //是否添加水印
-            boolean watermark = true;
+            boolean watermark = false;
 
             String formattedPrompt = String.format("%s  --resolution %s  --duration %d --camerafixed %s --watermark %s",
                     promptText, resolution, duration, cameraFixed, watermark);

+ 7 - 0
byzs-module-ai/src/main/resources/mapper/mapgame/MapGameMapper.xml

@@ -0,0 +1,7 @@
+<?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="cn.iocoder.byzs.module.ai.dal.mysql.mapgame.MapGameMapper">
+
+
+
+</mapper>

+ 35 - 11
byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/ai/WebAiController.java

@@ -12,12 +12,15 @@ import cn.iocoder.byzs.module.ai.controller.admin.chat.vo.message.AiChatMessageS
 import cn.iocoder.byzs.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO;
 import cn.iocoder.byzs.module.ai.controller.admin.image.vo.AiImageDrawReqVO;
 import cn.iocoder.byzs.module.ai.controller.admin.image.vo.AiImageRespVO;
+import cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo.MapGamePageReqVO;
+import cn.iocoder.byzs.module.ai.controller.admin.mapgame.vo.MapGameRespVO;
 import cn.iocoder.byzs.module.ai.controller.admin.model.vo.chatRole.AiChatRolePageReqVO;
 import cn.iocoder.byzs.module.ai.controller.admin.video.vo.AiVideoDrawReqVO;
 import cn.iocoder.byzs.module.ai.controller.admin.video.vo.AiVideoRespVO;
 import cn.iocoder.byzs.module.ai.controller.admin.virtualdevice.vo.VirtualDevicePageReqVO;
 import cn.iocoder.byzs.module.ai.controller.admin.virtualdevice.vo.VirtualDeviceRespVO;
 import cn.iocoder.byzs.module.ai.dal.dataobject.image.AiImageDO;
+import cn.iocoder.byzs.module.ai.dal.dataobject.mapgame.MapGameDO;
 import cn.iocoder.byzs.module.ai.dal.dataobject.model.AiChatRoleDO;
 import cn.iocoder.byzs.module.ai.dal.dataobject.model.AiModelDO;
 import cn.iocoder.byzs.module.ai.dal.dataobject.video.AiVideoDO;
@@ -25,6 +28,7 @@ import cn.iocoder.byzs.module.ai.dal.dataobject.virtualdevice.VirtualDeviceDO;
 import cn.iocoder.byzs.module.ai.service.chat.AiChatConversationService;
 import cn.iocoder.byzs.module.ai.service.chat.AiChatMessageService;
 import cn.iocoder.byzs.module.ai.service.image.AiImageService;
+import cn.iocoder.byzs.module.ai.service.mapgame.MapGameService;
 import cn.iocoder.byzs.module.ai.service.model.AiChatRoleService;
 import cn.iocoder.byzs.module.ai.service.model.AiModelService;
 import cn.iocoder.byzs.module.ai.service.video.AiVideoService;
@@ -70,6 +74,8 @@ public class WebAiController {
     private WebAiServiceImpl webAiService;
     @Resource
     private VirtualDeviceService virtualDeviceService;
+    @Resource
+    private MapGameService mapGameService;
 
 
     // ================ 模型数据 ================
@@ -83,17 +89,6 @@ public class WebAiController {
         return success(BeanUtils.toBean(pageResult, WebAiChatRoleVO.class));
     }
 
-    @GetMapping("/selectVirtualDevice")
-    @Operation(summary = "获得虚拟设备分页")
-    @PermitAll
-    @TenantIgnore
-    public CommonResult<PageResult<VirtualDeviceRespVO>> selectVirtualDevice(@Valid VirtualDevicePageReqVO pageReqVO) {
-        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
-        pageReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
-        PageResult<VirtualDeviceDO> pageResult = virtualDeviceService.getVirtualDevicePage(pageReqVO);
-        return success(BeanUtils.toBean(pageResult, VirtualDeviceRespVO.class));
-    }
-
     @PermitAll
     @TenantIgnore
     @GetMapping("/getModelIdByType")
@@ -186,4 +181,33 @@ public class WebAiController {
         List<AiVideoDO> videoList = videoService.getVideoList(ids);
         return success(BeanUtils.toBean(videoList, AiVideoRespVO.class));
     }
+
+
+    // ================ 虚拟实验室 ================
+
+    @GetMapping("/selectVirtualDevice")
+    @Operation(summary = "获得虚拟设备分页")
+    @PermitAll
+    @TenantIgnore
+    public CommonResult<PageResult<VirtualDeviceRespVO>> selectVirtualDevice(@Valid VirtualDevicePageReqVO pageReqVO) {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        pageReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
+        PageResult<VirtualDeviceDO> pageResult = virtualDeviceService.getVirtualDevicePage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, VirtualDeviceRespVO.class));
+    }
+
+
+    // ================ blockly 地图编辑游戏================
+
+    @GetMapping("/selectMapGame")
+    @Operation(summary = "获得AI-blockly地图编程游戏分页")
+    @PermitAll
+    @TenantIgnore
+    public CommonResult<PageResult<MapGameRespVO>> selectMapGame(@Valid MapGamePageReqVO pageReqVO) {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        pageReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
+
+        PageResult<MapGameDO> pageResult = mapGameService.getMapGamePage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, MapGameRespVO.class));
+    }
 }

+ 2 - 1
byzs-web/src/main/java/cn/iocoder/byzs/module/web/service/ai/WebAiServiceImpl.java

@@ -15,6 +15,7 @@ import cn.iocoder.byzs.module.ai.service.chat.AiChatConversationService;
 import cn.iocoder.byzs.module.ai.service.model.AiChatRoleService;
 import cn.iocoder.byzs.module.ai.util.tts.StreamTtsService;
 import cn.iocoder.byzs.module.ai.util.tts.WavHeader;
+import com.alibaba.nls.client.protocol.SampleRateEnum;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.ai.chat.messages.MessageType;
@@ -303,7 +304,7 @@ public class WebAiServiceImpl {
     private byte[] processAudioData(byte[] audioBytes, AtomicBoolean isFirstChunk) {
         if (isFirstChunk.getAndSet(false)) {
             // 仅首包添加WAV头
-            byte[] processedAudio = WavHeader.addWavHeader(audioBytes, 16000, 16, 1);
+            byte[] processedAudio = WavHeader.addWavHeader(audioBytes, SampleRateEnum.SAMPLE_RATE_16K.value, 16, 1);
             log.info("首包音频带WAV头,长度={} bytes", processedAudio.length);
             return processedAudio;
         } else {