package jnpf.onlinedev.service; import cn.dev33.satoken.stp.StpUtil; import jnpf.base.UserInfo; import jnpf.base.entity.VisualdevEntity; import jnpf.base.entity.VisualdevReleaseEntity; import jnpf.base.service.UploadEditAccess; import jnpf.base.service.VisualdevReleaseService; import jnpf.base.service.VisualdevService; import jnpf.base.util.FlowFormDataUtil; import jnpf.base.util.UploadEditStateMachine; import jnpf.exception.DataException; import jnpf.exception.WorkFlowException; import jnpf.onlinedev.model.OnlineInfoModel; import jnpf.onlinedev.model.PaginationModel; import jnpf.onlinedev.model.UploadTemplateQuery; import jnpf.onlinedev.util.OnlinePublicUtils; import jnpf.util.JsonUtil; import jnpf.util.TicketUtil; import jnpf.util.UserProvider; import jnpf.util.context.RequestContext; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.*; /** 上传模板入口:复用原生查询与权限,只授权文件引用,不复制文件或保存业务单据。 */ @Service @RequiredArgsConstructor public class UploadTemplateService { static final String MODEL_ID = "859351030394158725"; static final String MENU_ID = "859363791895428741"; private final VisualdevReleaseService releases; private final VisualdevService models; private final VisualDevListService lists; private final FlowFormDataUtil formData; private final UploadEditAccess access; public Map list(UploadTemplateQuery query) throws WorkFlowException { access.authorizeTemporary(query.getContext(), UserProvider.getLoginUserId()); StpUtil.checkPermission(MODEL_ID); if (query.getCurrentPage() < 1 || query.getCurrentPage() > 100000 || query.getKeyword() != null && query.getKeyword().length() > 200) { throw new DataException("模板查询参数无效"); } VisualdevReleaseEntity release = releases.getById(MODEL_ID); VisualdevEntity model = models.getReleaseInfo(MODEL_ID); if (release == null || model == null) throw new DataException("文件/记录模板管理尚未发布"); PaginationModel page = new PaginationModel(); page.setCurrentPage(query.getCurrentPage()); page.setPageSize(20); page.setMenuId(MENU_ID); page.setSystemCode(RequestContext.getAppCode()); page.setQueryJson(JsonUtil.getObjectToString(Collections.singletonMap("wenben_mingcheng", Objects.toString(query.getKeyword(), "").trim()))); List> rows = lists.getDataList(OnlinePublicUtils.getVisualJsonModel(release), page); List> result = new ArrayList<>(); for (Map row : rows) { String id = UploadEditAccess.rowId(row); if (id.isBlank()) continue; // 仅对原生权限查询可见的记录读取详情;详情继续执行源表单字段权限。 Map detail = formData.getFilePermissionDataInfo(model, id, OnlineInfoModel.builder().menuId(MENU_ID).build()); if (detail == null || detail.isEmpty()) continue; List> files = UploadEditStateMachine.files(detail.get("biz_files")).stream() .filter(UploadTemplateService::isDocx).map(UploadTemplateService::canonical).toList(); result.add(Map.of("id", id, "name", Objects.toString(detail.get("wenben_mingcheng"), ""), "files", files)); } return Map.of("list", result, "total", page.getTotal(), "currentPage", page.getCurrentPage(), "pageSize", 20); } @SuppressWarnings("unchecked") public Map select(UploadTemplateQuery query) throws WorkFlowException { // 重新校验当前页、数据权限及文件成员关系;不接受列表展示时的过期授权。 Map page = list(query); List> rows = (List>) page.get("list"); Map row = rows.stream().filter(r -> Objects.equals(r.get("id"), query.getTemplateId())) .findFirst().orElseThrow(() -> new DataException("模板已变化或无权使用,请刷新模板列表")); List> files = (List>) row.get("files"); Map file = files.stream().filter(f -> Objects.equals(f.get("fileId"), query.getFileId())) .findFirst().orElseThrow(() -> new DataException("模板文件已变化,请重新选择")); UserInfo user = UserProvider.getUser(); Map selected = new LinkedHashMap<>(file); jnpf.base.model.uploadedit.UploadEditContext target = new jnpf.base.model.uploadedit.UploadEditContext(); target.setModelId(query.getContext().getModelId()); target.setField(query.getContext().getField()); target.setParentField(query.getContext().getParentField()); if (access.isDmsAuditTemporary(target) && "wenjian".equals(query.getContext().getField()) && (query.getContext().getParentField() == null || query.getContext().getParentField().isBlank())) selected.put(jnpf.base.util.UploadTemplateSource.FIELD, query.getTemplateId()); Map proof = new LinkedHashMap<>(selected); proof.put("purpose", "upload-edit-source"); proof.put("tenantId", user.getTenantId() == null || user.getTenantId().isEmpty() ? "0" : user.getTenantId()); proof.put("ownerId", user.getUserId()); Map result = new LinkedHashMap<>(selected); result.put("uploadReceipt", TicketUtil.createTicket(JsonUtil.getObjectToString(proof), 86400L)); return result; } static boolean isDocx(Map file) { return !Objects.toString(file.get("fileId"), "").isBlank() && Objects.toString(file.get("name"), "").toLowerCase(Locale.ROOT).endsWith(".docx"); } static Map canonical(Map file) { Map result = new LinkedHashMap<>(); for (String key : List.of("fileId", "name", "fileSize", "fileExtension", "url", "contentSavedAt")) result.put(key, file.get(key)); result.put("fileExtension", "docx"); return result; } }