Commit 010404dc by landerliang@163.com

不使用Quartz管理定时任务了,改为纯Scheduled,根据多少个任务开多少个线程,目前站点能够正常使用

parent 18d6e520
......@@ -39,7 +39,7 @@ import org.springframework.web.client.RestTemplate;
* @date 2018/11/15 9:20:19
*/
@MapperScan("me.zhengjie.modules.system.repository")
//@EnableAsync
@EnableAsync
@RestController
@Api(hidden = true)
@EnableScheduling
......
......@@ -40,7 +40,7 @@ public class AsyncTaskExecutePool implements AsyncConfigurer {
}
@Override
public Executor getAsyncExecutor() {
public ThreadPoolTaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(config.getCorePoolSize());
......@@ -50,11 +50,15 @@ public class AsyncTaskExecutePool implements AsyncConfigurer {
executor.setQueueCapacity(config.getQueueCapacity());
//活跃时间
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
//优雅关闭线程 用来设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
executor.setWaitForTasksToCompleteOnShutdown(true);
//线程名字前缀
executor.setThreadNamePrefix("el-async-");
//当pool已经达到最大size则丢弃前面的任务,不抛出异常
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
// setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
// CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
......
package me.zhengjie.modules.quartz.config;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author Lander
*/
@Slf4j
public class CustomAbortPolicy implements RejectedExecutionHandler {
public void CustomAbortPolicy() { }
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("进入拒绝策略。。。。。。。。。。");
if (!executor.isShutdown()) {
try {
log.error("full-->>线程池已满,执行拒绝策略");
while (executor.getQueue().remainingCapacity() == 0);
executor.execute(r);
} catch (Exception e) {
log.error("rejectedExecutionException====>>>>>"+e.toString());
}
}
}
}
......@@ -32,11 +32,11 @@ import java.util.List;
* @date 2019-01-07
*/
@Component
@RequiredArgsConstructor
//@RequiredArgsConstructor
public class JobRunner implements ApplicationRunner {
private static final Logger log = LoggerFactory.getLogger(JobRunner.class);
private final QuartzJobRepository quartzJobRepository;
private final QuartzManage quartzManage;
//private final QuartzJobRepository quartzJobRepository;
//private final QuartzManage quartzManage;
/**
* 项目启动时重新激活启用的定时任务
......@@ -46,8 +46,8 @@ public class JobRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) {
log.info("--------------------注入定时任务---------------------");
List<QuartzJob> quartzJobs = quartzJobRepository.findByIsPauseIsFalse();
quartzJobs.forEach(quartzManage::addJob);
//List<QuartzJob> quartzJobs = quartzJobRepository.findByIsPauseIsFalse();
//quartzJobs.forEach(quartzManage::addJob);
log.info("--------------------定时任务注入完成---------------------");
}
}
......@@ -15,11 +15,16 @@
*/
package me.zhengjie.modules.quartz.config;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.config.thread.AsyncTaskExecutePool;
import me.zhengjie.config.thread.AsyncTaskProperties;
import org.quartz.Scheduler;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
......@@ -29,9 +34,17 @@ import org.springframework.stereotype.Component;
* @author /
* @date 2019-01-07
*/
@Slf4j
@Configuration
public class QuartzConfig {
/** 注入配置类 */
private final AsyncTaskProperties config;
private final AsyncTaskExecutePool asyncTaskExecutePool;
public QuartzConfig(AsyncTaskProperties config, AsyncTaskExecutePool asyncTaskExecutePool) {
this.config = config;
this.asyncTaskExecutePool = asyncTaskExecutePool;
}
/**
* 解决Job中注入Spring Bean为null的问题
*/
......@@ -54,6 +67,32 @@ public class QuartzConfig {
}
}
@Bean(name ="quartzTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
/*ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数
executor.setCorePoolSize(config.getCorePoolSize());
// 最大线程数
executor.setMaxPoolSize(config.getMaxPoolSize());
// 任务队列大小
executor.setQueueCapacity(config.getQueueCapacity());
// 线程前缀名
executor.setThreadNamePrefix("CartReptiles-Quartz");
// 线程的空闲时间
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
executor.setThreadFactory(new ThreadFactoryBuilder().setNameFormat("Quartz定时任务-runner-%d").build());
// 拒绝策略
executor.setRejectedExecutionHandler(new CustomAbortPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
// 线程初始化
//executor.initialize();
return executor;*/
return asyncTaskExecutePool.getAsyncExecutor();
}
/**
* 注入scheduler到spring
* @param quartzJobFactory /
......
......@@ -145,7 +145,7 @@ public class QuartzJobServiceImpl implements QuartzJobService {
}
}
//@Async
@Async
@Override
@Transactional(rollbackFor = Exception.class)
public void executionSubJob(String[] tasks) throws InterruptedException {
......
......@@ -27,15 +27,68 @@ import org.springframework.stereotype.Component;
@Component
public class TestTask {
/*private final JobMapper jobMapper;
private final ReportService reportService;
@Autowired
public TestTask(JobMapper jobMapper, ReportService reportService) {
this.jobMapper = jobMapper;
this.reportService = reportService;
}*/
public void run(){
log.info("run 执行成功");
/* log.info(">>> ================================ 开始自动爬取新的检测报告进行下载、签章、上传 ====================================");
//查询全部非管理员任务 且 状态为 执行中的
QueryWrapper<QuartzJob> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().and(i -> {
i.notIn(QuartzJob::getDeptId,19)
.eq(QuartzJob::getIsPause,0);
});
List<QuartzJob> quartzJobs = jobMapper.selectList(queryWrapper);
try {
quartzJobs.forEach( quartzJob -> {
String params = quartzJob.getParams();
if(StrUtil.isNotBlank(params)){
JSONObject jsonParam = JSONObject.parseObject(params);
log.info(">>> 环保账户: {}, 环保密码:{}, 授权人签名盘符:{}, 批准人签名盘符:{}, 公章签名盘符:{}, 部门编号:{}",
jsonParam.getString("account"),jsonParam.getString("password"),
jsonParam.getString("snKey1"),jsonParam.getString("snKey2"),jsonParam.getString("snKey3"),jsonParam.getInteger("deptId"));
AssertUtil.isNotNull(jsonParam.get("account"),"缺少环保系统账户,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("password"),"缺少环保系统密码,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snKey1"),"缺少授权人签名盘符,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snKey2"),"缺少批准人签名盘符,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snKey3"),"缺少公章签名盘符,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snKey4"),"缺少MA章签名盘符,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snName1"),"缺少授权人签章名称,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snName2"),"缺少批准人签章名称,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snName3"),"缺少公章签章名称,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snName4"),"缺少MA章名称,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("deptId"),"缺少部门id,自动任务执行终止!");
reportService.autoDownloadAndSignAndUploadReport(jsonParam.getString("account"),jsonParam.getString("password"),
jsonParam.getString("snKey1"),jsonParam.getString("snKey2"),jsonParam.getString("snKey3"),
jsonParam.getString("snName1"),jsonParam.getString("snName2"),jsonParam.getString("snName3")
,jsonParam.getString("snKey4"),jsonParam.getString("snName4"),jsonParam.getInteger("deptId"));
}
public void run1(String str){
log.info("run1 执行成功,参数为: {}" + str);
});
} catch (Exception e) {
log.error(e.getMessage());
}
public void run2(){
log.info("run2 执行成功");
log.info(">> ========================================== 本次自动签章任务执行完毕 ==========================================");*/
}
}
......@@ -32,6 +32,7 @@ import me.zhengjie.utils.StringUtils;
import me.zhengjie.utils.ThrowableUtil;
import org.quartz.JobExecutionContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.*;
import java.util.concurrent.*;
......@@ -41,12 +42,10 @@ import java.util.concurrent.*;
* @author /
* @date 2019-01-07
*/
//@Async
@Async
@SuppressWarnings({"unchecked","all"})
public class ExecutionJob extends QuartzJobBean {
/** 该处仅供参考 */
private final static ThreadPoolExecutor EXECUTOR = ThreadPoolExecutorUtil.getPoll();
private final ThreadPoolTaskExecutor EXECUTOR = (ThreadPoolTaskExecutor) SpringContextHolder.getBean("quartzTaskExecutor");
@Override
public void executeInternal(JobExecutionContext context) {
......@@ -70,6 +69,7 @@ public class ExecutionJob extends QuartzJobBean {
// 执行任务
System.out.println("--------------------------------------------------------------");
System.out.println("任务开始执行,任务名称:" + quartzJob.getJobName());
System.out.println("-------------------当前线程池大小:" + EXECUTOR.getPoolSize() +",线程池最大数:" + EXECUTOR.getMaxPoolSize() +"---------------------");
QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(),
quartzJob.getParams());
Future<?> future = EXECUTOR.submit(task);
......@@ -93,6 +93,7 @@ public class ExecutionJob extends QuartzJobBean {
if(StringUtils.isNotBlank(uuid)) {
redisUtils.set(uuid, false);
}
System.out.println("任务执行失败,任务名称:" + quartzJob.getJobName());
System.out.println("--------------------------------------------------------------");
long times = System.currentTimeMillis() - startTime;
......
......@@ -51,6 +51,7 @@ public class QuartzManage {
.withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression()))
.build();
cronTrigger.getJobDataMap().put(QuartzJob.JOB_KEY, quartzJob);
//重置启动时间
......@@ -63,6 +64,7 @@ public class QuartzManage {
if (quartzJob.getIsPause()) {
pauseJob(quartzJob);
}
} catch (Exception e){
log.error("创建定时任务失败", e);
throw new BadRequestException("创建定时任务失败");
......
......@@ -23,26 +23,29 @@ public class MyConstants {
/**
* 身份证文件名后缀
*/
public static final String IDCARD_SUFFIX = "_sfz.jpg";
public static final String IDCARD_SUFFIX = "\\IMG_0000.jpg";
/**
* 检测申请表文件后缀
* 行驶证1文件后缀
*/
public static final String APPLY_SUFFIX = "_jcsqb.jpg";
public static final String DRIVER_SUFFIX1 = "\\IMG_0001.jpg";
/**
* 维修凭证文件后缀
* 行驶证2文件后缀
*/
public static final String CERTIFICATE_SUFFIX = "_wxpz.jpg";
public static final String DRIVER_SUFFIX2 = "\\IMG_0002.jpg";
/**
* 行驶证1文件后缀
* 检测申请表文件后缀
*/
public static final String DRIVER_SUFFIX1 = "_xsz1.jpg";
public static final String APPLY_SUFFIX = "\\IMG_0003.jpg";
/**
* 行驶证2文件后缀
* 维修凭证文件后缀
*/
public static final String DRIVER_SUFFIX2 = "_xsz2.jpg";
public static final String CERTIFICATE_SUFFIX = "\\IMG_0004.jpg";
}
/*
* 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.system.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.persistence.Transient;
import javax.validation.constraints.NotBlank;
/**
* @author Zheng Jie
* @date 2019-01-07
*/
@Data
@TableName("sys_quartz_job")
public class QuartzJob{
public static final String JOB_KEY = "JOB_KEY";
@TableId(type = IdType.AUTO)
private Long jobId;
@TableField(exist = false)
@ApiModelProperty(value = "用于子任务唯一标识", hidden = true)
private String uuid;
@ApiModelProperty(value = "定时器名称")
private String jobName;
@NotBlank
@ApiModelProperty(value = "Bean名称")
private String beanName;
@ApiModelProperty(value = "方法名称")
private String methodName;
@ApiModelProperty(value = "参数")
private String params;
@ApiModelProperty(value = "cron表达式")
private String cronExpression;
@ApiModelProperty(value = "状态,暂时或启动")
private Boolean isPause = false;
@ApiModelProperty(value = "负责人")
private String personInCharge;
@ApiModelProperty(value = "报警邮箱")
private String email;
@ApiModelProperty(value = "子任务")
private String subTask;
@ApiModelProperty(value = "失败后暂停")
private Boolean pauseAfterFailure;
@ApiModelProperty(value = "备注")
private String description;
@ApiModelProperty("部门id")
private Long deptId;
}
package me.zhengjie.modules.system.repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import me.zhengjie.modules.system.domain.QuartzJob;
import org.springframework.stereotype.Repository;
/**
* @author Lander
*/
@Repository
public interface JobMapper extends BaseMapper<QuartzJob> {
}
......@@ -36,14 +36,9 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* 检测报告service
......@@ -71,6 +66,8 @@ public class ReportService {
private static List<TestReportVo> reportVoList;
private final TaskErrorMapper taskErrorMapper;
@Value("${uploadFilePath}")
private String uploadFilePath;
@Autowired
public ReportService(UserMapper userMapper, DeptMapper deptMapper, CarReportUtil carReportUtil, ReportPdfMapper reportPdfMapper, SignatureService signatureService, RestTemplate restTemplate, TaskErrorMapper taskErrorMapper) {
......@@ -123,7 +120,7 @@ public class ReportService {
* 自动下载检测报告并签章上传
*
*/
public synchronized void autoDownloadAndSignAndUploadReport(String account,String password,String snKey1,String snKey2,String snKey3,
public void autoDownloadAndSignAndUploadReport(String account,String password,String snKey1,String snKey2,String snKey3,
String snName1,String snName2,String snName3,String snKey4,String snName4,Integer deptId){
......@@ -142,7 +139,11 @@ public class ReportService {
//下载报告pdf 并写入数据库
reportPdfVo = new ReportPdfVo();
String path = carReportUtil.downloadReport(account, password, reportDetailsReqVo);
String path = carReportUtil.authDownloadReport(account, password, reportDetailsReqVo);
//如果下载成功
if(StrUtil.isNotBlank(path)){
reportPdfVo.setPath(path);
reportPdfVo.setVehicleId(testReportVo.getVehicleID());
reportPdfVo.setUniqueString(testReportVo.getUniqueString());
......@@ -189,20 +190,18 @@ public class ReportService {
reportPdfVo.setPath(signatureReport.getPath());
reportPdfVo.setReportName(signatureReport.getReportName());
//上传文件 (连同检测报告全部文件)
Integer success = carReportUtil.autoUploadReportPost(account, password, reportPdfVo, signatureVo1.getDeptId());
//上传成功的文件小于2个则视为上传失败,清除下载记录
/*if(success < 2){
deleteReportPdf(signatureReport.getReportNum());
}*/
if(success >= 2){
log.info(">> 成功自动上传:{} 个文件,本次上传任务完成!",success);
//写入pdf下载记录
reportPdfMapper.insert(reportPdfVo);
}
} else {
log.error(">> 自动下载检测报告失败!");
}
}
}
} catch (Exception e) {
......@@ -370,6 +369,10 @@ public class ReportService {
reportPdfMapper.updateById(reportPdfVo);
}
if(!FileUtil.exist(uploadFilePath + detailsReqVo)){
FileUtil.mkdir(uploadFilePath + detailsReqVo);
}
return reportPdfVo;
}
}
......
package me.zhengjie.modules.system.task;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.system.domain.QuartzJob;
import me.zhengjie.modules.system.repository.JobMapper;
import me.zhengjie.modules.system.service.ReportService;
import me.zhengjie.utils.AssertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
public class Task {
@Autowired
private JobMapper jobMapper;
@Autowired
private ReportService reportService;
@Scheduled(initialDelay = 2000,fixedDelay = 20000)
public void run(){
log.info(">>> ================================ 开始自动爬取新的检测报告进行下载、签章、上传 ====================================");
//查询全部非管理员任务 且 状态为 执行中的
QueryWrapper<QuartzJob> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().and(i -> {
i.notIn(QuartzJob::getDeptId,19)
.eq(QuartzJob::getIsPause,0);
});
List<QuartzJob> quartzJobs = jobMapper.selectList(queryWrapper);
try {
quartzJobs.forEach( quartzJob -> {
AutoScanReportThread autoScanReportThread = new AutoScanReportThread();
autoScanReportThread.setParams(quartzJob.getParams());
autoScanReportThread.start();
});
} catch (Exception e) {
log.error(e.getMessage());
}
log.info(">> ========================================== 本次自动签章任务执行完毕 ==========================================");
}
/**
* 自动扫描线程
*/
class AutoScanReportThread extends Thread {
private String params;
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
@Override
public void run() {
if(StrUtil.isNotBlank(params)){
JSONObject jsonParam = JSONObject.parseObject(params);
log.info(">>> 环保账户: {}, 环保密码:{}, 授权人签名盘符:{}, 批准人签名盘符:{}, 公章签名盘符:{}, 部门编号:{}",
jsonParam.getString("account"),jsonParam.getString("password"),
jsonParam.getString("snKey1"),jsonParam.getString("snKey2"),jsonParam.getString("snKey3"),jsonParam.getInteger("deptId"));
AssertUtil.isNotNull(jsonParam.get("account"),"缺少环保系统账户,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("password"),"缺少环保系统密码,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snKey1"),"缺少授权人签名盘符,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snKey2"),"缺少批准人签名盘符,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snKey3"),"缺少公章签名盘符,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snKey4"),"缺少MA章签名盘符,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snName1"),"缺少授权人签章名称,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snName2"),"缺少批准人签章名称,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snName3"),"缺少公章签章名称,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("snName4"),"缺少MA章名称,自动任务执行终止!");
AssertUtil.isNotNull(jsonParam.get("deptId"),"缺少部门id,自动任务执行终止!");
reportService.autoDownloadAndSignAndUploadReport(jsonParam.getString("account"),jsonParam.getString("password"),
jsonParam.getString("snKey1"),jsonParam.getString("snKey2"),jsonParam.getString("snKey3"),
jsonParam.getString("snName1"),jsonParam.getString("snName2"),jsonParam.getString("snName3")
,jsonParam.getString("snKey4"),jsonParam.getString("snName4"),jsonParam.getInteger("deptId"));
}
}
}
}
package me.zhengjie.modules.system.util;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.img.Img;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.*;
......@@ -230,6 +231,10 @@ public class CarReportUtil {
uploadRecord.setState(1);
success ++;
}
//将源文件压缩
Img.from(FileUtil.file(uploadFilePath + reportPdfVo.getCarNum() + MyConstants.APPLY_SUFFIX))
.setQuality(0.8)//压缩比率
.write(FileUtil.file(uploadFilePath + reportPdfVo.getCarNum() + MyConstants.APPLY_SUFFIX));
uploadRecordService.saveRecord(uploadRecord);
......@@ -255,6 +260,10 @@ public class CarReportUtil {
uploadRecord.setState(1);
success ++;
}
//将源文件压缩
Img.from(FileUtil.file(uploadFilePath + reportPdfVo.getCarNum() + MyConstants.IDCARD_SUFFIX))
.setQuality(0.8)//压缩比率
.write(FileUtil.file(uploadFilePath + reportPdfVo.getCarNum() + MyConstants.IDCARD_SUFFIX));
uploadRecordService.saveRecord(uploadRecord);
//行驶证1文件上传
......@@ -279,6 +288,11 @@ public class CarReportUtil {
uploadRecord.setState(1);
success ++;
}
//将源文件压缩
Img.from(FileUtil.file(uploadFilePath + reportPdfVo.getCarNum() + MyConstants.DRIVER_SUFFIX1))
.setQuality(0.8)//压缩比率
.write(FileUtil.file(uploadFilePath + reportPdfVo.getCarNum() + MyConstants.DRIVER_SUFFIX1));
uploadRecordService.saveRecord(uploadRecord);
//行驶证2文件上传
......@@ -303,6 +317,10 @@ public class CarReportUtil {
uploadRecord.setState(1);
success ++;
}
//将源文件压缩
Img.from(FileUtil.file(uploadFilePath + reportPdfVo.getCarNum() + MyConstants.DRIVER_SUFFIX2))
.setQuality(0.8)//压缩比率
.write(FileUtil.file(uploadFilePath + reportPdfVo.getCarNum() + MyConstants.DRIVER_SUFFIX2));
uploadRecordService.saveRecord(uploadRecord);
......@@ -330,6 +348,10 @@ public class CarReportUtil {
uploadRecord.setState(1);
success ++;
}
//将源文件压缩
Img.from(FileUtil.file(uploadFilePath + reportPdfVo.getCarNum() + MyConstants.CERTIFICATE_SUFFIX))
.setQuality(0.8)//压缩比率
.write(FileUtil.file(uploadFilePath + reportPdfVo.getCarNum() + MyConstants.CERTIFICATE_SUFFIX));
uploadRecordService.saveRecord(uploadRecord);
}
......@@ -349,7 +371,7 @@ public class CarReportUtil {
throw new BusinessException(e.getLocalizedMessage());
}
if(driver != null){
driver.close();
driver.quit();
}
return success;
......@@ -732,6 +754,164 @@ public class CarReportUtil {
}
/**
* 自动任务的下载检测报告 并 转 PDF
* @param username
* @param password
* @param detailsReqVo
* @return
*/
public String authDownloadReport(String username,String password,ReportDetailsReqVo detailsReqVo) {
//登录环保
WebDriver driver = null;
try {
//把检测报告编号作为该报告文件的文件名
String fileName = detailsReqVo.getReportNum();
//如果已经下载有检测报告则直接return
String reportHtmlPath = getReportPath(fileName,".html");
/*if(FileUtil.isNotEmpty(FileUtil.file(fileName))){
return getReportPath(fileName,".pdf");
}*/
//登录环保
driver = loginEp(username, password,BrowserVersion.INTERNET_EXPLORER);
Thread.sleep(1000);
//抓取检测报告超链接
WebElement inspecReportBtn = driver.findElement(new By.ById("mainMenuTree_3_a"));
inspecReportBtn.click();
//延迟加载html
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS)
.setScriptTimeout(60,TimeUnit.SECONDS).pageLoadTimeout(120,TimeUnit.SECONDS);
Thread.sleep(3000);
//点击完检测报告的超链接后,抓取frame窗口的元素
WebElement homeFrame = driver.findElement(new By.ByXPath("//*[@id=\"tabs\"]/div[2]/div[2]/div/iframe"));
//切换到iframe页面
driver = driver.switchTo().frame(homeFrame);
//延迟加载html
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS)
.setScriptTimeout(60,TimeUnit.SECONDS).pageLoadTimeout(120,TimeUnit.SECONDS);
Thread.sleep(2000);
WebElement element = driver.findElement(new By.ByXPath("//*[@id=\"table_Condition\"]/tbody/tr[2]/td[3]/input"));
element.click();
//获取车牌号输入框
WebElement carNumInput = driver.findElement(new By.ByXPath("//*[@id=\"conWindow\"]/div[1]/div/table/tbody/tr[1]/td[2]/input"));
carNumInput.sendKeys(detailsReqVo.getCarNum());
//点击检索按钮
driver.findElement(new By.ById("btnVin")).click();
//延迟加载html
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS)
.setScriptTimeout(60,TimeUnit.SECONDS).pageLoadTimeout(120,TimeUnit.SECONDS);
Thread.sleep(2000);
//抓取检索后的列表
List<WebElement> trElements = driver.findElements(new By.ByXPath("//*[contains(@id,'datagrid-row-')]"));
AssertUtil.isTrue(trElements.size()>0,"获取该检测报告失败!");
//拿出对应的那条记录(根据检测编码)
WebElement trElement =null;
for (WebElement tr: trElements){
if(tr.getText().contains(detailsReqVo.getCarNum())){
trElement = tr;
}
}
//点击检索出来的列表
trElement.click();
//延迟加载html
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS)
.setScriptTimeout(60, TimeUnit.SECONDS).pageLoadTimeout(120, TimeUnit.SECONDS);
Thread.sleep(3000);
//抓取检测报告frame
WebElement reportFrame = driver.findElement(new By.ById("iframe_divReport"));
//切换到检测报告frame
driver = driver.switchTo().frame(reportFrame);
Thread.sleep(2000);
//抓取打印预览按钮进行点击
//WebElement printView = reportDriver.findElement(new By.ById("A1"));
WebElement printView =driver.findElement(new By.ById("btnPlaySelectAll"));
printView.click();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS)
.setScriptTimeout(20, TimeUnit.SECONDS).pageLoadTimeout(120, TimeUnit.SECONDS);
boolean isError = driver.getPageSource().contains("无检测方法结果数据不允许打印操作");
AssertUtil.isNotTrue(isError,"无检测方法结果数据不允许打印操作");
Thread.sleep(3000);
//手动在授权人签字栏加上当天日期
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd");
String todayStr = simpleDateFormat.format(DateUtil.date());
//替换掉css样式的链接以及去掉多余的元素
Document parse = Jsoup.parse(driver.getPageSource());
parse.select("a").remove();
String reportHtml = parse.html();
reportHtml = reportHtml.replace("src=\"../..", "src=\"" + host).replace("src=\"/businesscom", "src=\"" + host + "businesscom")
.replace("黑体","SimSun").replace("<br> \n" +
" <br>","<br style=\"page-break-after:always;\"> \n" +
" <br style=\"page-break-after:always;\">")
.replace("<br> \n" +
" <font color=\"#FF00FF\"> 打印控件未安装!点击这里 ,安装后请刷新页面或重新进入。 </font> \n" +
" <br> \n" +
" <br> \n" +
" <font color=\"#FF00FF\"> (如果此前正常,仅因浏览器升级或重安装而出问题,需重新执行以上安装) </font>", " ")
.replace("<div>","<div style=\"margin-left:-460px\">")
.replace("<td style=\"width:13.25%;\"> 授权签字人 </td> \n" +
" <td colspan=\"4\" style=\"width:30%;border-left:none;border-right:none;\"></td>",
"<td style=\"width:13.25%;\"> 授权签字人 </td> \n" +
" <td colspan=\"4\" style=\"width:30%;border-left:none;border-right:none;padding-left:100px\">" + todayStr + "</td>");
Document parse1 = Jsoup.parse(reportHtml);
String imgSrc = parse1.getElementById("qrImg").attr("src");
Object[] cookies = driver.manage().getCookies().toArray();
byte[] respBytes = HttpUtil.createGet(imgSrc).header("Cookie", cookies[0].toString() + ";" + cookies[1].toString() + ";" + cookies[2].toString()).execute().bodyBytes();
FileUtil.writeBytes(respBytes, getReportPath(fileName,".png"));
//将二维码转换成base64流 踩坑: 不转base64的话,转PDF后,图片显示不出来
BASE64Encoder encoder = new BASE64Encoder();
String base64Qrcode = encoder.encode(respBytes);
//将base64流的二维码加到页面上
parse1.getElementById("qrImg").attr("src","data:image/png;base64," + base64Qrcode);
FileUtil.writeBytes(parse1.html().getBytes("UTF-8"), reportHtmlPath);
//将保存到本地的html转成pdf
PdfUtil.convert(reportHtmlPath,getReportPath(fileName,".pdf"));
//离开当前检测报告页返回列表页面
//driver.switchTo().parentFrame();
log.info(">> 检测报告下载完成!");
if(driver != null){
driver.quit();
}
return getReportPath(fileName, ".pdf");
} catch (InterruptedException | UnsupportedEncodingException | UnhandledAlertException e) {
e.printStackTrace();
}
return null;
}
/**
* 下载检测报告 并 转 PDF
......@@ -821,12 +1001,12 @@ public class CarReportUtil {
//WebElement printView = reportDriver.findElement(new By.ById("A1"));
WebElement printView = driver.findElement(new By.ById("btnPlaySelectAll"));
printView.click();
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS)
.setScriptTimeout(60, TimeUnit.SECONDS).pageLoadTimeout(120, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS)
.setScriptTimeout(20, TimeUnit.SECONDS).pageLoadTimeout(120, TimeUnit.SECONDS);
boolean isError = driver.getPageSource().contains("无检测方法结果数据不允许打印操作");
AssertUtil.isNotTrue(isError,"无检测方法结果数据不允许打印操作");
Thread.sleep(2500);
Thread.sleep(3000);
//手动在授权人签字栏加上当天日期
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd");
......@@ -852,7 +1032,6 @@ public class CarReportUtil {
"<td style=\"width:13.25%;\"> 授权签字人 </td> \n" +
" <td colspan=\"4\" style=\"width:30%;border-left:none;border-right:none;padding-left:100px\">" + todayStr + "</td>");
Document parse1 = Jsoup.parse(reportHtml);
System.out.println("检测报告二维码html:" + parse1.getElementById("qrImg").toString());
String imgSrc = parse1.getElementById("qrImg").attr("src");
Object[] cookies = driver.manage().getCookies().toArray();
byte[] respBytes = HttpUtil.createGet(imgSrc).header("Cookie", cookies[0].toString() + ";" + cookies[1].toString() + ";" + cookies[2].toString()).execute().bodyBytes();
......@@ -879,9 +1058,7 @@ public class CarReportUtil {
log.info(">> 检测报告下载完成!");
if(driver != null){
driver.close();
}
return getReportPath(fileName, ".pdf");
} catch (InterruptedException | UnsupportedEncodingException | UnhandledAlertException e) {
e.printStackTrace();
......@@ -963,7 +1140,7 @@ public class CarReportUtil {
MyContext.PHOTO_TABLE_NAME,MyContext.PHOTO_WHERE,fldsVo.getFld(),conditionVoList,null,5);
JSONObject body = JSONUtil.createObj();
body.put("data",queryDataVo);
body.put("rows",10);
body.put("rows",5);
body.put("page",1);
body.put("sort","DetectEndTime");
body.put("order","DESC");
......@@ -983,6 +1160,13 @@ public class CarReportUtil {
//将结果转vo对象
InspecPageVo pageVo = JSONUtil.toBean(queryResult, InspecPageVo.class);
List<TestReportVo> collect = pageVo.getRows().stream().filter(i -> ((Integer.valueOf(i.getPDFCount())==0)||Integer.valueOf(i.getPDFCount())== 2)).collect(Collectors.toList());
collect.forEach(testReportVo -> {
if(StrUtil.isNotBlank(testReportVo.getVLPN())){
if(!FileUtil.exist(uploadFilePath + testReportVo.getVLPN())){
FileUtil.mkdir(uploadFilePath + testReportVo.getVLPN());
}
}
});
pageVo.setRows(collect);
pageVo.setTotal(collect.size());
return pageVo.getRows();
......@@ -997,17 +1181,16 @@ public class CarReportUtil {
* @throws InterruptedException
*/
public List<TestReportVo> taskReportList (String username,String password) {
WebDriver driver = null;
List<TestReportVo> testReportVoIPage = null;
List<TestReportVo> testReportVoIPage = new ArrayList<>();
try {
//登录环保检测系统
driver = loginEp(username, password,null);
driver = loginEp(username, password,BrowserVersion.CHROME);
WebElement inspecReportBtn = driver.findElement(new By.ById("mainMenuTree_3_a"));
AssertUtil.isNotNull(inspecReportBtn,"抓取报告单菜单失败");
String[] reportA = inspecReportBtn.getAttribute("onclick").split("/");
//String[] reportA = inspecReportBtn.getAttribute("onclick").split("/");
//抓取当前登录用户的站点名称
WebElement stationSpan = driver.findElement(new By.ById("orgName"));
......@@ -1033,15 +1216,22 @@ public class CarReportUtil {
testReportVo.setSiteName(stationSpan.getText());
System.out.println(testReportVo.toString());
});
} catch (HttpException e) {
log.error(e.getMessage());
if(testReportVoIPage == null){
testReportVoIPage = new ArrayList<>();
}
if(driver != null){
driver.close();
driver.quit();
}
return testReportVoIPage;
} catch (HttpException e) {
log.error(e.getMessage());
}
return testReportVoIPage;
}
}
......@@ -4,7 +4,7 @@ import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.system.interceptor.HtmlToPdfInterceptor;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.*;
/**
* @author Lander
......@@ -14,6 +14,19 @@ import java.io.File;
public class PdfUtil {
public static void run(InputStream is){
try{
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
log.info(">> HTML转PDF INFO :{}",line.toString()); //输出内容
}
}catch (IOException e){
e.printStackTrace();
}
}
/**
* html转pdf
......@@ -54,9 +67,9 @@ public class PdfUtil {
try {
Process proc = Runtime.getRuntime().exec(cmd.toString());
HtmlToPdfInterceptor error = new HtmlToPdfInterceptor(proc.getErrorStream());
HtmlToPdfInterceptor output = new HtmlToPdfInterceptor(proc.getInputStream());
HtmlToPdfInterceptor out = new HtmlToPdfInterceptor(proc.getInputStream());
error.start();
output.start();
out.start();
proc.waitFor();
} catch (Exception e) {
result = false;
......
......@@ -35,16 +35,17 @@ spring:
max-file-size: 100MB
max-request-size: 100MB #最大请求文件的大小
task:
pool:
# 核心线程池大小
core-pool-size: 10
core-pool-size: 25
# 最大线程数
max-pool-size: 30
# 活跃时间
keep-alive-seconds: 60
keep-alive-seconds: 50
# 队列容量
queue-capacity: 50
queue-capacity: 30
#七牛云
qiniu:
......
......@@ -22,7 +22,7 @@
<appender-ref ref="console" />
</logger>
<logger name="jdbc.resultset" level="ERROR" additivity="false">
<logger name="jdbc.resultset" level="INFO" additivity="false">
<appender-ref ref="console" />
</logger>
......
......@@ -166,8 +166,8 @@ class BackendApplicationTests {
});
log.info(">> 检测报告下载完成!");
frameDriver.close();
driver.close();
frameDriver.quit();
driver.quit();
}
......@@ -315,8 +315,8 @@ class BackendApplicationTests {
//点击上传已勾选的文件
frameDriver.findElement(new By.ById("Button3")).click();
frameDriver.close();
driver.close();
frameDriver.quit();
driver.quit();
log.info(">> ======== 资料已上传完成 =========== <<");
}
......
package me.zhengjie;
import cn.hutool.core.img.Img;
import cn.hutool.core.io.FileUtil;
import me.zhengjie.modules.security.service.UserDetailsServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
......@@ -16,38 +18,20 @@ public class LoginCacheTest {
@Resource(name = "userDetailsService")
private UserDetailsServiceImpl userDetailsService;
public synchronized void testSyncronized(Integer i){
System.out.println(i + "进入同步方法");
}
public void testSync(Integer i){
System.out.println(i + "开始异步执行同步方法。。。");
if(i ==2){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
@Test
public void testCreateFileDirect(){
String dir = "666";
if(!FileUtil.exist("C:\\reptiles\\uploadPicture\\" + dir)){
FileUtil.mkdir("C:\\reptiles\\uploadPicture\\" + dir);
}
testSyncronized(i);
}
@Test
public void testCache() {
long start1 = System.currentTimeMillis();
int size = 10000;
for (int i = 0; i < size; i++) {
userDetailsService.loadUserByUsername("admin");
}
long end1 = System.currentTimeMillis();
//关闭缓存
userDetailsService.setEnableCache(false);
long start2 = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
userDetailsService.loadUserByUsername("admin");
}
long end2 = System.currentTimeMillis();
System.out.print("使用缓存:" + (end1 - start1) + "毫秒\n 不使用缓存:" + (end2 - start2) + "毫秒");
Img.from(FileUtil.file("C:\\Users\\Lander.LAPTOP-6VMQUJS1\\Desktop\\test-report\\桂BFF605_xsz2.jpg"))
.setQuality(0.8)//压缩比率
.write(FileUtil.file("C:\\Users\\Lander.LAPTOP-6VMQUJS1\\Desktop\\test-report\\桂BFF605_xsz2.jpg"));
}
@Test
......
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