gaoluyang
2 天以前 feedd62ec46b9faada80505387526acf914cf4c5
海西州-同仁堂
1.添加操作日志生成
已修改30个文件
已添加4个文件
456 ■■■■■ 文件已修改
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/util/OperateLogUtils.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/filter/ApiAccessLogFilter.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/LogRecordConstants.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseOrderServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceRecordController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/enums/LogRecordConstants.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeContractServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/enums/LogRecordConstants.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/unit/MdmUnitMeasureServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/LogRecordConstants.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/metering/MesDvMeteringServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/LogRecordConstants.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/LogRecordConstants.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-server/src/main/resources/application-hm.yaml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/service/LogRecordServiceImpl.java
@@ -60,11 +60,30 @@
    public static void fillModuleFields(OperateLogCreateReqDTO reqDTO, LogRecord logRecord) {
        reqDTO.setType(logRecord.getType()); // å¤§æ¨¡å—类型,例如:CRM å®¢æˆ·
        reqDTO.setSubType(logRecord.getSubType());// æ“ä½œåç§°ï¼Œä¾‹å¦‚:转移客户
        reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // ä¸šåŠ¡ç¼–å·ï¼Œä¾‹å¦‚ï¼šå®¢æˆ·ç¼–å·
        reqDTO.setBizId(parseBizId(logRecord.getBizNo())); // ä¸šåŠ¡ç¼–å·ï¼Œä¾‹å¦‚ï¼šå®¢æˆ·ç¼–å·
        reqDTO.setAction(logRecord.getAction());// æ“ä½œå†…容,例如:修改编号为 1 çš„用户信息,将性别从男改成女,将姓名从超级管理员改成源码。
        reqDTO.setExtra(logRecord.getExtra()); // æ‹“展字段,有些复杂的业务,需要记录一些字段 ( JSON æ ¼å¼ ),例如说,记录订单编号,{ orderId: "1"}
    }
    /**
     * è§£æžä¸šåŠ¡ç¼–å·ã€‚æ‰¹é‡å¯¼å…¥ç­‰åœºæ™¯æ²¡æœ‰å•ä¸€ä¸šåŠ¡ç¼–å·ï¼ˆæ³¨è§£çš„ bizNo æ²¡å¡«æˆ–填了非数字),
     * è¿™é‡Œç”¨ 0 å…œåº•——不能让 parseLong æŠ›å¼‚常,否则 {@link #record} çš„ catch ä¼šæŠŠæ•´æ¡æ—¥å¿—静默吞掉
     *
     * @param bizNo ä¸šåŠ¡ç¼–å·å­—ç¬¦ä¸²
     * @return ä¸šåŠ¡ç¼–å·ï¼Œè§£æžå¤±è´¥æ—¶ä¸º 0
     */
    private static long parseBizId(String bizNo) {
        if (bizNo == null || bizNo.isBlank()) {
            return 0L;
        }
        try {
            return Long.parseLong(bizNo.trim());
        } catch (NumberFormatException ex) {
            log.warn("[parseBizId][业务编号({}) ä¸æ˜¯æ•°å­—,用 0 å…œåº•]", bizNo);
            return 0L;
        }
    }
    private static void fillRequestFields(OperateLogCreateReqDTO reqDTO) {
        // èŽ·å¾— Request å¯¹è±¡
        HttpServletRequest request = ServletUtils.getRequest();
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/operatelog/core/util/OperateLogUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package cn.iocoder.yudao.framework.operatelog.core.util;
import com.mzt.logapi.context.LogRecordContext;
import java.util.Collection;
import java.util.Map;
/**
 * æ“ä½œæ—¥å¿—的工具类
 *
 * ä¸»è¦è§£å†³ã€Œå¯¼å…¥ã€è¿™ç±»æ‰¹é‡æ“ä½œçš„æ—¥å¿—文案:一次导入只写一条汇总日志,
 * è€Œä¸æ˜¯é€è¡Œå†™ï¼ˆä¸€æ¬¡å¯¼å…¥å‡ ç™¾è¡Œå°±æ˜¯å‡ ç™¾æ¡æ—¥å¿—,日志页会没法看)。
 *
 * ç”¨æ³•:在导入方法返回前调用 {@link #putImportSummary},注解文案里引用 {{#importSummary}}:
 * <pre>
 * &#64;LogRecord(type = XXX_TYPE, subType = XXX_IMPORT_SUB_TYPE, bizNo = "0", success = XXX_IMPORT_SUCCESS)
 * public XxxImportRespVO importXxxList(...) {
 *     ...
 *     OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
 *     return respVO;
 * }
 * </pre>
 *
 * æ³¨æ„ï¼šæ³¨è§£çš„ bizNo å¿…须给数字(导入没有单一业务编号,统一填 "0")。
 *
 * @author è¶…级管理员
 */
public class OperateLogUtils {
    /**
     * å¯¼å…¥æ±‡æ€»æ–‡æ¡ˆåœ¨ {@link LogRecordContext} é‡Œçš„变量名,对应注解文案的 {{#importSummary}}
     */
    public static final String IMPORT_SUMMARY = "importSummary";
    /**
     * è®°å½•导入结果的汇总变量(新增/更新/失败条数),直接传各模块导入 RespVO çš„字段
     *
     * å„模块的导入结果字段形态不统一:成功的一般是 Collection(createUsernames / createList /
     * createCustomerNames â€¦ï¼‰ï¼Œå¤±è´¥çš„则多是 Map(failureList / failureDeptNames,key ä¸ºåç§°æˆ–行号),
     * ä¸”有的模块没有「更新」这一列(builder æœªèµ‹å€¼æ—¶ä¸º null)。所以这里统一按「集合 / Map / æ•°å­— / null」
     * å–条数,取不到按 0 å¤„理——统计失败不能让整条导入日志丢掉。
     *
     * @param createResult  æ–°å¢žæˆåŠŸçš„é›†åˆï¼ˆæˆ–æ¡æ•°ï¼‰
     * @param updateResult  æ›´æ–°æˆåŠŸçš„é›†åˆï¼ˆæˆ–æ¡æ•°ï¼‰ï¼Œæ²¡æœ‰åˆ™ä¼  null
     * @param failureResult å¤±è´¥çš„集合 / Map(或条数)
     */
    public static void putImportSummary(Object createResult, Object updateResult, Object failureResult) {
        LogRecordContext.putVariable(IMPORT_SUMMARY, "新增 " + size(createResult) + " æ¡ã€æ›´æ–° "
                + size(updateResult) + " æ¡ã€å¤±è´¥ " + size(failureResult) + " æ¡");
    }
    private static int size(Object result) {
        if (result == null) {
            return 0;
        }
        if (result instanceof Collection) {
            return ((Collection<?>) result).size();
        }
        if (result instanceof Map) {
            return ((Map<?, ?>) result).size();
        }
        if (result instanceof Number) {
            return ((Number) result).intValue();
        }
        return 0;
    }
}
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/filter/ApiAccessLogFilter.java
@@ -49,7 +49,22 @@
@Slf4j
public class ApiAccessLogFilter extends ApiRequestFilter {
    private static final String[] SANITIZE_KEYS = new String[]{"password", "token", "accessToken", "refreshToken"};
    /**
     * æ•æ„Ÿå­—段名列表:请求参数 / è¯·æ±‚体里命中这些 key çš„字段,不会写入访问日志
     *
     * è¿™é‡Œæ˜¯ã€Œå…¨é‡å…œåº•」名单,覆盖各模块命名不统一的密码与密钥字段:
     * 1. å¯†ç ï¼špassword、oldPassword / newPassword / confirmPassword(改名场景,精确匹配 "password" å‘½ä¸ä¸­ï¼‰
     * 2. ä»¤ç‰Œï¼štoken、accessToken / access_token、refreshToken / refresh_token(OAuth2 çš„ refresh_token èµ° query å‚数,
     *    æ˜¯ä¸‹åˆ’线命名,与原有的驼峰 refreshToken ä¸æ˜¯åŒä¸€ä¸ª key)
     * 3. å¯†é’¥ï¼šsecret、clientSecret / client_secret、apiKey / apiSecret(AI、短信)、accessKey(对象存储)、privateKey
     *
     * ä¸ªåˆ«æŽ¥å£çš„æ•æ„Ÿ key ä¸Žæ­£å¸¸ä¸šåŠ¡å­—æ®µé‡åï¼ˆä¾‹å¦‚çŸ­ä¿¡éªŒè¯ç  code、业务单据编码),不能放进这份全局名单,
     * ç”±å¯¹åº”接口自行用 @ApiAccessLog(sanitizeKeys = ...) æŒ‡å®šã€‚
     */
    private static final String[] SANITIZE_KEYS = new String[]{
            "password", "oldPassword", "newPassword", "confirmPassword",
            "token", "accessToken", "access_token", "refreshToken", "refresh_token",
            "secret", "clientSecret", "client_secret", "apiKey", "apiSecret", "accessKey", "privateKey"};
    private final String applicationName;
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java
@@ -41,8 +41,8 @@
    String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海";
    String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}";
    String CRM_CUSTOMER_RECEIVE_SUCCESS = "{{#ownerUserName != null ? '将客户【' + #customer.name + '】分配给【' + #ownerUserName + '】' : '领取客户【' + #customer.name + '】'}}";
    String CRM_CUSTOMER_IMPORT_SUB_TYPE = "{{#isUpdate ? '导入并更新客户' : '导入客户'}}";
    String CRM_CUSTOMER_IMPORT_SUCCESS = "{{#isUpdate ? '导入并更新了客户【'+ #customer.name +'】' : '导入了客户【'+ #customer.name +'】'}}";
    String CRM_CUSTOMER_IMPORT_SUB_TYPE = "导入客户";
    String CRM_CUSTOMER_IMPORT_SUCCESS = "导入了客户:{{#importSummary}}";
    String CRM_CUSTOMER_UPDATE_DEAL_STATUS_SUB_TYPE = "更新客户成交状态";
    String CRM_CUSTOMER_UPDATE_DEAL_STATUS_SUCCESS = "更新了客户【{{#customerName}}】的成交状态为【{{#dealStatus ? '已成交' : '未成交'}}】";
    String CRM_CUSTOMER_FOLLOW_UP_SUB_TYPE = "客户跟进";
@@ -117,6 +117,8 @@
    String CRM_CONTRACT_SUBMIT_SUCCESS = "提交合同【{{#contractName}}】审批成功";
    String CRM_CONTRACT_FOLLOW_UP_SUB_TYPE = "合同跟进";
    String CRM_CONTRACT_FOLLOW_UP_SUCCESS = "合同跟进【{{#contractName}}】";
    String CRM_CONTRACT_IMPORT_SUB_TYPE = "导入合同";
    String CRM_CONTRACT_IMPORT_SUCCESS = "导入了合同:{{#importSummary}}";
    // ======================= CRM_PRODUCT äº§å“ =======================
@@ -171,5 +173,7 @@
    String CRM_INVOICE_DELETE_SUCCESS = "删除了合同【{getContractById{#invoice.contractId}}】的编号为【{{#invoice.no}}】的开票";
    String CRM_INVOICE_SUBMIT_SUB_TYPE = "提交开票审批";
    String CRM_INVOICE_SUBMIT_SUCCESS = "提交编号为【{{#invoiceNo}}】的开票审批成功";
    String CRM_INVOICE_IMPORT_SUB_TYPE = "导入开票";
    String CRM_INVOICE_IMPORT_SUCCESS = "导入了开票:{{#importSummary}}";
}
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -10,6 +10,7 @@
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
@@ -272,6 +273,8 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_IMPORT_SUB_TYPE, bizNo = "0",
            success = CRM_CONTRACT_IMPORT_SUCCESS)
    public CrmContractImportRespVO importContractList(List<CrmContractImportExcelVO> importList) {
        CrmContractImportRespVO respVO = CrmContractImportRespVO.builder()
                .createList(new ArrayList<>())
@@ -279,6 +282,8 @@
                .failureList(new LinkedHashMap<>())
                .build();
        if (CollUtil.isEmpty(importList)) {
            // ç©ºæ–‡ä»¶ä¹Ÿè¦ç»™æ—¥å¿—文案兜底,避免 {{#importSummary}} å–不到值
            OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
            return respVO;
        }
@@ -317,6 +322,8 @@
                respVO.getFailureList().put(label, resolveImportErrorMessage(ex));
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
        return respVO;
    }
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -9,6 +9,7 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractTransferReqVO;
@@ -291,6 +292,8 @@
    }
    @Override
    @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_IMPORT_SUB_TYPE, bizNo = "0",
            success = CRM_CUSTOMER_IMPORT_SUCCESS)
    public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers,
                                                      CrmCustomerImportReqVO importReqVO) {
        // æ ¡éªŒéžç©º
@@ -322,8 +325,6 @@
                    permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
                            .setBizId(customer.getId()).setUserId(importReqVO.getOwnerUserId()).setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
                }
                // 1.3 è®°å½•操作日志
                getSelf().importCustomerLog(customer, false);
                return;
            }
@@ -338,23 +339,11 @@
                    .setId(existCustomer.getId());
            customerMapper.updateById(updateCustomer);
            respVO.getUpdateCustomerNames().add(importCustomer.getName());
            // 2.2 è®°å½•操作日志
            getSelf().importCustomerLog(updateCustomer, true);
        });
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateCustomerNames(), respVO.getUpdateCustomerNames(),
                respVO.getFailureCustomerNames());
        return respVO;
    }
    /**
     * è®°å½•导入客户时的操作日志
     *
     * @param customer å®¢æˆ·ä¿¡æ¯
     * @param isUpdate æ˜¯å¦æ›´æ–°ï¼›true - æ›´æ–°ï¼Œfalse - æ–°å¢ž
     */
    @LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_IMPORT_SUB_TYPE, bizNo = "{{#customer.id}}",
            success = CRM_CUSTOMER_IMPORT_SUCCESS)
    public void importCustomerLog(CrmCustomerDO customer, boolean isUpdate) {
        LogRecordContext.putVariable("customer", customer);
        LogRecordContext.putVariable("isUpdate", isUpdate);
    }
    // ==================== å…¬æµ·ç›¸å…³æ“ä½œ ====================
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java
@@ -11,6 +11,7 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceImportExcelVO;
@@ -131,12 +132,16 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = CRM_INVOICE_TYPE, subType = CRM_INVOICE_IMPORT_SUB_TYPE, bizNo = "0",
            success = CRM_INVOICE_IMPORT_SUCCESS)
    public CrmInvoiceImportRespVO importInvoiceList(List<CrmInvoiceImportExcelVO> importList) {
        CrmInvoiceImportRespVO respVO = CrmInvoiceImportRespVO.builder()
                .createList(new ArrayList<>())
                .failureList(new LinkedHashMap<>())
                .build();
        if (CollUtil.isEmpty(importList)) {
            // ç©ºæ–‡ä»¶ä¹Ÿè¦ç»™æ—¥å¿—文案兜底,避免 {{#importSummary}} å–不到值
            OperateLogUtils.putImportSummary(respVO.getCreateList(), null, respVO.getFailureList());
            return respVO;
        }
@@ -160,6 +165,8 @@
                respVO.getFailureList().put(label, resolveImportErrorMessage(ex));
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用(开票导入无「更新」分支,故传 null)
        OperateLogUtils.putImportSummary(respVO.getCreateList(), null, respVO.getFailureList());
        return respVO;
    }
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/LogRecordConstants.java
@@ -8,5 +8,22 @@
 */
public interface LogRecordConstants {
    // ======================= ERP_SALE_ORDER é”€å”®è®¢å• =======================
    String ERP_SALE_ORDER_TYPE = "ERP é”€å”®è®¢å•";
    String ERP_SALE_ORDER_IMPORT_SUB_TYPE = "导入销售订单";
    String ERP_SALE_ORDER_IMPORT_SUCCESS = "导入了销售订单:{{#importSummary}}";
    // ======================= ERP_PURCHASE_ORDER é‡‡è´­è®¢å• =======================
    String ERP_PURCHASE_ORDER_TYPE = "ERP é‡‡è´­è®¢å•";
    String ERP_PURCHASE_ORDER_IMPORT_SUB_TYPE = "导入采购订单";
    String ERP_PURCHASE_ORDER_IMPORT_SUCCESS = "导入了采购订单:{{#importSummary}}";
    // ======================= ERP_PURCHASE_REQUEST é‡‡è´­ç”³è¯· =======================
    String ERP_PURCHASE_REQUEST_TYPE = "ERP é‡‡è´­ç”³è¯·";
    String ERP_PURCHASE_REQUEST_IMPORT_SUB_TYPE = "导入采购申请";
    String ERP_PURCHASE_REQUEST_IMPORT_SUCCESS = "导入了采购申请:{{#importSummary}}";
}
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseOrderServiceImpl.java
@@ -7,6 +7,7 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
@@ -36,6 +37,7 @@
import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO;
import cn.iocoder.yudao.module.mes.api.arrivalnotice.MesArrivalNoticeApi;
import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.repository.ProcessDefinition;
@@ -54,6 +56,7 @@
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.erp.enums.LogRecordConstants.*;
/**
 * ERP é‡‡è´­è®¢å• Service å®žçŽ°ç±»
@@ -177,6 +180,8 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = ERP_PURCHASE_ORDER_TYPE, subType = ERP_PURCHASE_ORDER_IMPORT_SUB_TYPE, bizNo = "0",
            success = ERP_PURCHASE_ORDER_IMPORT_SUCCESS)
    public ErpPurchaseOrderImportRespVO importPurchaseOrderList(List<ErpPurchaseOrderImportExcelVO> importList,
                                                               Boolean directApprove) {
        ErpPurchaseOrderImportRespVO respVO = ErpPurchaseOrderImportRespVO.builder()
@@ -185,6 +190,8 @@
                .failureList(new LinkedHashMap<>())
                .build();
        if (CollUtil.isEmpty(importList)) {
            // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
            OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
            return respVO;
        }
@@ -226,6 +233,8 @@
                respVO.getFailureList().put(label, resolveImportErrorMessage(ex));
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
        return respVO;
    }
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java
@@ -6,6 +6,7 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
@@ -36,6 +37,7 @@
import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.repository.ProcessDefinition;
@@ -52,6 +54,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.erp.enums.LogRecordConstants.*;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
/**
@@ -167,6 +170,8 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = ERP_PURCHASE_REQUEST_TYPE, subType = ERP_PURCHASE_REQUEST_IMPORT_SUB_TYPE, bizNo = "0",
            success = ERP_PURCHASE_REQUEST_IMPORT_SUCCESS)
    public ErpPurchaseRequestImportRespVO importPurchaseRequestList(List<ErpPurchaseRequestImportExcelVO> importList) {
        ErpPurchaseRequestImportRespVO respVO = ErpPurchaseRequestImportRespVO.builder()
                .createList(new ArrayList<>())
@@ -174,6 +179,8 @@
                .failureList(new LinkedHashMap<>())
                .build();
        if (CollUtil.isEmpty(importList)) {
            // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
            OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
            return respVO;
        }
@@ -215,6 +222,8 @@
                respVO.getFailureList().put(label, resolveImportErrorMessage(ex));
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
        return respVO;
    }
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
@@ -7,6 +7,7 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
@@ -36,6 +37,7 @@
import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsRespDTO;
import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.flowable.engine.repository.ProcessDefinition;
import lombok.extern.slf4j.Slf4j;
@@ -59,6 +61,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.erp.enums.LogRecordConstants.*;
/**
 * ERP é”€å”®è®¢å• Service å®žçŽ°ç±»
@@ -190,6 +193,8 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = ERP_SALE_ORDER_TYPE, subType = ERP_SALE_ORDER_IMPORT_SUB_TYPE, bizNo = "0",
            success = ERP_SALE_ORDER_IMPORT_SUCCESS)
    public ErpSaleOrderImportRespVO importSaleOrderList(List<ErpSaleOrderImportExcelVO> importList) {
        ErpSaleOrderImportRespVO respVO = ErpSaleOrderImportRespVO.builder()
                .createList(new ArrayList<>())
@@ -197,6 +202,8 @@
                .failureList(new LinkedHashMap<>())
                .build();
        if (CollUtil.isEmpty(importList)) {
            // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
            OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
            return respVO;
        }
@@ -235,6 +242,8 @@
                respVO.getFailureList().put(label, resolveImportErrorMessage(ex));
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
        return respVO;
    }
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceRecordController.java
@@ -7,6 +7,7 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordImportExcelVO;
import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordImportReqVO;
import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordPageReqVO;
@@ -19,6 +20,7 @@
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.mzt.logapi.starter.annotation.LogRecord;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -38,6 +40,7 @@
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.hrm.enums.ErrorCodeConstants.EMPLOYEE_NOT_EXISTS;
import static cn.iocoder.yudao.module.hrm.enums.LogRecordConstants.*;
@Tag(name = "管理后台 - HRM è€ƒå‹¤è®°å½•")
@RestController
@@ -204,12 +207,18 @@
    @PostMapping("/import")
    @Operation(summary = "导入考勤记录")
    @PreAuthorize("@ss.hasPermission('hrm:attendance-record:import')")
    @LogRecord(type = HRM_ATTENDANCE_RECORD_TYPE, subType = HRM_ATTENDANCE_RECORD_IMPORT_SUB_TYPE, bizNo = "0",
            success = HRM_ATTENDANCE_RECORD_IMPORT_SUCCESS)
    public CommonResult<String> importExcel(@Valid HrmAttendanceRecordImportReqVO importReqVO) throws IOException {
        List<HrmAttendanceRecordImportExcelVO> list = ExcelUtils.read(importReqVO.getFile(), HrmAttendanceRecordImportExcelVO.class);
        if (CollUtil.isEmpty(list)) {
            // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
            OperateLogUtils.putImportSummary(0, null, null);
            return success("没有可导入的数据");
        }
        int successCount = 0;
        int createCount = 0; // æ–°å¢žçš„记录数
        int updateCount = 0; // æ›´æ–°çš„记录数(仅勾选「支持更新」时才会走更新)
        Set<String> missingNames = new LinkedHashSet<>();
        Set<String> duplicateNames = new LinkedHashSet<>();
        Set<String> invalidRows = new LinkedHashSet<>();
@@ -255,6 +264,7 @@
                        .location(item.getLocation()).remark(item.getRemark())
                        .dataSource(2).build();
                attendanceRecordService.createImportedRecord(record);
                createCount++;
            } else if (Boolean.TRUE.equals(importReqVO.getUpdateSupport())) {
                record.setClockInTime(item.getClockInTime());
                record.setClockOutTime(item.getClockOutTime());
@@ -263,6 +273,7 @@
                record.setLocation(item.getLocation());
                record.setRemark(item.getRemark());
                attendanceRecordService.updateImportedRecord(record);
                updateCount++;
            }
            successCount++;
        }
@@ -276,6 +287,9 @@
        if (!invalidRows.isEmpty()) {
            msg.append(";以下记录数据不完整,未能导入:").append(String.join("、", invalidRows));
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(createCount, updateCount,
                missingNames.size() + duplicateNames.size() + invalidRows.size());
        return success(msg.toString());
    }
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/enums/LogRecordConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.hrm.enums;
/**
 * Hrm æ“ä½œæ—¥å¿—枚举
 * ç›®çš„:统一管理,也减少 Service é‡Œå„种“复杂”字符串
 *
 * @author è¶…级管理员
 */
public interface LogRecordConstants {
    // ======================= HRM_ATTENDANCE_RECORD è€ƒå‹¤è®°å½• =======================
    String HRM_ATTENDANCE_RECORD_TYPE = "HRM è€ƒå‹¤è®°å½•";
    String HRM_ATTENDANCE_RECORD_IMPORT_SUB_TYPE = "导入考勤记录";
    String HRM_ATTENDANCE_RECORD_IMPORT_SUCCESS = "导入了考勤记录:{{#importSummary}}";
    // ======================= HRM_EMPLOYEE å‘˜å·¥ =======================
    String HRM_EMPLOYEE_TYPE = "HRM å‘˜å·¥";
    String HRM_EMPLOYEE_IMPORT_SUB_TYPE = "导入员工";
    String HRM_EMPLOYEE_IMPORT_SUCCESS = "导入了员工:{{#importSummary}}";
    // ======================= HRM_EMPLOYEE_CONTRACT å‘˜å·¥åˆåŒ =======================
    String HRM_EMPLOYEE_CONTRACT_TYPE = "HRM å‘˜å·¥åˆåŒ";
    String HRM_EMPLOYEE_CONTRACT_IMPORT_SUB_TYPE = "导入员工合同";
    String HRM_EMPLOYEE_CONTRACT_IMPORT_SUCCESS = "导入了员工合同:{{#importSummary}}";
}
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeContractServiceImpl.java
@@ -5,6 +5,7 @@
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractPageReqVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractRespVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractSaveReqVO;
@@ -20,6 +21,7 @@
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -38,6 +40,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.hrm.enums.LogRecordConstants.*;
/**
 * å‘˜å·¥åˆåŒ Service å®žçŽ°ç±»
@@ -332,6 +335,8 @@
    }
    @Override
    @LogRecord(type = HRM_EMPLOYEE_CONTRACT_TYPE, subType = HRM_EMPLOYEE_CONTRACT_IMPORT_SUB_TYPE, bizNo = "0",
            success = HRM_EMPLOYEE_CONTRACT_IMPORT_SUCCESS)
    public HrmEmployeeContractImportRespVO importContractList(List<HrmEmployeeContractImportExcelVO> importContracts,
                                                              HrmEmployeeContractImportReqVO importReqVO) {
        // 1. è¿‡æ»¤å‘˜å·¥å§“名为空的行
@@ -381,6 +386,9 @@
                respVO.getFailureNames().put(name, ex.getMessage());
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateNames(), respVO.getUpdateNames(),
                respVO.getFailureNames());
        return respVO;
    }
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
@@ -6,6 +6,7 @@
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeEducationSaveReqVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeEmergencyContactSaveReqVO;
import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeImportExcelVO;
@@ -34,6 +35,7 @@
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserCreateReqDTO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserUpdateReqDTO;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -54,6 +56,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.hrm.enums.LogRecordConstants.*;
/**
 * å‘˜å·¥ä¿¡æ¯ Service å®žçŽ°ç±»
@@ -381,6 +384,8 @@
    }
    @Override
    @LogRecord(type = HRM_EMPLOYEE_TYPE, subType = HRM_EMPLOYEE_IMPORT_SUB_TYPE, bizNo = "0",
            success = HRM_EMPLOYEE_IMPORT_SUCCESS)
    public HrmEmployeeImportRespVO importEmployeeList(List<HrmEmployeeImportExcelVO> importEmployees,
                                                      HrmEmployeeImportReqVO importReqVO) {
        // 1. æ ¡éªŒéžç©º
@@ -430,6 +435,9 @@
                respVO.getFailureNames().put(name, ex.getMessage());
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateNames(), respVO.getUpdateNames(),
                respVO.getFailureNames());
        return respVO;
    }
yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/enums/LogRecordConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.mdm.enums;
/**
 * MDM æ“ä½œæ—¥å¿—枚举
 * ç›®çš„:统一管理,也减少 Service é‡Œå„种“复杂”字符串
 *
 * @author è¶…级管理员
 */
public interface LogRecordConstants {
    // ======================= MDM_ITEM ç‰©æ–™ =======================
    String MDM_ITEM_TYPE = "MDM ç‰©æ–™";
    String MDM_ITEM_IMPORT_SUB_TYPE = "导入物料";
    String MDM_ITEM_IMPORT_SUCCESS = "导入了物料:{{#importSummary}}";
    // ======================= MDM_UNIT_MEASURE è®¡é‡å•位 =======================
    String MDM_UNIT_MEASURE_TYPE = "MDM è®¡é‡å•位";
    String MDM_UNIT_MEASURE_IMPORT_SUB_TYPE = "导入计量单位";
    String MDM_UNIT_MEASURE_IMPORT_SUCCESS = "导入了计量单位:{{#importSummary}}";
}
yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java
@@ -7,6 +7,7 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemImportExcelVO;
import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemImportRespVO;
import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemPageReqVO;
@@ -26,6 +27,7 @@
import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemSyncReqDTO;
import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemTypeRespDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@@ -39,6 +41,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.mdm.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.mdm.enums.LogRecordConstants.*;
/**
 * MDM ç‰©æ–™ä¸»æ•°æ® Service å®žçŽ°ç±»
@@ -431,6 +434,8 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = MDM_ITEM_TYPE, subType = MDM_ITEM_IMPORT_SUB_TYPE, bizNo = "0",
            success = MDM_ITEM_IMPORT_SUCCESS)
    public MdmItemImportRespVO importItemList(List<MdmItemImportExcelVO> importList, Boolean isUpdateSupport) {
        if (CollUtil.isEmpty(importList)) {
            throw exception(MDM_ITEM_IMPORT_LIST_IS_EMPTY);
@@ -547,6 +552,8 @@
                respVO.getFailureList().put(StrUtil.blankToDefault(importVO.getName(), importVO.getCode()), reason == null ? "导入失败" : reason);
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
        return respVO;
    }
yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/unit/MdmUnitMeasureServiceImpl.java
@@ -5,6 +5,7 @@
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.mdm.controller.admin.unit.vo.MdmUnitMeasureImportExcelVO;
import cn.iocoder.yudao.module.mdm.controller.admin.unit.vo.MdmUnitMeasureImportRespVO;
import cn.iocoder.yudao.module.mdm.controller.admin.unit.vo.MdmUnitMeasurePageReqVO;
@@ -12,6 +13,7 @@
import cn.iocoder.yudao.module.mdm.dal.dataobject.unit.MdmUnitMeasureDO;
import cn.iocoder.yudao.module.mdm.dal.mysql.item.MdmItemMapper;
import cn.iocoder.yudao.module.mdm.dal.mysql.unit.MdmUnitMeasureMapper;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -21,6 +23,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mdm.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.mdm.enums.LogRecordConstants.*;
/**
 * MDM è®¡é‡å•位 Service å®žçŽ°ç±»
@@ -130,6 +133,8 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = MDM_UNIT_MEASURE_TYPE, subType = MDM_UNIT_MEASURE_IMPORT_SUB_TYPE, bizNo = "0",
            success = MDM_UNIT_MEASURE_IMPORT_SUCCESS)
    public MdmUnitMeasureImportRespVO importUnitMeasureList(List<MdmUnitMeasureImportExcelVO> importList, Boolean isUpdateSupport) {
        if (CollUtil.isEmpty(importList)) {
            throw exception(MDM_UNIT_MEASURE_IMPORT_LIST_IS_EMPTY);
@@ -194,6 +199,8 @@
                importedCodeIdMap.put(importVO.getCode(), newObj.getId());
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
        return respVO;
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/LogRecordConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
package cn.iocoder.yudao.module.mes.enums;
/**
 * MES æ“ä½œæ—¥å¿—枚举
 * ç›®çš„:统一管理,也减少 Service é‡Œå„种“复杂”字符串
 *
 * @author è¶…级管理员
 */
public interface LogRecordConstants {
    // ======================= MES_WM_MATERIAL_STOCK ç‰©æ–™åº“å­˜ =======================
    String MES_WM_MATERIAL_STOCK_TYPE = "MES ç‰©æ–™åº“å­˜";
    String MES_WM_MATERIAL_STOCK_IMPORT_SUB_TYPE = "导入物料库存";
    String MES_WM_MATERIAL_STOCK_IMPORT_SUCCESS = "导入了物料库存:{{#importSummary}}";
    // ======================= MES_DV_METERING ä»ªè¡¨ =======================
    String MES_DV_METERING_TYPE = "MES ä»ªè¡¨";
    String MES_DV_METERING_IMPORT_SUB_TYPE = "导入仪表";
    String MES_DV_METERING_IMPORT_SUCCESS = "导入了仪表:{{#importSummary}}";
    // ======================= MES_DV_MACHINERY è®¾å¤‡ =======================
    String MES_DV_MACHINERY_TYPE = "MES è®¾å¤‡";
    String MES_DV_MACHINERY_IMPORT_SUB_TYPE = "导入设备";
    String MES_DV_MACHINERY_IMPORT_SUCCESS = "导入了设备:{{#importSummary}}";
    // ======================= MES_MD_ITEM_TYPE ç‰©æ–™åˆ†ç±» =======================
    // å‰ç¼€é‡Œçš„ ITEM_TYPE æ˜¯ä¸šåŠ¡å¯¹è±¡åï¼ˆç‰©æ–™ç±»åž‹ï¼‰çš„ä¸€éƒ¨åˆ†ï¼Œæ‰€ä»¥å¸¸é‡åä»¥ _TYPE_TYPE ç»“尾,不是笔误
    String MES_MD_ITEM_TYPE_TYPE = "MES ç‰©æ–™åˆ†ç±»";
    String MES_MD_ITEM_TYPE_IMPORT_SUB_TYPE = "导入物料分类";
    String MES_MD_ITEM_TYPE_IMPORT_SUCCESS = "导入了物料分类:{{#importSummary}}";
    // ======================= MES_QC_IPQC è¿‡ç¨‹æ£€éªŒå• =======================
    String MES_QC_IPQC_TYPE = "MES è¿‡ç¨‹æ£€éªŒå•";
    String MES_QC_IPQC_IMPORT_SUB_TYPE = "导入过程检验单";
    String MES_QC_IPQC_IMPORT_SUCCESS = "导入了过程检验单:{{#importSummary}}";
    // ======================= MES_QC_IQC æ¥æ–™æ£€éªŒå• =======================
    String MES_QC_IQC_TYPE = "MES æ¥æ–™æ£€éªŒå•";
    String MES_QC_IQC_IMPORT_SUB_TYPE = "导入来料检验单";
    String MES_QC_IQC_IMPORT_SUCCESS = "导入了来料检验单:{{#importSummary}}";
    // ======================= MES_QC_OQC å‡ºè´§æ£€éªŒå• =======================
    String MES_QC_OQC_TYPE = "MES å‡ºè´§æ£€éªŒå•";
    String MES_QC_OQC_IMPORT_SUB_TYPE = "导入出货检验单";
    String MES_QC_OQC_IMPORT_SUCCESS = "导入了出货检验单:{{#importSummary}}";
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java
@@ -6,6 +6,7 @@
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportExcelVO;
import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryPageReqVO;
@@ -21,6 +22,7 @@
import cn.iocoder.yudao.module.mes.service.dv.repair.MesDvRepairService;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkshopService;
import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -34,6 +36,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.mes.enums.LogRecordConstants.*;
/**
 * MES è®¾å¤‡å°è´¦ Service å®žçŽ°ç±»
@@ -197,6 +200,8 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = MES_DV_MACHINERY_TYPE, subType = MES_DV_MACHINERY_IMPORT_SUB_TYPE, bizNo = "0",
            success = MES_DV_MACHINERY_IMPORT_SUCCESS)
    public MesDvMachineryImportRespVO importMachineryList(List<MesDvMachineryImportExcelVO> importMachineryList,
                                                          boolean updateSupport) {
        // 1. å‚数校验
@@ -298,6 +303,8 @@
                respVO.getFailureCodes().put(key, "设备编码已存在");
            }
        });
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateCodes(), respVO.getUpdateCodes(), respVO.getFailureCodes());
        return respVO;
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/metering/MesDvMeteringServiceImpl.java
@@ -10,6 +10,7 @@
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.infra.api.config.ConfigApi;
import cn.iocoder.yudao.module.mes.controller.admin.dv.metering.vo.MesDvMeteringPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.dv.metering.vo.MesDvMeteringSaveReqVO;
@@ -17,6 +18,7 @@
import cn.iocoder.yudao.module.mes.dal.mysql.dv.metering.MesDvMeteringMapper;
import cn.iocoder.yudao.module.mes.service.dv.meteringcheck.MesDvMeteringCheckService;
import cn.hutool.core.util.StrUtil;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -36,6 +38,7 @@
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.DV_METERING_CODE_DUPLICATE;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.DV_METERING_HAS_CHECK_RECORD;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.DV_METERING_NOT_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.LogRecordConstants.*;
/**
 * MES è®¡é‡å™¨å…· Service å®žçŽ°ç±»
@@ -83,6 +86,8 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = MES_DV_METERING_TYPE, subType = MES_DV_METERING_IMPORT_SUB_TYPE, bizNo = "0",
            success = MES_DV_METERING_IMPORT_SUCCESS)
    public MesDvMeteringImportRespVO importMeteringList(List<MesDvMeteringImportExcelVO> importList) {
        MesDvMeteringImportRespVO respVO = MesDvMeteringImportRespVO.builder()
                .createList(new ArrayList<>())
@@ -90,6 +95,8 @@
                .failureList(new LinkedHashMap<>())
                .build();
        if (CollUtil.isEmpty(importList)) {
            // ç©ºæ–‡ä»¶ä¹Ÿè¦ç»™æ—¥å¿—文案兜底,避免 {{#importSummary}} å–不到值
            OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
            return respVO;
        }
@@ -122,6 +129,8 @@
                respVO.getFailureList().put(label, resolveImportErrorMessage(ex));
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
        return respVO;
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java
@@ -5,6 +5,7 @@
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.mdm.api.category.MdmItemCategoryApi;
import cn.iocoder.yudao.module.mdm.api.category.dto.MdmItemCategoryRespDTO;
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.type.MesMdItemTypeImportExcelVO;
@@ -13,6 +14,7 @@
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.type.MesMdItemTypeSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO;
import cn.iocoder.yudao.module.mes.dal.mysql.md.item.MesMdItemTypeMapper;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -22,6 +24,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.mes.enums.LogRecordConstants.*;
/**
 * MES ç‰©æ–™äº§å“åˆ†ç±» Service å®žçŽ°ç±»
@@ -235,6 +238,8 @@
    @Override
    @org.springframework.transaction.annotation.Transactional(rollbackFor = Exception.class)
    @LogRecord(type = MES_MD_ITEM_TYPE_TYPE, subType = MES_MD_ITEM_TYPE_IMPORT_SUB_TYPE, bizNo = "0",
            success = MES_MD_ITEM_TYPE_IMPORT_SUCCESS)
    public MesMdItemTypeImportRespVO importItemTypeList(List<MesMdItemTypeImportExcelVO> importList, Boolean isUpdateSupport) {
        if (CollUtil.isEmpty(importList)) {
            throw exception(MD_ITEM_TYPE_IMPORT_LIST_IS_EMPTY);
@@ -303,6 +308,8 @@
                importedCodeIdMap.put(importVO.getCode(), newObj.getId());
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
        return respVO;
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java
@@ -9,6 +9,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcImportExcelVO;
import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO;
@@ -44,6 +45,7 @@
import cn.iocoder.yudao.module.mes.service.qc.ncr.MesQcNcrService;
import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
@@ -62,6 +64,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.mes.enums.LogRecordConstants.*;
/**
 * MES è¿‡ç¨‹æ£€éªŒå•(IPQC) Service å®žçŽ°ç±»
@@ -472,10 +475,14 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = MES_QC_IPQC_TYPE, subType = MES_QC_IPQC_IMPORT_SUB_TYPE, bizNo = "0",
            success = MES_QC_IPQC_IMPORT_SUCCESS)
    public MesQcImportRespVO importIpqcList(List<MesQcIpqcImportExcelVO> importList) {
        MesQcImportRespVO respVO = MesQcImportRespVO.builder()
                .createList(new ArrayList<>()).failureList(new LinkedHashMap<>()).build();
        if (CollUtil.isEmpty(importList)) {
            // ç©ºæ–‡ä»¶ä¹Ÿè¦ç»™æ—¥å¿—文案兜底,避免 {{#importSummary}} å–不到值
            OperateLogUtils.putImportSummary(respVO.getCreateList(), null, respVO.getFailureList());
            return respVO;
        }
        qcImportHelper.startImport();
@@ -499,6 +506,8 @@
                respVO.getFailureList().put(label, MesQcImportHelper.resolveImportErrorMessage(ex));
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), null, respVO.getFailureList());
        return respVO;
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java
@@ -6,6 +6,7 @@
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcImportExcelVO;
import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO;
@@ -35,6 +36,7 @@
import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -49,6 +51,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.mes.enums.LogRecordConstants.*;
/**
 * MES æ¥æ–™æ£€éªŒå•(IQC) Service å®žçŽ°ç±»
@@ -437,10 +440,14 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = MES_QC_IQC_TYPE, subType = MES_QC_IQC_IMPORT_SUB_TYPE, bizNo = "0",
            success = MES_QC_IQC_IMPORT_SUCCESS)
    public MesQcImportRespVO importIqcList(List<MesQcIqcImportExcelVO> importList) {
        MesQcImportRespVO respVO = MesQcImportRespVO.builder()
                .createList(new ArrayList<>()).failureList(new LinkedHashMap<>()).build();
        if (CollUtil.isEmpty(importList)) {
            // ç©ºæ–‡ä»¶ä¹Ÿè¦ç»™æ—¥å¿—文案兜底,避免 {{#importSummary}} å–不到值
            OperateLogUtils.putImportSummary(respVO.getCreateList(), null, respVO.getFailureList());
            return respVO;
        }
        qcImportHelper.startImport();
@@ -464,6 +471,8 @@
                respVO.getFailureList().put(label, MesQcImportHelper.resolveImportErrorMessage(ex));
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), null, respVO.getFailureList());
        return respVO;
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java
@@ -6,6 +6,7 @@
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcImportExcelVO;
import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcSaveReqVO;
@@ -34,6 +35,7 @@
import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -51,6 +53,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.mes.enums.LogRecordConstants.*;
/**
 * MES å‡ºè´§æ£€éªŒå•(OQC) Service å®žçŽ°ç±»
@@ -413,10 +416,14 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = MES_QC_OQC_TYPE, subType = MES_QC_OQC_IMPORT_SUB_TYPE, bizNo = "0",
            success = MES_QC_OQC_IMPORT_SUCCESS)
    public MesQcImportRespVO importOqcList(List<MesQcOqcImportExcelVO> importList) {
        MesQcImportRespVO respVO = MesQcImportRespVO.builder()
                .createList(new ArrayList<>()).failureList(new LinkedHashMap<>()).build();
        if (CollUtil.isEmpty(importList)) {
            // ç©ºæ–‡ä»¶ä¹Ÿè¦ç»™æ—¥å¿—文案兜底,避免 {{#importSummary}} å–不到值
            OperateLogUtils.putImportSummary(respVO.getCreateList(), null, respVO.getFailureList());
            return respVO;
        }
        qcImportHelper.startImport();
@@ -440,6 +447,8 @@
                respVO.getFailureList().put(label, MesQcImportHelper.resolveImportErrorMessage(ex));
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), null, respVO.getFailureList());
        return respVO;
    }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
@@ -8,6 +8,7 @@
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockAdjustReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockImportExcelVO;
@@ -40,6 +41,7 @@
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -57,6 +59,7 @@
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.mes.enums.LogRecordConstants.*;
/**
 * MES åº“存台账 Service å®žçŽ°ç±»
@@ -593,6 +596,8 @@
    }
    @Override
    @LogRecord(type = MES_WM_MATERIAL_STOCK_TYPE, subType = MES_WM_MATERIAL_STOCK_IMPORT_SUB_TYPE, bizNo = "0",
            success = MES_WM_MATERIAL_STOCK_IMPORT_SUCCESS)
    public MesWmMaterialStockImportRespVO importMaterialStockList(List<MesWmMaterialStockImportExcelVO> importList) {
        // æ“ä½œç±»åž‹å–值:增加 / å‡å°‘ / è¦†ç›–
        final String OP_ADD = "增加";
@@ -755,6 +760,8 @@
                respVO.getFailureNames().put(key, ex.getMessage());
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateNames(), respVO.getUpdateNames(), respVO.getFailureNames());
        return respVO;
    }
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/LogRecordConstants.java
@@ -42,4 +42,9 @@
    String LOG_AWARD_ORDER_SUB_TYPE = "生成采购订单";
    String LOG_AWARD_ORDER_SUCCESS = "定标记录生成了采购订单";
    // ======================= SRM_SUPPLIER ä¾›åº”商 =======================
    String LOG_SUPPLIER_TYPE = "SRM ä¾›åº”商";
    String LOG_SUPPLIER_IMPORT_SUB_TYPE = "导入供应商";
    String LOG_SUPPLIER_IMPORT_SUCCESS = "导入了供应商:{{#importSummary}}";
}
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierServiceImpl.java
@@ -8,6 +8,7 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.srm.controller.admin.supplier.vo.SrmSupplierImportExcelVO;
import cn.iocoder.yudao.module.srm.controller.admin.supplier.vo.SrmSupplierImportRespVO;
import cn.iocoder.yudao.module.srm.controller.admin.supplier.vo.SrmSupplierPageReqVO;
@@ -23,6 +24,7 @@
import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderBidMapper;
import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.srm.enums.SupplierTypeEnum;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -35,6 +37,8 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.module.srm.enums.LogRecordConstants.*;
@Service
@Validated
@@ -111,6 +115,8 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(type = LOG_SUPPLIER_TYPE, subType = LOG_SUPPLIER_IMPORT_SUB_TYPE, bizNo = "0",
            success = LOG_SUPPLIER_IMPORT_SUCCESS)
    public SrmSupplierImportRespVO importSupplierList(List<SrmSupplierImportExcelVO> importList, Boolean updateSupport) {
        if (CollUtil.isEmpty(importList)) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.SUPPLIER_IMPORT_LIST_IS_EMPTY);
@@ -149,6 +155,8 @@
                respVO.getFailureList().put(name, reason == null ? "导入失败" : reason);
            }
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateList(), respVO.getUpdateList(), respVO.getFailureList());
        return respVO;
    }
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
@@ -2,6 +2,7 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
@@ -129,6 +130,7 @@
    @PostMapping("/sms-login")
    @PermitAll
    @Operation(summary = "使用短信验证码登录")
    @ApiAccessLog(sanitizeKeys = {"code"}) // éªŒè¯ç æœ¬èº«å°±æ˜¯ç™»å½•凭证,不能写进访问日志
    // å¯æŒ‰éœ€å¼€å¯é™æµï¼šhttps://github.com/YunaiV/ruoyi-vue-pro/issues/851
    // @RateLimiter(time = 60, count = 6, keyResolver = ExpressionRateLimiterKeyResolver.class, keyArg = "#reqVO.mobile")
    public CommonResult<AuthLoginRespVO> smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) {
@@ -146,6 +148,7 @@
    @PostMapping("/reset-password")
    @PermitAll
    @Operation(summary = "重置密码")
    @ApiAccessLog(sanitizeKeys = {"code"}) // éªŒè¯ç ç­‰ä»·äºŽé‡ç½®å¯†ç çš„凭证,不能写进访问日志
    public CommonResult<Boolean> resetPassword(@RequestBody @Valid AuthResetPasswordReqVO reqVO) {
        authService.resetPassword(reqVO);
        return success(true);
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/LogRecordConstants.java
@@ -19,6 +19,8 @@
    String SYSTEM_USER_DELETE_SUCCESS = "删除了用户【{{#user.nickname}}】";
    String SYSTEM_USER_UPDATE_PASSWORD_SUB_TYPE = "重置用户密码";
    String SYSTEM_USER_UPDATE_PASSWORD_SUCCESS = "将用户【{{#user.nickname}}】的密码从【{{#user.password}}】重置为【{{#newPassword}}】";
    String SYSTEM_USER_IMPORT_SUB_TYPE = "导入用户";
    String SYSTEM_USER_IMPORT_SUCCESS = "导入了用户:{{#importSummary}}";
    // ======================= SYSTEM_ROLE è§’色 =======================
@@ -30,4 +32,16 @@
    String SYSTEM_ROLE_DELETE_SUB_TYPE = "删除角色";
    String SYSTEM_ROLE_DELETE_SUCCESS = "删除了角色【{{#role.name}}】";
    // ======================= SYSTEM_POST å²—位 =======================
    String SYSTEM_POST_TYPE = "SYSTEM å²—位";
    String SYSTEM_POST_IMPORT_SUB_TYPE = "导入岗位";
    String SYSTEM_POST_IMPORT_SUCCESS = "导入了岗位:{{#importSummary}}";
    // ======================= SYSTEM_DEPT éƒ¨é—¨ =======================
    String SYSTEM_DEPT_TYPE = "SYSTEM éƒ¨é—¨";
    String SYSTEM_DEPT_IMPORT_SUB_TYPE = "导入部门";
    String SYSTEM_DEPT_IMPORT_SUCCESS = "导入了部门:{{#importSummary}}";
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java
@@ -14,7 +14,9 @@
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import com.google.common.annotations.VisibleForTesting;
import com.mzt.logapi.starter.annotation.LogRecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
@@ -27,6 +29,7 @@
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.system.enums.LogRecordConstants.*;
/**
 * éƒ¨é—¨ Service å®žçŽ°ç±»
@@ -240,6 +243,8 @@
    }
    @Override
    @LogRecord(type = SYSTEM_DEPT_TYPE, subType = SYSTEM_DEPT_IMPORT_SUB_TYPE, bizNo = "0",
            success = SYSTEM_DEPT_IMPORT_SUCCESS)
    public DeptImportRespVO importDeptList(List<DeptImportExcelVO> importDepts, boolean isUpdateSupport) {
        if (CollUtil.isEmpty(importDepts)) {
            throw exception(DEPT_IMPORT_LIST_IS_EMPTY);
@@ -302,6 +307,9 @@
            fullPathDeptIdMap.put(myFullPath, newDept.getId());
        }
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateDeptNames(), respVO.getUpdateDeptNames(),
                respVO.getFailureDeptNames());
        return respVO;
    }
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java
@@ -20,12 +20,15 @@
import java.util.LinkedHashMap;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostImportExcelVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostImportRespVO;
import com.mzt.logapi.starter.annotation.LogRecord;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.system.enums.LogRecordConstants.*;
/**
 * å²—位 Service å®žçŽ°ç±»
@@ -163,6 +166,8 @@
    }
    @Override
    @LogRecord(type = SYSTEM_POST_TYPE, subType = SYSTEM_POST_IMPORT_SUB_TYPE, bizNo = "0",
            success = SYSTEM_POST_IMPORT_SUCCESS)
    public PostImportRespVO importPostList(List<PostImportExcelVO> importPosts, boolean isUpdateSupport) {
        if (CollUtil.isEmpty(importPosts)) {
            throw exception(POST_IMPORT_LIST_IS_EMPTY);
@@ -207,6 +212,9 @@
            postMapper.updateById(updatePost);
            respVO.getUpdatePostNames().add(importPost.getName());
        });
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreatePostNames(), respVO.getUpdatePostNames(),
                respVO.getFailurePostNames());
        return respVO;
    }
}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
@@ -31,6 +31,7 @@
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
import cn.iocoder.yudao.framework.operatelog.core.util.OperateLogUtils;
import com.google.common.annotations.VisibleForTesting;
import com.mzt.logapi.context.LogRecordContext;
import com.mzt.logapi.service.impl.DiffParseFunction;
@@ -506,6 +507,8 @@
    }
    @Override
    @LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_IMPORT_SUB_TYPE, bizNo = "0",
            success = SYSTEM_USER_IMPORT_SUCCESS)
    @Transactional(rollbackFor = Exception.class) // æ·»åŠ äº‹åŠ¡ï¼Œå¼‚å¸¸åˆ™å›žæ»šæ‰€æœ‰å¯¼å…¥
    public UserImportRespVO importUserList(List<UserImportExcelVO> importUsers, boolean isUpdateSupport) {
        // 1.1 å‚数校验
@@ -559,6 +562,9 @@
            userMapper.updateById(updateUser);
            respVO.getUpdateUsernames().add(importUser.getUsername());
        });
        // è®°å½•导入结果汇总,供 @LogRecord çš„ success æ–‡æ¡ˆå¼•用
        OperateLogUtils.putImportSummary(respVO.getCreateUsernames(), respVO.getUpdateUsernames(),
                respVO.getFailureUsernames());
        return respVO;
    }
yudao-server/src/main/resources/application-hm.yaml
@@ -185,7 +185,7 @@
  security:
    mock-enable: true
  access-log: # è®¿é—®æ—¥å¿—的配置项
    enable: false
    enable: true # æƒ ç‰§å¼€å¯ï¼šæ‰€æœ‰ /admin-api、/app-api è¯·æ±‚落 infra_api_access_log(含入参),作为操作留痕兜底;密码/密钥类字段由框架统一脱敏(ApiAccessLogFilter.SANITIZE_KEYS),短信验证码等与业务字段重名的 key ç”±æŽ¥å£ç”¨ @ApiAccessLog(sanitizeKeys = ...) æŒ‡å®š
  demo: false # å…³é—­æ¼”示模式
  storage: # æ–‡ä»¶ä¸Šä¼ é…ç½®
    path: /data/javaWork/mom/file # æ–‡ä»¶å­˜å‚¨æ ¹ç›®å½•