feat(image): 添加虚拟机挂载和卸载ISO功能

- 在 ExternalApiClient 中添加 removeIso 和 attachIso 接口
- 新增 ImageOperationIsoReq 类用于 ISO操作请求
- 在 ImageVirtualMachinesController 中添加挂载和卸载 ISO 的 API
- 在 ImageVirtualMachinesService 接口中定义 removeIso 和 attachIso 方法
- 实现 ImageVirtualMachinesServiceImpl 中的 removeIso 和 attachIso 方法- 新增 OperateLog 相关的实体类、控制器、Mapper 和服务接口
master
chenhao 2025-09-03 11:00:13 +08:00
parent 9878dd2cf8
commit 24deac28ae
15 changed files with 569 additions and 16 deletions

View File

@ -3,6 +3,7 @@ package com.unisinsight.project.controller;
import cn.hutool.json.JSONUtil;
import com.unisinsight.project.entity.req.DeleteIdReq;
import com.unisinsight.project.entity.req.ImageDesktopReq;
import com.unisinsight.project.entity.req.ImageVirtualMachinesReq;
import com.unisinsight.project.entity.res.ImageVirtualMachinesRes;
import com.unisinsight.project.entity.res.PageResult;
@ -135,6 +136,24 @@ public class ImageVirtualMachinesController {
log.info("终端重启请求参数为:{}", JSONUtil.toJsonStr(req));
return service.reboot(req);
}
@ApiOperation(value = "终端挂载文件")
@PostMapping("/iso/attach")
public Result<?> attachIso(@RequestBody ImageVirtualMachinesReq req) {
if (Objects.isNull(req)) {
return Result.errorResult(BaseErrorCode.PARAMS_CHK_ERROR);
}
log.info("终端挂载文件请求参数为:{}", JSONUtil.toJsonStr(req));
return service.attachIso(req);
}
@ApiOperation(value = "终端卸载文件")
@PostMapping("/iso/remove")
public Result<?> removeIso(@RequestBody ImageVirtualMachinesReq req) {
if (Objects.isNull(req)) {
return Result.errorResult(BaseErrorCode.PARAMS_CHK_ERROR);
}
log.info("终端卸载文件请求参数为:{}", JSONUtil.toJsonStr(req));
return service.removeIso(req);
}
}

View File

@ -0,0 +1,101 @@
package com.unisinsight.project.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.unisinsight.project.entity.dao.OperateLog;
import com.unisinsight.project.entity.req.OperateLogReq;
import com.unisinsight.project.entity.res.OperateLogRes;
import com.unisinsight.project.service.OperateLogService;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;
import com.unisinsight.project.exception.Result;
import lombok.extern.slf4j.Slf4j;
import com.unisinsight.project.exception.BaseErrorCode;
import java.util.Objects;
import com.unisinsight.project.entity.req.DeleteIdReq;
import cn.hutool.json.JSONUtil;
/**
* (OperateLog)
*
* @author ch
* @since 2025-09-03 10:51:42
*/
@RestController
@Api(tags = "日志记录")
@Slf4j
@RequestMapping("/api/nex/v1/operate/log")
public class OperateLogController {
/**
*
*/
@Resource
private OperateLogService service;
/**
*
*
* @param page
* @param operateLog
* @return
*/
@PostMapping("/select/page")
@ApiOperation(value = "分页查询")
public Result selectPage(@RequestBody OperateLogReq operateLogReq) {
if (Objects.isNull(operateLogReq)) {
return Result.errorResult(BaseErrorCode.PARAMS_CHK_ERROR);
}
log.info("分页查询请求参数为:{}", JSONUtil.toJsonStr(operateLogReq));
return service.selectPage(operateLogReq);
}
@ApiOperation(value = "新增")
@PostMapping("/add")
public Result<?> insertImageVirtualMachines(@RequestBody OperateLogReq operateLogReq) {
if (Objects.isNull(operateLogReq)) {
return Result.errorResult(BaseErrorCode.PARAMS_CHK_ERROR);
}
log.info("新增请求参数为:{}", JSONUtil.toJsonStr(operateLogReq));
return service.insert(operateLogReq);
}
@ApiOperation(value = "$tableInfo.comment修改")
@PostMapping("/update")
public Result<?> updateUser(@RequestBody OperateLogReq operateLogReq) {
if (Objects.isNull(operateLogReq)) {
return Result.errorResult(BaseErrorCode.PARAMS_CHK_ERROR);
}
log.info("修改请求参数为:{}", JSONUtil.toJsonStr(operateLogReq));
return service.update(operateLogReq);
}
@ApiOperation(value = "查询")
@PostMapping("/query")
public Result<?> queryUser(@RequestBody OperateLogReq operateLogReq) {
if (Objects.isNull(operateLogReq)) {
return Result.errorResult(BaseErrorCode.PARAMS_CHK_ERROR);
}
log.info("查询请求参数为:{}", JSONUtil.toJsonStr(operateLogReq));
return service.query(operateLogReq);
}
@ApiOperation(value = "删除")
@PostMapping("/delete")
public Result<?> delete(@RequestBody DeleteIdReq deleteIdReq) {
if (Objects.isNull(deleteIdReq)) {
return Result.errorResult(BaseErrorCode.PARAMS_CHK_ERROR);
}
log.info("删除请求参数为:{}", JSONUtil.toJsonStr(deleteIdReq));
return service.delete(deleteIdReq);
}
}

View File

@ -0,0 +1,64 @@
package com.unisinsight.project.entity.dao;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* (OperateLog)
*
* @author ch
* @since 2025-09-03 10:51:42
*/
@TableName(value = "operate_log")
@Data
@ApiModel("")
public class OperateLog extends Model<OperateLog> {
/**
* ${column.comment}
**/
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty("${column.comment}")
private Integer id;
/**
*
**/
@TableField(value = "username")
@ApiModelProperty("用户名")
private String username;
/**
*
**/
@TableField(value = "device_id")
@ApiModelProperty("序列号")
private String deviceId;
/**
*
**/
@TableField("log_desc")
@ApiModelProperty("操作详情")
private String logDesc;
/**
*
**/
@TableField(value = "operate_time",fill = FieldFill.INSERT)
@ApiModelProperty("操作时间")
private Date operateTime;
}

View File

@ -63,6 +63,9 @@ public class ImageDesktopReq {
@JsonProperty("storage_path")
@ApiModelProperty("镜像存储路径")
private String storagePath;
@JsonProperty("storage_pool_name")
@ApiModelProperty("镜像存储路径")
private String storagePoolName;
/**
*
**/

View File

@ -0,0 +1,30 @@
package com.unisinsight.project.entity.req;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
/**
* @author : ch
* @version : 1.0
* @ClassName : ImageOperationReq
* @Description :
* @DATE : Created in 16:14 2025/8/25
* <pre> Copyright: Copyright(c) 2025 </pre>
* <pre> Company : </pre>
* Modification History:
* Date Author Version Discription
* --------------------------------------------------------------------------
* 2025/08/25 ch 1.0 Why & What is modified: <> *
*/
@Data
@Builder
public class ImageOperationIsoReq {
@JsonProperty("vm_name")
private String vmName;
@JsonProperty("iso_path")
private String isoPath;
}

View File

@ -0,0 +1,65 @@
package com.unisinsight.project.entity.req;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* (OperateLog)
*
* @author ch
* @since 2025-09-03 10:51:43
*/
@Data
@ApiModel("")
public class OperateLogReq {
/**
* ${column.comment}
**/
@JsonProperty("id")
@ApiModelProperty("${column.comment}")
private Integer id;
/**
*
**/
@JsonProperty("username")
@ApiModelProperty("用户名")
private String username;
/**
*
**/
@JsonProperty("device_id")
@ApiModelProperty("序列号")
private String deviceId;
/**
*
**/
@JsonProperty("log_desc")
@ApiModelProperty("操作详情")
private String logDesc;
/**
*
**/
@JsonProperty("operate_time")
@ApiModelProperty("操作时间")
private Date operateTime;
/**
*
*/
@ApiModelProperty(value = "查询页", notes = "分页查询时再传")
@JsonProperty("page_num")
private Integer pageNum;
/**
*
*/
@ApiModelProperty(value = "每页数量", notes = "分页查询时再传")
@JsonProperty("page_size")
private Integer pageSize;
}

View File

@ -0,0 +1,53 @@
package com.unisinsight.project.entity.res;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* (OperateLog)
*
* @author ch
* @since 2025-09-03 10:51:44
*/
@Data
@ApiModel("")
public class OperateLogRes implements Serializable {
/**
* ${column.comment}
**/
@JsonProperty("id")
@ApiModelProperty("${column.comment}")
private Integer id;
/**
*
**/
@JsonProperty("username")
@ApiModelProperty("用户名")
private String username;
/**
*
**/
@JsonProperty("device_id")
@ApiModelProperty("序列号")
private String deviceId;
/**
*
**/
@JsonProperty("log_desc")
@ApiModelProperty("操作详情")
private String logDesc;
/**
*
**/
@JsonProperty("operate_time")
@ApiModelProperty("操作时间")
private Date operateTime;
}

View File

@ -87,4 +87,8 @@ public interface ExternalApiClient {
@PostMapping("/api/v1/vm/reboot")
ApiResponse<ImageStatusRes> rebootImage(@RequestBody ImageOperationReq operationReq);
@PostMapping("/api/v1/vm/remove-iso")
ApiResponse removeIso(@RequestBody ImageOperationReq operationReq);
@PostMapping("/api/v1/vm/attach-iso")
ApiResponse attachIso(@RequestBody ImageOperationIsoReq operationReq);
}

View File

@ -0,0 +1,18 @@
package com.unisinsight.project.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import com.unisinsight.project.entity.dao.OperateLog;
/**
* (OperateLog)访
*
* @author ch
* @since 2025-09-03 10:51:43
*/
public interface OperateLogMapper extends BaseMapper<OperateLog> {
}

View File

@ -3,6 +3,7 @@ package com.unisinsight.project.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.unisinsight.project.entity.dao.ImageVirtualMachines;
import com.unisinsight.project.entity.req.DeleteIdReq;
import com.unisinsight.project.entity.req.ImageDesktopReq;
import com.unisinsight.project.entity.req.ImageVirtualMachinesReq;
import com.unisinsight.project.entity.res.ImageVirtualMachinesRes;
import com.unisinsight.project.entity.res.PageResult;
@ -55,7 +56,10 @@ public interface ImageVirtualMachinesService extends IService<ImageVirtualMachin
* @return
*/
Result<?> reboot(ImageVirtualMachinesReq req);
Result<?> removeIso(ImageVirtualMachinesReq req);
Result<?> attachIso(ImageVirtualMachinesReq req);
}

View File

@ -0,0 +1,31 @@
package com.unisinsight.project.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.unisinsight.project.entity.dao.OperateLog;
import com.unisinsight.project.entity.req.DeleteIdReq;
import com.unisinsight.project.entity.req.OperateLogReq;
import com.unisinsight.project.entity.res.OperateLogRes;
import com.unisinsight.project.entity.res.PageResult;
import com.unisinsight.project.exception.Result;
/**
* (OperateLog)
*
* @author ch
* @since 2025-09-03 10:51:44
*/
public interface OperateLogService extends IService<OperateLog> {
Result<PageResult<OperateLogRes>> selectPage(OperateLogReq operateLogReq);
Result<?> insert(OperateLogReq operateLogReq);
Result<?> update(OperateLogReq operateLogReq);
Result<?> query(OperateLogReq operateLogReq);
Result<?> delete(DeleteIdReq deleteIdReq);
}

View File

@ -1,6 +1,7 @@
package com.unisinsight.project.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.unisinsight.project.entity.dao.StoragePool;
import com.unisinsight.project.entity.req.StoragePoolReq;
import com.unisinsight.project.entity.res.PageResult;
@ -9,7 +10,7 @@ import com.unisinsight.project.entity.res.StoragePoolRes;
/**
*
*/
public interface StoragePoolService {
public interface StoragePoolService extends IService<StoragePool> {
/**
*

View File

@ -8,10 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.unisinsight.project.entity.dao.Image;
import com.unisinsight.project.entity.dao.ImageDesktop;
import com.unisinsight.project.entity.dao.ImageTool;
import com.unisinsight.project.entity.dao.ImageVirtualMachines;
import com.unisinsight.project.entity.dao.*;
import com.unisinsight.project.entity.dto.ApiResponse;
import com.unisinsight.project.entity.dto.VmInfoDTO;
import com.unisinsight.project.entity.req.*;
@ -23,10 +20,7 @@ import com.unisinsight.project.exception.Result;
import com.unisinsight.project.feign.ExternalApiClient;
import com.unisinsight.project.feign.ExternalTorrentClient;
import com.unisinsight.project.mapper.ImageVirtualMachinesMapper;
import com.unisinsight.project.service.ImageDesktopService;
import com.unisinsight.project.service.ImageService;
import com.unisinsight.project.service.ImageToolService;
import com.unisinsight.project.service.ImageVirtualMachinesService;
import com.unisinsight.project.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
@ -59,6 +53,8 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
private ImageToolService imageToolService;
@Autowired
private ImageDesktopService imageDesktopService;
@Autowired
private StoragePoolService storagePoolService;
@Override
@ -160,7 +156,7 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
.autoMountVirtio(imageVirtualMachinesReq.getAutoMountVirtio())
.autostart(false)
//驱动
.virtioWinPath(imageTool.getStorePath())
.virtioWinPath(imageTool == null ? "" : imageTool.getStorePath())
.description(imageVirtualMachinesReq.getDescription())
.build();
@ -263,7 +259,7 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
public Result<?> cloneTemplate(ImageVirtualMachinesReq req) {
// 查询虚拟机信息
LambdaQueryWrapper<ImageVirtualMachines> queryWrapper=new LambdaQueryWrapper<>();
queryWrapper.eq(ImageVirtualMachines::getImageName, req.getImageName());
queryWrapper.eq(ImageVirtualMachines::getId, req.getId());
ImageVirtualMachines imageVirtualMachines = getOne(queryWrapper);
if (ObjectUtils.isEmpty(imageVirtualMachines)) {
log.info("查询镜像虚拟机返回为空");
@ -271,7 +267,7 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
}
// 调用远程接口获取虚拟机详细信息
ApiResponse<VmInfoDTO> vmInfoResponse = externalApiClient.getVmInfo(req.getImageName());
ApiResponse<VmInfoDTO> vmInfoResponse = externalApiClient.getVmInfo(imageVirtualMachines.getImageName());
if (vmInfoResponse == null || !"200".equals(vmInfoResponse.getCode()) || vmInfoResponse.getData() == null) {
log.error("获取虚拟机信息失败: {}", vmInfoResponse);
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "获取虚拟机信息失败");
@ -282,10 +278,13 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
String diskPath = vmInfo.getDiskPath();
String type = "linux".equalsIgnoreCase(imageVirtualMachines.getOsVersion()) ? "vhd" : "qcow2";
// 根据虚拟机信息调用远程虚拟机信息
String fileName = imageVirtualMachines.getOsVersion() + "_desktop_" + System.currentTimeMillis();
boolean response = externalTorrentClient.start(diskPath,
diskPath.replaceAll(imageVirtualMachines.getImageName(),imageVirtualMachines.getImageName()+"_desktop"),
imageVirtualMachines.getImageName()+".json", "vhd");
"/vms/desktop/" + type + "/" + fileName + "." + type,
imageVirtualMachines.getImageName() + ".json", type);
if (!response) {
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "克隆虚拟机到桌面镜像失败");
@ -293,7 +292,7 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
// 克隆成功后生成桌面镜像数据
ImageDesktop imageDesktop = new ImageDesktop();
imageDesktop.setDesktopName(req.getImageName() + "_desktop");
imageDesktop.setDesktopName(fileName);
imageDesktop.setImageVirtualId(Math.toIntExact(req.getId()));
imageDesktop.setOsVersion(imageVirtualMachines.getOsVersion());
imageDesktop.setCreateUser("admin");
@ -402,5 +401,37 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl<ImageVirtualMac
return Result.successResult();
}
@Override
public Result<?> removeIso(ImageVirtualMachinesReq req) {
ImageOperationReq operationReq = ImageOperationReq.builder().vmName(req.getImageName()).build();
ApiResponse apiResponse = externalApiClient.removeIso(operationReq);
if (apiResponse == null || !"200".equals(apiResponse.getCode())) {
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "删除虚拟机ISO失败");
}
return Result.successResult();
}
@Override
public Result<?> attachIso(ImageVirtualMachinesReq req) {
//查询驱动信息
LambdaQueryWrapper<ImageTool> imageToolLambdaQueryWrapper = new LambdaQueryWrapper<>();
imageToolLambdaQueryWrapper.eq(ImageTool::getFileName, req.getImageToolName());
ImageTool imageTool = imageToolService.getOne(imageToolLambdaQueryWrapper);
if (imageTool == null) {
return Result.errorResult(BaseErrorCode.HTTP_ERROR_CODE_500, "驱动不存在");
}
ImageOperationIsoReq operationIsoReq = ImageOperationIsoReq.builder()
.vmName(req.getImageName())
.isoPath(imageTool.getStorePath())
.build();
ApiResponse apiResponse = externalApiClient.attachIso(operationIsoReq);
if (apiResponse == null || !"200".equals(apiResponse.getCode())) {
return Result.errorResult(BaseErrorCode.HTTP_REQUEST_FAILURE, "删除虚拟机ISO失败");
}
return Result.successResult();
}
}

View File

@ -0,0 +1,108 @@
package com.unisinsight.project.service.impl;
import org.springframework.stereotype.Service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.unisinsight.project.entity.dao.OperateLog;
import com.unisinsight.project.entity.req.DeleteIdReq;
import com.unisinsight.project.entity.req.OperateLogReq;
import com.unisinsight.project.entity.res.OperateLogRes;
import com.unisinsight.project.entity.res.PageResult;
import com.unisinsight.project.exception.BaseErrorCode;
import com.unisinsight.project.exception.Result;
import com.unisinsight.project.mapper.OperateLogMapper;
import com.unisinsight.project.service.OperateLogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Slf4j
/**
* (OperateLog)
*
* @author ch
* @since 2025-09-03 10:51:44
*/
@Service("operateLogService")
public class OperateLogServiceImpl extends ServiceImpl<OperateLogMapper, OperateLog> implements OperateLogService {
@Resource
private OperateLogMapper mapper;
@Override
public Result<PageResult<OperateLogRes>> selectPage(OperateLogReq operateLogReq) {
Page<OperateLog> page = new Page<>(operateLogReq.getPageNum(), operateLogReq.getPageSize());
LambdaQueryWrapper<OperateLog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.orderByAsc(OperateLog::getId);
Page<OperateLog> operateLogPage = mapper.selectPage(page, queryWrapper);
log.info("分页查询返回:{}", JSONUtil.toJsonStr(operateLogPage));
if (CollectionUtil.isEmpty(operateLogPage.getRecords())) {
log.info("分页查询返回为空");
return Result.successResult();
} else {
PageResult<OperateLogRes> convert = PageResult.convertIPage(operateLogPage, OperateLogRes.class);
List<OperateLogRes> data = convert.getData();
convert.setData(data);
return Result.successResult(convert);
}
}
@Override
public Result<?> insert(OperateLogReq operateLogReq) {
OperateLog operateLog = BeanUtil.copyProperties(operateLogReq, OperateLog.class);
int insert = mapper.insert(operateLog);
log.info("新增insert:{}", insert);
if (insert == 1) {
return Result.successResult();
} else {
return Result.errorResult(BaseErrorCode.HTTP_ERROR_CODE_500);
}
}
@Override
public Result<?> update(OperateLogReq operateLogReq) {
OperateLog operateLog = BeanUtil.copyProperties(operateLogReq, OperateLog.class);
int updated = mapper.updateById(operateLog);
log.info("修改updated:{}", updated);
if (updated == 1) {
return Result.successResult();
} else {
return Result.errorResult(BaseErrorCode.HTTP_ERROR_CODE_500);
}
}
@Override
public Result<?> query(OperateLogReq operateLogReq) {
OperateLog operateLog = mapper.selectById(operateLogReq.getId());
if (ObjectUtils.isEmpty(operateLog)) {
log.info("查询返回为空");
return Result.successResult();
}
OperateLogRes res = BeanUtil.copyProperties(operateLog, OperateLogRes.class);
log.info("查询返回:{}", JSONUtil.toJsonStr(res));
return Result.successResult(res);
}
@Override
public Result<?> delete(DeleteIdReq deleteIdReq) {
int deleted = mapper.deleteById(deleteIdReq.getId());
log.info("删除insert:{}", deleted);
if (deleted == 1) {
return Result.successResult();
} else {
return Result.errorResult(BaseErrorCode.HTTP_ERROR_CODE_500);
}
}
}

View File

@ -0,0 +1,21 @@
<?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.unisinsight.project.mapper.OperateLogMapper">
<resultMap type="com.unisinsight.project.entity.dao.OperateLog" id="OperateLogMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
<result property="deviceId" column="device_id" jdbcType="VARCHAR"/>
<result property="logDesc" column="log_desc" jdbcType="VARCHAR"/>
<result property="operateTime" column="operate_time" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id, username, device_id,
log_desc, operate_time
</sql>
</mapper>