From 5601de3381510357240da8e1e95bb2897e24d42c Mon Sep 17 00:00:00 2001 From: like <1025687351@qq.com> Date: Wed, 16 Apr 2025 17:10:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=96=8A=E8=AF=9D=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resource/api/RemoteFileService.java | 4 + .../resource/api/RemoteFileServiceMock.java | 9 ++ .../resource/dubbo/RemoteFileServiceImpl.java | 8 ++ dk-modules/sample/pom.xml | 6 +- .../controller/WaylineFileController.java | 26 ++++ .../wayline/mapper/IAudioFileMapper.java | 17 +++ .../wayline/model/entity/AudioFileEntity.java | 68 +++++++++ .../wayline/service/IAudioFileService.java | 21 +++ .../wayline/service/IWaylineFileService.java | 9 ++ .../service/impl/AudioFileServiceImpl.java | 68 +++++++++ .../service/impl/WaylineFileServiceImpl.java | 136 +++++++++++++++++- 11 files changed, 368 insertions(+), 4 deletions(-) create mode 100644 dk-modules/sample/src/main/java/org/dromara/sample/wayline/mapper/IAudioFileMapper.java create mode 100644 dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/entity/AudioFileEntity.java create mode 100644 dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IAudioFileService.java create mode 100644 dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/AudioFileServiceImpl.java diff --git a/dk-api/api-resource/src/main/java/org/dromara/resource/api/RemoteFileService.java b/dk-api/api-resource/src/main/java/org/dromara/resource/api/RemoteFileService.java index 2204de6..d5a9e7e 100644 --- a/dk-api/api-resource/src/main/java/org/dromara/resource/api/RemoteFileService.java +++ b/dk-api/api-resource/src/main/java/org/dromara/resource/api/RemoteFileService.java @@ -3,6 +3,7 @@ package org.dromara.resource.api; import org.dromara.common.core.exception.ServiceException; import org.dromara.resource.api.domain.RemoteFile; +import java.util.Collection; import java.util.List; /** @@ -35,4 +36,7 @@ public interface RemoteFileService { * @return 列表 */ List selectByIds(String ossIds); + + Boolean remove(Collection ids, Boolean isValid) throws ServiceException; + } diff --git a/dk-api/api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceMock.java b/dk-api/api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceMock.java index 5ce7c5a..80dfe2d 100644 --- a/dk-api/api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceMock.java +++ b/dk-api/api-resource/src/main/java/org/dromara/resource/api/RemoteFileServiceMock.java @@ -1,9 +1,11 @@ package org.dromara.resource.api; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.StringUtils; import org.dromara.resource.api.domain.RemoteFile; +import java.util.Collection; import java.util.List; /** @@ -50,4 +52,11 @@ public class RemoteFileServiceMock implements RemoteFileService { return List.of(); } + + @Override + public Boolean remove(Collection ids, Boolean isValid) throws ServiceException { + log.warn("服务调用异常 -> 降级处理"); + return null; + } + } diff --git a/dk-modules/resource/src/main/java/org/dromara/resource/dubbo/RemoteFileServiceImpl.java b/dk-modules/resource/src/main/java/org/dromara/resource/dubbo/RemoteFileServiceImpl.java index 96305d3..5ec4f09 100644 --- a/dk-modules/resource/src/main/java/org/dromara/resource/dubbo/RemoteFileServiceImpl.java +++ b/dk-modules/resource/src/main/java/org/dromara/resource/dubbo/RemoteFileServiceImpl.java @@ -18,6 +18,7 @@ import org.dromara.resource.service.ISysOssService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Collection; import java.util.List; /** @@ -96,4 +97,11 @@ public class RemoteFileServiceImpl implements RemoteFileService { return remoteFile; }).toList(); } + + @Override + public Boolean remove(Collection ids, Boolean isValid) throws ServiceException{ + sysOssService.deleteWithValidByIds(ids,isValid); + return null; + } + } diff --git a/dk-modules/sample/pom.xml b/dk-modules/sample/pom.xml index 7f3292f..ac6066c 100644 --- a/dk-modules/sample/pom.xml +++ b/dk-modules/sample/pom.xml @@ -131,7 +131,11 @@ aws-java-sdk-sts 1.12.261 - + + ws.schild + jave-core + 3.4.0 + org.dromara api-workflow diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineFileController.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineFileController.java index 4ae1ae6..fe5cd46 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineFileController.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/controller/WaylineFileController.java @@ -15,6 +15,7 @@ import org.dromara.common.sdk.cloudapi.wayline.api.IHttpWaylineService; import org.dromara.common.sdk.common.HttpResultResponse; import org.dromara.common.sdk.common.PaginationData; import org.dromara.sample.wayline.model.dto.WaylineFileDTO; +import org.dromara.sample.wayline.model.entity.AudioFileEntity; import org.dromara.sample.wayline.model.entity.WaylineFileEntity; import org.dromara.sample.wayline.service.IWaylineFileService; @@ -24,6 +25,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.io.File; import java.io.IOException; import java.net.URL; import java.sql.SQLException; @@ -197,4 +199,28 @@ public class WaylineFileController implements IHttpWaylineService { } return HttpResultResponse.error(); } + + + @PostMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/file/audio/add") + @Operation(summary = "添加音频文件", description = "添加音频文件。") + public HttpResultResponse audioAdd(@PathVariable(name = "workspace_id") String workspaceId, MultipartFile file) { + if (Objects.isNull(file)) { + return HttpResultResponse.error("未收到文件。"); + } + return HttpResultResponse.success(waylineFileService.transformation(file, workspaceId)); + } + + @PostMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/file/audio/{fileId}") + @Operation(summary = "删除音频文件", description = "删除音频文件。") + public HttpResultResponse audioDeleted(@PathVariable(name = "workspace_id") String workspaceId, @PathVariable(name = "fileId")String fileId) { + waylineFileService.audioDeleted(workspaceId,fileId); + return HttpResultResponse.success(); + } + + @GetMapping("${url.wayline.prefix}${url.wayline.version}/workspaces/{workspace_id}/waylines/file/audio/page") + @Operation(summary = "音频文件列表", description = "音频文件列表。") + public HttpResultResponse> getAudioPage(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize, @PathVariable(name = "workspace_id") String workspaceId) { + PaginationData data = waylineFileService.getAudioPage(workspaceId, pageNum,pageSize); + return HttpResultResponse.success(data); + } } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/mapper/IAudioFileMapper.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/mapper/IAudioFileMapper.java new file mode 100644 index 0000000..f464f38 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/mapper/IAudioFileMapper.java @@ -0,0 +1,17 @@ +package org.dromara.sample.wayline.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.dromara.common.sdk.cloudapi.wayline.GetWaylineListRequest; +import org.dromara.sample.wayline.model.entity.AudioFileEntity; +import org.dromara.sample.wayline.model.entity.WaylineFileEntity; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +public interface IAudioFileMapper extends BaseMapper { + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/entity/AudioFileEntity.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/entity/AudioFileEntity.java new file mode 100644 index 0000000..b6383a1 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/model/entity/AudioFileEntity.java @@ -0,0 +1,68 @@ +package org.dromara.sample.wayline.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Data +@TableName("audio_file") +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class AudioFileEntity implements Serializable { + + @TableId(type = IdType.AUTO) + private Integer id; + + @TableField("file_id") + private String fileId; + + @TableField("file_name") + private String fileName; + + @TableField("old_name") + private String oldName; + + @TableField("file_path") + private String filePath; + + @TableField("sign") + private String sign; + + @TableField("workspace_id") + private String workspaceId; + + @TableField("fingerprint") + private String fingerprint; + + @TableField("tinny_fingerprint") + private String tinnyFingerprint; + + @TableField("object_key") + private String objectKey; + + @TableField("user_name") + private String username; + + @TableField(value = "create_time", fill = FieldFill.INSERT) + private Date createTime; + + @TableField("oss_id") + private Long ossId; + + @TableField("input_stream_base") + private String inputStreamBase; + + @TableField(exist = false) + private byte[] inputStream; +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IAudioFileService.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IAudioFileService.java new file mode 100644 index 0000000..240fe91 --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IAudioFileService.java @@ -0,0 +1,21 @@ +package org.dromara.sample.wayline.service; + +import org.dromara.common.sdk.cloudapi.wayline.GetWaylineListRequest; +import org.dromara.common.sdk.cloudapi.wayline.GetWaylineListResponse; +import org.dromara.common.sdk.common.PaginationData; +import org.dromara.sample.wayline.model.dto.WaylineFileDTO; +import org.springframework.web.multipart.MultipartFile; + +import java.net.URL; +import java.sql.SQLException; +import java.util.List; +import java.util.Optional; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +public interface IAudioFileService { + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineFileService.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineFileService.java index 0c16986..13e4e30 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineFileService.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/IWaylineFileService.java @@ -4,8 +4,10 @@ import org.dromara.common.sdk.cloudapi.wayline.GetWaylineListRequest; import org.dromara.common.sdk.cloudapi.wayline.GetWaylineListResponse; import org.dromara.common.sdk.common.PaginationData; import org.dromara.sample.wayline.model.dto.WaylineFileDTO; +import org.dromara.sample.wayline.model.entity.AudioFileEntity; import org.springframework.web.multipart.MultipartFile; +import java.io.File; import java.net.URL; import java.sql.SQLException; import java.util.List; @@ -93,4 +95,11 @@ public interface IWaylineFileService { * @return */ PaginationData getWaylinesByParamNew(String workspaceId, GetWaylineListRequest param); + + AudioFileEntity transformation(MultipartFile file, String workspaceId); + + void audioDeleted(String workspaceId, String fileId); + + PaginationData getAudioPage(String workspaceId, int pageNum, int pageSize); + } diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/AudioFileServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/AudioFileServiceImpl.java new file mode 100644 index 0000000..5a0ecab --- /dev/null +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/AudioFileServiceImpl.java @@ -0,0 +1,68 @@ +package org.dromara.sample.wayline.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.seata.common.util.CollectionUtils; +import org.apache.dubbo.config.annotation.DubboReference; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Node; +import org.dom4j.io.SAXReader; +import org.dromara.common.oss.core.OssClient; +import org.dromara.common.oss.entity.UploadResult; +import org.dromara.common.oss.factory.OssFactory; +import org.dromara.common.sdk.cloudapi.device.DeviceDomainEnum; +import org.dromara.common.sdk.cloudapi.device.DeviceEnum; +import org.dromara.common.sdk.cloudapi.device.DeviceSubTypeEnum; +import org.dromara.common.sdk.cloudapi.device.DeviceTypeEnum; +import org.dromara.common.sdk.cloudapi.wayline.GetWaylineListRequest; +import org.dromara.common.sdk.cloudapi.wayline.GetWaylineListResponse; +import org.dromara.common.sdk.cloudapi.wayline.WaylineTypeEnum; +import org.dromara.common.sdk.common.Pagination; +import org.dromara.common.sdk.common.PaginationData; +import org.dromara.resource.api.RemoteFileService; +import org.dromara.resource.api.domain.RemoteFile; +import org.dromara.sample.wayline.mapper.IWaylineFileMapper; +import org.dromara.sample.wayline.model.dto.KmzFileProperties; +import org.dromara.sample.wayline.model.dto.WaylineFileDTO; +import org.dromara.sample.wayline.model.entity.WaylineFileEntity; +import org.dromara.sample.wayline.service.IAudioFileService; +import org.dromara.sample.wayline.service.IWaylineFileService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.DigestUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; +import ws.schild.jave.Encoder; +import ws.schild.jave.MultimediaObject; +import ws.schild.jave.encode.AudioAttributes; +import ws.schild.jave.encode.EncodingAttributes; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.security.MessageDigest; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import static org.dromara.sample.wayline.model.dto.KmzFileProperties.WAYLINE_FILE_SUFFIX; + +/** + * @author sean + * @version 0.3 + * @date 2021/12/22 + */ +@Service +@Transactional +public class AudioFileServiceImpl implements IAudioFileService { + +} diff --git a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineFileServiceImpl.java b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineFileServiceImpl.java index 2479134..2386b39 100644 --- a/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineFileServiceImpl.java +++ b/dk-modules/sample/src/main/java/org/dromara/sample/wayline/service/impl/WaylineFileServiceImpl.java @@ -1,10 +1,14 @@ package org.dromara.sample.wayline.service.impl; +import cn.hutool.crypto.digest.MD5; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import io.seata.common.util.CollectionUtils; +import org.apache.dubbo.config.annotation.DubboReference; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Node; @@ -21,9 +25,13 @@ import org.dromara.common.sdk.cloudapi.wayline.GetWaylineListResponse; import org.dromara.common.sdk.cloudapi.wayline.WaylineTypeEnum; import org.dromara.common.sdk.common.Pagination; import org.dromara.common.sdk.common.PaginationData; +import org.dromara.resource.api.RemoteFileService; +import org.dromara.resource.api.domain.RemoteFile; +import org.dromara.sample.wayline.mapper.IAudioFileMapper; import org.dromara.sample.wayline.mapper.IWaylineFileMapper; import org.dromara.sample.wayline.model.dto.KmzFileProperties; import org.dromara.sample.wayline.model.dto.WaylineFileDTO; +import org.dromara.sample.wayline.model.entity.AudioFileEntity; import org.dromara.sample.wayline.model.entity.WaylineFileEntity; import org.dromara.sample.wayline.service.IWaylineFileService; import org.springframework.beans.factory.annotation.Autowired; @@ -32,12 +40,16 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.DigestUtils; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; +import ws.schild.jave.Encoder; +import ws.schild.jave.MultimediaObject; +import ws.schild.jave.encode.AudioAttributes; +import ws.schild.jave.encode.EncodingAttributes; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.security.MessageDigest; import java.sql.SQLException; import java.util.*; import java.util.stream.Collectors; @@ -58,6 +70,12 @@ public class WaylineFileServiceImpl implements IWaylineFileService { @Autowired private IWaylineFileMapper mapper; + @Autowired + private IAudioFileMapper audioFileMapper; + + @DubboReference + private RemoteFileService remoteFileService; + @Override public PaginationData getWaylinesByParam(String workspaceId, GetWaylineListRequest param) { // Paging Query @@ -239,6 +257,118 @@ public class WaylineFileServiceImpl implements IWaylineFileService { return new PaginationData<>(records, new Pagination(page.getCurrent(), page.getSize(), page.getTotal())); } + @Override + public AudioFileEntity transformation(MultipartFile multipartFile, String workspaceId) { + File file = new File(multipartFile.getOriginalFilename()); + AudioFileEntity audioFileEntity = new AudioFileEntity(); + RemoteFile upload = new RemoteFile(); + try { +// multipartFile.transferTo(file); + // 1. 获取项目根目录路径 + String projectRoot = System.getProperty("user.dir"); + + // 2. 创建目标文件对象 + file = new File(projectRoot + File.separator + multipartFile.getOriginalFilename()); + + // 3. 写入MP3文件(这里假设已有字节数据) + Files.write(file.toPath(), multipartFile.getBytes()); + + // 4. 这里使用文件(例如播放、处理等操作) + System.out.println("文件已保存至:" + file.getAbsolutePath()); + // TODO: 在此处添加实际使用文件的代码 + + } catch (IOException e) { + throw new RuntimeException("保存到本地失败"); + } + + try { + File target = new File(multipartFile.getOriginalFilename().replaceAll("\\.[^.]*$", "") +".opus"); + audioFileEntity.setOldName(multipartFile.getOriginalFilename()); + AudioAttributes audio = new AudioAttributes(); + audio.setCodec("libopus"); + audio.setBitRate(32_000); // 32kbps + audio.setChannels(2); + audio.setSamplingRate(48000); + EncodingAttributes attrs = new EncodingAttributes(); + attrs.setOutputFormat("opus"); + attrs.setAudioAttributes(audio); + + Encoder encoder = new Encoder(); + encoder.encode(new MultimediaObject(file), target, attrs); + System.out.println("转换成功"); + upload = remoteFileService.upload(target.getName(), target.getName(), multipartFile.getContentType(), Files.readAllBytes(target.toPath())); + //转md5 + MessageDigest md = MessageDigest.getInstance("MD5"); + try (FileInputStream fis = new FileInputStream(target)) { + byte[] buffer = new byte[8192]; // 缓冲区大小 + int bytesRead; + // 分块更新哈希值 + while ((bytesRead = fis.read(buffer)) != -1) { + md.update(buffer, 0, bytesRead); + } + } + // 转换为十六进制字符串 + byte[] digest = md.digest(); + StringBuilder sb = new StringBuilder(); + for (byte b : digest) { + sb.append(String.format("%02x", b & 0xff)); + } + String md5 = sb.toString(); + //转流 + audioFileEntity.setInputStream(Files.readAllBytes(target.toPath())); + //刪除臨時文件 + Files.delete(file.toPath()); + Files.delete(target.toPath()); + //插入文件数据库 + audioFileEntity.setFileId(UUID.randomUUID().toString()); + audioFileEntity.setFileName(upload.getOriginalName()); + audioFileEntity.setFilePath(upload.getUrl()); + audioFileEntity.setSign(md5); + audioFileEntity.setWorkspaceId(workspaceId); + audioFileEntity.setObjectKey(upload.getName()); + audioFileEntity.setOssId(upload.getOssId()); + if (audioFileEntity.getInputStream() != null){ + String base64Data = Base64.getEncoder().encodeToString(audioFileEntity.getInputStream()); + audioFileEntity.setInputStreamBase(base64Data); + } + audioFileMapper.insert(audioFileEntity); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("转换file失败"); + } + return audioFileEntity; + } + + @Override + public void audioDeleted(String workspaceId, String fileId) { + AudioFileEntity audioFileEntity = audioFileMapper.selectOne(new QueryWrapper().eq("workspace_id", workspaceId).eq("file_id", fileId)); + List list = new ArrayList<>(); + list.add(audioFileEntity.getOssId()); + remoteFileService.remove(list, true); + audioFileMapper.delete(new QueryWrapper().eq("workspace_id",workspaceId).eq("file_id",fileId)); + + } + + @Override + public PaginationData getAudioPage(String workspaceId, int pageNum, int pageSize) { + Page pageQuery = new Page<>(pageNum, pageSize); + Page page1 = audioFileMapper.selectPage( + pageQuery, + new QueryWrapper() + .eq("workspace_id", workspaceId)); + + // Wrap the results of a paging query into a custom paging object. + List records = page1.getRecords(); + for (AudioFileEntity audioFileEntity : records){ + if (io.seata.common.util.StringUtils.isNotBlank(audioFileEntity.getInputStreamBase())){ + byte[] data = Base64.getDecoder().decode(audioFileEntity.getInputStreamBase()); + audioFileEntity.setInputStream(data); + } + } + return new PaginationData<>(records, new Pagination(page1.getCurrent(), page1.getSize(), page1.getTotal())); + + } + private Optional validKmzFile(MultipartFile file) { String filename = file.getOriginalFilename(); if (Objects.nonNull(filename) && !filename.endsWith(WAYLINE_FILE_SUFFIX)) {