Commit abb0e9de authored by liqin's avatar liqin 💬

bug fixed

parent 76fd4dcf
......@@ -147,10 +147,10 @@ public class FastDFSUtils {
return new int[]{0, 0};
}
private static ByteArrayOutputStream translateToByteArray(InputStream inputStream) throws IOException {
public static InputStream translateToByteArray(InputStream inputStream) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(inputStream, out);
return out;
return new ByteArrayInputStream(out.toByteArray());
}
// private static class UploadFileSender implements UploadCallback {
......
......@@ -3,7 +3,7 @@ package cn.wisenergy.chnmuseum.party.common.mybatis;
public class MysqlGenerator {
private static final String[] tableNames = new String[]{
"copyright_owner_board_cat"
"asset"
};
// private static final String projectPath = "D:\\develop\\Project\\chnmuseum-party";
private static final String projectPath = "/opt/ss";
......
package cn.wisenergy.chnmuseum.party.common.util;
import java.util.LinkedList;
import java.util.List;
/**
* Find LCS(Longest Common Substring) of N strings (N>=2)
* <p>
* Copyright (c) 2011 ljs (http://blog.csdn.net/ljsspace/)
* Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
* </p>
*
* @author ljs
* 2011-06-29
*/
public class LCSUtil {
private static class SuffixNode {
private String key;
private List<SuffixNode> children = new LinkedList<>();
//use "#" for terminal char
private boolean terminal;
public SuffixNode() {
this.key = "";
}
public SuffixNode(String key) {
this.key = key;
}
@Override
public String toString() {
return this.key + (this.terminal ? "#" : "") + "(" + children.size() + ")";
}
}
private SuffixNode root;
private final String text;
//terminators should be ordered according to input strings
private final char[] terminators;
public LCSUtil(String text, char[] terminators) {
this.text = text;
this.terminators = terminators;
}
private void insert(SuffixNode currNode, String key, int startIndex) throws Exception {
boolean done = false;
for (int i = 0; i < currNode.children.size(); i++) {
SuffixNode child = currNode.children.get(i);
//use min(child.key.length, key.length)
int len = Math.min(child.key.length(), key.length());
int j = 0;
for (; j < len; j++) {
if (key.charAt(j) != child.key.charAt(j)) {
break;
}
}
if (j == 0) {
//this child doesn't match any character with the new key
//order keys by lexi-order
if (key.charAt(0) < child.key.charAt(0)) {
//e.g. child="e" (currNode="abc")
// abc abc
// / / =========> / | /
// e f insert "c" c# e f
SuffixNode node = new SuffixNode(key);
currNode.children.add(i, node);
node.terminal = true;
done = true;
break;
}
} else {
//current child's key partially matches with the new key; 0<j<=len
if (j == len) {
if (key.length() == child.key.length()) {
if (child.terminal) {
throw new Exception("Duplicate Key is found when insertion!");
} else {
//e.g. child="ab"
// ab ab#
// / / =========> / /
// e f insert "ab" e f
child.terminal = true;
}
} else if (key.length() > child.key.length()) {
//e.g. child="ab#"
// ab# ab#
// / / ==========> / | /
// e f insert "abc" c# e f
String subkey = key.substring(j);
//recursion
insert(child, subkey, startIndex + j);
} else { //key.length()<child.key.length()
//e.g. child="abc#"
// abc# ab#
// / / =========> /
// e f insert "ab" c#
// / /
// e f
String childSubkey = child.key.substring(j); //c
SuffixNode subChildNode = new SuffixNode(childSubkey);
subChildNode.terminal = child.terminal;
subChildNode.children = child.children; //inherited from parent
child.key = key; //ab
child.terminal = true; //ab#
child.children = new LinkedList<>();
child.children.add(subChildNode);
}
} else {//0<j<len
//e.g. child="abc#"
// abc# ab
// / / ==========> / /
// e f insert "abd" c# d#
// / /
// e f
//split at j
String childSubkey = child.key.substring(j); //c
String subkey = key.substring(j); //d
SuffixNode subChildNode = new SuffixNode(childSubkey);
subChildNode.terminal = child.terminal;
subChildNode.children = child.children; //inherited from parent
//update child's key
child.key = child.key.substring(0, j);
//child is not terminal now due to split, it is inherited by subChildNode
child.terminal = false;
//Note: no need to merge subChildNode
SuffixNode node = new SuffixNode(subkey);
node.terminal = true;
child.children = new LinkedList<>();
if (subkey.charAt(0) < childSubkey.charAt(0)) {
child.children.add(node);
child.children.add(subChildNode);
} else {
child.children.add(subChildNode);
child.children.add(node);
}
}
done = true;
break;
}
}
if (!done) {
SuffixNode node = new SuffixNode(key);
node.terminal = true;
currNode.children.add(node);
}
}
public void insert(String suffix, int startIndex) throws Exception {
if (suffix == null || suffix.length() == 0) {
return;
}
if (root == null) {
root = new SuffixNode();
}
insert(root, suffix, startIndex);
}
//build a suffix-tree for a string of text
public void buildSuffixTree() throws Exception {
for (int i = 0; i < text.length(); i++) {
this.insert(text.substring(i), i);
}
}
//for test purpose only
public void printTree() {
this.print(0, this.root);
}
private void print(int level, SuffixNode node) {
for (int i = 0; i < level; i++) {
System.out.format(" ");
}
System.out.format("|");
for (int i = 0; i < level; i++) {
System.out.format("-");
}
if (node.terminal) {
System.out.format("%s#%n", node.key);
} else {
System.out.format("%s%n", node.key);
}
for (SuffixNode child : node.children) {
print(level + 1, child);
}
}
public String findLCS() {
return findLCS(root);
}
//return the longest substring starting with current node (but not including currNode.key)
private String findLCS(SuffixNode currNode) {
int maxDepth = currNode.key.length();
int currDepth = currNode.key.length();
String longestSubstrSuffix = "";
for (int i = 0; i < currNode.children.size(); i++) {
SuffixNode child = currNode.children.get(i);
if (!child.terminal) {
int depth = currDepth + child.key.length();
//terminators are unique, so terminal child is excluded
boolean containsTerminators = containTerminators(child);
if (containsTerminators) {
if (depth > maxDepth) {
maxDepth = depth;
longestSubstrSuffix = child.key;
}
String longestChildSubstrSuffix = findLCS(child);
if (longestChildSubstrSuffix.length() > 0) { //not a part of LCS if longestChildSubstrSuffix's lenght is 0
int maxChildDepth = longestChildSubstrSuffix.length() + depth;
if (maxChildDepth > maxDepth) {
maxDepth = maxChildDepth;
//the substring is relative to currNode
longestSubstrSuffix = child.key + longestChildSubstrSuffix;
}
}
}
}
}
return longestSubstrSuffix;
}
private boolean containTerminators(SuffixNode currNode) {
boolean[] done = new boolean[terminators.length];
return containTerminators(currNode, done);
}
private boolean containTerminators(SuffixNode currNode, boolean[] done) {
boolean allDone = false;
for (int i = 0; i < currNode.children.size(); i++) {
SuffixNode child = currNode.children.get(i);
if (child.terminal) {
//Note: here the order of terminator is important
for (int j = 0; j < terminators.length; j++) {
int pos = child.key.indexOf(terminators[j]);
if (pos >= 0) {
done[j] = true;
break;
}
}
} else {
containTerminators(child, done);
}
allDone = true;
for (int j = 0; j < done.length; j++) {
if (!done[j]) {
allDone = false;
break;
}
}
if (allDone) {
break;
}
}
return allDone;
}
// public static void main(String[] args) throws Exception {
// System.out.println("****************************");
// System.out.format("LCS for 3 strings:{abc,bcabca,aabcf}%n");
// String text = "abc$bcabca@aabcf%";
// LCSUtil strie = new LCSUtil(text, new char[]{'$', '@', '%'});
// strie.buildSuffixTree();
// //strie.printTree();
//
// String longestSubstr = strie.findLCS();
// System.out.format("%s%n", longestSubstr);
//
//
// System.out.println("****************************");
// System.out.format("LCS for 3 strings:{abcd,bcca,aabc}%n");
// text = "abcd$bcca@aabc%";
// strie = new LCSUtil(text, new char[]{'$', '@', '%'});
// strie.buildSuffixTree();
// //strie.printTree();
//
// longestSubstr = strie.findLCS();
// System.out.format("%s%n", longestSubstr);
//
//
// System.out.println("****************************");
// System.out.format("LCS for 2 strings:{asdfldkjxlfjax123456789abckljddfdfe123456789ees, xsdldkjalfla123456789abcfleur123456789ljafa}%n");
// text = "asdfldkjxlfjax123456789abckljddfdfe123456789ees$xsdldkjalfla123456789abcfleur123456789ljafa@";
// strie = new LCSUtil(text, new char[]{'$', '@'});
// strie.buildSuffixTree();
// //strie.printTree();
//
// longestSubstr = strie.findLCS();
// System.out.format("%s%n", longestSubstr);
//
// System.out.println("****************************");
// System.out.format("LCS for 5 strings:{abcd,abce,abd,bdess,ace}%n");
// text = "abcd$abce@abd%bdess&ace#";
// strie = new LCSUtil(text, new char[]{'$', '@', '%', '&', '#'});
// strie.buildSuffixTree();
// //strie.printTree();
//
// longestSubstr = strie.findLCS();
// System.out.format("%s%n", longestSubstr);
// }
}
......@@ -37,10 +37,14 @@ public class Asset implements Serializable {
@TableField("ref_item_id")
private String refItemId;
@ApiModelProperty("文件名")
@ApiModelProperty("原始文件名")
@TableField("file_name")
private String fileName;
@ApiModelProperty("加密后文件名")
@TableField("file_name_crypto")
private String fileNameCrypto;
@ApiModelProperty("扩展名")
@TableField("file_ext_name")
private String fileExtName;
......@@ -61,6 +65,10 @@ public class Asset implements Serializable {
@TableField("file_url")
private String fileUrl;
@ApiModelProperty("加密链接")
@TableField("file_url_crypto")
private String fileUrlCrypto;
@ApiModelProperty("视频缩略图")
@TableField("thumbnail")
private String thumbnail;
......@@ -73,10 +81,14 @@ public class Asset implements Serializable {
@TableField("md5")
private String md5;
@ApiModelProperty(value = "crc32", hidden = true)
@ApiModelProperty(hidden = true)
@TableField("crc32")
private Long crc32;
@ApiModelProperty(hidden = true)
@TableField("video_content_name")
private String videoContentName;
@ApiModelProperty("创建日期")
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
......
......@@ -7,7 +7,6 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
......@@ -42,8 +41,6 @@ public class VideoContent implements Serializable {
@ApiModelProperty("视频内容名称")
@TableField("name")
@NotBlank(message = "视频内容名称不能为空", groups = {Add.class, Update.class})
@Length(max = 20, message = "视频内容名称字数不能超过20")
private String name;
@ApiModelProperty("视频内容版权方ID")
......
......@@ -4,7 +4,9 @@ import cn.hutool.core.util.ArrayUtil;
import cn.wisenergy.chnmuseum.party.common.dfs.FastDFSUtils;
import cn.wisenergy.chnmuseum.party.common.enums.*;
import cn.wisenergy.chnmuseum.party.common.mvc.InterfaceException;
import cn.wisenergy.chnmuseum.party.common.util.LCSUtil;
import cn.wisenergy.chnmuseum.party.common.util.TimeUtils;
import cn.wisenergy.chnmuseum.party.common.video.VideoEncryptUtil;
import cn.wisenergy.chnmuseum.party.common.vo.BatchUploadResVO;
import cn.wisenergy.chnmuseum.party.common.vo.ImageUploadResult;
import cn.wisenergy.chnmuseum.party.model.Asset;
......@@ -20,6 +22,7 @@ import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.context.annotation.Scope;
......@@ -28,6 +31,8 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
......@@ -51,6 +56,10 @@ public class FileUploadController extends BaseController {
private static final String[] AUDIO_TYPE = new String[]{"MP3", "AAC", "WMA", "FLAC", "RM", "OGG"};
private static final String[] VIDEO_TYPE = new String[]{"MP4", "FLV", "MPEG", "MPG", "MOV"};
private static final String[] DOC_TYPE = new String[]{"PDF", "DOC", "DOCX", "PPT", "PPTX"};
private static final char[] SPLITTER_CHAR_2 = new char[]{'@', '#'};
private static final char[] SPLITTER_CHAR_3 = new char[]{'@', '#', '$'};
private static final char[] SPLITTER_CHAR_4 = new char[]{'@', '#', '$', '%'};
private static final char[] SPLITTER_CHAR_5 = new char[]{'@', '#', '$', '%', '&'};
private static final String[] DATUM_TYPE = ArrayUtil.addAll(DOC_TYPE, IMAGE_TYPE, VIDEO_TYPE);
@Resource
......@@ -409,7 +418,6 @@ public class FileUploadController extends BaseController {
return getFailResult("目前仅支持" + String.join("、", VIDEO_TYPE) + "格式");
}
}
final boolean matchChinese = Arrays.stream(files).anyMatch(s -> Objects.requireNonNull(s.getOriginalFilename()).contains("汉语"));
if (!matchChinese) {
return getFailResult("文件必须包含汉语视频");
......@@ -417,6 +425,49 @@ public class FileUploadController extends BaseController {
if (files.length > 5) {
return getFailResult("一种语言只能对应一个文件,只能上传包含5种语言的视频");
}
String videoContentName = null;
String text;
LCSUtil strie = null;
final String[] fileBaseNameArray = Arrays.stream(files).map(x -> FilenameUtils.getBaseName(x.getOriginalFilename())).toArray(String[]::new);
switch (fileBaseNameArray.length) {
case 1:
videoContentName = fileBaseNameArray[0];
break;
case 2:
text = fileBaseNameArray[0] + SPLITTER_CHAR_2[0] + fileBaseNameArray[1] + SPLITTER_CHAR_2[1];
strie = new LCSUtil(text, SPLITTER_CHAR_2);
break;
case 3:
text = fileBaseNameArray[0] + SPLITTER_CHAR_3[0] + fileBaseNameArray[1] + SPLITTER_CHAR_3[1] + fileBaseNameArray[2] + SPLITTER_CHAR_3[2];
strie = new LCSUtil(text, SPLITTER_CHAR_3);
break;
case 4:
text = fileBaseNameArray[0] + SPLITTER_CHAR_4[0] + fileBaseNameArray[1] + SPLITTER_CHAR_4[1] + fileBaseNameArray[2] + SPLITTER_CHAR_4[2] + fileBaseNameArray[3] + SPLITTER_CHAR_4[3];
strie = new LCSUtil(text, SPLITTER_CHAR_4);
break;
case 5:
text = fileBaseNameArray[0] + SPLITTER_CHAR_5[0] + fileBaseNameArray[1] + SPLITTER_CHAR_5[1] + fileBaseNameArray[2] + SPLITTER_CHAR_5[2] + fileBaseNameArray[3] + SPLITTER_CHAR_5[3] + fileBaseNameArray[4] + SPLITTER_CHAR_5[4];
strie = new LCSUtil(text, SPLITTER_CHAR_5);
break;
default:
break;
}
if (strie != null) {
strie.buildSuffixTree();
videoContentName = strie.findLCS();
if (StringUtils.isBlank(videoContentName)) {
return getFailResult("请修改你的文件名并保持前缀一致后再上传");
} else {
videoContentName = StringUtils.removeEnd(videoContentName.trim(), "{");
videoContentName = StringUtils.removeEnd(videoContentName.trim(), "[");
videoContentName = StringUtils.removeEnd(videoContentName.trim(), "【");
videoContentName = StringUtils.removeEnd(videoContentName.trim(), "(");
videoContentName = StringUtils.removeEnd(videoContentName.trim(), "(");
videoContentName = StringUtils.removeEnd(videoContentName.trim(), "-");
videoContentName = StringUtils.removeEnd(videoContentName.trim(), "_");
videoContentName = StringUtils.removeEnd(videoContentName.trim(), "之");
}
}
int successCount = 0;
int failureCount = 0;
......@@ -447,13 +498,15 @@ public class FileUploadController extends BaseController {
handleList.add(handleResult);
continue;
}
final String baseName = FilenameUtils.getBaseName(originalFilename);
String extName = FilenameUtils.getExtension(originalFilename);
String finalExtName = extName;
boolean anyMatch = Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()));
if (anyMatch) {
if ("MPEG".equals(extName.toUpperCase()) || "MOV".equals(extName.toUpperCase())) {
extName = "mp4";
originalFilename = FilenameUtils.getBaseName(originalFilename) + "." + extName;
originalFilename = baseName + "." + extName;
}
String language = null;
final Set<MetaData> metaDataSet = new HashSet<>();
......@@ -475,9 +528,14 @@ public class FileUploadController extends BaseController {
metaDataSet.add(new MetaData("language", LanguageEnum.UYG.name()));
language = LanguageEnum.UYG.name();
}
String fileUrl = FastDFSUtils.uploadVideo(file.getInputStream(), file.getSize(), originalFilename, metaDataSet);
final Set<MetaData> fileMetaData = FastDFSUtils.getFileMetaData(fileUrl);
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
IOUtils.copy(file.getInputStream(), byteArrayOutputStream);
final String fileUrl = FastDFSUtils.uploadVideo(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), file.getSize(), originalFilename, metaDataSet);
metaDataSet.add(new MetaData("fileName", baseName + ".chnmuseum"));
final String fileUrlCrypto = FastDFSUtils.uploadVideo(VideoEncryptUtil.encrypt(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), VideoEncryptUtil.cipher), file.getSize(), baseName + ".chnmuseum", metaDataSet);
final Set<MetaData> fileMetaData = FastDFSUtils.getFileMetaData(fileUrlCrypto);
String md5 = fileMetaData.stream().filter(x -> "MD5".equals(x.getName())).map(MetaData::getValue).findFirst().get();
final FileInfo fileInfo = FastDFSUtils.getFileInfo(fileUrl);
final int crc32 = fileInfo.getCrc32();
final Asset one = this.assetService.getOne(Wrappers.<Asset>lambdaQuery().eq(Asset::getCrc32, (long) crc32).last(" limit 1"));
......@@ -485,14 +543,17 @@ public class FileUploadController extends BaseController {
final long fileSize = fileInfo.getFileSize();
final Asset asset = Asset.builder()
.fileName(originalFilename)
.fileNameCrypto(baseName + ".chnmuseum")
.fileExtName(extName)
.fileType(FileTypeEnum.VIDEO.name())
.fileSize(fileSize)
.fileUrl(fileUrl)
.fileUrlCrypto(fileUrlCrypto)
.fileCat(FileCatEnum.VIDEO_CONTENT.name())
.language(language)
.md5(md5)
.crc32((long) crc32)
.videoContentName(videoContentName)
.createTime(createTime)
.updateTime(createTime)
.build();
......
......@@ -79,6 +79,11 @@ public class VideoContentController extends BaseController {
asset.setFileCat(FileCatEnum.VIDEO_CONTENT.name());
asset.setRefItemId(videoContent.getId());
this.assetService.updateById(asset);
if (StringUtils.isBlank(videoContent.getName())) {
videoContent.setName(asset.getVideoContentName());
this.videoContentService.updateById(videoContent);
}
}
final Audit audit = Audit.builder()
......@@ -120,6 +125,12 @@ public class VideoContentController extends BaseController {
asset.setFileCat(FileCatEnum.VIDEO_CONTENT.name());
asset.setRefItemId(videoContent.getId());
this.assetService.updateById(asset);
if (StringUtils.isBlank(videoContent.getName())) {
videoContent.setName(asset.getVideoContentName());
this.videoContentService.updateById(videoContent);
}
collect.remove(videoFileId);
}
collect.forEach((k, v) -> this.assetService.removeById(k));
......
......@@ -7,23 +7,26 @@
<id column="id" property="id"/>
<result column="ref_item_id" property="refItemId"/>
<result column="file_name" property="fileName"/>
<result column="file_name_crypto" property="fileNameCrypto"/>
<result column="file_ext_name" property="fileExtName"/>
<result column="file_type" property="fileType"/>
<result column="file_size" property="fileSize"/>
<result column="file_cat" property="fileCat"/>
<result column="file_size" property="fileSize"/>
<result column="file_url" property="fileUrl"/>
<result column="file_url_crypto" property="fileUrlCrypto"/>
<result column="thumbnail" property="thumbnail"/>
<result column="language" property="language"/>
<result column="md5" property="md5"/>
<result column="crc32" property="crc32"/>
<result column="video_content_name" property="videoContentName"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, ref_item_id, file_name, file_ext_name, file_type, file_size, file_cat, file_url, thumbnail, language, md5,
crc32, create_time, update_time
id, ref_item_id, file_name, file_name_crypto, file_ext_name, file_type, file_cat, file_size, file_url,
file_url_crypto, thumbnail, language, md5, crc32, video_content_name, create_time, update_time
</sql>
</mapper>
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