feature:角色配置能力部分实现

This commit is contained in:
Erlei Chen
2025-03-27 14:06:40 +08:00
parent 4b90e70aad
commit 41db6aafd9
8 changed files with 369 additions and 32 deletions
@@ -95,6 +95,17 @@ public class UserAgentController extends BaseController {
return new Result<Agent>().ok(null);
}
@GetMapping("/{agentId}")
@Operation(summary = "获取智能体信息")
@RequiresPermissions("sys:role:normal")
public Result<Agent> getAgent(@PathVariable String agentId) {
if (StringUtils.isBlank(agentId)) {
log.error("智能体ID不能为空");
}
Agent agent = agentService.getById(agentId);
return new Result<Agent>().ok(agent);
}
@GetMapping
@Operation(summary = "智能体列表")
@RequiresPermissions("sys:role:normal")
@@ -0,0 +1,134 @@
package xiaozhi.modules.agentTemplate.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
import xiaozhi.common.controller.BaseController;
import xiaozhi.common.user.UserDetail;
import xiaozhi.common.utils.Result;
import xiaozhi.modules.agent.domain.AgentTemplate;
import xiaozhi.modules.agent.service.AgentTemplateService;
import xiaozhi.modules.agent.vo.AgentTemplateVO;
import xiaozhi.modules.device.domain.Device;
import xiaozhi.modules.device.service.DeviceService;
import xiaozhi.modules.model.domain.ModelConfig;
import xiaozhi.modules.model.domain.TtsVoice;
import xiaozhi.modules.model.service.ModelConfigService;
import xiaozhi.modules.model.service.TtsVoiceService;
import xiaozhi.modules.security.user.SecurityUser;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Slf4j
@Tag(name = "智能体模板管理")
@AllArgsConstructor
@RestController
@RequestMapping("/user/agent/template")
public class UserAgentTemplateController extends BaseController {
private final AgentTemplateService agentTemplateService;
private final ModelConfigService modelConfigService;
private final TtsVoiceService ttsVoiceService;
private final DeviceService deviceService;
@PostMapping
@Operation(summary = "添加智能体模板")
@RequiresPermissions("sys:role:normal")
public Result<AgentTemplate> addTemplate(@RequestBody AgentTemplate agentTemplate) {
UserDetail user = SecurityUser.getUser();
if (StringUtils.isBlank(agentTemplate.getAgentName())) {
log.error("智能体模板名称不能为空");
}
try {
agentTemplate = new AgentTemplate();
agentTemplate.setId(UUID.randomUUID().toString().replace("-", ""));
agentTemplate.setAgentName(agentTemplate.getAgentName());
agentTemplate.setCreator(user.getId());
agentTemplate.setCreatedAt(new Date());
agentTemplateService.save(agentTemplate);
} catch (Exception e) {
log.error("对象赋值异常", e);
}
return new Result<AgentTemplate>().ok(agentTemplate);
}
@DeleteMapping("/{templateId}")
@Operation(summary = "删除智能体模板")
@RequiresPermissions("sys:role:normal")
public Result<AgentTemplate> delTemplate(@PathVariable String templateId) {
UserDetail user = SecurityUser.getUser();
if (StringUtils.isBlank(templateId)) {
log.error("智能体模板ID不能为空");
}
boolean bool = agentTemplateService.removeById(templateId);
if (!bool) {
return new Result<AgentTemplate>().error("删除失败");
}
return new Result<AgentTemplate>().ok(null);
}
@GetMapping
@Operation(summary = "智能体模板模板列表")
@RequiresPermissions("sys:role:normal")
public Result<List<AgentTemplate>> templateList() {
List<AgentTemplate> list = agentTemplateService.list();
return new Result<List<AgentTemplate>>().ok(list);
}
@GetMapping("/vo")
@Operation(summary = "智能体模板模板列表")
@RequiresPermissions("sys:role:normal")
public Result<List<AgentTemplateVO>> templateVOList() {
UserDetail user = SecurityUser.getUser();
List<AgentTemplate> templates = agentTemplateService.list();
List<AgentTemplateVO> list = new ArrayList<>();
this.convertAgentTemplateVOList(list, templates);
return new Result<List<AgentTemplateVO>>().ok(list);
}
/**
* 将Agent对象列表转换为AgentTemplateVO对象列表
* 此方法遍历Agent对象列表,将每个Agent对象转换为AgentTemplateVO对象,并添加到AgentTemplateVO列表中
*
* @param agentVOList 转换后的AgentTemplateVO对象列表
* @param agentList 原始的Agent对象列表
*/
private void convertAgentTemplateVOList(List<AgentTemplateVO> agentVOList, List<AgentTemplate> agentList) {
// 遍历Agent对象列表
for (AgentTemplate agentTemplate : agentList) {
// 创建一个新的AgentTemplateVO对象
AgentTemplateVO agentTemplateVO = new AgentTemplateVO();
// 将当前Agent对象的属性值转换并设置到AgentTemplateVO对象中
this.convertAgentTemplateVO(agentTemplateVO, agentTemplate);
// 将转换后的AgentTemplateVO对象添加到AgentTemplateVO列表中
agentVOList.add(agentTemplateVO);
}
}
private void convertAgentTemplateVO(AgentTemplateVO agentTemplateVO, AgentTemplate agentTemplate) {
try {
BeanUtils.copyProperties(agentTemplateVO, agentTemplate);
agentTemplateVO.setTtsModelName("未知");
TtsVoice ttsVoice = ttsVoiceService.getOne(new QueryWrapper<TtsVoice>().eq("id", agentTemplate.getTtsVoiceId()));
if (ObjectUtils.isNotNull(ttsVoice)) {
agentTemplateVO.setTtsModelName(ttsVoice.getName());
}
agentTemplateVO.setLlmModelName("未知");
ModelConfig modelConfig = modelConfigService.getOne(new QueryWrapper<ModelConfig>().eq("id", agentTemplate.getLlmModelId()));
if (ObjectUtils.isNotNull(modelConfig)) {
agentTemplateVO.setLlmModelName(modelConfig.getModelName());
}
} catch (Exception e) {
log.error("[convertAgentTemplateVO]对象转换报错", e);
}
}
}
@@ -0,0 +1,14 @@
package xiaozhi.modules.agent.vo;
import lombok.Data;
import xiaozhi.modules.agent.domain.Agent;
import xiaozhi.modules.agent.domain.AgentTemplate;
@Data
public class AgentTemplateVO extends AgentTemplate {
//角色音色
private String ttsModelName;
//角色模型
private String llmModelName;
}
@@ -0,0 +1,146 @@
package xiaozhi.modules.model.controller;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import xiaozhi.common.controller.BaseController;
import xiaozhi.common.redis.RedisUtils;
import xiaozhi.common.user.UserDetail;
import xiaozhi.common.utils.Result;
import xiaozhi.modules.device.constant.DeviceConstant;
import xiaozhi.modules.device.domain.Device;
import xiaozhi.modules.device.service.DeviceService;
import xiaozhi.modules.device.utils.CodeGeneratorUtil;
import xiaozhi.modules.device.vo.DeviceOtaVO;
import xiaozhi.modules.ota.domain.Ota;
import xiaozhi.modules.ota.service.OtaService;
import xiaozhi.modules.security.user.SecurityUser;
import java.util.Date;
@Slf4j
@Tag(name = "模型数据管理")
@AllArgsConstructor
@RestController
@RequestMapping("/model/")
public class ModelController extends BaseController {
private final DeviceService deviceService;
private final OtaService otaService;
@Resource
private RedisUtils redisUtils;
@CrossOrigin(originPatterns = "*", methods = {RequestMethod.GET, RequestMethod.POST})
@RequestMapping(path = "/", method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/json")
@Operation(summary = "设备OTA升级")
public String ota(@RequestHeader(required = false) HttpHeaders headers, @RequestBody(required = false) JSONObject jsonObject) {
log.info("OTA升级请求:header:{}body:{}", headers, jsonObject);
if (ObjectUtils.isNull(headers) || StringUtils.isBlank(headers.getFirst("device-id"))) {
log.error("设备ID不能为空");
return "{\"error\": \"Device ID is required\"}";
}
DeviceOtaVO otaVO = new DeviceOtaVO();
Device device = deviceService.getOne(new UpdateWrapper<Device>().eq("mac_address", headers.getFirst("device-id").toUpperCase()).eq("id", headers.getFirst("client-Id").replace("-", "")));
if (ObjectUtils.isNull(device)) {
// 从 Redis 中获取设备信息
Object redisValue = redisUtils.hGet(DeviceConstant.REDIS_KEY_PREFIX_DEVICE_ACTIVATION_MAC, headers.getFirst("device-id").toUpperCase());
if (ObjectUtils.isNull(redisValue)) {
String code = CodeGeneratorUtil.generateCode(6);
log.info("[gen]授权码已广播:{}", code);
otaVO.setActivation(new DeviceOtaVO.Activation(code, "youxlife.com\n" + code));
redisUtils.hSet(DeviceConstant.REDIS_KEY_PREFIX_DEVICE_ACTIVATION_MAC, headers.getFirst("device-id").toUpperCase(), code, RedisUtils.HOUR_ONE_EXPIRE);
redisUtils.hSet(DeviceConstant.REDIS_KEY_PREFIX_DEVICE_ACTIVATION_CODE, code, jsonObject, RedisUtils.HOUR_ONE_EXPIRE);
} else {
log.warn("[get]授权码已广播:{}", redisValue);
otaVO.setActivation(new DeviceOtaVO.Activation(redisValue.toString(), "youxlife.com\n" + redisValue));
}
}
if (ObjectUtils.isNull(device) || device.getAutoUpdate() == 1) {
//{"version":"1.0.0","url":"http://https://youxlife.oss-cn-zhangjiakou.aliyuncs.com/v1.4.5.bin"}
String board = ObjectUtils.isNull(device)?headers.getFirst("user-agent").split("/")[0]:device.getBoard();
Ota ota = otaService.getOne(new UpdateWrapper<Ota>().eq("board", board).eq("is_enabled", 1));
if (ObjectUtils.isNull(ota)) {
log.warn("OTA升级信息未配置");
} else {
otaVO.setFirmware(new DeviceOtaVO.Firmware(ota.getAppVersion(), ota.getUrl()));
}
}
otaVO.setServer_time(new DeviceOtaVO.ServerTime(new Date().getTime(), 8 * 60));
return JSONUtil.toJsonStr(otaVO);
}
@GetMapping("/sys/getOtalist")
@Operation(summary = "设备OTA列表")
@RequiresPermissions("sys:role:superAdmin")
public Result<Page<Ota>> getOtalist(@RequestParam Integer pageNo, @RequestParam Integer pageSize) {
UserDetail user = SecurityUser.getUser();
Page page = new Page<Ota>(pageNo, pageSize);
page = otaService.page(page);
return new Result<Page<Ota>>().ok(page);
}
@PostMapping("/sys/save")
@Operation(summary = "添加设备OTA")
@RequiresPermissions("sys:role:superAdmin")
public Result<Ota> save(@RequestBody Ota ota) {
UserDetail user = SecurityUser.getUser();
ota.setCreator(user.getId());
ota.setCreateDate(new Date());
boolean bool = otaService.save(ota);
if (!bool) {
return new Result().error("设备OTA添加失败");
}
return new Result<Ota>().ok(null);
}
@PostMapping("/sys/update")
@Operation(summary = "更新设备OTA")
@RequiresPermissions("sys:role:superAdmin")
public Result<Ota> update(@RequestBody Ota ota) {
UserDetail user = SecurityUser.getUser();
boolean bool = otaService.update(
new UpdateWrapper<Ota>().eq("id", ota.getId())
.set("board", ota.getBoard().trim().toLowerCase())
.set("app_version", ota.getAppVersion())
.set("url", ota.getUrl())
.set("is_enabled", ota.getIsEnabled())
.set("updater", user.getId())
.set("update_date", new Date())
);
if (!bool) {
return new Result().error("设备OTA更新失败");
}
return new Result<Ota>().ok(null);
}
@PostMapping("/sys/toggleEnabled")
@Operation(summary = "切换设备OTA可用状态")
@RequiresPermissions("sys:role:superAdmin")
public Result<Ota> toggleEnabled(@RequestBody Ota ota) {
UserDetail user = SecurityUser.getUser();
boolean bool = otaService.update(
new UpdateWrapper<Ota>().eq("id", ota.getId())
.set("is_enabled", ota.getIsEnabled())
.set("updater", user.getId())
.set("update_date", new Date())
);
if (!bool) {
return new Result().error("切换设备OTA可用状态失败");
}
return new Result<Ota>().ok(null);
}
}