package cn.iocoder.yudao.module.mes.controller.admin.pro.qrexport; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.security.core.service.SecurityFrameworkService; import cn.iocoder.yudao.module.mes.controller.admin.pro.qrexport.vo.MesProQrExportCountRespVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.qrexport.vo.MesProQrExportTaskRespVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.qrexport.vo.MesProQrExportTaskSubmitReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.qrexport.MesProQrExportTaskDO; import cn.iocoder.yudao.module.mes.enums.pro.MesProQrExportBizTypeEnum; import cn.iocoder.yudao.module.mes.enums.pro.MesProQrExportTaskStatusEnum; import cn.iocoder.yudao.module.mes.framework.qrexport.MesProQrExportProperties; import cn.iocoder.yudao.module.mes.service.pro.qrexport.MesProQrExportTaskService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.io.IOException; import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.FORBIDDEN; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_QR_EXPORT_PARAMS_INVALID; /** * 二维码大批量导出任务接口 *
* 数量不超过分界线的导出不走这里(调用方直接调原下载接口,秒级返回、不排队); * 超过分界线才提交任务、轮询进度、完成后下载。 *
* 说明:下载与取消未额外限制「只能操作自己创建的任务」。能进入本接口的用户已持有对应模块的导出权限,
* 也就已经可以直接调用同步导出接口拿到同样的 ZIP 内容,再加一层创建人校验并不能提供实际保护。
*/
@Tag(name = "管理后台 - MES 二维码导出任务")
@RestController
@RequestMapping("/mes/pro/qr-export")
@Validated
public class MesProQrExportTaskController {
/**
* 任一模块的导出权限即可访问本接口;具体业务类型再逐项校验
*/
private static final String ANY_EXPORT_PERMISSION =
"@ss.hasAnyPermissions('mes:pro-bag-code:export','mes:pro-pallet:export','mes:pro-batch:export')";
@Resource
private MesProQrExportTaskService taskService;
@Resource
private MesProQrExportProperties properties;
@Resource
private SecurityFrameworkService securityFrameworkService;
@GetMapping("/count")
@Operation(summary = "统计二维码导出张数并给出导出方式(SYNC 直接下载 / ASYNC 后台任务)")
@PreAuthorize(ANY_EXPORT_PERMISSION)
public CommonResult
* 单靠「任一导出权限」会让只有托盘导出权限的用户也能导出袋码,故按类型再校验一次。
*/
private void assertBizPermission(MesProQrExportBizTypeEnum bizType) {
String permission = switch (bizType) {
case BAG_LABEL, BAG_BUSINESS -> "mes:pro-bag-code:export";
case PALLET_LABEL, PALLET_BUSINESS -> "mes:pro-pallet:export";
case BATCH_LABEL, BATCH_BUSINESS -> "mes:pro-batch:export";
};
if (!securityFrameworkService.hasAnyPermissions(permission)) {
throw exception(FORBIDDEN);
}
}
private MesProQrExportTaskRespVO convert(MesProQrExportTaskDO task) {
MesProQrExportTaskRespVO respVO = new MesProQrExportTaskRespVO();
respVO.setId(task.getId());
respVO.setBizType(task.getBizType());
respVO.setTaskName(task.getTaskName());
respVO.setStatus(task.getStatus());
MesProQrExportTaskStatusEnum statusEnum = parseStatus(task.getStatus());
respVO.setStatusName(statusEnum == null ? null : statusEnum.getName());
respVO.setTotalCount(task.getTotalCount());
respVO.setFinishedCount(task.getFinishedCount());
respVO.setProgress(calcProgress(task));
respVO.setFileSize(task.getFileSize());
respVO.setErrorMsg(task.getErrorMsg());
respVO.setDownloadable(MesProQrExportTaskStatusEnum.FINISHED.getStatus().equals(task.getStatus())
&& task.getFilePath() != null && !task.getFilePath().isBlank());
respVO.setCreateTime(task.getCreateTime());
respVO.setFinishTime(task.getFinishTime());
return respVO;
}
private Integer calcProgress(MesProQrExportTaskDO task) {
Integer total = task.getTotalCount();
if (total == null || total <= 0) {
return 0;
}
int finished = task.getFinishedCount() == null ? 0 : task.getFinishedCount();
return (int) Math.min(100L, (long) finished * 100 / total);
}
private MesProQrExportTaskStatusEnum parseStatus(Integer status) {
if (status == null) {
return null;
}
for (MesProQrExportTaskStatusEnum value : MesProQrExportTaskStatusEnum.values()) {
if (value.getStatus().equals(status)) {
return value;
}
}
return null;
}
}