Commit 1ada0292 authored by 韩桐桐's avatar 韩桐桐

接警记录导出附带电话录音文件

parent a012d891
...@@ -14,6 +14,8 @@ import org.springframework.cloud.openfeign.FeignClient; ...@@ -14,6 +14,8 @@ import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.typroject.tyboot.core.restful.utils.ResponseModel; import org.typroject.tyboot.core.restful.utils.ResponseModel;
import feign.Response;
@FeignClient(value = "AMOS-API-PRIVILEGE", configuration = {FeignConfiguration.class}) @FeignClient(value = "AMOS-API-PRIVILEGE", configuration = {FeignConfiguration.class})
public interface PrivilegeFeginService { public interface PrivilegeFeginService {
...@@ -38,5 +40,14 @@ public interface PrivilegeFeginService { ...@@ -38,5 +40,14 @@ public interface PrivilegeFeginService {
@RequestMapping(value = "/privilege/v1/auth/mobile/verifycode", method = RequestMethod.POST) @RequestMapping(value = "/privilege/v1/auth/mobile/verifycode", method = RequestMethod.POST)
FeignClientResult mobileVerifyCode(@RequestBody VerifyCodeAuthModel model) throws InnerInvokException; FeignClientResult mobileVerifyCode(@RequestBody VerifyCodeAuthModel model) throws InnerInvokException;
/**
*
* 以流的形式下载文件
*
* @param path 下载文件路径,minio中存储路径(存储桶+存储文件夹+存储名称)
* @return res
* @throws InnerInvokException
*/
@RequestMapping(value = "/systemctl/v1/filestorage/stream", method = RequestMethod.GET)
Response downloadFileByStream(@RequestParam(value = "path") String path) throws InnerInvokException;
} }
...@@ -5,48 +5,46 @@ import com.alibaba.fastjson.JSONObject; ...@@ -5,48 +5,46 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.biz.common.controller.BaseController;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils; import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.module.common.api.excel.ExcelUtil; import com.yeejoin.amos.boot.module.common.api.excel.ExcelUtil;
import com.yeejoin.amos.boot.module.elevator.api.common.BizCommonConstant; import com.yeejoin.amos.boot.module.elevator.api.common.BizCommonConstant;
import com.yeejoin.amos.boot.module.elevator.api.common.StringUtil; import com.yeejoin.amos.boot.module.elevator.api.common.StringUtil;
import com.yeejoin.amos.boot.module.elevator.api.dto.ElevatorDto; import com.yeejoin.amos.boot.module.elevator.api.dto.ElevatorDto;
import com.yeejoin.amos.boot.module.elevator.api.dto.ExportDto; import com.yeejoin.amos.boot.module.elevator.api.dto.ExportDto;
import com.yeejoin.amos.boot.module.elevator.api.dto.TemplateExportDto;
import com.yeejoin.amos.boot.module.elevator.api.dto.VoiceRecordFileDto;
import com.yeejoin.amos.boot.module.elevator.api.entity.TemplateExport; import com.yeejoin.amos.boot.module.elevator.api.entity.TemplateExport;
import com.yeejoin.amos.boot.module.elevator.api.service.IMaintenanceUnitService; import com.yeejoin.amos.boot.module.elevator.api.service.IMaintenanceUnitService;
import com.yeejoin.amos.boot.module.elevator.api.service.IRescueStationService; import com.yeejoin.amos.boot.module.elevator.api.service.IRescueStationService;
import com.yeejoin.amos.boot.module.elevator.api.service.IUseUnitService; import com.yeejoin.amos.boot.module.elevator.api.service.IUseUnitService;
import com.yeejoin.amos.boot.module.elevator.biz.service.impl.ElevatorServiceImpl; import com.yeejoin.amos.boot.module.elevator.biz.service.impl.ElevatorServiceImpl;
import com.yeejoin.amos.boot.module.elevator.biz.service.impl.TemplateExportServiceImpl;
import com.yeejoin.amos.boot.module.elevator.biz.service.impl.VoiceRecordFileServiceImpl; import com.yeejoin.amos.boot.module.elevator.biz.service.impl.VoiceRecordFileServiceImpl;
import com.yeejoin.amos.boot.module.elevator.biz.utils.RedisUtil; import com.yeejoin.amos.boot.module.elevator.biz.utils.RedisUtil;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel; import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StopWatch; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping; import org.typroject.tyboot.core.foundation.enumeration.UserType;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RestController;
import com.yeejoin.amos.boot.biz.common.controller.BaseController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import com.yeejoin.amos.boot.module.elevator.biz.service.impl.TemplateExportServiceImpl;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil; import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest; import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseHelper; import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel; import org.typroject.tyboot.core.restful.utils.ResponseModel;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import org.springframework.web.bind.annotation.*; import java.util.List;
import com.yeejoin.amos.boot.module.elevator.api.dto.TemplateExportDto; import java.util.Map;
import org.typroject.tyboot.core.restful.doc.TycloudOperation; import java.util.Objects;
import org.typroject.tyboot.core.foundation.enumeration.UserType; import java.util.concurrent.Executor;
import java.util.stream.Collectors;
/** /**
* 模板表 * 模板表
...@@ -54,6 +52,7 @@ import org.typroject.tyboot.core.foundation.enumeration.UserType; ...@@ -54,6 +52,7 @@ import org.typroject.tyboot.core.foundation.enumeration.UserType;
* @author system_generator * @author system_generator
* @date 2021-10-25 * @date 2021-10-25
*/ */
@Slf4j
@RestController @RestController
@Api(tags = "导出Api") @Api(tags = "导出Api")
@RequestMapping(value = "/template-export") @RequestMapping(value = "/template-export")
...@@ -83,6 +82,7 @@ public class TemplateExportController extends BaseController { ...@@ -83,6 +82,7 @@ public class TemplateExportController extends BaseController {
@Autowired @Autowired
Executor customExecutor; Executor customExecutor;
/** /**
* 新增模板表 * 新增模板表
* *
...@@ -249,7 +249,18 @@ public class TemplateExportController extends BaseController { ...@@ -249,7 +249,18 @@ public class TemplateExportController extends BaseController {
sheetName = "通话录音"; sheetName = "通话录音";
AgencyUserModel userModel = this.getSelectedOrgInfo().getUserModel(); AgencyUserModel userModel = this.getSelectedOrgInfo().getUserModel();
if (!ObjectUtils.isEmpty(userModel)) { if (!ObjectUtils.isEmpty(userModel)) {
list = voiceRecordFileServiceImpl.selectExportData(exportDto.getExportId(), userModel); List<VoiceRecordFileDto> voiceRecordFileDtos = voiceRecordFileServiceImpl.selectExportData(exportDto.getExportId(), userModel);
byte[] excelBytes = ExcelUtil.generateExcelBytes(sheetName, voiceRecordFileDtos, heads, headstr, exportDto.getFileType());
// 录音文件获取
List<JSONObject> recordFiles = voiceRecordFileDtos.stream()
.filter(s -> ObjectUtils.isNotEmpty(s.getFilePath()) && ObjectUtils.isNotEmpty(s.getWorkNum()))
.map(s -> templateExportServiceImpl.downloadRecordFile(s))
.filter(Objects::nonNull)
.collect(Collectors.toList());
// 打包zip返回
templateExportServiceImpl.packZip(response, fileName, excelBytes, exportDto.getFileType(), recordFiles);
return;
} }
} }
ExcelUtil.createTemplateWithHeaders(response, fileName, sheetName, list,heads,headstr,exportDto.getFileType()); ExcelUtil.createTemplateWithHeaders(response, fileName, sheetName, list,heads,headstr,exportDto.getFileType());
......
package com.yeejoin.amos.boot.module.elevator.biz.service.impl; package com.yeejoin.amos.boot.module.elevator.biz.service.impl;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.boot.module.elevator.api.dto.VoiceRecordFileDto;
import com.yeejoin.amos.boot.module.elevator.api.entity.TemplateExport; import com.yeejoin.amos.boot.module.elevator.api.entity.TemplateExport;
import com.yeejoin.amos.boot.module.elevator.api.mapper.TemplateExportMapper; import com.yeejoin.amos.boot.module.elevator.api.mapper.TemplateExportMapper;
import com.yeejoin.amos.boot.module.elevator.api.service.ITemplateExportService; import com.yeejoin.amos.boot.module.elevator.api.service.ITemplateExportService;
import com.yeejoin.amos.boot.module.elevator.api.dto.TemplateExportDto; import com.yeejoin.amos.boot.module.elevator.api.dto.TemplateExportDto;
import com.yeejoin.amos.boot.module.elevator.flc.api.feign.PrivilegeFeginService;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StreamUtils;
import org.typroject.tyboot.core.rdbms.service.BaseService; import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List; import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/** /**
* 模板表服务实现类 * 模板表服务实现类
...@@ -15,19 +33,88 @@ import java.util.List; ...@@ -15,19 +33,88 @@ import java.util.List;
* @author system_generator * @author system_generator
* @date 2021-10-25 * @date 2021-10-25
*/ */
@Slf4j
@Service @Service
public class TemplateExportServiceImpl extends BaseService<TemplateExportDto,TemplateExport,TemplateExportMapper> implements ITemplateExportService { public class TemplateExportServiceImpl extends BaseService<TemplateExportDto, TemplateExport, TemplateExportMapper> implements ITemplateExportService {
/** /**
* 分页查询 * 分页查询
*/ */
public Page<TemplateExportDto> queryForTemplateExportPage(Page<TemplateExportDto> page) { public Page<TemplateExportDto> queryForTemplateExportPage(Page<TemplateExportDto> page) {
return this.queryForPage(page, null, false); return this.queryForPage(page, null, false);
} }
/** /**
* 列表查询 示例 * 列表查询 示例
*/ */
public List<TemplateExportDto> queryForTemplateExportList() { public List<TemplateExportDto> queryForTemplateExportList() {
return this.queryForList("" , false); return this.queryForList("", false);
}
@Autowired
PrivilegeFeginService privilegeFeginService;
/**
* 将excel和录音文件打包zip返回
*
* @param response 响应体
* @param excelBytes excel文件
* @param recordFiles 录音文件
*/
public void packZip(HttpServletResponse response, String fileName, byte[] excelBytes, String fileType, List<JSONObject> recordFiles) {
// 打包zip
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream)) {
// 写入excel
zip.putNextEntry(new ZipEntry(fileName + "." + ("1039".equals(fileType) ? ExcelTypeEnum.XLS : ExcelTypeEnum.XLSX)));
IOUtils.write(excelBytes, zip);
zip.closeEntry();
// 写入录音
for (JSONObject recordFile : recordFiles) {
try {
String workNum = recordFile.getString("workNum");
byte[] fileByte = (byte[]) recordFile.get("fileByte");
zip.putNextEntry(new ZipEntry("工单号【" + workNum + "】录音.MP3"));
IOUtils.write(fileByte, zip);
zip.closeEntry();
} catch (IOException e) {
log.error("打包zip失败:" + e.getMessage());
throw new BadRequest("打包zip失败");
}
}
// 所有条目写入完成后关闭 ZipOutputStream
zip.finish();
// 设置响应头并将压缩文件写入 HttpServletResponse
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/zip");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".zip", "UTF-8"));
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
IOUtils.write(outputStream.toByteArray(), response.getOutputStream());
} catch (IOException e) {
throw new RuntimeException("导出异常:", e);
}
} }
public JSONObject downloadRecordFile(VoiceRecordFileDto s) {
try {
Response fileResponse = privilegeFeginService.downloadFileByStream(s.getFilePath());
if (fileResponse.status() != 200) {
log.error("下载失败,状态码:{}, filePath: {}", fileResponse.status(), s.getFilePath());
return null;
}
try (InputStream inputStream = fileResponse.body().asInputStream()) {
byte[] data = StreamUtils.copyToByteArray(inputStream);
return new JSONObject()
.fluentPut("workNum", s.getWorkNum())
.fluentPut("fileByte", data);
}
} catch (Exception e) {
log.error("下载异常,filePath: {}", s.getFilePath(), e);
return null;
}
}
} }
\ No newline at end of file
...@@ -30,14 +30,49 @@ import java.nio.file.StandardOpenOption; ...@@ -30,14 +30,49 @@ import java.nio.file.StandardOpenOption;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class ExcelUtil { public class ExcelUtil {
private static final Integer DUTY_CAR_START_INDEX = 5; private static final Integer DUTY_CAR_START_INDEX = 5;
public static byte[] generateExcelBytes(String sheetName, List<?> data, List<List<String>> heads,
List<String> headStr, String fileType) {
// 1. 设置单元格样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = setMyCellStyle();
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
try {
List<List<Object>> listData = new ArrayList<>();
for (Object obj : data) {
List<Object> rowData = new ArrayList<>();
for (String head : headStr) {
String methodName = "get" + head.substring(0, 1).toUpperCase() + head.substring(1);
Method getMethod = obj.getClass().getMethod(methodName);
Object value = getMethod.invoke(obj);
rowData.add(value);
}
listData.add(rowData);
}
ExcelTypeEnum typeEnum = "1039".equals(fileType) ? ExcelTypeEnum.XLS : ExcelTypeEnum.XLSX;
EasyExcel.write(outputStream)
.excelType(typeEnum)
.sheet(sheetName)
.registerWriteHandler(new TemplateCellWriteHandler()) // 保留自定义处理器
.registerWriteHandler(horizontalCellStyleStrategy) // 保留样式策略
.head(heads)
.doWrite(listData);
return outputStream.toByteArray();
} catch (Exception e) {
throw new RuntimeException("生成Excel失败: " + e.getMessage(), e);
}
} catch (IOException e) {
e.printStackTrace();
}
return new byte[0];
}
/** /**
* 生成excel模板 * 生成excel模板
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment