音频文件上传

This commit is contained in:
cuizhibin 2025-06-23 15:41:40 +08:00
parent fe75768d05
commit 978b022d54
11 changed files with 470 additions and 9 deletions

View File

@ -0,0 +1,46 @@
package com.dite.znpt.domain.entity;
import java.io.Serial;
import java.time.LocalDateTime;
import java.io.Serializable;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.baomidou.mybatisplus.annotation.*;
import com.dite.znpt.domain.AuditableEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* @author huise23
* @date 2025/06/23 13:39
* @Description: 音频文件信息表实体类
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("audio_file_info")
@ApiModel(value="AudioFileInfoEntity对象", description="音频文件信息表")
public class AudioFileInfoEntity extends AuditableEntity implements Serializable {
@Serial
private static final long serialVersionUID = -86870801917845298L;
@ExcelProperty("id")
@ApiModelProperty("id")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
@ExcelProperty("图片id")
@ApiModelProperty("图片id")
@TableField("image_id")
private String imageId;
@ExcelProperty("文件保存路径")
@ApiModelProperty("文件保存路径")
@TableField("file_path")
private String filePath;
}

View File

@ -0,0 +1,32 @@
package com.dite.znpt.domain.vo;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author huise23
* @date 2025/06/23 13:39
* @Description: 音频文件信息请求实体
*/
@Data
@ApiModel("音频文件信息列表请求实体")
public class AudioFileInfoListReq implements Serializable {
private static final long serialVersionUID = -88739013562163458L;
@ApiModelProperty("音频文件信息Id")
private String audioId;
@ApiModelProperty("图片id")
private String imageId;
@ApiModelProperty("图片ids")
private List<String> imageIds;
}

View File

@ -0,0 +1,39 @@
package com.dite.znpt.domain.vo;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.dite.znpt.domain.entity.AudioFileInfoEntity;
/**
* @author huise23
* @date 2025/06/23 13:39
* @Description: 音频文件信息响应实体
*/
@Data
@ApiModel("音频文件信息响应实体")
public class AudioFileInfoResp {
@ExcelProperty("id")
@ApiModelProperty("id")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
@ExcelProperty("图片id")
@ApiModelProperty("图片id")
@TableField("image_id")
private String imageId;
@ExcelProperty("文件保存路径")
@ApiModelProperty("文件保存路径")
@TableField("file_path")
private String filePath;
}

View File

@ -1,6 +1,7 @@
package com.dite.znpt.domain.vo; package com.dite.znpt.domain.vo;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.dite.znpt.domain.entity.AudioFileInfoEntity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
@ -9,6 +10,7 @@ import lombok.Data;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
/** /**
* @Author: gaoxiong * @Author: gaoxiong
@ -29,6 +31,9 @@ public class ImageListResp implements Serializable {
@TableField("image_name") @TableField("image_name")
private String imageName; private String imageName;
@ApiModelProperty("部件id")
private String partId;
@ApiModelProperty("部件名称") @ApiModelProperty("部件名称")
private String partName; private String partName;
@ -83,4 +88,7 @@ public class ImageListResp implements Serializable {
@ApiModelProperty("影像类型描述") @ApiModelProperty("影像类型描述")
private String imageTypeLabel; private String imageTypeLabel;
@ApiModelProperty("关联图像的音频列表")
private List<AudioFileInfoResp> audioList;
} }

View File

@ -1,6 +1,7 @@
package com.dite.znpt.domain.vo; package com.dite.znpt.domain.vo;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.dite.znpt.domain.entity.AudioFileInfoEntity;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
@ -9,6 +10,7 @@ import lombok.Data;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
/** /**
* @author Bear.G * @author Bear.G
@ -42,4 +44,7 @@ public class ImageResp implements Serializable {
@ApiModelProperty("图像拍摄信息") @ApiModelProperty("图像拍摄信息")
private ImageCollectInfo imageCollectInfo; private ImageCollectInfo imageCollectInfo;
@ApiModelProperty("关联图像的音频列表")
private List<AudioFileInfoResp> audioList;
} }

View File

@ -0,0 +1,19 @@
package com.dite.znpt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dite.znpt.domain.entity.AudioFileInfoEntity;
import com.dite.znpt.domain.vo.AudioFileInfoListReq;
import com.dite.znpt.domain.vo.AudioFileInfoResp;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author huise23
* @date 2025/06/23 13:39
* @Description: 音频文件信息表数据库访问层
*/
public interface AudioFileInfoMapper extends BaseMapper<AudioFileInfoEntity> {
List<AudioFileInfoResp> queryBySelective(AudioFileInfoListReq audioFileInfoReq);
}

View File

@ -0,0 +1,68 @@
package com.dite.znpt.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dite.znpt.domain.entity.AudioFileInfoEntity;
import com.dite.znpt.domain.vo.AudioFileInfoListReq;
import com.dite.znpt.domain.vo.AudioFileInfoResp;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* @author huise23
* @date 2025/06/23 13:39
* @Description: 音频文件信息表服务接口
*/
public interface AudioFileInfoService extends IService<AudioFileInfoEntity> {
/**
* 功能描述查询音频文件信息列表
*
* @param audioFileInfoReq 音频文件信息
* @return {@link List }<{@link AudioFileInfoEntity }>
* @author huise23
* @date 2025/06/23 13:39
**/
List<AudioFileInfoEntity> selectList(AudioFileInfoListReq audioFileInfoReq);
/**
* 功能描述查询单条音频文件信息
*
* @param audioId 音频文件信息Id
* @return {@link AudioFileInfoResp }
* @author huise23
* @date 2025/06/23 13:39
**/
AudioFileInfoResp selectById(String audioId);
/**
* 功能描述查询单条音频文件信息
*
* @param imageIds 图像id列表
* @return {@link List<AudioFileInfoResp> }
* @author huise23
* @date 2025/06/23 13:39
**/
List<AudioFileInfoResp> selectByImageIds(List<String> imageIds);
/**
* 功能描述删除音频文件信息
*
* @param audioId 音频文件信息Id
* @author huise23
* @date 2025/06/23 13:39
**/
void deleteById(String audioId);
/**
* 功能描述批量上传
*
* @param imageId 图像id
* @param files 文件
* @return {@link List }<{@link AudioFileInfoResp }>
* @author cuizhibin
* @date 2025/06/23 13:57
**/
List<AudioFileInfoResp> batchUpload(String imageId, MultipartFile[] files);
}

View File

@ -0,0 +1,126 @@
package com.dite.znpt.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dite.znpt.constant.Message;
import com.dite.znpt.domain.entity.AudioFileInfoEntity;
import com.dite.znpt.domain.entity.ImageEntity;
import com.dite.znpt.domain.vo.AudioFileInfoListReq;
import com.dite.znpt.domain.vo.AudioFileInfoResp;
import com.dite.znpt.domain.vo.PartResp;
import com.dite.znpt.enums.FilePathEnum;
import com.dite.znpt.exception.ServiceException;
import com.dite.znpt.mapper.AudioFileInfoMapper;
import com.dite.znpt.mapper.ImageMapper;
import com.dite.znpt.service.AudioFileInfoService;
import com.dite.znpt.service.PartService;
import com.dite.znpt.util.PageUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author huise23
* @date 2025/06/23 13:39
* @Description: 音频文件信息表服务实现类
*/
@Service
@RequiredArgsConstructor
public class AudioFileInfoServiceImpl extends ServiceImpl<AudioFileInfoMapper, AudioFileInfoEntity> implements AudioFileInfoService {
private final PartService partService;
private final ImageMapper imageMapper;
/**
* 功能描述查询音频文件信息列表
*
* @param audioFileInfoReq 音频文件信息信息
* @return {@link List }<{@link AudioFileInfoEntity }>
* @author huise23
* @date 2025/06/23 13:39
**/
@Override
public List<AudioFileInfoEntity> selectList(AudioFileInfoListReq audioFileInfoReq) {
PageUtil.startPage();
return lambdaQuery()
.eq(Objects.nonNull(audioFileInfoReq.getImageId()), AudioFileInfoEntity::getImageId, audioFileInfoReq.getImageId())
.in(CollUtil.isNotEmpty(audioFileInfoReq.getImageIds()), AudioFileInfoEntity::getImageId, audioFileInfoReq.getImageIds())
.eq(Objects.nonNull(audioFileInfoReq.getAudioId()), AudioFileInfoEntity::getId, audioFileInfoReq.getAudioId()).list();
}
/**
* 功能描述查询单条音频文件信息
*
* @param audioId 音频文件信息Id
* @return {@link AudioFileInfoEntity }
* @author huise23
* @date 2025/06/23 13:39
**/
@Override
public AudioFileInfoResp selectById(String audioId) {
AudioFileInfoListReq req = new AudioFileInfoListReq();
req.setAudioId(audioId);
List<AudioFileInfoResp> list = baseMapper.queryBySelective(req);
return CollUtil.isNotEmpty(list) ? CollUtil.getFirst(list) : null;
}
/**
* 功能描述查询单条音频文件信息
*
* @param imageIds 图像id列表
* @return {@link List<AudioFileInfoResp> }
* @author huise23
* @date 2025/06/23 13:39
**/
@Override
public List<AudioFileInfoResp> selectByImageIds(List<String> imageIds) {
AudioFileInfoListReq req = new AudioFileInfoListReq();
req.setImageIds(imageIds);
return baseMapper.queryBySelective(req);
}
/**
* 功能描述删除音频文件信息
*
* @param audioId 音频文件信息Id
* @author huise23
* @date 2025/06/23 13:39
**/
@Override
public void deleteById(String audioId) {
removeById(audioId);
}
@Override
public List<AudioFileInfoResp> batchUpload(String imageId, MultipartFile[] files) {
ImageEntity image = imageMapper.selectById(imageId);
if(null == image){
throw new ServiceException(Message.IMAGE_ID_IS_NOT_EXIST);
}
PartResp partResp = partService.detail(image.getPartId());
String audioFilePrefix = FilePathEnum.AUDIO.getFileAbsolutePath() + partResp.getProjectName().concat(FileUtil.FILE_SEPARATOR).concat(partResp.getTurbineName()).concat(FileUtil.FILE_SEPARATOR);
List<AudioFileInfoEntity> list = new ArrayList<>();
for (MultipartFile file : files) {
AudioFileInfoEntity audio = new AudioFileInfoEntity();
audio.setImageId(imageId);
if (!file.isEmpty()) {
try {
String path = audioFilePrefix + file.getOriginalFilename();
FileUtil.writeBytes(file.getBytes(),path);
audio.setFilePath(FilePathEnum.AUDIO.getImageDownPath(path));
list.add(audio);
} catch (Exception e) {
e.printStackTrace();
}
}
}
baseMapper.insert(list);
return BeanUtil.copyToList(list, AudioFileInfoResp.class);
}
}

View File

@ -3,6 +3,7 @@ import java.util.ArrayList;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.PathUtil; import cn.hutool.core.io.file.PathUtil;
@ -14,6 +15,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dite.znpt.constant.Constants; import com.dite.znpt.constant.Constants;
import com.dite.znpt.constant.Message; import com.dite.znpt.constant.Message;
import com.dite.znpt.domain.bo.PartFullInfoBo; import com.dite.znpt.domain.bo.PartFullInfoBo;
import com.dite.znpt.domain.entity.AudioFileInfoEntity;
import com.dite.znpt.domain.entity.ImageCollectEntity; import com.dite.znpt.domain.entity.ImageCollectEntity;
import com.dite.znpt.domain.entity.ImageEntity; import com.dite.znpt.domain.entity.ImageEntity;
import com.dite.znpt.domain.entity.PartEntity; import com.dite.znpt.domain.entity.PartEntity;
@ -22,12 +24,14 @@ import com.dite.znpt.domain.vo.*;
import com.dite.znpt.enums.*; import com.dite.znpt.enums.*;
import com.dite.znpt.exception.ServiceException; import com.dite.znpt.exception.ServiceException;
import com.dite.znpt.mapper.ImageMapper; import com.dite.znpt.mapper.ImageMapper;
import com.dite.znpt.service.AudioFileInfoService;
import com.dite.znpt.service.ImageCollectService; import com.dite.znpt.service.ImageCollectService;
import com.dite.znpt.service.ImageService; import com.dite.znpt.service.ImageService;
import com.dite.znpt.service.PartService; import com.dite.znpt.service.PartService;
import com.dite.znpt.util.EXIFUtil; import com.dite.znpt.util.EXIFUtil;
import com.dite.znpt.util.PageUtil; import com.dite.znpt.util.PageUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -67,15 +71,22 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, ImageEntity> impl
@Resource @Resource
private PartService partService; private PartService partService;
@Autowired
private AudioFileInfoService audioFileInfoService;
@Override @Override
public List<ImageListResp> list(ImageListReq req) { public List<ImageListResp> list(ImageListReq req) {
List<ImageListResp> partList= this.baseMapper.queryImageList(req); List<ImageListResp> partList= this.baseMapper.queryImageList(req);
partList.forEach(resp -> { if (CollUtil.isNotEmpty(partList)) {
resp.setWeatherLabel(WeatherEnum.getDescByCode(resp.getWeather())); Map<String, List<AudioFileInfoResp>> audioMap = audioFileInfoService.selectByImageIds(partList.stream().map(ImageListResp::getImageId).collect(Collectors.toList()))
resp.setShootingMethodLabel(ShootingMethodEnum.getDescByCode(resp.getShootingMethod())); .stream().collect(Collectors.groupingBy(AudioFileInfoResp::getImageId));
resp.setImageTypeLabel(ImageTypeEnum.getDescByCode(resp.getImageType())); partList.forEach(resp -> {
}); resp.setAudioList(BeanUtil.copyToList(audioMap.get(resp.getImageId()), AudioFileInfoResp.class));
resp.setWeatherLabel(WeatherEnum.getDescByCode(resp.getWeather()));
resp.setShootingMethodLabel(ShootingMethodEnum.getDescByCode(resp.getShootingMethod()));
resp.setImageTypeLabel(ImageTypeEnum.getDescByCode(resp.getImageType()));
});
}
return partList; return partList;
} }
@ -114,11 +125,14 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, ImageEntity> impl
@Override @Override
public ImageResp detail(String imageId) { public ImageResp detail(String imageId) {
ImageResp imageResp = this.baseMapper.detail(imageId); ImageResp imageResp = this.baseMapper.detail(imageId);
if(null != imageResp && null != imageResp.getImageCollectInfo()){ if (null != imageResp) {
imageResp.getImageCollectInfo().setWeatherLabel(WeatherEnum.getDescByCode(imageResp.getImageCollectInfo().getWeather())); List<AudioFileInfoResp> list = audioFileInfoService.selectByImageIds(ListUtil.toList(imageId));
imageResp.getImageCollectInfo().setShootingMethodLabel(ShootingMethodEnum.getDescByCode(imageResp.getImageCollectInfo().getShootingMethodLabel())); imageResp.setAudioList(list);
if (null != imageResp.getImageCollectInfo()) {
imageResp.getImageCollectInfo().setWeatherLabel(WeatherEnum.getDescByCode(imageResp.getImageCollectInfo().getWeather()));
imageResp.getImageCollectInfo().setShootingMethodLabel(ShootingMethodEnum.getDescByCode(imageResp.getImageCollectInfo().getShootingMethodLabel()));
}
} }
return imageResp; return imageResp;
} }

View File

@ -0,0 +1,30 @@
<?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.dite.znpt.mapper.AudioFileInfoMapper">
<sql id="Base_Column_List">
a.audio_id, a.image_id, a.file_path, a.update_by,
a.create_time, a.create_by, a.update_time
</sql>
<select id="queryBySelective" resultType="com.dite.znpt.domain.vo.AudioFileInfoResp">
select
<include refid="Base_Column_List"/>
from audio_file_info a
<where>
<if test="audioId != null and audioId != ''">
and a.audio_id = #{audioId}
</if>
<if test="imageId != null and imageId != ''">
and a.image_id = #{imageId}
</if>
<if test="imageIds != null and imageIds.size() != 0">
and a.image_id in
<foreach collection="imageIds" open="(" close=")" item="imageId" separator=",">
#{imageId}
</foreach>
</if>
</where>
</select>
</mapper>

View File

@ -0,0 +1,74 @@
package com.dite.znpt.web.controller;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ArrayUtil;
import com.dite.znpt.domain.PageResult;
import com.dite.znpt.domain.Result;
import com.dite.znpt.domain.entity.AudioFileInfoEntity;
import com.dite.znpt.domain.vo.*;
import com.dite.znpt.enums.ImageSourceEnum;
import com.dite.znpt.service.AudioFileInfoService;
import com.dite.znpt.service.ImageCollectService;
import com.dite.znpt.service.ImageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
* @author cuizhibin
* @date 2025/06/23 13:39
* @description 音频控制器
*/
@Api(tags = "音频信息")
@RestController
@RequestMapping("/audio")
@RequiredArgsConstructor
public class AudioController {
private final AudioFileInfoService audioFileInfoService;
@ApiOperation(value = "分页查询音频列表", httpMethod = "GET")
@GetMapping("/page")
public PageResult<AudioFileInfoEntity> page(AudioFileInfoListReq req) {
return PageResult.ok(audioFileInfoService.selectList(req));
}
@ApiOperation(value = "查询音频列表", httpMethod = "GET")
@GetMapping("/list")
public Result<List<AudioFileInfoEntity>> list(AudioFileInfoListReq req){
return Result.ok(audioFileInfoService.selectList(req));
}
@ApiOperation(value = "查询音频详情", httpMethod = "GET")
@GetMapping("/detail/{audioId}")
public Result<AudioFileInfoResp> detail(@PathVariable String audioId){
return Result.ok(audioFileInfoService.selectById(audioId));
}
@ApiOperation(value = "删除图像", httpMethod = "DELETE")
@DeleteMapping("/{imageId}")
public Result remove(@PathVariable String imageId){
audioFileInfoService.deleteById(imageId);
return Result.ok();
}
@ApiOperation(value = "上传音频", httpMethod = "POST")
@PostMapping("/upload/{imageId}")
public Result<AudioFileInfoResp> uploadBatch(@PathVariable String imageId, @RequestParam("file") MultipartFile file) {
return Result.ok(audioFileInfoService.batchUpload(imageId, new MultipartFile[]{file}).get(0));
}
@ApiOperation(value = "批量上传音频", httpMethod = "POST")
@PostMapping("/upload-batch/{imageId}")
public Result<List<AudioFileInfoResp>> uploadBatch(@PathVariable String imageId, @RequestParam("files") MultipartFile[] files) {
return Result.ok(audioFileInfoService.batchUpload(imageId, files));
}
}