feature:OTA能力完善

This commit is contained in:
Erlei Chen
2025-03-26 17:00:54 +08:00
parent bdd18b384b
commit ee0da9fc3a
31 changed files with 1044 additions and 225 deletions
@@ -9,6 +9,7 @@ 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.redis.RedisUtils;
@@ -48,21 +49,22 @@ public class UserAgentController extends BaseController {
@PostMapping
@Operation(summary = "添加智能体")
@RequiresPermissions("sys:role:normal")
public Result<Agent> addAgent(@RequestBody Agent agent) {
UserDetail user = SecurityUser.getUser();
if(StringUtils.isBlank(agent.getAgentName())){
if (StringUtils.isBlank(agent.getAgentName())) {
log.error("智能体名称不能为空");
}
Agent oldAgent = agentService.getOne(new QueryWrapper<Agent>().eq("agent_name", agent.getAgentName()));
if(ObjectUtils.isNull(oldAgent)){
if (ObjectUtils.isNull(oldAgent)) {
AgentTemplate agentTemplate = agentTemplateService.getOne(new QueryWrapper<AgentTemplate>().eq("is_default", 1));
if(ObjectUtils.isNull(agentTemplate)){
if (ObjectUtils.isNull(agentTemplate)) {
}else{
} else {
try {
oldAgent = new Agent();
BeanUtils.copyProperties(oldAgent, agentTemplate);
oldAgent.setId(UUID.randomUUID().toString().replace("-",""));
oldAgent.setId(UUID.randomUUID().toString().replace("-", ""));
oldAgent.setAgentName(agent.getAgentName());
oldAgent.setUserId(user.getId());
oldAgent.setCreator(user.getId());
@@ -72,17 +74,33 @@ public class UserAgentController extends BaseController {
log.error("对象赋值异常", e);
}
}
}else{
} else {
}
return new Result<Agent>().ok(agent);
}
@DeleteMapping("/{agentId}")
@Operation(summary = "删除智能体")
@RequiresPermissions("sys:role:normal")
public Result<Agent> delAgent(@PathVariable String agentId) {
UserDetail user = SecurityUser.getUser();
if (StringUtils.isBlank(agentId)) {
log.error("智能体ID不能为空");
}
boolean bool = agentService.removeById(agentId);
if (!bool) {
return new Result<Agent>().error("删除失败");
}
return new Result<Agent>().ok(null);
}
@GetMapping
@Operation(summary = "智能体列表")
@RequiresPermissions("sys:role:normal")
public Result<List<AgentVO>> agentList() {
UserDetail user = SecurityUser.getUser();
List<Agent> agents = agentService.list(new QueryWrapper<Agent>().eq("user_id",user.getId()));
List<Agent> agents = agentService.list(new QueryWrapper<Agent>().eq("user_id", user.getId()));
List<AgentVO> list = new ArrayList<>();
this.convertAgetVOList(list, agents);
return new Result<List<AgentVO>>().ok(list);
@@ -90,19 +108,18 @@ public class UserAgentController extends BaseController {
@GetMapping("/loadAgentConfig/{deviceId}")
@Operation(summary = "下载智能体配置")
// public Result<AgentConfigVO> loadAgentConfig(@PathVariable String deviceId){
public Result<JSONObject> loadAgentConfig(@PathVariable String deviceId){
public Result<JSONObject> loadAgentConfig(@PathVariable String deviceId) {
Device device = deviceService.getOne(new QueryWrapper<Device>().eq("mac_address", deviceId.toUpperCase()));
if(ObjectUtils.isNull(device)){
if (ObjectUtils.isNull(device)) {
return new Result<JSONObject>().error("设备不存在");
}
Agent agent = agentService.getOne(new QueryWrapper<Agent>().eq("id", device.getAgentId()));
if(ObjectUtils.isNull(agent)){
if (ObjectUtils.isNull(agent)) {
return new Result<JSONObject>().error("智能体不存在");
}
AgentConfigVO agentConfigVO = new AgentConfigVO();
// return new Result<AgentConfigVO>().ok(agentConfigVO);
String json = "{\n" +
String json = "{\n" +
" \"ASR\": {\n" +
" \"FunASR\": {\n" +
" \"model_dir\": \"models/SenseVoiceSmall\",\n" +
@@ -160,9 +177,9 @@ public class UserAgentController extends BaseController {
* @param agentVOList 转换后的AgentVO对象列表
* @param agentList 原始的Agent对象列表
*/
private void convertAgetVOList(List<AgentVO> agentVOList, List<Agent> agentList){
private void convertAgetVOList(List<AgentVO> agentVOList, List<Agent> agentList) {
// 遍历Agent对象列表
for(Agent agent : agentList) {
for (Agent agent : agentList) {
// 创建一个新的AgentVO对象
AgentVO agentVO = new AgentVO();
// 将当前Agent对象的属性值转换并设置到AgentVO对象中
@@ -171,17 +188,18 @@ public class UserAgentController extends BaseController {
agentVOList.add(agentVO);
}
}
private void convertAgentVO(AgentVO agentVO, Agent agent){
private void convertAgentVO(AgentVO agentVO, Agent agent) {
try {
BeanUtils.copyProperties(agentVO, agent);
agentVO.setTtsModelName("未知");
TtsVoice ttsVoice = ttsVoiceService.getOne(new QueryWrapper<TtsVoice>().eq("id", agent.getTtsVoiceId()));
if(ObjectUtils.isNotNull(ttsVoice)){
if (ObjectUtils.isNotNull(ttsVoice)) {
agentVO.setTtsModelName(ttsVoice.getName());
}
agentVO.setLlmModelName("未知");
ModelConfig modelConfig = modelConfigService.getOne(new QueryWrapper<ModelConfig>().eq("id", agent.getLlmModelId()));
if(ObjectUtils.isNotNull(modelConfig)){
if (ObjectUtils.isNotNull(modelConfig)) {
agentVO.setLlmModelName(modelConfig.getModelName());
}
agentVO.setLastConnectedAt("今天");
@@ -189,7 +207,7 @@ public class UserAgentController extends BaseController {
long deviceCount = deviceService.count(new QueryWrapper<Device>().eq("agent_id", agent.getId()));
agentVO.setDeviceCount(deviceCount);
} catch (Exception e) {
log.error("[convertAgentVO]对象转换报错",e);
log.error("[convertAgentVO]对象转换报错", e);
}
}
}
@@ -2,6 +2,7 @@ package xiaozhi.modules.device.controller;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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;
@@ -9,6 +10,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.redis.RedisUtils;
@@ -20,6 +22,7 @@ import xiaozhi.modules.device.constant.DeviceConstant;
import xiaozhi.modules.device.domain.Device;
import xiaozhi.modules.device.service.DeviceService;
import xiaozhi.modules.device.vo.DeviceCodeVO;
import xiaozhi.modules.ota.domain.Ota;
import xiaozhi.modules.security.user.SecurityUser;
import java.util.Date;
@@ -36,6 +39,7 @@ public class UserDeviceController extends BaseController {
@GetMapping("/bind/{agentId}")
@Operation(summary = "已绑定设备列表")
@RequiresPermissions("sys:role:normal")
public Result<Page<Device>> bindDeviceList(@PathVariable String agentId, @RequestParam Integer pageNo, @RequestParam Integer pageSize) {
if (StringUtils.isBlank(agentId)) {
log.error("智能体ID不能为空");
@@ -56,6 +60,7 @@ public class UserDeviceController extends BaseController {
@PostMapping("/bind/{agentId}")
@Operation(summary = "绑定设备")
@RequiresPermissions("sys:role:normal")
public Result<Device> bindDevice(@PathVariable String agentId, @RequestBody DeviceCodeVO deviceCodeVO) {
if (ObjectUtils.isNull(deviceCodeVO) || StringUtils.isBlank(deviceCodeVO.getDeviceCode())) {
log.error("授权码不能为空");
@@ -112,16 +117,58 @@ public class UserDeviceController extends BaseController {
@PutMapping("/unbind/{deviceId}")
@Operation(summary = "解绑设备")
@RequiresPermissions("sys:role:normal")
public Result<Device> bindDevice(@PathVariable String deviceId) {
if (StringUtils.isBlank(deviceId)) {
log.error("设备ID不能为空");
return new Result().error("设备ID不能为空");
}
UserDetail user = SecurityUser.getUser();
boolean bool = deviceService.removeById(deviceId);
if (!bool) {
return new Result().error("解绑失败");
}
return new Result<Device>().ok(null);
}
@PostMapping("/autoUpdate/{deviceId}")
@Operation(summary = "切换设备OTA升级状态")
@RequiresPermissions("sys:role:normal")
public Result<Device> toggleAutoUpdate(@PathVariable String deviceId, @RequestBody Device device) {
if (StringUtils.isBlank(deviceId)) {
log.error("设备ID不能为空");
return new Result().error("设备ID不能为空");
}
UserDetail user = SecurityUser.getUser();
boolean bool = deviceService.update(
new UpdateWrapper<Device>().eq("id", deviceId)
.set("auto_update", device.getAutoUpdate())
.set("updater", user.getId())
.set("update_date", new Date())
);
if (!bool) {
return new Result<Device>().error("切换设备OTA升级状态失败");
}
return new Result<Device>().ok(null);
}
@PostMapping("/alias/{deviceId}")
@Operation(summary = "设置设备别名")
@RequiresPermissions("sys:role:normal")
public Result<Device> setAlias(@PathVariable String deviceId, @RequestBody Device device) {
if (StringUtils.isBlank(deviceId)) {
log.error("设备ID不能为空");
return new Result().error("设备ID不能为空");
}
UserDetail user = SecurityUser.getUser();
boolean bool = deviceService.update(
new UpdateWrapper<Device>().eq("id", deviceId)
.set("alias", device.getAlias())
.set("updater", user.getId())
.set("update_date", new Date())
);
if (!bool) {
return new Result<Device>().error("设置设备别名失败");
}
return new Result<Device>().ok(null);
}
}
@@ -0,0 +1,71 @@
package xiaozhi.modules.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* 模型配置表
* @TableName ai_model_provider
*/
@TableName(value ="ai_model_provider")
@Data
public class ModelProvider implements Serializable {
/**
* 主键
*/
@TableId
private String id;
/**
* 模型类型(Memory/ASR/VAD/LLM/TTS)
*/
private String modelType;
/**
* 供应器类型
*/
private String providerCode;
/**
* 供应器名称
*/
private String name;
/**
* 供应器字段列表(JSON格式)
*/
private Object fields;
/**
* 排序
*/
private Integer sort;
/**
* 创建者
*/
private Long creator;
/**
* 创建时间
*/
private Date createDate;
/**
* 更新者
*/
private Long updater;
/**
* 更新时间
*/
private Date updateDate;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
@@ -0,0 +1,20 @@
package xiaozhi.modules.model.mapper;
import org.apache.ibatis.annotations.Mapper;
import xiaozhi.modules.model.domain.ModelProvider;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author chenerlei
* @description 针对表【ai_model_provider(模型配置表)】的数据库操作Mapper
* @createDate 2025-03-24 18:24:13
* @Entity xiaozhi.modules.model.domain.ModelProvider
*/
@Mapper
public interface ModelProviderMapper extends BaseMapper<ModelProvider> {
}
@@ -0,0 +1,13 @@
package xiaozhi.modules.model.service;
import xiaozhi.modules.model.domain.ModelProvider;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author chenerlei
* @description 针对表【ai_model_provider(模型配置表)】的数据库操作Service
* @createDate 2025-03-24 18:24:13
*/
public interface ModelProviderService extends IService<ModelProvider> {
}
@@ -0,0 +1,22 @@
package xiaozhi.modules.model.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import xiaozhi.modules.model.domain.ModelProvider;
import xiaozhi.modules.model.service.ModelProviderService;
import xiaozhi.modules.model.mapper.ModelProviderMapper;
import org.springframework.stereotype.Service;
/**
* @author chenerlei
* @description 针对表【ai_model_provider(模型配置表)】的数据库操作Service实现
* @createDate 2025-03-24 18:24:13
*/
@Service
public class ModelProviderServiceImpl extends ServiceImpl<ModelProviderMapper, ModelProvider>
implements ModelProviderService{
}
@@ -1,26 +1,33 @@
package xiaozhi.modules.device.controller;
package xiaozhi.modules.ota.controller;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.springframework.data.redis.core.RedisTemplate;
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.agent.domain.Agent;
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.sys.service.SysParamsService;
import xiaozhi.modules.ota.domain.Ota;
import xiaozhi.modules.ota.service.OtaService;
import xiaozhi.modules.security.user.SecurityUser;
import java.util.Date;
@@ -31,10 +38,9 @@ import java.util.Date;
@RequestMapping("/ota")
public class OtaController extends BaseController {
private final DeviceService deviceService;
private final SysParamsService sysParamsService;
private final OtaService otaService;
@Resource
private RedisUtils redisUtils;
private final String OTA_PARAM_CODE = "OTA";
@CrossOrigin(originPatterns = "*", methods = {RequestMethod.GET, RequestMethod.POST})
@RequestMapping(path = "/", method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/json")
@@ -66,16 +72,77 @@ public class OtaController extends BaseController {
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 value = sysParamsService.getValue(OTA_PARAM_CODE);
if (StringUtils.isBlank(value)) {
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 {
JSONObject object = new JSONObject(value);
otaVO.setFirmware(new DeviceOtaVO.Firmware(object.getStr("version"), object.getStr("url")));
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);
}
}
@@ -0,0 +1,66 @@
package xiaozhi.modules.ota.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* OTA升级信息表
* @TableName ai_ota
*/
@TableName(value ="ai_ota")
@Data
public class Ota implements Serializable {
/**
* 记录唯一标识
*/
@TableId
private String id;
/**
* 设备硬件型号
*/
private String board;
/**
* 固件版本号
*/
private String appVersion;
/**
* 下载地址
*/
private String url;
/**
* 是否启用
*/
private Integer isEnabled;
/**
* 创建者
*/
private Long creator;
/**
* 创建时间
*/
private Date createDate;
/**
* 更新者
*/
private Long updater;
/**
* 更新时间
*/
private Date updateDate;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
@@ -0,0 +1,20 @@
package xiaozhi.modules.ota.mapper;
import org.apache.ibatis.annotations.Mapper;
import xiaozhi.modules.ota.domain.Ota;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author chenerlei
* @description 针对表【ai_ota(OTA升级信息表)】的数据库操作Mapper
* @createDate 2025-03-24 18:25:14
* @Entity xiaozhi.modules.ota.domain.Ota
*/
@Mapper
public interface OtaMapper extends BaseMapper<Ota> {
}
@@ -0,0 +1,13 @@
package xiaozhi.modules.ota.service;
import xiaozhi.modules.ota.domain.Ota;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author chenerlei
* @description 针对表【ai_ota(OTA升级信息表)】的数据库操作Service
* @createDate 2025-03-24 18:25:14
*/
public interface OtaService extends IService<Ota> {
}
@@ -0,0 +1,22 @@
package xiaozhi.modules.ota.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import xiaozhi.modules.ota.domain.Ota;
import xiaozhi.modules.ota.service.OtaService;
import xiaozhi.modules.ota.mapper.OtaMapper;
import org.springframework.stereotype.Service;
/**
* @author chenerlei
* @description 针对表【ai_ota(OTA升级信息表)】的数据库操作Service实现
* @createDate 2025-03-24 18:25:14
*/
@Service
public class OtaServiceImpl extends ServiceImpl<OtaMapper, Ota>
implements OtaService{
}
@@ -42,21 +42,22 @@ spring:
wall:
config:
multi-statement-allow: true
redis:
host: localhost # Redis服务器地址
port: 6379 # Redis服务器连接端口
password: # Redis服务器连接密码(默认为空)
database: 0 # Redis数据库索引(默认为0
# jedis:
# pool:
# max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# max-idle: 8 # 连接池中的最大空闲连接
# min-idle: 0 # 连接池中的最空闲连接
timeout: 10000ms # 连接超时时间(毫秒)
lettuce:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
max-idle: 8 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最空闲连接
shutdown-timeout: 100ms # 客户端优雅关闭的等待时间
data:
redis:
host: localhost # Redis服务器地址
port: 6379 # Redis服务器连接端口
password: # Redis服务器连接密码(默认为
database: 0 # Redis数据库索引(默认为0
# jedis:
# pool:
# max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# max-idle: 8 # 连接池中的最空闲连接
# min-idle: 0 # 连接池中的最小空闲连接
timeout: 10000ms # 连接超时时间(毫秒)
lettuce:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
max-idle: 8 # 连接池中的最空闲连接
min-idle: 0 # 连接池中的最小空闲连接
shutdown-timeout: 100ms # 客户端优雅关闭的等待时间
@@ -0,0 +1,15 @@
-- OTA升级信息表
DROP TABLE IF EXISTS `ai_ota`;
CREATE TABLE `ai_ota` (
`id` VARCHAR(32) NOT NULL COMMENT '记录唯一标识',
`board` VARCHAR(50) COMMENT '设备硬件型号',
`app_version` VARCHAR(20) COMMENT '固件版本号',
`url` VARCHAR(500) COMMENT '下载地址',
`is_enabled` TINYINT(1) DEFAULT 0 COMMENT '是否启用',
`creator` BIGINT COMMENT '创建者',
`create_date` DATETIME COMMENT '创建时间',
`updater` BIGINT COMMENT '更新者',
`update_date` DATETIME COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uni_ai_ota_board` (`board`) COMMENT '设备型号唯一索引,用于快速查找升级信息'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='OTA升级信息表';
@@ -15,4 +15,11 @@ databaseChangeLog:
changes:
- sqlFile:
encoding: utf8
path: classpath:db/changelog/202503141346.sql
path: classpath:db/changelog/202503141346.sql
- changeSet:
id: 202503241020
author: dreamchen
changes:
- sqlFile:
encoding: utf8
path: classpath:db/changelog/202503241020.sql
@@ -0,0 +1,24 @@
<?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="xiaozhi.modules.model.mapper.ModelProviderMapper">
<resultMap id="BaseResultMap" type="xiaozhi.modules.model.domain.ModelProvider">
<id property="id" column="id" />
<result property="modelType" column="model_type" />
<result property="providerCode" column="provider_code" />
<result property="name" column="name" />
<result property="fields" column="fields" />
<result property="sort" column="sort" />
<result property="creator" column="creator" />
<result property="createDate" column="create_date" />
<result property="updater" column="updater" />
<result property="updateDate" column="update_date" />
</resultMap>
<sql id="Base_Column_List">
id,model_type,provider_code,name,fields,sort,
creator,create_date,updater,update_date
</sql>
</mapper>
@@ -0,0 +1,23 @@
<?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="xiaozhi.modules.ota.mapper.OtaMapper">
<resultMap id="BaseResultMap" type="xiaozhi.modules.ota.domain.Ota">
<id property="id" column="id" />
<result property="board" column="board" />
<result property="appVersion" column="app_version" />
<result property="url" column="url" />
<result property="isEnabled" column="is_enabled" />
<result property="creator" column="creator" />
<result property="createDate" column="create_date" />
<result property="updater" column="updater" />
<result property="updateDate" column="update_date" />
</resultMap>
<sql id="Base_Column_List">
id,board,app_version,url,is_enabled,creator,
create_date,updater,update_date
</sql>
</mapper>