对接AI工牌

This commit is contained in:
2025-11-02 20:49:45 +08:00
parent 6c40d95604
commit b462cce2b0
4 changed files with 373 additions and 0 deletions

View File

@@ -0,0 +1,183 @@
package com.rj.service.impl;
import com.rj.service.ISoundRecordingUploadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.time.Instant;
import java.util.regex.Pattern;
/**
* 录音上传服务实现类
*
* @author rj
* @date 2025-01-03
*/
@Slf4j
@Service
public class SoundRecordingUploadServiceImpl implements ISoundRecordingUploadService {
/**
* 分片索引正则表达式
* A开头启动/运行段如A001, A005
* Z开头停止段Z后面数字表示总段数如Z999表示总共999段Z001表示只有一段
*/
private static final Pattern CHUNK_INDEX_PATTERN = Pattern.compile("^[AZ]\\d{3}$");
/**
* 时间格式正则表达式yyMMddHHmmss
*/
private static final Pattern TIME_PATTERN = Pattern.compile("^\\d{12}$");
@Override
public ResponseData uploadRecording(String deviceNo, String deviceType, MultipartFile soundRecording,
String fileName, String chunkIndex, String startTime, String endTime, String usrNo) {
log.info("开始处理录音上传 - deviceNo: {}, fileName: {}, chunkIndex: {}, startTime: {}, endTime: {}",
deviceNo, fileName, chunkIndex, startTime, endTime);
try {
// 参数验证
String validationError = validateParameters(deviceNo, soundRecording, fileName, chunkIndex, startTime, endTime);
if (validationError != null) {
log.warn("参数验证失败 - deviceNo: {}, error: {}", deviceNo, validationError);
return createErrorResponse(400, 1, validationError);
}
// 解析分片信息
ChunkInfo chunkInfo = parseChunkIndex(chunkIndex);
log.info("分片信息解析 - prefix: {}, chunkNumber: {}, isLastChunk: {}, totalChunks: {}",
chunkInfo.prefix, chunkInfo.chunkNumber, chunkInfo.isLastChunk, chunkInfo.totalChunks);
// TODO: 这里可以添加文件保存逻辑
// 1. 保存文件到指定目录
// 2. 如果是分片上传,需要管理分片状态
// 3. 如果是最后一片,需要合并分片或标记完成
log.info("录音文件上传成功 - deviceNo: {}, fileName: {}, fileSize: {} bytes",
deviceNo, fileName, soundRecording.getSize());
// 返回成功响应
return createSuccessResponse();
} catch (Exception e) {
log.error("录音上传处理异常 - deviceNo: {}, fileName: {}, error: {}",
deviceNo, fileName, e.getMessage(), e);
return createErrorResponse(500, 1, "服务器内部错误:" + e.getMessage());
}
}
/**
* 验证参数
*/
private String validateParameters(String deviceNo, MultipartFile soundRecording, String fileName,
String chunkIndex, String startTime, String endTime) {
if (deviceNo == null || deviceNo.trim().isEmpty()) {
return "设备序列号不能为空";
}
if (soundRecording == null || soundRecording.isEmpty()) {
return "录音文件不能为空";
}
if (fileName == null || fileName.trim().isEmpty()) {
return "文件名称不能为空";
}
if (chunkIndex == null || chunkIndex.trim().isEmpty()) {
return "分片索引不能为空";
}
// 验证分片索引格式
if (!CHUNK_INDEX_PATTERN.matcher(chunkIndex).matches()) {
return "分片索引格式错误应为A开头或Z开头后跟3位数字如A001或Z999";
}
if (startTime == null || startTime.trim().isEmpty()) {
return "录音开始时间不能为空";
}
if (!TIME_PATTERN.matcher(startTime).matches()) {
return "录音开始时间格式错误应为yyMMddHHmmss如240510130000";
}
if (endTime == null || endTime.trim().isEmpty()) {
return "录音结束时间不能为空";
}
if (!TIME_PATTERN.matcher(endTime).matches()) {
return "录音结束时间格式错误应为yyMMddHHmmss如240510135959";
}
return null;
}
/**
* 解析分片索引
*/
private ChunkInfo parseChunkIndex(String chunkIndex) {
char prefix = chunkIndex.charAt(0);
int chunkNumber = Integer.parseInt(chunkIndex.substring(1));
boolean isLastChunk = prefix == 'Z';
int totalChunks = isLastChunk ? chunkNumber : 0;
return new ChunkInfo(prefix, chunkNumber, isLastChunk, totalChunks);
}
/**
* 创建成功响应
*/
private ResponseData createSuccessResponse() {
ResponseData response = new ResponseData();
response.code = 200;
response.status = 0;
response.success = true;
response.message = "请求成功";
response.timestamp = Instant.now().getEpochSecond();
return response;
}
/**
* 创建错误响应
*/
private ResponseData createErrorResponse(int code, int status, String message) {
ResponseData response = new ResponseData();
response.code = code;
response.status = status;
response.success = false;
response.message = message;
response.timestamp = Instant.now().getEpochSecond();
return response;
}
/**
* 分片信息内部类
*/
private static class ChunkInfo {
char prefix;
int chunkNumber;
boolean isLastChunk;
int totalChunks;
ChunkInfo(char prefix, int chunkNumber, boolean isLastChunk, int totalChunks) {
this.prefix = prefix;
this.chunkNumber = chunkNumber;
this.isLastChunk = isLastChunk;
this.totalChunks = totalChunks;
}
}
/**
* 响应数据内部类
*/
public static class ResponseData {
public Integer code;
public Integer status;
public Boolean success;
public String message;
public Long timestamp;
}
}