开发临时文件上传功能,todo 未完成
parent
7297bfa9e3
commit
2f8b923ae3
@ -0,0 +1,49 @@
|
||||
package me.zhengjie.common.http;
|
||||
|
||||
/**
|
||||
* FileName: ResponseCode
|
||||
* Author: x
|
||||
* Date: 2019/12/11 20:30
|
||||
* Description: 自定义Response响应返回体 -> 这边采用的是
|
||||
* History:
|
||||
* <author> <time> <version> <desc>
|
||||
* x 2019/12/11 v 1.0 创建此文件
|
||||
*/
|
||||
public enum ResponseCode {
|
||||
|
||||
SUCCESS(0,"SUCCESS"),
|
||||
ERROR(1,"ERROR"),
|
||||
|
||||
// 成功的一些特殊提示
|
||||
SUCCESS_ONCE_LINK_MSG(0,"下载成功,一次性链接已经失效"),
|
||||
// 通用请求参数校验
|
||||
ILLEGAL_ARGUMENT(1,"请求参数格式错误"),
|
||||
EMPTY_ARGUMENT(1,"请求参数为空"),
|
||||
NO_MATCH_ARGUMENT_SET(1,"不能满足要求的参数设置"),
|
||||
NO_FILE_INPUT(1,"没有文件输入"),
|
||||
// 特殊需要进行前端返回说明的参数定义
|
||||
TASK_NAME_IS_EXIST(1,"任务名称已经存在"),
|
||||
ONCE_LINK_MSG_ERROR(1,"链接失效,下载文件失败~"),
|
||||
// 请求结果性的错误
|
||||
NODATA_ERROR(1,"查询结果为空"),
|
||||
TASK_BUILD_ERROR(1,"任务建立失败"),
|
||||
NO_RELEVANT_CONTENT_WAS_FOUND(1,"未查询到相关内容"),
|
||||
DECRYPT_ERROR(1,"解密错误,请联系我");
|
||||
|
||||
|
||||
private final int code;
|
||||
private final String desc;
|
||||
|
||||
ResponseCode(int code, String desc){
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package me.zhengjie.common.json;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用于进行一次性链接返回的转换Json体
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class OnceLinkMsgJsonContent implements Serializable {
|
||||
|
||||
/**
|
||||
* 链接地址
|
||||
*/
|
||||
private String onceLink;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package me.zhengjie.common.json;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用于向下游进行推送的Json转换实体 - 用于外呼端通用
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class PushDBJsonContent {
|
||||
|
||||
/**
|
||||
* 活动id
|
||||
*/
|
||||
private Long actId;
|
||||
|
||||
/**
|
||||
* 活动名称
|
||||
*/
|
||||
private String actName;
|
||||
|
||||
/**
|
||||
* 外呼号码
|
||||
*/
|
||||
private List<Client> clientList;
|
||||
|
||||
|
||||
/**
|
||||
* 包装类
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Client{
|
||||
/**
|
||||
* 具体的外呼号码
|
||||
*/
|
||||
private String cellphone;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package me.zhengjie.config.thread;
|
||||
|
||||
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 线程池配置总类,用于配置线程池
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
public class ThreadPoolConfig {
|
||||
|
||||
/**
|
||||
* 从配置文件中加载线程池相关的配置
|
||||
*/
|
||||
|
||||
/**
|
||||
* produce
|
||||
*/
|
||||
@Value(value = "${save.task.thread_pool.corePoolSize}")
|
||||
private int saveCorePoolSize = 2;
|
||||
@Value(value = "${save.task.thread_pool.maxPoolSize}")
|
||||
private int saveMaxPoolSize = 16;
|
||||
@Value(value = "${save.task.thread_pool.queueCapacity}")
|
||||
private int saveQueueCapacity = 3;
|
||||
@Value(value = "${save.task.thread_pool.ThreadNamePrefix}")
|
||||
private String saveThreadNamePrefix = "SaveToFileTaskExecutor-"; // fixme 这个属性暂时没用起来
|
||||
|
||||
|
||||
@Bean(value = "SendBigDataTaskExecutor")
|
||||
public Executor SendBigDataTaskExecutor(){
|
||||
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
|
||||
saveCorePoolSize,
|
||||
saveMaxPoolSize,
|
||||
3,
|
||||
TimeUnit.SECONDS,
|
||||
new LinkedBlockingDeque<>(saveQueueCapacity),
|
||||
Executors.defaultThreadFactory(),
|
||||
new ThreadPoolExecutor.DiscardOldestPolicy()
|
||||
);
|
||||
return threadPoolExecutor;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package me.zhengjie.modules.upload.consts;
|
||||
|
||||
/**
|
||||
* 常量定义
|
||||
*/
|
||||
public class UploadFileConst {
|
||||
|
||||
/**
|
||||
* ext 文件类型分隔符 - 通配
|
||||
*/
|
||||
public static final String FILE_SPLIT = ".";
|
||||
|
||||
/**
|
||||
* 文件路径的分隔
|
||||
*/
|
||||
public static final String FILE_PATH_SPLIT = ",";
|
||||
|
||||
/**
|
||||
* 正在执行的标识
|
||||
*/
|
||||
public static final Integer DOING_TAG = 1;
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.upload.domain;
|
||||
|
||||
import lombok.Data;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.*;
|
||||
import java.sql.Timestamp;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @website https://el-admin.vip
|
||||
* @description /
|
||||
* @author x
|
||||
* @date 2021-01-03
|
||||
**/
|
||||
@Entity
|
||||
@Data
|
||||
@Table(name="tb_upload_file")
|
||||
public class UploadFile implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
@ApiModelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "upload_time")
|
||||
@ApiModelProperty(value = "上传日期")
|
||||
private Timestamp uploadTime;
|
||||
|
||||
@Column(name = "opration")
|
||||
@ApiModelProperty(value = "操作人")
|
||||
private String opration;
|
||||
|
||||
@Column(name = "file_count")
|
||||
@ApiModelProperty(value = "文件解析总数")
|
||||
private Long fileCount;
|
||||
|
||||
@Column(name = "file_trans_success_count")
|
||||
@ApiModelProperty(value = "上传成功总数")
|
||||
private Long fileTransSuccessCount;
|
||||
|
||||
@Column(name = "upload_tag")
|
||||
@ApiModelProperty(value = "上传状态")
|
||||
private Integer uploadTag;
|
||||
|
||||
@Column(name = "lcoal_save_path")
|
||||
@ApiModelProperty(value = "文件上传保存路径")
|
||||
private String localSavePath;
|
||||
|
||||
public void copy(UploadFile source){
|
||||
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.upload.repository;
|
||||
|
||||
import me.zhengjie.modules.upload.domain.UploadFile;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
/**
|
||||
* @website https://el-admin.vip
|
||||
* @author x
|
||||
* @date 2021-01-03
|
||||
**/
|
||||
public interface UploadFileRepository extends JpaRepository<UploadFile, Long>, JpaSpecificationExecutor<UploadFile> {
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.upload.rest;
|
||||
|
||||
import me.zhengjie.annotation.AnonymousAccess;
|
||||
import me.zhengjie.annotation.Log;
|
||||
import me.zhengjie.common.http.CommonResponse;
|
||||
import me.zhengjie.common.http.ResponseCode;
|
||||
import me.zhengjie.modules.upload.domain.UploadFile;
|
||||
import me.zhengjie.modules.upload.service.UploadFileService;
|
||||
import me.zhengjie.modules.upload.service.dto.UploadFileQueryCriteria;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @website https://el-admin.vip
|
||||
* @author x
|
||||
* @date 2021-01-03
|
||||
**/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = "上传文件解析发送管理")
|
||||
@RequestMapping("/api/uploadFile")
|
||||
public class UploadFileController {
|
||||
|
||||
private final UploadFileService uploadFileService;
|
||||
|
||||
@Log("导出数据")
|
||||
@ApiOperation("导出数据")
|
||||
@GetMapping(value = "/download")
|
||||
@PreAuthorize("@el.check('uploadFile:list')")
|
||||
public void download(HttpServletResponse response, UploadFileQueryCriteria criteria) throws IOException {
|
||||
uploadFileService.download(uploadFileService.queryAll(criteria), response);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@Log("查询上传文件解析发送")
|
||||
@ApiOperation("查询上传文件解析发送")
|
||||
@PreAuthorize("@el.check('uploadFile:list')")
|
||||
public ResponseEntity<Object> query(UploadFileQueryCriteria criteria, Pageable pageable){
|
||||
return new ResponseEntity<>(uploadFileService.queryAll(criteria,pageable),HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Log("新增上传文件解析发送")
|
||||
@ApiOperation("新增上传文件解析发送")
|
||||
@PreAuthorize("@el.check('uploadFile:add')")
|
||||
public ResponseEntity<Object> create(@Validated @RequestBody UploadFile resources){
|
||||
return new ResponseEntity<>(uploadFileService.create(resources),HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Log("修改上传文件解析发送")
|
||||
@ApiOperation("修改上传文件解析发送")
|
||||
@PreAuthorize("@el.check('uploadFile:edit')")
|
||||
public ResponseEntity<Object> update(@Validated @RequestBody UploadFile resources){
|
||||
uploadFileService.update(resources);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
@Log("删除上传文件解析发送")
|
||||
@ApiOperation("删除上传文件解析发送")
|
||||
@PreAuthorize("@el.check('uploadFile:del')")
|
||||
@DeleteMapping
|
||||
public ResponseEntity<Object> delete(@RequestBody Long[] ids) {
|
||||
uploadFileService.deleteAll(ids);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
// ==== 去重开发 =====
|
||||
|
||||
|
||||
@Log("上传并加密任务")
|
||||
@ApiOperation("上传并加密任务")
|
||||
@PostMapping(value = "/sendTask")
|
||||
@AnonymousAccess // fixme 需要测试完成后进行去除和使用上面的权限注解
|
||||
public ResponseEntity<Object> sendTask(@RequestParam(value = "files") MultipartFile[] files) {
|
||||
// 校验上传是否有文件
|
||||
if (files!= null && files.length<= 0){
|
||||
return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.NO_FILE_INPUT), HttpStatus.OK);
|
||||
}
|
||||
// 生成本地文件
|
||||
uploadFileService.encryptDataAndSaveToFile(files);
|
||||
|
||||
return new ResponseEntity<>(CommonResponse.createBySuccess(ResponseCode.SUCCESS), HttpStatus.OK);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.upload.service;
|
||||
|
||||
import me.zhengjie.modules.upload.domain.UploadFile;
|
||||
import me.zhengjie.modules.upload.service.dto.UploadFileDto;
|
||||
import me.zhengjie.modules.upload.service.dto.UploadFileQueryCriteria;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @website https://el-admin.vip
|
||||
* @description 服务接口
|
||||
* @author x
|
||||
* @date 2021-01-03
|
||||
**/
|
||||
public interface UploadFileService {
|
||||
|
||||
/**
|
||||
* 查询数据分页
|
||||
* @param criteria 条件
|
||||
* @param pageable 分页参数
|
||||
* @return Map<String,Object>
|
||||
*/
|
||||
Map<String,Object> queryAll(UploadFileQueryCriteria criteria, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 查询所有数据不分页
|
||||
* @param criteria 条件参数
|
||||
* @return List<UploadFileDto>
|
||||
*/
|
||||
List<UploadFileDto> queryAll(UploadFileQueryCriteria criteria);
|
||||
|
||||
/**
|
||||
* 根据ID查询
|
||||
* @param id ID
|
||||
* @return UploadFileDto
|
||||
*/
|
||||
UploadFileDto findById(Long id);
|
||||
|
||||
/**
|
||||
* 创建
|
||||
* @param resources /
|
||||
* @return UploadFileDto
|
||||
*/
|
||||
UploadFileDto create(UploadFile resources);
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param resources /
|
||||
*/
|
||||
void update(UploadFile resources);
|
||||
|
||||
/**
|
||||
* 多选删除
|
||||
* @param ids /
|
||||
*/
|
||||
void deleteAll(Long[] ids);
|
||||
|
||||
/**
|
||||
* 导出数据
|
||||
* @param all 待导出的数据
|
||||
* @param response /
|
||||
* @throws IOException /
|
||||
*/
|
||||
void download(List<UploadFileDto> all, HttpServletResponse response) throws IOException;
|
||||
|
||||
/**
|
||||
* 加密并生成存储文件
|
||||
*
|
||||
* @param files
|
||||
*/
|
||||
void encryptDataAndSaveToFile(MultipartFile[] files);
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.upload.service.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import java.sql.Timestamp;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @website https://el-admin.vip
|
||||
* @description /
|
||||
* @author x
|
||||
* @date 2021-01-03
|
||||
**/
|
||||
@Data
|
||||
public class UploadFileDto implements Serializable {
|
||||
|
||||
/** 主键 */
|
||||
private Long id;
|
||||
|
||||
/** 上传日期 */
|
||||
private Timestamp uploadTime;
|
||||
|
||||
/** 操作人 */
|
||||
private String opration;
|
||||
|
||||
/** 文件解析总数 */
|
||||
private Long fileCount;
|
||||
|
||||
/** 上传成功总数 */
|
||||
private Long fileTransSuccessCount;
|
||||
|
||||
/** 上传状态 */
|
||||
private Integer uploadTag;
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.upload.service.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import me.zhengjie.annotation.Query;
|
||||
|
||||
/**
|
||||
* @website https://el-admin.vip
|
||||
* @author x
|
||||
* @date 2021-01-03
|
||||
**/
|
||||
@Data
|
||||
public class UploadFileQueryCriteria{
|
||||
|
||||
/** 精确 */
|
||||
@Query
|
||||
private Long id;
|
||||
|
||||
/** 模糊 */
|
||||
@Query(type = Query.Type.INNER_LIKE)
|
||||
private String opration;
|
||||
|
||||
/** 精确 */
|
||||
@Query
|
||||
private Integer uploadTag;
|
||||
|
||||
/** BETWEEN */
|
||||
@Query(type = Query.Type.BETWEEN)
|
||||
private List<Timestamp> uploadTime;
|
||||
}
|
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.upload.service.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.system.OsInfo;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhengjie.modules.upload.domain.UploadFile;
|
||||
import me.zhengjie.modules.upload.task.SaveToFileTask;
|
||||
import me.zhengjie.utils.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.zhengjie.modules.upload.repository.UploadFileRepository;
|
||||
import me.zhengjie.modules.upload.service.UploadFileService;
|
||||
import me.zhengjie.modules.upload.service.dto.UploadFileDto;
|
||||
import me.zhengjie.modules.upload.service.dto.UploadFileQueryCriteria;
|
||||
import me.zhengjie.modules.upload.service.mapstruct.UploadFileMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import static me.zhengjie.modules.upload.consts.UploadFileConst.*;
|
||||
|
||||
|
||||
/**
|
||||
* @author x
|
||||
* @website https://el-admin.vip
|
||||
* @description 服务实现
|
||||
* @date 2021-01-03
|
||||
**/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class UploadFileServiceImpl implements UploadFileService {
|
||||
|
||||
/**
|
||||
* 远程服务器地址
|
||||
*/
|
||||
@Value("${remote.link.address}")
|
||||
private String remoteFileServerAddress;
|
||||
|
||||
/**
|
||||
* 远程上传临时存放文件地址 - linux环境
|
||||
*/
|
||||
@Value("${remote.link.file-base-path-linux}")
|
||||
private String remoteLinkFileBasePathLinux;
|
||||
|
||||
/**
|
||||
* 远程上传临时存放文件地址 - linux环境
|
||||
*/
|
||||
@Value("${remote.link.file-base-path-windows}")
|
||||
private String remoteLinkFileBasePathWindows;
|
||||
|
||||
/**
|
||||
* 远程上传临时存放文件地址 - linux环境
|
||||
*/
|
||||
@Value("${remote.link.file-base-path-mac}")
|
||||
private String remoteLinkFileBasePathMac;
|
||||
|
||||
|
||||
private final UploadFileRepository uploadFileRepository;
|
||||
private final UploadFileMapper uploadFileMapper;
|
||||
|
||||
@Autowired
|
||||
private SaveToFileTask saveToFileTask;
|
||||
|
||||
@Override
|
||||
public Map<String, Object> queryAll(UploadFileQueryCriteria criteria, Pageable pageable) {
|
||||
Page<UploadFile> page = uploadFileRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
|
||||
return PageUtil.toPage(page.map(uploadFileMapper::toDto));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UploadFileDto> queryAll(UploadFileQueryCriteria criteria) {
|
||||
return uploadFileMapper.toDto(uploadFileRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public UploadFileDto findById(Long id) {
|
||||
UploadFile uploadFile = uploadFileRepository.findById(id).orElseGet(UploadFile::new);
|
||||
ValidationUtil.isNull(uploadFile.getId(), "UploadFile", "id", id);
|
||||
return uploadFileMapper.toDto(uploadFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UploadFileDto create(UploadFile resources) {
|
||||
return uploadFileMapper.toDto(uploadFileRepository.save(resources));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(UploadFile resources) {
|
||||
UploadFile uploadFile = uploadFileRepository.findById(resources.getId()).orElseGet(UploadFile::new);
|
||||
ValidationUtil.isNull(uploadFile.getId(), "UploadFile", "id", resources.getId());
|
||||
uploadFile.copy(resources);
|
||||
uploadFileRepository.save(uploadFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll(Long[] ids) {
|
||||
for (Long id : ids) {
|
||||
uploadFileRepository.deleteById(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void download(List<UploadFileDto> all, HttpServletResponse response) throws IOException {
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
for (UploadFileDto uploadFile : all) {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("上传日期", uploadFile.getUploadTime());
|
||||
map.put("操作人", uploadFile.getOpration());
|
||||
map.put("文件解析总数", uploadFile.getFileCount());
|
||||
map.put("上传成功总数", uploadFile.getFileTransSuccessCount());
|
||||
map.put("上传状态", uploadFile.getUploadTag());
|
||||
list.add(map);
|
||||
}
|
||||
FileUtil.downloadExcel(list, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encryptDataAndSaveToFile(MultipartFile[] files) {
|
||||
// 1. 文件存储到本地
|
||||
long count = 0; // 统计总数
|
||||
String baseStr = RandomUtil.randomString(11) + File.separator; // 生成通用随机文件夹存放每次的文件
|
||||
StringBuilder pathBuilder = new StringBuilder();
|
||||
|
||||
for (MultipartFile file : files) {
|
||||
// 获取原来的文件后缀
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
if (StringUtils.isBlank(originalFilename)) {
|
||||
log.error("===================== [input file name is empty, please check ]===================");
|
||||
}
|
||||
|
||||
String extName = FileUtil.extName(originalFilename);
|
||||
String eachFilePath = buildFileWritePath(baseStr, extName);
|
||||
try {
|
||||
// 把文件保存到本地路径
|
||||
file.transferTo(Paths.get(eachFilePath));
|
||||
} catch (IOException e) {
|
||||
log.error("============== [transferTo file fail, path is {} ] ==============", eachFilePath);
|
||||
}
|
||||
// 统计行数
|
||||
List<String> tempList = FileUtil.readLines(eachFilePath, "UTF-8");
|
||||
if (CollectionUtil.isNotEmpty(tempList)){
|
||||
count += tempList.size();
|
||||
}
|
||||
// 保存所有的临时存放路径
|
||||
pathBuilder.append(eachFilePath);
|
||||
pathBuilder.append(FILE_PATH_SPLIT);
|
||||
|
||||
}
|
||||
|
||||
// 2. 更新上传记录为正在上传,解析了有多少条
|
||||
UploadFile uploadFile = new UploadFile();
|
||||
uploadFile.setUploadTime(new Timestamp(new Date().getTime()));
|
||||
uploadFile.setOpration("");//fixme 这边补充一下需要的操作人
|
||||
uploadFile.setFileCount(count);
|
||||
uploadFile.setFileTransSuccessCount(0L);
|
||||
uploadFile.setUploadTag(DOING_TAG);
|
||||
String tempFilesPath = pathBuilder.toString().substring(0, pathBuilder.length() - 1);
|
||||
if (StringUtils.isNotBlank(tempFilesPath)){
|
||||
uploadFile.setLocalSavePath(tempFilesPath); // 去掉最后的那个通配符 FILE_PATH_SPLIT
|
||||
}
|
||||
|
||||
UploadFile save = uploadFileRepository.save(uploadFile);
|
||||
// 2.1 如果临时生成失败就修改状态为失败
|
||||
if (Objects.isNull(save)){
|
||||
log.error("UploadFileServiceImpl:encryptDataAndSaveToFile | Operation Fail.UploadFile is Null");
|
||||
}
|
||||
// 3. 调用异步任务
|
||||
saveToFileTask.doRunTask(tempFilesPath);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建文件上传保存路径
|
||||
*/
|
||||
private String buildFileWritePath(String baseStr, String extName) {
|
||||
// 获取环境配置信息
|
||||
OsInfo osInfo = SystemUtil.getOsInfo();
|
||||
// 生成一个随机文件夹目录,方便整理和打包
|
||||
if (osInfo.isWindows()) {
|
||||
FileUtil.mkdir(remoteLinkFileBasePathWindows + baseStr);
|
||||
// 构建存储文件
|
||||
return remoteLinkFileBasePathWindows + baseStr + RandomUtil.randomString(11) + FILE_SPLIT + extName;
|
||||
} else if (osInfo.isLinux()) {
|
||||
FileUtil.mkdir(remoteLinkFileBasePathLinux + baseStr);
|
||||
// 构建存储文件
|
||||
return remoteLinkFileBasePathLinux + baseStr + RandomUtil.randomString(11) + FILE_SPLIT + extName;
|
||||
} else if (osInfo.isMac()) {
|
||||
FileUtil.mkdir(remoteLinkFileBasePathMac + baseStr);
|
||||
// 构建存储文件
|
||||
return remoteLinkFileBasePathMac + baseStr + RandomUtil.randomString(11) + FILE_SPLIT + extName;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.upload.service.mapstruct;
|
||||
|
||||
import me.zhengjie.base.BaseMapper;
|
||||
import me.zhengjie.modules.upload.domain.UploadFile;
|
||||
import me.zhengjie.modules.upload.service.dto.UploadFileDto;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
|
||||
/**
|
||||
* @website https://el-admin.vip
|
||||
* @author x
|
||||
* @date 2021-01-03
|
||||
**/
|
||||
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
public interface UploadFileMapper extends BaseMapper<UploadFileDto, UploadFile> {
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package me.zhengjie.modules.upload.task;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhengjie.utils.ConvertUtil;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
@Slf4j
|
||||
public class SaveToFileTask {
|
||||
|
||||
@Async(value = "SendBigDataTaskExecutor")
|
||||
public void doRunTask(String tempFilesPath){
|
||||
Long satrtMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
||||
log.info("====== [ task start running, task name is {} ] ======", "SendBigDataTask");
|
||||
runTask(tempFilesPath);
|
||||
Long endMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
||||
log.info("====== [ task start end, task name is {},cost milliSecond is {} ] ======", "SendBigDataTask", ConvertUtil.secondToTime(endMilliSecond - satrtMilliSecond));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行异步任务
|
||||
*
|
||||
* @param tempFilesPath 上传的多个临时文件路径,
|
||||
*/
|
||||
private void runTask(String tempFilesPath) {
|
||||
// 4. 调用加密接口进行加密
|
||||
|
||||
// 4.1 失败进行容错
|
||||
|
||||
// 4.2 把临时存储的文件进行删除
|
||||
|
||||
// 4.3 更新状态为成功,更新解析成功的条数
|
||||
|
||||
// 5. 文件传输给2号库服务器
|
||||
|
||||
// 5.1 文件传输和记录更新()
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue