mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	修改:CRM 产品分类和产品,优化了操作日志
This commit is contained in:
		| @@ -1,5 +1,6 @@ | ||||
| package cn.iocoder.yudao.module.crm.controller.admin.product.vo.category; | ||||
|  | ||||
| import com.mzt.logapi.starter.annotation.DiffLogField; | ||||
| import lombok.*; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| @@ -14,6 +15,7 @@ public class CrmProductCategoryCreateReqVO{ | ||||
|  | ||||
|     @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") | ||||
|     @NotNull(message = "分类名称不能为空") | ||||
|     @DiffLogField(name = "分类名称") | ||||
|     private String name; | ||||
|  | ||||
|     @Schema(description = "父级编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4680") | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product; | ||||
|  | ||||
| import lombok.*; | ||||
| import com.mzt.logapi.starter.annotation.DiffLogField; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
|  | ||||
| @Schema(description = "管理后台 - CRM 产品创建/修改 Request VO") | ||||
| @Data | ||||
| @@ -14,28 +14,35 @@ public class CrmProductSaveReqVO { | ||||
|  | ||||
|     @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "好产品") | ||||
|     @NotNull(message = "产品名称不能为空") | ||||
|     @DiffLogField(name = "产品名称") | ||||
|     private String name; | ||||
|  | ||||
|     @Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "12306") | ||||
|     @NotNull(message = "产品编码不能为空") | ||||
|     @DiffLogField(name = "产品编码") | ||||
|     private String no; | ||||
|  | ||||
|     @Schema(description = "单位", example = "2") | ||||
|     @DiffLogField(name = "单位", function = "getProductUnitName") | ||||
|     private Integer unit; | ||||
|  | ||||
|     @Schema(description = "价格, 单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") | ||||
|     @NotNull(message = "价格不能为空") | ||||
|     @DiffLogField(name = "价格") | ||||
|     private Long price; | ||||
|  | ||||
|     @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "上架") | ||||
|     @NotNull(message = "状态不能为空") | ||||
|     @DiffLogField(name = "状态", function = "getProductStatusName") | ||||
|     private Integer status; | ||||
|  | ||||
|     @Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | ||||
|     @NotNull(message = "产品分类编号不能为空") | ||||
|     @DiffLogField(name = "产品分类编号") | ||||
|     private Long categoryId; | ||||
|  | ||||
|     @Schema(description = "产品描述", example = "你说的对") | ||||
|     @DiffLogField(name = "产品描述") | ||||
|     private String description; | ||||
|  | ||||
|     @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31926") | ||||
|   | ||||
| @@ -0,0 +1,39 @@ | ||||
| package cn.iocoder.yudao.module.crm.framework.operatelog.core; | ||||
|  | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||||
| import cn.iocoder.yudao.module.crm.enums.DictTypeConstants; | ||||
| import com.mzt.logapi.service.IParseFunction; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| /** | ||||
|  * 产品状态的 {@link IParseFunction} 实现类 | ||||
|  * | ||||
|  * @author anhaohao | ||||
|  */ | ||||
| @Component | ||||
| @Slf4j | ||||
| public class CrmProductStatusParseFunction implements IParseFunction { | ||||
|  | ||||
|     public static final String NAME = "getProductStatusName"; | ||||
|  | ||||
|     @Override | ||||
|     public boolean executeBefore() { | ||||
|         return true; // 先转换值后对比 | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String functionName() { | ||||
|         return NAME; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String apply(Object value) { | ||||
|         if (StrUtil.isEmptyIfStr(value)) { | ||||
|             return ""; | ||||
|         } | ||||
|         return DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CRM_PRODUCT_STATUS, value.toString()); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,39 @@ | ||||
| package cn.iocoder.yudao.module.crm.framework.operatelog.core; | ||||
|  | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||||
| import cn.iocoder.yudao.module.crm.enums.DictTypeConstants; | ||||
| import com.mzt.logapi.service.IParseFunction; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| /** | ||||
|  * 产品单位的 {@link IParseFunction} 实现类 | ||||
|  * | ||||
|  * @author anhaohao | ||||
|  */ | ||||
| @Component | ||||
| @Slf4j | ||||
| public class CrmProductUnitParseFunction implements IParseFunction { | ||||
|  | ||||
|     public static final String NAME = "getProductUnitName"; | ||||
|  | ||||
|     @Override | ||||
|     public boolean executeBefore() { | ||||
|         return true; // 先转换值后对比 | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String functionName() { | ||||
|         return NAME; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String apply(Object value) { | ||||
|         if (StrUtil.isEmptyIfStr(value)) { | ||||
|             return ""; | ||||
|         } | ||||
|         return DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CRM_PRODUCT_UNIT, value.toString()); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -5,15 +5,13 @@ import cn.iocoder.yudao.module.crm.controller.admin.product.vo.category.CrmProdu | ||||
| import cn.iocoder.yudao.module.crm.controller.admin.product.vo.category.CrmProductCategoryListReqVO; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO; | ||||
| import cn.iocoder.yudao.module.crm.dal.mysql.product.CrmProductCategoryMapper; | ||||
| import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; | ||||
| import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; | ||||
| import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; | ||||
| import com.mzt.logapi.context.LogRecordContext; | ||||
| import com.mzt.logapi.starter.annotation.LogRecord; | ||||
| import jakarta.annotation.Resource; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
|  | ||||
| import jakarta.annotation.Resource; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
| @@ -40,10 +38,8 @@ public class CrmProductCategoryServiceImpl implements CrmProductCategoryService | ||||
|     private CrmProductService crmProductService; | ||||
|  | ||||
|     @Override | ||||
|     @LogRecord(type = CRM_PRODUCT_CATEGORY_TYPE, subType = CRM_PRODUCT_CATEGORY_CREATE_SUB_TYPE, bizNo = "{{#createReqVO.id}}", | ||||
|     @LogRecord(type = CRM_PRODUCT_CATEGORY_TYPE, subType = CRM_PRODUCT_CATEGORY_CREATE_SUB_TYPE, bizNo = "{{#productCategoryId}}", | ||||
|             success = CRM_PRODUCT_CATEGORY_CREATE_SUCCESS) | ||||
|     // TODO @hao:产品分类,应该没数据权限。可以删除下哈; | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#createReqVO.id", level = CrmPermissionLevelEnum.WRITE) | ||||
|     public Long createProductCategory(CrmProductCategoryCreateReqVO createReqVO) { | ||||
|         // 1.1 校验父分类存在 | ||||
|         validateParentProductCategory(createReqVO.getParentId()); | ||||
| @@ -53,13 +49,14 @@ public class CrmProductCategoryServiceImpl implements CrmProductCategoryService | ||||
|         // 2. 插入分类 | ||||
|         CrmProductCategoryDO category = BeanUtils.toBean(createReqVO, CrmProductCategoryDO.class); | ||||
|         productCategoryMapper.insert(category); | ||||
|         // 记录操作日志上下文 | ||||
|         LogRecordContext.putVariable("productCategoryId", category.getId()); | ||||
|         return category.getId(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @LogRecord(type = CRM_PRODUCT_CATEGORY_TYPE, subType = CRM_PRODUCT_CATEGORY_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", | ||||
|             success = CRM_PRODUCT_CATEGORY_UPDATE_SUCCESS) | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) | ||||
|     public void updateProductCategory(CrmProductCategoryCreateReqVO updateReqVO) { | ||||
|         // 1.1 校验存在 | ||||
|         validateProductCategoryExists(updateReqVO.getId()); | ||||
| @@ -107,7 +104,6 @@ public class CrmProductCategoryServiceImpl implements CrmProductCategoryService | ||||
|     @Override | ||||
|     @LogRecord(type = CRM_PRODUCT_CATEGORY_TYPE, subType = CRM_PRODUCT_CATEGORY_DELETE_SUB_TYPE, bizNo = "{{#id}}", | ||||
|             success = CRM_PRODUCT_CATEGORY_DELETE_SUCCESS) | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) | ||||
|     public void deleteProductCategory(Long id) { | ||||
|         // 1.1 校验存在 | ||||
|         validateProductCategoryExists(id); | ||||
| @@ -124,19 +120,16 @@ public class CrmProductCategoryServiceImpl implements CrmProductCategoryService | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#id", level = CrmPermissionLevelEnum.READ) | ||||
|     public CrmProductCategoryDO getProductCategory(Long id) { | ||||
|         return productCategoryMapper.selectById(id); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#listReqVO.id", level = CrmPermissionLevelEnum.READ) | ||||
|     public List<CrmProductCategoryDO> getProductCategoryList(CrmProductCategoryListReqVO listReqVO) { | ||||
|         return productCategoryMapper.selectList(listReqVO); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#listReqVO.id", level = CrmPermissionLevelEnum.READ) | ||||
|     public List<CrmProductCategoryDO> getProductCategoryList(Collection<Long> ids) { | ||||
|         return productCategoryMapper.selectBatchIds(ids); | ||||
|     } | ||||
|   | ||||
| @@ -16,6 +16,8 @@ import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; | ||||
| import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; | ||||
| import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.mzt.logapi.context.LogRecordContext; | ||||
| import com.mzt.logapi.service.impl.DiffParseFunction; | ||||
| import com.mzt.logapi.starter.annotation.LogRecord; | ||||
| import jakarta.annotation.Resource; | ||||
| import org.springframework.stereotype.Service; | ||||
| @@ -53,9 +55,8 @@ public class CrmProductServiceImpl implements CrmProductService { | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @LogRecord(type = CRM_PRODUCT_TYPE, subType = CRM_PRODUCT_CREATE_SUB_TYPE, bizNo = "{{#createReqVO.id}}", | ||||
|     @LogRecord(type = CRM_PRODUCT_TYPE, subType = CRM_PRODUCT_CREATE_SUB_TYPE, bizNo = "{{#productId}}", | ||||
|             success = CRM_PRODUCT_CREATE_SUCCESS) | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#createReqVO.id", level = CrmPermissionLevelEnum.WRITE) | ||||
|     public Long createProduct(CrmProductSaveReqVO createReqVO) { | ||||
|         // 校验产品 | ||||
|         adminUserApi.validateUserList(Collections.singleton(createReqVO.getOwnerUserId())); | ||||
| @@ -70,6 +71,9 @@ public class CrmProductServiceImpl implements CrmProductService { | ||||
|         permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(product.getOwnerUserId()) | ||||
|                 .setBizType(CrmBizTypeEnum.CRM_PRODUCT.getType()).setBizId(product.getId()) | ||||
|                 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); | ||||
|  | ||||
|         // 记录操作日志上下文 | ||||
|         LogRecordContext.putVariable("productId", product.getId()); | ||||
|         return product.getId(); | ||||
|     } | ||||
|  | ||||
| @@ -80,20 +84,24 @@ public class CrmProductServiceImpl implements CrmProductService { | ||||
|     public void updateProduct(CrmProductSaveReqVO updateReqVO) { | ||||
|         // 校验产品 | ||||
|         updateReqVO.setOwnerUserId(null); // 不修改负责人 | ||||
|         validateProductExists(updateReqVO.getId()); | ||||
|         CrmProductDO crmProductDO = validateProductExists(updateReqVO.getId()); | ||||
|         validateProductNoDuplicate(updateReqVO.getId(), updateReqVO.getNo()); | ||||
|         validateProductCategoryExists(updateReqVO.getCategoryId()); | ||||
|  | ||||
|         // 更新产品 | ||||
|         CrmProductDO updateObj = BeanUtils.toBean(updateReqVO, CrmProductDO.class); | ||||
|         productMapper.updateById(updateObj); | ||||
|  | ||||
|         // 记录操作日志上下文 | ||||
|         LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(crmProductDO,CrmProductSaveReqVO.class)); | ||||
|     } | ||||
|  | ||||
|     private void validateProductExists(Long id) { | ||||
|     private CrmProductDO validateProductExists(Long id) { | ||||
|         CrmProductDO product = productMapper.selectById(id); | ||||
|         if (product == null) { | ||||
|             throw exception(PRODUCT_NOT_EXISTS); | ||||
|         } | ||||
|         return product; | ||||
|     } | ||||
|  | ||||
|     private void validateProductNoDuplicate(Long id, String no) { | ||||
| @@ -138,7 +146,6 @@ public class CrmProductServiceImpl implements CrmProductService { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#pageReqVO.id", level = CrmPermissionLevelEnum.READ) | ||||
|     public PageResult<CrmProductDO> getProductPage(CrmProductPageReqVO pageReqVO) { | ||||
|         return productMapper.selectPage(pageReqVO); | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 anhaohao
					anhaohao