Commit 41dffba8 authored by yanzg's avatar yanzg

下载视频

parent ef174668
...@@ -3,6 +3,9 @@ package helper; ...@@ -3,6 +3,9 @@ package helper;
import com.yanzuoguang.util.helper.DesHelper; import com.yanzuoguang.util.helper.DesHelper;
import org.junit.Test; import org.junit.Test;
import java.nio.file.Path;
import java.nio.file.Paths;
public class TestDes { public class TestDes {
String pwd = "tubida@yanzuoguang@good@boy@!@#^%$"; String pwd = "tubida@yanzuoguang@good@boy@!@#^%$";
// String str = "{\"c\":\"64711099423332\",\"l\":1631524416,\"s\":\"671ec2998053b6de9b76bc8d09e00f1b\",\"t\":\"company-pangding-0000001\"}"; // String str = "{\"c\":\"64711099423332\",\"l\":1631524416,\"s\":\"671ec2998053b6de9b76bc8d09e00f1b\",\"t\":\"company-pangding-0000001\"}";
...@@ -15,4 +18,13 @@ public class TestDes { ...@@ -15,4 +18,13 @@ public class TestDes {
System.out.println(des.length()); System.out.println(des.length());
System.out.println(des); System.out.println(des);
} }
@Test
public void testPath(){
Path path = Paths.get("/etc/nginx/nginx.conf");
String serverPath = path.getParent().toString();
String name = path.getFileName().toFile().getName();
System.out.println(serverPath);
System.out.println(name);
}
} }
package com.yanzuoguang.cloud; package com.yanzuoguang.cloud;
import com.yanzuoguang.util.YzgError; import com.yanzuoguang.util.YzgError;
import com.yanzuoguang.util.exception.CodeException; import com.yanzuoguang.util.helper.DateHelper;
import com.yanzuoguang.util.helper.StringHelper; import com.yanzuoguang.util.helper.StringHelper;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Date;
/** /**
* 整个模块的所有配置信息 * 整个模块的所有配置信息
* *
...@@ -127,6 +129,21 @@ public class CloudConfig { ...@@ -127,6 +129,21 @@ public class CloudConfig {
return displayUrl; return displayUrl;
} }
/**
* 获取行记的显示的图片
*
* @return
*/
public String getTempFolder(String folder, Date date) {
return String.format("%s/%s/%s/%s",
folder,
DateHelper.getDateTimeString("yyyy", date),
DateHelper.getDateTimeString("MM", date),
DateHelper.getDateTimeString("dd", date)
);
}
/** /**
* 是否属于网关服务,网关服务不进行监控 * 是否属于网关服务,网关服务不进行监控
* *
......
package com.yanzuoguang.cloud.vo.req;
import com.yanzuoguang.util.vo.BaseVo;
import io.swagger.annotations.ApiModelProperty;
/**
* 加载文件
*
* @author 颜佐光
*/
public class YzgFileDownloadReqVo extends BaseVo {
/**
* 文件Id,用于后续文件下载
*/
@ApiModelProperty(notes = "文件Id,用于后续文件下载", position = 10)
private String fileId;
/**
* 公司Id,用于判断每个公司同一个人不能生成多次文件,同一个公司Id需要配置每日最大运行次数,默认每日为50
*/
@ApiModelProperty(notes = "公司Id,用于后续文件下载,同一个公司Id需要配置每日最大运行次数,默认为50", position = 20)
private String companyId;
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
public String getCompanyId() {
return companyId;
}
public void setCompanyId(String companyId) {
this.companyId = companyId;
}
}
package com.yanzuoguang.cloud.file; package com.yanzuoguang.cloud.file;
import com.rabbitmq.client.Channel; import com.rabbitmq.client.Channel;
import com.yanzuoguang.cloud.file.dao.YzgExcelService;
import com.yanzuoguang.cloud.vo.req.YzgFileCreateReqVo;
import com.yanzuoguang.cloud.vo.req.YzgFileStatusReqVo;
import com.yanzuoguang.mq.service.MqService; import com.yanzuoguang.mq.service.MqService;
import com.yanzuoguang.util.exception.CodeException; import com.yanzuoguang.util.exception.CodeException;
import com.yanzuoguang.util.helper.JsonHelper; import com.yanzuoguang.util.helper.JsonHelper;
import com.yanzuoguang.util.helper.StringHelper;
import com.yanzuoguang.util.log.Log; import com.yanzuoguang.util.log.Log;
import com.yanzuoguang.util.vo.file.YzgFileMoveReqVo; import com.yanzuoguang.util.vo.file.YzgFileMoveReqVo;
import com.yanzuoguang.util.vo.file.YzgFileVideoImageItemReqVo; import com.yanzuoguang.util.vo.file.YzgFileVideoImageItemReqVo;
import com.yanzuoguang.util.vo.file.YzgFileVideoImageReqVo; import com.yanzuoguang.util.vo.file.YzgFileVideoImageReqVo;
import org.springframework.amqp.core.Message; import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.*; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -23,35 +25,20 @@ import java.util.List; ...@@ -23,35 +25,20 @@ import java.util.List;
* 文件处理 * 文件处理
*/ */
@Component @Component
public class YzgFileConsumer implements InitializingBean, ApplicationContextAware { public class YzgFileConsumer implements InitializingBean {
@Autowired
private MqService mqService; private MqService mqService;
@Autowired
private YzgFileService fileService; private YzgFileService fileService;
@Autowired
private YzgFileProcedure fileProcedure; private YzgFileProcedure fileProcedure;
/** @Autowired
* Set the ApplicationContext that this object runs in. private YzgExcelService excelService;
* Normally this call will be used to initialize the object.
* <p>Invoked after population of normal bean properties but before an init callback such
* as {@link InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
*
* @param applicationContext the ApplicationContext object to be used by this object
* @throws ApplicationContextException in case of context initialization errors
* @throws BeansException if thrown by application context methods
* @see BeanInitializationException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
mqService = applicationContext.getBean(MqService.class);
fileService = applicationContext.getBean(YzgFileService.class);
fileProcedure = applicationContext.getBean(YzgFileProcedure.class);
}
/** /**
* Invoked by a BeanFactory after it has set all bean properties supplied * Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware). * (and satisfied BeanFactoryAware and ApplicationContextAware).
...@@ -184,4 +171,55 @@ public class YzgFileConsumer implements InitializingBean, ApplicationContextAwar ...@@ -184,4 +171,55 @@ public class YzgFileConsumer implements InitializingBean, ApplicationContextAwar
mqService.basicAck(message, channel); mqService.basicAck(message, channel);
} }
} }
/**
* 处理视频转换
*
* @param json
* @param message
* @param channel
*/
@RabbitListener(queues = {YzgFileProcedure.YZG_FILE_CREATE})
public void fileCreate(String json, Message message, Channel channel) {
YzgFileCreateReqVo fileReq = null;
try {
fileReq = JsonHelper.deserialize(json, YzgFileCreateReqVo.class);
if (StringHelper.isEmpty(fileReq.getFileId(), fileReq.getCallbackMQ())) {
return;
}
excelService.fileCreate(json, fileReq);
} catch (CodeException ex) {
Log.error(YzgFileConsumer.class, ex);
} catch (Exception ex) {
Log.error(YzgFileConsumer.class, ex);
fileProcedure.fileCreateDelay(json);
} finally {
mqService.basicAck(message, channel);
}
}
/**
* 处理视频转换
*
* @param json
* @param message
* @param channel
*/
@RabbitListener(queues = {YzgFileProcedure.YZG_FILE_STATUS})
public void fileStatus(String json, Message message, Channel channel) {
try {
YzgFileStatusReqVo fileReq = JsonHelper.deserialize(json, YzgFileStatusReqVo.class);
if (StringHelper.isEmpty(fileReq.getFileId(), fileReq.getFileStatus())) {
return;
}
excelService.updateStatus(fileReq);
} catch (CodeException ex) {
Log.error(YzgFileConsumer.class, ex);
} catch (Exception ex) {
Log.error(YzgFileConsumer.class, ex);
fileProcedure.fileStatus(json);
} finally {
mqService.basicAck(message, channel);
}
}
} }
...@@ -8,7 +8,6 @@ import com.yanzuoguang.util.MediaParameter; ...@@ -8,7 +8,6 @@ import com.yanzuoguang.util.MediaParameter;
import com.yanzuoguang.util.YzgError; import com.yanzuoguang.util.YzgError;
import com.yanzuoguang.util.cache.MemoryCache; import com.yanzuoguang.util.cache.MemoryCache;
import com.yanzuoguang.util.exception.CodeException; import com.yanzuoguang.util.exception.CodeException;
import com.yanzuoguang.util.helper.DateHelper;
import com.yanzuoguang.util.helper.FileHelper; import com.yanzuoguang.util.helper.FileHelper;
import com.yanzuoguang.util.helper.StringHelper; import com.yanzuoguang.util.helper.StringHelper;
import com.yanzuoguang.util.vo.file.*; import com.yanzuoguang.util.vo.file.*;
...@@ -89,7 +88,7 @@ public class YzgFileServiceImpl implements YzgFileService, ApplicationContextAwa ...@@ -89,7 +88,7 @@ public class YzgFileServiceImpl implements YzgFileService, ApplicationContextAwa
String saveFileName = StringHelper.getNewID() + ext; String saveFileName = StringHelper.getNewID() + ext;
// 获取临时文件路径 // 获取临时文件路径
String tempFolder = getTempFolder(folder); String tempFolder = cloudConfig.getTempFolder(folder, new Date());
String serverFolder = String.format("%s/%s", cloudConfig.getServerUrl(), tempFolder); String serverFolder = String.format("%s/%s", cloudConfig.getServerUrl(), tempFolder);
// 创建服务器路径 // 创建服务器路径
FileHelper.createDirectory(serverFolder); FileHelper.createDirectory(serverFolder);
...@@ -447,21 +446,6 @@ public class YzgFileServiceImpl implements YzgFileService, ApplicationContextAwa ...@@ -447,21 +446,6 @@ public class YzgFileServiceImpl implements YzgFileService, ApplicationContextAwa
} }
} }
/**
* 获取行记的显示的图片
*
* @return
*/
private String getTempFolder(String folder) {
String ret = String.format("%s/%s/%s/%s",
folder,
DateHelper.getDateTimeString("yyyy", new Date()),
DateHelper.getDateTimeString("MM", new Date()),
DateHelper.getDateTimeString("dd", new Date())
);
return ret;
}
private String checkFolder(String folderFrom) { private String checkFolder(String folderFrom) {
String folder = StringHelper.getFirst(folderFrom, "temp"); String folder = StringHelper.getFirst(folderFrom, "temp");
if (folder.contains("..")) { if (folder.contains("..")) {
......
package com.yanzuoguang.cloud.file.dao;
import com.yanzuoguang.cloud.CloudConfig;
import com.yanzuoguang.cloud.file.YzgFileProcedure;
import com.yanzuoguang.cloud.helper.HttpFileHelper;
import com.yanzuoguang.cloud.vo.YzgFileVo;
import com.yanzuoguang.cloud.vo.req.YzgFileCallbackReqVo;
import com.yanzuoguang.cloud.vo.req.YzgFileCreateReqVo;
import com.yanzuoguang.cloud.vo.req.YzgFileDownloadReqVo;
import com.yanzuoguang.cloud.vo.req.YzgFileStatusReqVo;
import com.yanzuoguang.util.exception.CodeException;
import com.yanzuoguang.util.exception.ExceptionHelper;
import com.yanzuoguang.util.helper.DateHelper;
import com.yanzuoguang.util.helper.JsonHelper;
import com.yanzuoguang.util.helper.StringHelper;
import com.yanzuoguang.util.vo.PageSizeData;
import com.yanzuoguang.util.vo.PageSizeReqVo;
import com.yanzuoguang.util.vo.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Date;
/**
* Excel文件操作服务
*
* @author 颜佐光
*/
@Component
public class YzgExcelService {
@Autowired
private CloudConfig cloudConfig;
@Autowired
private YzgFileDao fileDao;
@Autowired
private YzgFileProcedure fileProcedure;
/**
* 创建文件,不需要开启事务
*
* @param json
* @param fileReq
*/
public void fileCreate(String json, YzgFileCreateReqVo fileReq) {
try {
YzgFileVo load = fileDao.load(fileReq, YzgFileVo.class);
if (load == null) {
load = JsonHelper.to(fileReq, YzgFileVo.class);
fileDao.create(load);
}
// 生成回调参数
String serverFile = getServerPath(load);
YzgFileCallbackReqVo callbackReq = new YzgFileCallbackReqVo(
fileReq.getFileId(), fileReq.getCompanyId(),
fileReq.getCallbackMQ(), fileReq.getCallbackParameter(),
serverFile
);
// 判断文件状态
int fileStatus = StringHelper.toInt(load.getFileStatus());
switch (fileStatus) {
case YzgFileVo.FILE_STATUS_INIT:
if (fileDao.getUserCompanyCount(load) > fileReq.getCreateUserCompanyMax()) {
throw new CodeException("该用户在该公司当日生成文件达到最大次数");
}
if (fileDao.getCallbackCount(load) < fileReq.getCallBackMax()) {
fileProcedure.fileCallback(callbackReq);
}
// 等待15秒后再次发出请求,追踪文件进度
fileProcedure.fileCreateDelay(json);
break;
case YzgFileVo.FILE_STATUS_RELEASE:
fileProcedure.fileCallback(callbackReq);
// 等待15秒后再次发出请求,追踪文件进度
fileProcedure.fileCreateDelay(json);
break;
default:
return;
}
} catch (CodeException ex) {
if (fileReq != null && !StringHelper.isEmpty(fileReq.getFileId())) {
ResponseResult error = ExceptionHelper.getError(ex);
fileDao.updateStatus(new YzgFileStatusReqVo(fileReq.getFileId(), fileReq.getCompanyId(), error.getMessage()));
}
}
}
public void updateStatus(YzgFileStatusReqVo fileReq) {
fileDao.updateStatus(fileReq);
}
/**
* 获取文件数据
*
* @param req
* @param cls
* @param <T>
* @return
*/
public <T extends Object> PageSizeData<T> loadPage(PageSizeReqVo req, Class<T> cls) {
return fileDao.loadPage(req, cls);
}
/**
* 下载文件
*
* @param req
* @param response
* @throws IOException
*/
public void donwload(YzgFileDownloadReqVo req, HttpServletResponse response) throws IOException {
YzgFileVo load = fileDao.load(req, YzgFileVo.class);
if (load == null) {
throw new CodeException("文件不存在或者已经删除");
}
int fileStatus = StringHelper.toInt(load.getFileStatus());
if (fileStatus == YzgFileVo.FILE_STATUS_ERROR) {
throw new CodeException(load.getErrorMessage());
} else if (fileStatus != YzgFileVo.FILE_STATUS_OK) {
throw new CodeException("文件正在生成中");
}
String serverPath = getServerPath(load);
File file = new File(serverPath);
if (!file.exists()) {
throw new CodeException("文件已经被删除,或者服务器之间没有共享文件目录");
}
HttpFileHelper.localToDown(serverPath, load.getFileName() + ".xlsx", response);
}
private String getServerPath(YzgFileVo load) {
Date date = DateHelper.getDateTime(load.getCreateDate());
// 获取临时文件路径
String tempFolder = cloudConfig.getTempFolder(load.getCompanyId(), date);
return String.format("%s/%s/%s.xlsx", cloudConfig.getServerUrl(), tempFolder, load.getFileId());
}
}
...@@ -27,11 +27,11 @@ public class YzgFileDaoImpl extends BaseDaoImpl implements YzgFileDao, Initializ ...@@ -27,11 +27,11 @@ public class YzgFileDaoImpl extends BaseDaoImpl implements YzgFileDao, Initializ
" companyId VARCHAR(32) NOT NULL COMMENT '公司编号', " + " companyId VARCHAR(32) NOT NULL COMMENT '公司编号', " +
" companyName VARCHAR(100) NOT NULL DEFAULT '' COMMENT '公司名称', " + " companyName VARCHAR(100) NOT NULL DEFAULT '' COMMENT '公司名称', " +
" callbackMQ VARCHAR(100) NOT NULL DEFAULT '' COMMENT '功能点关键字,同一个callbackMQ的同时已开始的文件数不能超过3(可配置)', " + " callbackMQ VARCHAR(100) NOT NULL DEFAULT '' COMMENT '功能点关键字,同一个callbackMQ的同时已开始的文件数不能超过3(可配置)', " +
" callbackParameter LONGTEXT NOT NULL COMMENT '回调MQ参数', " + " callbackParameter LONGTEXT NOT NULL DEFAULT '' COMMENT '回调MQ参数', " +
" fileName VARCHAR(255) NOT NULL DEFAULT '' COMMENT '文件名称,用于下载时显示文件名,需要下载时用户输入或自动生成', " + " fileName VARCHAR(255) NOT NULL DEFAULT '' COMMENT '文件名称,用于下载时显示文件名,需要下载时用户输入或自动生成', " +
" fileStatus INT NOT NULL DEFAULT 0 COMMENT '文件状态:0-未开始,1-已开始,2-导出成功,3-导出失败', " + " fileStatus INT NOT NULL DEFAULT 0 COMMENT '文件状态:0-未开始,1-已开始,2-导出成功,3-导出失败', " +
" fileRow INT NOT NULL DEFAULT 0 COMMENT '导出行数', " + " fileRow INT NOT NULL DEFAULT 0 COMMENT '导出行数', " +
" errorMessage VARCHAR(255) NOT NULL DEFAULT '' COMMENT '错误消息', " + " errorMessage LONGTEXT NOT NULL DEFAULT '' COMMENT '错误消息', " +
" downloadDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '下载时间', " + " downloadDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '下载时间', " +
" downloadUserId VARCHAR(32) NOT NULL COMMENT '下载人', " + " downloadUserId VARCHAR(32) NOT NULL COMMENT '下载人', " +
" createDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', " + " createDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', " +
......
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