package com.doumee.api.common;
|
|
import com.doumee.api.BaseController;
|
import com.doumee.biz.system.SystemDictDataBiz;
|
import com.doumee.core.constants.Constants;
|
import com.doumee.core.model.ApiResponse;
|
import com.doumee.core.utils.DateUtil;
|
import com.doumee.core.utils.aliyun.ALiYunUtil;
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParams;
|
import io.swagger.annotations.ApiOperation;
|
|
import java.io.*;
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.Comparator;
|
import java.util.HashMap;
|
import java.util.Iterator;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Scanner;
|
import java.util.UUID;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import net.lingala.zip4j.core.ZipFile;
|
import net.lingala.zip4j.model.FileHeader;
|
import net.sf.json.JSONObject;
|
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
|
|
/**
|
* 公共接口
|
* @author 江蹄蹄
|
* @date 2022/03/15 13:58
|
*/
|
@RestController
|
@RequestMapping("/public")
|
@Api(tags = "公共接口")
|
public class PublicController extends BaseController {
|
|
@Autowired
|
private SystemDictDataBiz systemDictDataBiz;
|
|
/**
|
* 上传
|
*
|
* @param folder
|
* @param request
|
* @param response
|
* @throws Exception
|
*/
|
@ApiOperation(value = "上传", notes = "上传", httpMethod = "POST", position = 6)
|
@ApiImplicitParams({
|
@ApiImplicitParam(name = "folder", value = "文件夹 头像:avatar 文件:upload ", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
|
})
|
@PostMapping(value = "/upload", headers = "content-type=multipart/form-data")
|
public ApiResponse uploadMobile(String folder, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
return upload(multipartRequest, response, "public/"+folder + "/",
|
systemDictDataBiz.queryByCode(Constants.OSS, Constants.BUCKETNAME).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.ACCESS_ID).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.ACCESS_KEY).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.RESOURCE_PATH).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.ENDPOINT).getCode());
|
}
|
|
@ApiOperation(value = "富文本文件上传", notes = "富文本文件上传", httpMethod = "POST", position = 6)
|
@ApiImplicitParams({
|
@ApiImplicitParam(name = "folder", value = "文件夹 头像:avatar 文件:upload ", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
|
})
|
@PostMapping(value = "/uploadRichText", headers = "content-type=multipart/form-data")
|
public ApiResponse uploadRichText( HttpServletRequest request, HttpServletResponse response) throws Exception {
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
return upload(multipartRequest, response, "public/upload/",
|
systemDictDataBiz.queryByCode(Constants.OSS, Constants.BUCKETNAME).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.ACCESS_ID).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.ACCESS_KEY).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.RESOURCE_PATH).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.ENDPOINT).getCode());
|
}
|
|
public ApiResponse upload(HttpServletRequest request, HttpServletResponse response, String folder, String bucketName,
|
String access_id, String access_key, String resourcePath, String endpoint) throws Exception {
|
response.setCharacterEncoding("UTF-8");
|
response.setContentType("text/html;charset=UTF-8");
|
Map<String, Object> context = new HashMap<>();
|
CommonsMultipartResolver multipartResovler = new CommonsMultipartResolver();
|
if (multipartResovler.isMultipart(request)) {
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
Iterator<String> it = multipartRequest.getFileNames();
|
while (it.hasNext()) {
|
MultipartFile file = multipartRequest.getFile((String) it.next());// file
|
// multipartRequest.getFile((String)
|
// it.next());
|
if (file != null) {
|
// 1、上传到服务器临时文件夹
|
String uploadFileName = file.getOriginalFilename();
|
String originname = uploadFileName;
|
if (originname.lastIndexOf("/") >= 0) {
|
originname = originname.substring(originname.lastIndexOf("/") + 1);
|
}
|
String nfix = "";// 后缀名
|
if ( StringUtils.isNotBlank(uploadFileName)) {
|
nfix = uploadFileName.substring(uploadFileName.lastIndexOf("."));
|
}
|
if ( StringUtils.equalsIgnoreCase(nfix, ".exe")) {
|
context.put("code", 0);
|
context.put("message", "对不起,文件格式\".exe\"上传有误!");
|
return ApiResponse.failed("对不起,文件格式\".exe\"上传有误!");
|
}
|
String nowDate = DateUtil.getNowShortDate();// 当前时间(年月日)
|
String fileName = UUID.randomUUID().toString() + nfix;
|
String tempFileName = nowDate + "/" + fileName;
|
String key = folder + tempFileName;// 文件名
|
ALiYunUtil obs = new ALiYunUtil(endpoint,access_id, access_key);
|
if (obs.uploadOnlineObject(file.getInputStream(),bucketName, key,null)) {
|
// 移动成功,返回文件名
|
// sendSuccessMessage(response, resourcePath+key);
|
context.put("error", 0);
|
context.put("code", 200);
|
context.put("success", true);
|
context.put("url", resourcePath + key);
|
context.put("imgaddr", tempFileName);
|
context.put("imgname", fileName);
|
context.put("originname", originname);
|
// ApiResponse.writerJson(response, context);
|
return ApiResponse.success(context);
|
} else {
|
// 移动失败
|
context.put("code", 0);
|
context.put("success", false);
|
context.put("message", "上传失败");
|
// ApiResponse.writerJson(response, context);
|
return ApiResponse.failed("上传失败");
|
}
|
}
|
}
|
}
|
context.put("code", 0);
|
context.put("message", "上传失败");
|
// ApiResponse.writerJson(response, context);
|
return ApiResponse.failed("上传失败");
|
}
|
|
|
/**
|
* 压缩包上传
|
*
|
* @param request
|
* @param response
|
* @throws Exception
|
*/
|
@ApiOperation(value = "压缩包上传", notes = "上传", httpMethod = "POST", position = 6)
|
@PostMapping(value = "/zipUpload", headers = "content-type=multipart/form-data")
|
public ApiResponse zipUpload(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
response.setCharacterEncoding("UTF-8");
|
response.setContentType("text/html;charset=UTF-8");
|
Map<String, Object> context = new HashMap<>();
|
CommonsMultipartResolver multipartResovler = new CommonsMultipartResolver();
|
if (multipartResovler.isMultipart(request)) {
|
Iterator<String> it = multipartRequest.getFileNames();
|
while (it.hasNext()) {
|
MultipartFile file = multipartRequest.getFile((String) it.next());// file
|
// it.next());
|
if (file != null) {
|
// 1、上传到服务器临时文件夹
|
String uploadFileName = file.getOriginalFilename();
|
String originname = uploadFileName;
|
if (originname.lastIndexOf("/") >= 0) {
|
originname = originname.substring(originname.lastIndexOf("/") + 1);
|
}
|
String nfix = "";// 后缀名
|
if ( StringUtils.isNotBlank(uploadFileName)) {
|
nfix = uploadFileName.substring(uploadFileName.lastIndexOf("."));
|
}
|
String uuid = UUID.randomUUID().toString();
|
String fileName = uuid + nfix;
|
File newFile = new File( systemDictDataBiz.queryByCode(Constants.OSS,Constants.TESTCASE_UPLOAD_PATH).getCode() +"/"+fileName);
|
file.transferTo(newFile);
|
return this.Uncompress(systemDictDataBiz.queryByCode(Constants.OSS,Constants.TESTCASE_UPLOAD_PATH).getCode() +"/"+fileName , uuid);
|
}
|
}
|
}
|
return ApiResponse.failed("上传数据文件异常");
|
}
|
|
|
public ApiResponse Uncompress(String filePath,String uuid) {
|
Map<String,Object> test_cases = new LinkedHashMap<>();
|
String fileSavePath = filePath.replace(".zip","")+"/";
|
try {
|
File zipFile = new File(filePath);
|
ZipFile zFile = new ZipFile(zipFile);// 首先创建ZipFile指向磁盘上的.zip文件
|
zFile.setFileNameCharset("GBK");
|
File destDir = new File(fileSavePath);// 解压目录
|
zFile.extractAll(fileSavePath); // 将文件抽出到解压目录(解压)
|
List<net.lingala.zip4j.model.FileHeader > headerList = zFile.getFileHeaders();
|
List<File> extractedFileList= new ArrayList<File>();
|
for(FileHeader fileHeader : headerList) {
|
if (!fileHeader.isDirectory()) {
|
System.out.println(fileHeader.getFileName());
|
extractedFileList.add(new File(destDir,fileHeader.getFileName()));
|
}
|
}
|
|
File [] extractedFiles = new File[extractedFileList.size()];
|
extractedFileList.toArray(extractedFiles);
|
Map<String,Object> resultMap = new HashMap<>();
|
List<Map<String,Object>> resultList = new ArrayList<>();
|
List<Map<String,String>> inFileList = new ArrayList<>();
|
List<Map<String,String>> outFileList = new ArrayList<>();
|
Integer inNum = 0;
|
Integer outNum = 0;
|
//处理解压文件 文件名称(无后缀)、文件全名称、文件路径
|
for(File f:extractedFileList){
|
String fileName = f.getName();
|
String destDirFilePath = f.getAbsolutePath();
|
if(fileName.indexOf(".in")>=0){
|
inNum = inNum + 1;
|
Map<String,String> inFileMap = new HashMap<>();
|
inFileMap.put("fileName",fileName);
|
inFileMap.put("destDirFilePath",destDirFilePath);
|
inFileMap.put("checkName",fileName.replace(".in",""));
|
inFileList.add(inFileMap);
|
}else if(fileName.indexOf(".out")>=0){
|
outNum = outNum + 1 ;
|
Map<String,String> outFileMap = new HashMap<>();
|
outFileMap.put("fileName",fileName);
|
outFileMap.put("destDirFilePath",destDirFilePath);
|
outFileMap.put("checkName",fileName.replace(".out",""));
|
outFileList.add(outFileMap);
|
}else {
|
continue;
|
}
|
}
|
//输入输出文件数量不一致,返回异常
|
if(inNum != outNum || inNum == 0 ){
|
return ApiResponse.failed("输入文件与输出文件数量不一致");
|
}
|
//计算平均分值 默认总分 100分 若存在余数,向上取整
|
int avgScore = 100/inFileList.size();
|
if(100 % inFileList.size() > 0){
|
avgScore = avgScore + 1 ;
|
}
|
int index = 1;
|
//判断输入输出文件名称是否对应,不对应 提示错误信息
|
|
|
|
|
Collections.sort(inFileList, new Comparator<Map<String,String>>() {
|
@Override
|
public int compare(Map<String,String> o1, Map<String,String> o2) {
|
if(Integer.valueOf(o1.get("checkName")) > Integer.valueOf(o2.get("checkName"))){
|
return 1;
|
}else
|
if(Integer.valueOf(o1.get("checkName")) < Integer.valueOf(o2.get("checkName"))){
|
return -1;
|
}
|
return Integer.valueOf(o2.get("checkName")).compareTo(Integer.valueOf(o1.get("checkName")));
|
}
|
});
|
|
|
for (Map<String,String> inMap:inFileList) {
|
//最终返回行数据
|
Map<String,Object> resultLineMap = new HashMap<>();
|
resultLineMap.put("input_name",inMap.get("fileName"));
|
resultLineMap.put("score",avgScore);
|
boolean isCheck = false;
|
for (Map<String,String> outMap:outFileList) {
|
if (inMap.get("checkName").equals(outMap.get("checkName"))){
|
resultLineMap.put("output_name",outMap.get("fileName"));
|
Map<String,Object> test_cases_data = new HashMap<>();
|
test_cases_data.put("stripped_output_md5",DigestUtils.md5Hex(readFileContent(fileSavePath + outMap.get("fileName"))));
|
File inFile = new File(inMap.get("destDirFilePath"));
|
File outFile = new File(outMap.get("destDirFilePath"));
|
test_cases_data.put("input_size",inFile.length());
|
test_cases_data.put("output_size",outFile.length());
|
test_cases_data.put("input_name",inMap.get("fileName"));
|
test_cases_data.put("output_name",outMap.get("fileName"));
|
test_cases.put(Integer.toString(index),test_cases_data);
|
isCheck = true;
|
break;
|
}
|
}
|
if(!isCheck){
|
return ApiResponse.failed("未查询到输入文件【" + inMap.get("fileName") +"】对应输出文件");
|
}
|
resultList.add(resultLineMap);
|
index = index + 1 ;
|
}
|
String infoFilePath = fileSavePath+"info";
|
//info文件创建
|
File infoFile = new File(infoFilePath);
|
infoFile.createNewFile();
|
//info文件写入文件
|
Map<String,Object> infoMap = new HashMap<>();
|
infoMap.put("spj",false);
|
infoMap.put("test_cases",test_cases);
|
writeFileContent(infoFilePath, JSONObject.fromObject(infoMap).toString());
|
resultMap.put("dataList",resultList);
|
resultMap.put("test_case_id",uuid);
|
//删除上传的zip文件(不需要)
|
// zipFile.delete();
|
//开始异步上传到评测机的ftp服务器
|
// judgeServerService.startFtpUpload(fileSavePath);
|
return ApiResponse.success(resultMap);
|
}catch(Exception e) {
|
return ApiResponse.failed("文件解压异常");
|
}
|
}
|
|
public static String readFileContent(String filePath){
|
StringBuilder sbd = new StringBuilder();
|
try (Scanner sc = new Scanner(new FileReader(filePath))) {
|
while (sc.hasNextLine()) { //按行读取字符串
|
sbd.append(sc.nextLine()+"\n");
|
}
|
}catch (Exception e){
|
return "未读取到文件内容";
|
}
|
String str =sbd.toString();
|
if(str.endsWith("\n")&& str.length()>0){
|
//去除末尾空白换行
|
str = str.substring(0,str.length()-1);
|
}
|
return str.trim();
|
}
|
|
|
|
|
/**
|
* 向文件中写入内容
|
*
|
* @param filepath 文件路径与名称
|
* @param newstr 写入的内容
|
* @return
|
* @throws IOException
|
*/
|
public static boolean writeFileContent(String filepath, String newstr) throws IOException {
|
Boolean bool = false;
|
String filein = newstr + "\r\n";//新写入的行,换行
|
// String temp = "";
|
// FileInputStream fis = null;
|
// InputStreamReader isr = null;
|
// BufferedReader br = null;
|
// FileOutputStream fos = null;
|
PrintWriter pw = null;
|
try {
|
File file = new File(filepath);//文件路径(包括文件名称)
|
//将文件读入输入流
|
/* fis = new FileInputStream(file);
|
isr = new InputStreamReader(fis);
|
br = new BufferedReader(isr);
|
//文件原有内容
|
for (int i = 0; (temp = br.readLine()) != null; i++) {
|
buffer.append(temp);
|
// 行与行之间的分隔符 相当于“\n”
|
buffer = buffer.append(System.getProperty("line.separator"));
|
}
|
buffer.append(filein);*/
|
StringBuffer buffer = new StringBuffer(filein);
|
// fos = new FileOutputStream(file);
|
pw = new PrintWriter(file);
|
pw.write(buffer.toString().toCharArray());
|
pw.flush();
|
bool = true;
|
} catch (Exception e) {
|
// TODO: handle exception
|
e.printStackTrace();
|
} finally {
|
//不要忘记关闭
|
if (pw != null) {
|
pw.close();
|
}
|
/*
|
if (fos != null) {
|
fos.close();
|
}
|
if (br != null) {
|
br.close();
|
}
|
if (isr != null) {
|
isr.close();
|
}
|
if (fis != null) {
|
fis.close();
|
}*/
|
}
|
return bool;
|
}
|
|
|
/*
|
public ApiResponse uploadBatchFile(HttpServletResponse response, String folder, String bucketName,
|
String access_id, String access_key, String resourcePath, String endpoint,MultipartFile[] files) throws Exception {
|
response.setCharacterEncoding("UTF-8");
|
response.setContentType("text/html;charset=UTF-8");
|
Map<String,Object> resultMap = new HashMap<>();
|
List<Map<String,Object>> listMap = new ArrayList<>();
|
if (null != files && files.length > 0) {
|
//用于判断文件个数
|
final int length = files.length;
|
for (MultipartFile file : files) {
|
final String originalFilename = file.getOriginalFilename();
|
assert originalFilename != null;
|
// 1、上传到服务器临时文件夹
|
String uploadFileName = file.getOriginalFilename();
|
String originname = uploadFileName;
|
if (originname.lastIndexOf("/") >= 0) {
|
originname = originname.substring(originname.lastIndexOf("/") + 1);
|
}
|
String nfix = "";// 后缀名
|
if ( StringUtils.isNotBlank(uploadFileName)) {
|
nfix = uploadFileName.substring(uploadFileName.lastIndexOf("."));
|
}
|
Map<String, Object> context = new HashMap<>();
|
if ( StringUtils.equalsIgnoreCase(nfix, ".exe")) {
|
context.put("code", 0);
|
context.put("message", "对不起,文件格式\".exe\"上传有误!");
|
return ApiResponse.failed("对不起,文件格式\".exe\"上传有误!");
|
}
|
String nowDate = DateUtil.getNowShortDate();// 当前时间(年月日)
|
String fileName = UUID.randomUUID().toString() + nfix;
|
String tempFileName = nowDate + "/" + fileName;
|
String key = folder + tempFileName;// 文件名
|
ALiYunUtil obs = new ALiYunUtil(endpoint,access_id, access_key);
|
if (obs.uploadOnlineObject(file.getInputStream(),bucketName, key,null)) {
|
// 移动成功,返回文件名
|
// sendSuccessMessage(response, resourcePath+key);
|
context.put("error", 0);
|
context.put("code", 200);
|
context.put("success", true);
|
context.put("url", resourcePath + key);
|
context.put("imgaddr", tempFileName);
|
context.put("imgname", fileName);
|
context.put("originname", originname);
|
} else {
|
// 移动失败
|
resultMap.put("code", 0);
|
resultMap.put("success", false);
|
resultMap.put("message", "上传失败");
|
}
|
listMap.add(context);
|
}
|
resultMap.put("fileList",listMap);
|
return ApiResponse.success(resultMap);
|
}
|
return ApiResponse.failed("上传失败");
|
}
|
|
@ApiOperation(value = "富文本文件上传", notes = "富文本文件上传", httpMethod = "POST", position = 6)
|
@PostMapping(value = "/uploadBatch", headers = "content-type=multipart/form-data")
|
public void uploadBatch( HttpServletRequest request, HttpServletResponse response,MultipartFile[] files) throws Exception {
|
uploadBatchFile(response, "public/upload/",
|
systemDictDataBiz.queryByCode(Constants.OSS, Constants.BUCKETNAME).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.ACCESS_ID).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.ACCESS_KEY).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.RESOURCE_PATH).getCode(),
|
systemDictDataBiz.queryByCode(Constants.OSS,Constants.ENDPOINT).getCode(),files);
|
}*/
|
|
}
|