mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 02:28:03 +08:00 
			
		
		
		
	CRM:code review excel 导出的重构
This commit is contained in:
		| @ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.excel.core.handler; | |||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.hutool.core.map.MapUtil; | import cn.hutool.core.map.MapUtil; | ||||||
| import cn.hutool.extra.spring.SpringUtil; | import cn.hutool.extra.spring.SpringUtil; | ||||||
|  | import cn.hutool.poi.excel.ExcelUtil; | ||||||
| import cn.iocoder.yudao.framework.common.core.KeyValue; | import cn.iocoder.yudao.framework.common.core.KeyValue; | ||||||
| import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect; | import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect; | ||||||
| import cn.iocoder.yudao.framework.excel.core.service.ExcelColumnSelectDataService; | import cn.iocoder.yudao.framework.excel.core.service.ExcelColumnSelectDataService; | ||||||
| @ -27,7 +28,9 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | |||||||
|  */ |  */ | ||||||
| public class SelectSheetWriteHandler implements SheetWriteHandler { | public class SelectSheetWriteHandler implements SheetWriteHandler { | ||||||
|  |  | ||||||
|  |     // TODO @puhui999:注释哈; | ||||||
|     private static final List<String> ALPHABET = getExcelColumnNameList(); |     private static final List<String> ALPHABET = getExcelColumnNameList(); | ||||||
|  |  | ||||||
|     private static final List<ExcelColumnSelectDataService> EXCEL_COLUMN_SELECT_DATA_SERVICES = new ArrayList<>(); |     private static final List<ExcelColumnSelectDataService> EXCEL_COLUMN_SELECT_DATA_SERVICES = new ArrayList<>(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @ -43,6 +46,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { | |||||||
|  |  | ||||||
|     private static final String DICT_SHEET_NAME = "字典sheet"; |     private static final String DICT_SHEET_NAME = "字典sheet"; | ||||||
|  |  | ||||||
|  |     // TODO @puhui999:这个 selectMap 可以改成 Map<Integer, List<String>>,然后在 afterSheetCreate 里面进行排序。这样整体的理解成本会更简单 | ||||||
|     private final List<KeyValue<Integer, List<String>>> selectMap = new ArrayList<>(); // 使用 List + KeyValue 组合方便排序 |     private final List<KeyValue<Integer, List<String>>> selectMap = new ArrayList<>(); // 使用 List + KeyValue 组合方便排序 | ||||||
|  |  | ||||||
|     public SelectSheetWriteHandler(Class<?> head) { |     public SelectSheetWriteHandler(Class<?> head) { | ||||||
| @ -51,11 +55,14 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { | |||||||
|         if (MapUtil.isEmpty(beansMap)) { |         if (MapUtil.isEmpty(beansMap)) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |         // TODO @puhui999:static 是共享。如果并发情况下,会不会存在问题?         其实 EXCEL_COLUMN_SELECT_DATA_SERVICES 不用全局声明,直接 按照 ExcelColumnSelect 去拿下就好了; | ||||||
|         if (CollUtil.isEmpty(EXCEL_COLUMN_SELECT_DATA_SERVICES) || EXCEL_COLUMN_SELECT_DATA_SERVICES.size() != beansMap.values().size()) { |         if (CollUtil.isEmpty(EXCEL_COLUMN_SELECT_DATA_SERVICES) || EXCEL_COLUMN_SELECT_DATA_SERVICES.size() != beansMap.values().size()) { | ||||||
|             EXCEL_COLUMN_SELECT_DATA_SERVICES.clear(); |             EXCEL_COLUMN_SELECT_DATA_SERVICES.clear(); | ||||||
|             EXCEL_COLUMN_SELECT_DATA_SERVICES.addAll(convertList(beansMap.values(), b -> b)); |             EXCEL_COLUMN_SELECT_DATA_SERVICES.addAll(convertList(beansMap.values(), b -> b)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 解析下拉数据 |         // 解析下拉数据 | ||||||
|  |         // TODO @puhui999:感觉可以 head 循环 field,如果有 ExcelColumnSelect 则进行处理;而 ExcelProperty 可能是非必须的 | ||||||
|         Map<String, Field> excelPropertyFields = getFieldsWithAnnotation(head, ExcelProperty.class); |         Map<String, Field> excelPropertyFields = getFieldsWithAnnotation(head, ExcelProperty.class); | ||||||
|         Map<String, Field> excelColumnSelectFields = getFieldsWithAnnotation(head, ExcelColumnSelect.class); |         Map<String, Field> excelColumnSelectFields = getFieldsWithAnnotation(head, ExcelColumnSelect.class); | ||||||
|         int colIndex = 0; |         int colIndex = 0; | ||||||
| @ -157,6 +164,7 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { | |||||||
|  |  | ||||||
|  |  | ||||||
|     private static List<String> getExcelColumnNameList() { |     private static List<String> getExcelColumnNameList() { | ||||||
|  |         // TODO @puhui999:是不是可以使用 ExcelUtil.indexToColName() 替代 | ||||||
|         ArrayList<String> strings = new ArrayList<>(); |         ArrayList<String> strings = new ArrayList<>(); | ||||||
|         for (int i = 1; i <= 52; i++) { // 生成 52 列名称,需要更多请重写此方法 |         for (int i = 1; i <= 52; i++) { // 生成 52 列名称,需要更多请重写此方法 | ||||||
|             if (i <= 26) { |             if (i <= 26) { | ||||||
|  | |||||||
| @ -9,11 +9,14 @@ import java.util.List; | |||||||
|  * Excel 列下拉数据源获取接口 |  * Excel 列下拉数据源获取接口 | ||||||
|  * |  * | ||||||
|  * 为什么不直接解析字典还搞个接口?考虑到有的下拉数据不是从字典中获取的所有需要做一个兼容 |  * 为什么不直接解析字典还搞个接口?考虑到有的下拉数据不是从字典中获取的所有需要做一个兼容 | ||||||
|  |  * TODO @puhui999:是不是 @ExcelColumnSelect 可以搞两个属性,一个 dictType,一个 functionName;如果 dictType,则默认走字典,否则走 functionName | ||||||
|  |  *                  这样的话,ExcelColumnSelectDataService 改成 ExcelColumnSelectFunction 用于获取数据。 | ||||||
|  * |  * | ||||||
|  * @author HUIHUI |  * @author HUIHUI | ||||||
|  */ |  */ | ||||||
| public interface ExcelColumnSelectDataService { | public interface ExcelColumnSelectDataService { | ||||||
|  |  | ||||||
|  |     // TODO @puhui999:可以考虑改成 getName | ||||||
|     /** |     /** | ||||||
|      * 获得方法名称 |      * 获得方法名称 | ||||||
|      * |      * | ||||||
| @ -21,6 +24,7 @@ public interface ExcelColumnSelectDataService { | |||||||
|      */ |      */ | ||||||
|     String getFunctionName(); |     String getFunctionName(); | ||||||
|  |  | ||||||
|  |     // TODO @puhui999:可以考虑改成 getOptions;因为 select 下面是 option 哈,和前端 html 类似的标签; | ||||||
|     /** |     /** | ||||||
|      * 获得列下拉数据源 |      * 获得列下拉数据源 | ||||||
|      * |      * | ||||||
| @ -28,6 +32,7 @@ public interface ExcelColumnSelectDataService { | |||||||
|      */ |      */ | ||||||
|     List<String> getSelectDataList(); |     List<String> getSelectDataList(); | ||||||
|  |  | ||||||
|  |     // TODO @puhui999:这个建议放到 SelectSheetWriteHandler 里 | ||||||
|     default List<String> handle(String funcName) { |     default List<String> handle(String funcName) { | ||||||
|         if (StrUtil.isEmptyIfStr(funcName) || !StrUtil.equals(getFunctionName(), funcName)) { |         if (StrUtil.isEmptyIfStr(funcName) || !StrUtil.equals(getFunctionName(), funcName)) { | ||||||
|             return Collections.emptyList(); |             return Collections.emptyList(); | ||||||
|  | |||||||
| @ -1 +1,2 @@ | |||||||
|  | // TODO @puhui999:在 framework 目录,保持 config 和 core 目录的风格哈; | ||||||
| package cn.iocoder.yudao.module.crm.framework.excel; | package cn.iocoder.yudao.module.crm.framework.excel; | ||||||
| @ -3,8 +3,6 @@ package cn.iocoder.yudao.module.crm.framework.excel.service; | |||||||
| import cn.iocoder.yudao.framework.excel.core.service.ExcelColumnSelectDataService; | import cn.iocoder.yudao.framework.excel.core.service.ExcelColumnSelectDataService; | ||||||
| import cn.iocoder.yudao.framework.ip.core.Area; | import cn.iocoder.yudao.framework.ip.core.Area; | ||||||
| import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | ||||||
| import cn.iocoder.yudao.module.system.api.dict.DictDataApi; |  | ||||||
| import jakarta.annotation.Resource; |  | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
|  |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @ -19,9 +17,6 @@ public class AreaExcelColumnSelectDataServiceImpl implements ExcelColumnSelectDa | |||||||
|  |  | ||||||
|     public static final String FUNCTION_NAME = "getCrmAreaNameList"; // 防止和别的模块重名 |     public static final String FUNCTION_NAME = "getCrmAreaNameList"; // 防止和别的模块重名 | ||||||
|  |  | ||||||
|     @Resource |  | ||||||
|     private DictDataApi dictDataApi; |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String getFunctionName() { |     public String getFunctionName() { | ||||||
|         return FUNCTION_NAME; |         return FUNCTION_NAME; | ||||||
| @ -31,7 +26,7 @@ public class AreaExcelColumnSelectDataServiceImpl implements ExcelColumnSelectDa | |||||||
|     public List<String> getSelectDataList() { |     public List<String> getSelectDataList() { | ||||||
|         // 获取地区下拉数据 |         // 获取地区下拉数据 | ||||||
|         // TODO @puhui999:嘿嘿,这里改成省份、城市、区域,三个选项,难度大么? |         // TODO @puhui999:嘿嘿,这里改成省份、城市、区域,三个选项,难度大么? | ||||||
|         Area area = AreaUtils.parseArea(Area.ID_CHINA); |         Area area = AreaUtils.getArea(Area.ID_CHINA); | ||||||
|         return AreaUtils.getAreaNodePathList(area.getChildren()); |         return AreaUtils.getAreaNodePathList(area.getChildren()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -226,18 +226,19 @@ public class CrmContractServiceImpl implements CrmContractService { | |||||||
|             success = CRM_CONTRACT_DELETE_SUCCESS) |             success = CRM_CONTRACT_DELETE_SUCCESS) | ||||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) |     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) | ||||||
|     public void deleteContract(Long id) { |     public void deleteContract(Long id) { | ||||||
|         // 校验存在 |         // 1.1 校验存在 | ||||||
|         CrmContractDO contract = validateContractExists(id); |         CrmContractDO contract = validateContractExists(id); | ||||||
|         // 如果被 CrmReceivableDO 所使用,则不允许删除 |         // 1.2 如果被 CrmReceivableDO 所使用,则不允许删除 | ||||||
|         if (CollUtil.isNotEmpty(receivableService.getReceivableByContractId(contract.getId()))) { |         if (CollUtil.isNotEmpty(receivableService.getReceivableByContractId(contract.getId()))) { | ||||||
|             throw exception(CONTRACT_DELETE_FAIL); |             throw exception(CONTRACT_DELETE_FAIL); | ||||||
|         } |         } | ||||||
|         // 删除 |  | ||||||
|  |         // 2.1 删除合同 | ||||||
|         contractMapper.deleteById(id); |         contractMapper.deleteById(id); | ||||||
|         // 删除数据权限 |         // 2.2 删除数据权限 | ||||||
|         crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTRACT.getType(), id); |         crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTRACT.getType(), id); | ||||||
|  |  | ||||||
|         // 记录操作日志上下文 |         // 3. 记录操作日志上下文 | ||||||
|         LogRecordContext.putVariable("contractName", contract.getName()); |         LogRecordContext.putVariable("contractName", contract.getName()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -122,6 +122,7 @@ public interface CrmReceivableService { | |||||||
|      */ |      */ | ||||||
|     Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds); |     Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds); | ||||||
|  |  | ||||||
|  |     // TODO @puhui999:这个搞成根据数量判断,会更好一点哈; | ||||||
|     /** |     /** | ||||||
|      * 更具合同编号查询回款列表 |      * 更具合同编号查询回款列表 | ||||||
|      * |      * | ||||||
|  | |||||||
| @ -224,12 +224,13 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { | |||||||
|         if (ObjUtil.equal(receivable.getAuditStatus(), CrmAuditStatusEnum.APPROVE.getStatus())) { |         if (ObjUtil.equal(receivable.getAuditStatus(), CrmAuditStatusEnum.APPROVE.getStatus())) { | ||||||
|             throw exception(RECEIVABLE_DELETE_FAIL_IS_APPROVE); |             throw exception(RECEIVABLE_DELETE_FAIL_IS_APPROVE); | ||||||
|         } |         } | ||||||
|         // 2. 删除 |  | ||||||
|  |         // 2.1 删除回款 | ||||||
|         receivableMapper.deleteById(id); |         receivableMapper.deleteById(id); | ||||||
|         // 3. 删除数据权限 |         // 2.2 删除数据权限 | ||||||
|         permissionService.deletePermission(CrmBizTypeEnum.CRM_RECEIVABLE.getType(), id); |         permissionService.deletePermission(CrmBizTypeEnum.CRM_RECEIVABLE.getType(), id); | ||||||
|  |  | ||||||
|         // 4. 记录操作日志上下文 |         // 3. 记录操作日志上下文 | ||||||
|         LogRecordContext.putVariable("receivable", receivable); |         LogRecordContext.putVariable("receivable", receivable); | ||||||
|         LogRecordContext.putVariable("period", getReceivablePeriod(receivable.getPlanId())); |         LogRecordContext.putVariable("period", getReceivablePeriod(receivable.getPlanId())); | ||||||
|     } |     } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV