src/main/java/com/ruoyi/basic/enums/RecordTypeEnum.java
@@ -7,7 +7,207 @@ SALES_LEDGER("sales_ledger"), SUPPLIER_MANAGE("supplier_manage"), APPROVAL_PROCESS("approval_process"), QR_CODE_SCAN_RECORDS("qr_code_scan_records"); QR_CODE_SCAN_RECORDS("qr_code_scan_records"), // Water Record WATER_RECORD("water_record"), // Warehouse WAREHOUSE_GOODS_SHELVES_ROWCOL("warehouse_goods_shelves_rowcol"), WAREHOUSE_GOODS_SHELVES("warehouse_goods_shelves"), DOCUMENTATION_FILE("documentation_file"), DOCUMENTATION_RETURN_MANAGEMENT("documentation_return_management"), DOCUMENTATION_BORROW_MANAGEMENT("documentation_borrow_management"), DOCUMENTATION("documentation"), WAREHOUSE("warehouse"), DOCUMENT_CLASSIFICATION("document_classification"), // Technology TECHNOLOGY_ROUTING_OPERATION_PARAM("technology_routing_operation_param"), TECHNOLOGY_ROUTING("technology_routing"), TECHNOLOGY_ROUTING_OPERATION("technology_routing_operation"), TECHNOLOGY_BOM("technology_bom"), TECHNOLOGY_PARAM("technology_param"), TECHNOLOGY_OPERATION_PARAM("technology_operation_param"), TECHNOLOGY_OPERATION("technology_operation"), TECHNOLOGY_BOM_STRUCTURE("technology_bom_structure"), // Stock STOCK_OUT_RECORD("stock_out_record"), STOCK_UNINVENTORY("stock_uninventory"), STOCK_INVENTORY("stock_inventory"), STOCK_IN_RECORD("stock_in_record"), // Staff STAFF_WORK_EXPERIENCE("staff_work_experience"), STAFF_SALARY_MAIN("staff_salary_main"), STAFF_SCHEDULING("staff_scheduling"), STAFF_SALARY_DETAIL("staff_salary_detail"), STAFF_ON_JOB("staff_on_job"), STAFF_LEAVE("staff_leave"), STAFF_CONTRACT("staff_contract"), STAFF_EMERGENCY_CONTACT("staff_emergency_contact"), STAFF_EDUCATION("staff_education"), SCHEME_APPLICABLE_STAFF("scheme_applicable_staff"), PERSONAL_SHIFT("personal_shift"), SCHEME_INSURANCE_DETAIL("scheme_insurance_detail"), PERSONAL_ATTENDANCE_RECORDS("personal_attendance_records"), PERSONAL_ATTENDANCE_LOCATION_CONFIG("personal_attendance_location_config"), BANK("bank"), HOLIDAY_APPLICATION("holiday_application"), // Sales SHIPMENT_APPROVAL("shipment_approval"), SALESPERSON_MANAGEMENT("salesperson_management"), SALES_QUOTATION_PRODUCT("sales_quotation_product"), SALES_QUOTATION("sales_quotation"), SALES_LEDGER_PRODUCT("sales_ledger_product"), PURCHASE_LEDGER_FILE("purchase_ledger_file"), RECEIPT_PAYMENT("receipt_payment"), PAYMENT_SHIPPING("payment_shipping"), INVOICE_REGISTRATION_PRODUCT("invoice_registration_product"), LOSS("loss"), INVOICE_REGISTRATION("invoice_registration"), INVOICE_LEDGER_FILE("invoice_ledger_file"), INVOICE_LEDGER("invoice_ledger"), COMMON_FILE("common_file"), // Safe SAFE_TRAINING_FILE("safe_training_file"), SAFE_TRAINING_DETAILS("safe_training_details"), SAFE_TRAINING("safe_training"), SAFE_HIDDEN_FILE("safe_hidden_file"), SAFE_HAZARD_RECORD("safe_hazard_record"), SAFE_HIDDEN("safe_hidden"), SAFE_HAZARD("safe_hazard"), SAFE_CONTINGENCY_PLAN("safe_contingency_plan"), SAFE_CERTIFICATION_FILE("safe_certification_file"), SAFE_CERTIFICATION("safe_certification"), SAFE_ACCIDENT("safe_accident"), // Quality QUALITY_UNQUALIFIED("quality_unqualified"), QUALITY_TEST_STANDARD_PARAM("quality_test_standard_param"), QUALITY_TEST_STANDARD_BINDING("quality_test_standard_binding"), QUALITY_TEST_STANDARD("quality_test_standard"), QUALITY_INSPECT_FILE("quality_inspect_file"), QUALITY_INSPECT_PARAM("quality_inspect_param"), QUALITY_INSPECT("quality_inspect"), // Purchase TICKET_REGISTRATION("ticket_registration"), PURCHASE_RETURN_ORDER_PRODUCTS("purchase_return_order_products"), PURCHASE_RETURN_ORDERS("purchase_return_orders"), SALES_LEDGER_PRODUCT_TEMPLATE("sales_ledger_product_template"), PURCHASE_LEDGER("purchase_ledger"), PURCHASE_LEDGER_TEMPLATE("purchase_ledger_template"), PRODUCT_RECORD("product_record"), PAYMENT_REGISTRATION("payment_registration"), INVOICE_PURCHASE("invoice_purchase"), // Project Management SHIPPING_ADDRESS("shipping_address"), ROLES("roles"), PLAN("plan"), PLAN_NODE("plan_node"), INFO_STAGE("info_stage"), CONTRACT_INFO("contract_info"), INFO("info"), // Production PRODUCTION_PRODUCT_OUTPUT("production_product_output"), PRODUCTION_ORDER_ROUTING_OPERATION("production_order_routing_operation"), PRODUCTION_PRODUCT_INPUT("production_product_input"), PRODUCTION_PRODUCT_MAIN("production_product_main"), PRODUCTION_PLAN("production_plan"), PRODUCTION_ORDER_ROUTING_OPERATION_PARAM("production_order_routing_operation_param"), PRODUCTION_ORDER_ROUTING("production_order_routing"), PRODUCTION_ORDER_PICK_RECORD("production_order_pick_record"), PRODUCTION_ORDER_PICK("production_order_pick"), PRODUCTION_ORDER_BOM("production_order_bom"), PRODUCTION_OPERATION_TASK("production_operation_task"), PRODUCTION_ORDER("production_order"), PRODUCTION_ACCOUNT("production_account"), PRODUCTION_BOM_STRUCTURE("production_bom_structure"), PRODUCTION_OPERATION_MAIN_PARAM("production_operation_main_param"), // Procurement Record RETURN_SALE_PRODUCT("return_sale_product"), PROCUREMENT_PLAN("procurement_plan"), PROCUREMENT_RECORD_OUT("procurement_record_out"), PROCUREMENT_RECORD_STORAGE("procurement_record_storage"), RETURN_MANAGEMENT("return_management"), PROCUREMENT_PRICE_MANAGEMENT("procurement_price_management"), GAS_TANK_WARNING("gas_tank_warning"), CUSTOM_STORAGE("custom_storage"), PROCUREMENT_EXCEPTION_RECORD("procurement_exception_record"), INBOUND_MANAGEMENT("inbound_management"), // Office Supplies OFFICE_SUPPLIES("office_supplies"), // OA OA_PROJECT_PHASE_TASK("oa_project_phase_task"), OA_PROJECT("oa_project"), OA_PROJECT_PHASE("oa_project_phase"), // Measuring Instrument Ledger SPARE_PARTS("spare_parts"), MEASURING_INSTRUMENT_LEDGER_RECORD("measuring_instrument_ledger_record"), MEASURING_INSTRUMENT_LEDGER("measuring_instrument_ledger"), SPARE_PARTS_REQUISITION_RECORD("spare_parts_requisition_record"), // Labor Issue LABOR_ISSUE("labor_issue"), // Inspection Task TIMING_TASK("timing_task"), QR_CODE("qr_code"), // Equipment Energy Consumption ENERGY_PERIOD("energy_period"), EQUIPMENT_ENERGY_CONSUMPTION("equipment_energy_consumption"), ELECTRICITY_CONSUMPTION_AREA("electricity_consumption_area"), // Device MAINTENANCE_TASK("maintenance_task"), DEVICE_REPAIR("device_repair"), DEVICE_MAINTENANCE_FILE("device_maintenance_file"), DEVICE_DEFECT_RECORD("device_defect_record"), DEVICE_MAINTENANCE("device_maintenance"), DEVICE_LEDGER("device_ledger"), // Customer Visits CUSTOMER_VISITS("customer_visits"), // Compensation Performance COMPENSATION_PERFORMANCE("compensation_performance"), // Collaborative Approval STAFF_CONTACTS_PERSONAL("staff_contacts_personal"), SEAL_APPLICATION_MANAGEMENT("seal_application_management"), RULES_REGULATIONS_MANAGEMENT_FILE("rules_regulations_management_file"), RULES_REGULATIONS_MANAGEMENT("rules_regulations_management"), READING_STATUS("reading_status"), NOTICE("notice"), NOTICE_TYPE("notice_type"), MEET_DRAFT("meet_draft"), MEETING_ROOM("meeting_room"), MEETING_MINUTES("meeting_minutes"), MEET_APPLICATION("meet_application"), DUTY_PLAN("duty_plan"), // Basic SUPPLIER_MANAGE_FILE("supplier_manage_file"), PRODUCT_MODEL("product_model"), CUSTOMER_RETURN_VISIT("customer_return_visit"), PRODUCT("product"), CUSTOMER("customer"), CUSTOMER_PRIVATE_POOL("customer_private_pool"), CUSTOMER_FOLLOW_UP_FILE("customer_follow_up_file"), CUSTOMER_FOLLOW_UP("customer_follow_up"), CUSTOMER_PRIVATE("customer_private"), // Approve WORKING_HOURS_SETTING("working_hours_setting"), OVERTIME_SETTING("overtime_setting"), RPA_PROCESS_AUTOMATION("rpa_process_automation"), HOLIDAY_SETTINGS("holiday_settings"), ONLINE_MEETING("online_meeting"), KNOWLEDGE_BASE("knowledge_base"), NOTIFICATION_MANAGEMENT("notification_management"), APPROVE_NODE("approve_node"), APPROVE_PROCESS_CONFIG_NODE("approve_process_config_node"), APPROVE_LOG("approve_log"), ANNUAL_LEAVE_SETTING("annual_leave_setting"), FILE_SHARING("file_sharing"), // After Sales Service AFTER_SALES_SERVICE("after_sales_service"), AFTER_SALES_SERVICE_FILE("after_sales_service_file"), AFTER_SALES_NEAR_EXPIRY("after_sales_near_expiry"), // Account ACCOUNT_INCOME("account_income"), BORROW_INFO("borrow_info"), SALES_REFUND_AMOUNT_ORDER("sales_refund_amount_order"), SALES_RECEIPT_RETURN("sales_receipt_return"), ACCOUNT_EXPENSE("account_expense"), ACCOUNT_FILE("account_file"); private final String type; RecordTypeEnum(String type) { this.type = type; } src/main/java/com/ruoyi/basic/utils/FileUtil.java
@@ -369,6 +369,24 @@ } /** * 通过文件用途、关联记录类型、关联记录id获取文件关联信息 attachment * * @param recordType 关联记录类型 * @param recordId 关联记录id */ public List<StorageAttachment> getStorageAttachmentsByRecordTypeAndRecordId(RecordTypeEnum recordType, Long recordId) { if (recordId == null || recordId <= 0) { throw new RuntimeException("关联记录id不能为空"); } if (recordType == null) { throw new RuntimeException("关联记录类型不能为空"); } return storageAttachmentMapper.selectList(new LambdaQueryWrapper<StorageAttachment>() .eq(StorageAttachment::getRecordType, recordType.getType()) .eq(StorageAttachment::getRecordId, recordId)); } /** * 通过文件用途、关联记录类型、关联记录id获取文件信息 blob * * @param application 文件用途 @@ -394,6 +412,30 @@ } /** * 通过文件用途、关联记录类型、关联记录id获取文件信息 blob * * @param recordType 关联记录类型 * @param recordId 关联记录id */ public List<StorageBlobVO> getStorageBlobVOsByRecordTypeAndRecordId(RecordTypeEnum recordType, Long recordId) { List<StorageAttachment> storageAttachments = getStorageAttachmentsByRecordTypeAndRecordId(recordType, recordId); if (CollectionUtils.isEmpty(storageAttachments)) { return null; } List<Long> storageBlobIds = storageAttachments.stream().map(StorageAttachment::getStorageBlobId).collect(Collectors.toList()); List<StorageBlob> storageBlobs = storageBlobMapper.selectByIds(storageBlobIds); List<StorageBlobVO> storageBlobDTOS = new ArrayList<>(); for (StorageBlob storageBlob : storageBlobs) { StorageBlobVO storageBlobVO = new StorageBlobVO(); BeanUtils.copyProperties(storageBlob, storageBlobVO); storageBlobVO.setPreviewURL(buildSignedPreviewUrl(storageBlobVO)); storageBlobVO.setDownloadURL(buildSignedDownloadUrl(storageBlobVO)); storageBlobDTOS.add(storageBlobVO); } return storageBlobDTOS; } /** * 通过文件用途、关联记录类型、关联记录id获取文件信息 自定义过期时间(分钟) blob * * @param application 文件用途 src/main/java/com/ruoyi/projectManagement/service/impl/PlanServiceImpl.java
@@ -6,7 +6,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.ruoyi.basic.dto.StorageBlobVO; import com.ruoyi.basic.enums.RecordTypeEnum; import com.ruoyi.basic.service.CustomerFollowUpFileService; import com.ruoyi.basic.utils.FileUtil; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.projectManagement.mapper.PlanMapper; import com.ruoyi.projectManagement.mapper.PlanNodeMapper; @@ -40,6 +43,7 @@ private final CustomerFollowUpFileService customerFollowUpFileService; private final PlanNodeMapper planNodeMapper; private final FileUtil fileUtil; @Lazy @Autowired @@ -49,9 +53,8 @@ @Transactional(rollbackFor = Exception.class) public void savePlan(SavePlanVo savePlanVo) { Plan plan = BeanUtil.copyProperties(savePlanVo, Plan.class); // 附件处理 , 拼接 String attachments = String.join(",", Optional.ofNullable(savePlanVo.getAttachmentIds()).orElse(Collections.emptyList())); plan.setAttachment(attachments); // 附件处理 fileUtil.saveStorageAttachmentByRecordTypeAndRecordId("", RecordTypeEnum.PLAN, savePlanVo.getId(), savePlanVo.getStorageBlobDTOs()); if (savePlanVo.getId() == null) { planMapper.insert(plan); } else { @@ -136,12 +139,14 @@ IPage<Plan> planIPage = planMapper.selectPlanPage(searchPlanVo); IPage<PlanVo> resultPage = planIPage.convert(plan -> BeanUtil.copyProperties(plan, PlanVo.class)); // 文件获取 customerFollowUpFileService.fillAttachment(resultPage.getRecords(), PlanVo::getAttachment, PlanVo::setAttachmentList); Map<Long, List<PlanNodeVo>> collect = getPlanNodeByPlanIds(resultPage.getRecords().stream().map(PlanVo::getId).collect(Collectors.toList())) .stream() .map(it -> BeanUtil.copyProperties(it, PlanNodeVo.class)) .collect(Collectors.groupingBy(PlanNodeVo::getProjectManagementPlanId, Collectors.toList())); resultPage.getRecords().forEach(planVo -> planVo.setPlanNodeList(collect.getOrDefault(planVo.getId(), Collections.emptyList()))); resultPage.getRecords().forEach(planVo -> { planVo.setPlanNodeList(collect.getOrDefault(planVo.getId(), Collections.emptyList())); planVo.setStorageBlobVOs(fileUtil.getStorageBlobVOsByRecordTypeAndRecordId(RecordTypeEnum.PLAN, planVo.getId())); }); return resultPage; } src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoStageHandleService.java
@@ -4,7 +4,10 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.ruoyi.basic.dto.StorageBlobVO; import com.ruoyi.basic.enums.RecordTypeEnum; import com.ruoyi.basic.service.CustomerFollowUpFileService; import com.ruoyi.basic.utils.FileUtil; import com.ruoyi.common.enums.IsDeleteEnum; import com.ruoyi.common.enums.PlanStageEnum; import com.ruoyi.projectManagement.dto.InfoStageDto; @@ -40,6 +43,7 @@ @Lazy @Autowired private InfoStageHandleService infoStageHandleService; private final FileUtil fileUtil; @Transactional public void save(@NotNull SaveInfoStageVo saveInfoStageVo) { @@ -47,6 +51,8 @@ // 附件处理 String attachmentIds = StrUtil.join(",", Optional.ofNullable(saveInfoStageVo.getAttachmentIds()).orElse(Collections.emptyList())); infoStage.setAttachment(attachmentIds); fileUtil.saveStorageAttachmentByRecordTypeAndRecordId("", RecordTypeEnum.INFO_STAGE, infoStage.getProjectManagementInfoId(), saveInfoStageVo.getStorageBlobDTOs()); if (infoStage.getId() == null) { infoStageMapper.insert(infoStage); @@ -153,7 +159,10 @@ List<InfoStageDto> listByInfoId = getListDtoByInfoId(infoId); List<InfoStageVo> infoStageVos = BeanUtil.copyToList(listByInfoId, InfoStageVo.class); // 处理附件 customerFollowUpFileService.fillAttachment(infoStageVos, InfoStageVo::getAttachment, InfoStageVo::setAttachmentList); for (InfoStageVo infoStageVo : infoStageVos) { List<StorageBlobVO> storageBlobVOs = fileUtil.getStorageBlobVOsByRecordTypeAndRecordId(RecordTypeEnum.INFO_STAGE, infoStageVo.getId()); infoStageVo.setStorageBlobVOs(storageBlobVOs != null ? storageBlobVOs : new ArrayList<>()); } return infoStageVos; } src/main/java/com/ruoyi/projectManagement/vo/InfoStageVo.java
@@ -1,5 +1,6 @@ package com.ruoyi.projectManagement.vo; import com.ruoyi.basic.dto.StorageBlobVO; import com.ruoyi.common.vo.SimpleFileVo; import com.ruoyi.projectManagement.dto.InfoStageDto; import lombok.AllArgsConstructor; @@ -21,4 +22,5 @@ public class InfoStageVo extends InfoStageDto implements java.io.Serializable { private List<SimpleFileVo> attachmentList; // 附件列表 private List<StorageBlobVO> storageBlobVOs; } src/main/java/com/ruoyi/projectManagement/vo/PlanVo.java
@@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnore; import com.ruoyi.basic.dto.StorageBlobDTO; import com.ruoyi.basic.dto.StorageBlobVO; import com.ruoyi.common.vo.SimpleFileVo; import lombok.AllArgsConstructor; import lombok.Data; @@ -44,5 +46,5 @@ private LocalDateTime updateTime; private List<PlanNodeVo> planNodeList; private List<StorageBlobVO> storageBlobVOs; } src/main/java/com/ruoyi/projectManagement/vo/SaveInfoStageVo.java
@@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.basic.dto.StorageBlobDTO; import com.ruoyi.basic.dto.StorageBlobVO; import com.ruoyi.projectManagement.dto.InfoStageDto; import lombok.AllArgsConstructor; import lombok.Data; @@ -24,5 +26,5 @@ public class SaveInfoStageVo extends InfoStageDto implements java.io.Serializable { private List<String> attachmentIds; private List<StorageBlobDTO> StorageBlobDTOs; } src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java
@@ -1,6 +1,7 @@ package com.ruoyi.projectManagement.vo; import com.ruoyi.basic.dto.StorageBlobDTO; import com.ruoyi.sales.pojo.SalesLedgerProduct; import lombok.AllArgsConstructor; import lombok.Data; @@ -32,5 +33,5 @@ @Valid private List<SavePlanNodeVo> savePlanNodeList; private List<StorageBlobDTO> storageBlobDTOs; } src/main/java/com/ruoyi/projectManagement/vo/SearchPlanVo.java
@@ -1,12 +1,15 @@ package com.ruoyi.projectManagement.vo; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.basic.dto.StorageBlobDTO; import com.ruoyi.basic.dto.StorageBlobVO; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.List; /** * @author buhuazhen src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.basic.dto.StorageBlobDTO; import com.ruoyi.basic.dto.StorageBlobVO; import com.ruoyi.sales.pojo.CommonFile; import com.ruoyi.sales.pojo.SalesLedgerProduct; import io.swagger.v3.oas.annotations.media.Schema; @@ -61,4 +62,5 @@ private LocalDate deliveryDate; private List<StorageBlobDTO> storageBlobDTOs; private List<StorageBlobVO> StorageBlobVOs; } src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.service.AccountIncomeService; import com.ruoyi.basic.dto.CustomerPrivatePoolDto; import com.ruoyi.basic.dto.StorageBlobVO; import com.ruoyi.basic.enums.ApplicationTypeEnum; import com.ruoyi.basic.enums.RecordTypeEnum; import com.ruoyi.basic.mapper.CustomerMapper; @@ -199,6 +200,9 @@ resultDto.setProductData(products); resultDto.setSalesLedgerFiles(salesLedgerFiles); } // 5. 查询附件 List<StorageBlobVO> StorageBlobVOs = fileUtil.getStorageBlobVOsByRecordTypeAndRecordId(RecordTypeEnum.SALES_LEDGER, salesLedger.getId()); resultDto.setStorageBlobVOs(StorageBlobVOs); return resultDto; }