通过实现文件上传下载的任务中心功能,可以将一个产品中所有涉及到文件下载的地方,在文件下载后,都去任务中心统一查看和下载。
任务中心的表结构如下:
创建SQL语句:
CREATE TABLE `mission_center` (
`mission_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`file_id` decimal(10,0) DEFAULT NULL COMMENT '文件id',
`mission_name` varchar(63) DEFAULT NULL COMMENT '任务名称/附件名',
`mission_status_code` varchar(100) NOT NULL COMMENT '任务状态',
`mission_type_code` varchar(100) NOT NULL COMMENT '任务类型',
`iam_organization_id` bigint(20) NOT NULL COMMENT '租户ID',
`user_id` bigint(20) DEFAULT NULL COMMENT '账户id',
`download_times` bigint(20) DEFAULT '0' COMMENT '下载次数',
`remarks` text COMMENT '备注',
`is_deleted` varchar(2) NOT NULL DEFAULT 'N' COMMENT '删除状态',
`object_version_number` bigint(20) NOT NULL DEFAULT '1' COMMENT '行版本号,用来处理锁',
`created_by` bigint(20) NOT NULL DEFAULT '-1',
`creation_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_updated_by` bigint(20) NOT NULL DEFAULT '-1',
`last_update_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`mission_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4288 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
查询任务中心SQL,可以查询到登录用户的任务中心列表:
List<FileMissionCenter> fileMissionCenters = fileMissionCenterMapper.selectByUser(userId);
页面上显示的效果:
更新一条任务:
fileMissionCenterMapper.updateMission(fileMissionCenter)
插入一条任务:
fileMissionCenterMapper.insert(fileMissionCenter)
删除一条任务:
fileMissionCenterMapper.deleteMission(missionId)
如果是在微服务产品中,可以将任务中心单独封装成一个服务之后,在其他服务中调用任务中心。
@FeignClient(value = "yqcloud-scheduler-server", fallback = JobFeignClientFallback.class)
public interface JobFeignClient {
@PostMapping("/v1/{iam_organization_id}/file/mission/center")
@ResponseBody
@ApiOperation(value = "添加任务中心")
FileMissionCenter insertMission(@PathVariable(name = "iam_organization_id") Long iamOrganizationId,
@RequestParam(value = "missionTypeCode", required = false) String missionTypeCode, @RequestBody FileMissionCenter fileMissionCenter);
@PutMapping("/v1/{iam_organization_id}/file/mission/edit")
@ResponseBody
@ApiOperation(value = "更新任务")
Integer updateMission(@PathVariable(name = "iam_organization_id") Long iamOrganizationId, @RequestBody FileMissionCenter fileMissionCenter);
}
调用的代码:
public Boolean downLoadZipToMissionCenter(Long iamOrganizationId, Long eventId, HttpServletRequest request) {
EventOrder eventOrder = eventOrderV2Service.queryById(iamOrganizationId, eventId);
Long userId = AuditHelper.audit().getUser();
FileMissionCenter fileMissionCenter = new FileMissionCenter();
fileMissionCenter.setUserId(userId);
fileMissionCenter.setMissionStatusCode("processing");
fileMissionCenter.setMissionTypeCode("EXPORT");
fileMissionCenter.setMissionName(eventOrder.getTitle() + "Zip下载deno");
//先插入文件操作类型和任务状态为进行中
FileMissionCenter mission = schedulerFeignClient.insertMission(iamOrganizationId, EXPORT, fileMissionCenter);
if (mission.getMissionId() == null) {
throw new CommonException("mission.insert.failure");
}
fileMissionCenter.setMissionId(mission.getMissionId());
Boolean result = true;
try {
//方法中调用文件服务
downLoadZip(request,iamOrganizationId,eventOrder,fileMissionCenter);
} catch (Exception e) {
//当出现异常时,修改导入的状态为失败
fileMissionCenter.setRemarks(e.getMessage());
fileMissionCenter.setMissionStatusCode("failure");
schedulerFeignClient.updateMission(iamOrganizationId, fileMissionCenter);
}
return result;
}
downLoadZip部分代码:在将文件上传到文件服务器成功后,将文件id写入任务中,并修改任务状态为success
//插入任务中心表
FileMissionCenter fileMissionCenter = new FileMissionCenter();
fileMissionCenter.setMissionId(missionId);
fileMissionCenter.setFileId(fileDO.getFileId());//上传的文件id
fileMissionCenter.setMissionStatusCode("success");
fileMissionCenter.setMissionTypeCode(missionTypeCode);
fileMissionCenter.setMissionName(filename);
Integer integer = schedulerFeignClient.updateMission(iamOrganizationId, fileMissionCenter);
点开任务中心后,可以将任务中心上传或者下载的文档下载下来,部分代码如下:
//通过任务id查到任务详情
FileMissionCenter fileMissionCenter = schedulerFeignClient.queryById(iamOrganizationId, missionId);
//下载任务中对应的文件
FileDO fileDO = downloadFile(iamOrganizationId, fileId);
//设置下载数
fileMissionCenter.setDownloadTimes(fileMissionCenter.getDownloadTimes() + 1);
fileMissionCenter.setMissionStatusCode("download");
Integer integer = schedulerFeignClient.updateMission(iamOrganizationId, fileMissionCenter);
删除任务和任务对应的文件:
//删除任务
fileMissionCenterMapper.deleteMission(missionId);
删除任务对应的文件
fileFeignClient.deleteFileForMission(fileMissionCenter.getIamOrganizationId(), fileMissionCenter.getFileId());
在任务中心的文件可以设置定时删除任务:
代码如下:
public int deleteMissionJob(Long iamOrganizationId, int deleteTime) {
//查询已失效的数据
List<FileMissionCenter> fileMissionCenters = fileMissionCenterMapper.invalidationData(deleteTime, iamOrganizationId);
//定时删除
int i = fileMissionCenterMapper.deleteMissionJob(deleteTime, iamOrganizationId);
if (i > 1 && fileMissionCenters.size() == i) {
Set<Long> fileIds = fileMissionCenters.stream().map(FileMissionCenter::getFileId).collect(Collectors.toSet());
//删除文件
ResponseEntity<Boolean> responseEntity = fileFeignClient.deleteFileForJob(iamOrganizationId, deleteTime, fileIds);
return i;
}
return 0;
}
查询已经失效的SQL:使用当前日期减去设定的一个过期日期是否大于创建日期来判定是否已失效。
<select id="invalidationData" resultMap="BaseResultMap">
SELECT
<include refid="queryColumn"/>
FROM mission_center
<where>
DATE_SUB(CURDATE(), INTERVAL #{deleteTime} DAY) >= date(creation_date) and is_deleted ="N"
and iam_organization_id = #{iamOrganizationId}
</where>
</select>
通过创建定时任务,每天凌晨通过定时job来执行一次这个方法就可以实现逾期自动删除。
后续梳理一下如何使用quartz实现定时任务的执行。