diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/serviceImpl.java.vm index 28b1a369..bdbfa37c 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/serviceImpl.java.vm +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/serviceImpl.java.vm @@ -77,6 +77,15 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service { Map params = bo.getParams(); MPJLambdaWrapper<${ClassName}> lqw = JoinWrappers.lambda(${ClassName}.class) .selectAll(${ClassName}.class) + #set($hasDelFlag=false) + #foreach($col in $columns) + #if($col.javaField=='delFlag') + #set($hasDelFlag=true) + #end + #end + #if($hasDelFlag) + .eq(${ClassName}::getDelFlag, "0") + #end #foreach($column in $columns) #if($column.query) #set($queryType=$column.queryType) diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/controller/BaseTemplateVariableController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/controller/BaseTemplateVariableController.java index 1af8f103..2e8a2b3d 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/controller/BaseTemplateVariableController.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/controller/BaseTemplateVariableController.java @@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.oa.base.service.ITemplateVariableAssignService; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import org.dromara.common.idempotent.annotation.RepeatSubmit; @@ -18,7 +19,9 @@ import org.dromara.common.core.validate.EditGroup; import org.dromara.common.log.enums.BusinessType; import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.oa.base.domain.vo.BaseTemplateVariableVo; +import org.dromara.oa.base.domain.vo.TemplateVariableAssignVo; import org.dromara.oa.base.domain.bo.BaseTemplateVariableBo; +import org.dromara.oa.base.domain.bo.TemplateVariableAssignRequest; import org.dromara.oa.base.service.IBaseTemplateVariableService; import org.dromara.common.mybatis.core.page.TableDataInfo; @@ -36,6 +39,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; public class BaseTemplateVariableController extends BaseController { private final IBaseTemplateVariableService baseTemplateVariableService; + private final ITemplateVariableAssignService templateVariableAssignService; /** * 查询模板变量信息列表 @@ -113,4 +117,17 @@ public class BaseTemplateVariableController extends BaseController { return R.ok(list); } + /** + * 根据合同信息为模板变量赋值 + * + * @param request 赋值请求(包含模板类型、合同ID) + * @return 赋值后的模板变量列表 + */ +// @SaCheckPermission("oa/base:templateVariable:assign") + @PostMapping("/assign") + public R> assignTemplateVariables(@Validated @RequestBody TemplateVariableAssignRequest request) { + List result = templateVariableAssignService.assignTemplateVariables(request); + return R.ok(result); + } + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/domain/bo/TemplateVariableAssignRequest.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/domain/bo/TemplateVariableAssignRequest.java new file mode 100644 index 00000000..15ac9e6c --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/domain/bo/TemplateVariableAssignRequest.java @@ -0,0 +1,35 @@ +package org.dromara.oa.base.domain.bo; + +import lombok.Data; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * 模板变量赋值请求对象 + * + * @author Yinq + * @date 2025-01-XX + */ +@Data +public class TemplateVariableAssignRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 模板类型(1合同 2发货单) + */ + @NotNull(message = "模板类型不能为空") + private String templateType; + + /** + * 合同ID + */ + @NotNull(message = "合同ID不能为空") + private Long contractId; +} + diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/domain/vo/TemplateVariableAssignVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/domain/vo/TemplateVariableAssignVo.java new file mode 100644 index 00000000..76d2e3b2 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/domain/vo/TemplateVariableAssignVo.java @@ -0,0 +1,40 @@ +package org.dromara.oa.base.domain.vo; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 模板变量赋值结果视图对象 + * + * @author Yinq + * @date 2025-01-XX + */ +@Data +public class TemplateVariableAssignVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 变量名称 + */ + private String varName; + + /** + * 变量显示名称 + */ + private String varLabel; + + /** + * 已赋值的变量值 + */ + private Object varValue; + + /** + * 变量类型(1文本 2数值 3时间 4数组) + */ + private String varType; +} + diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/IBaseTemplateVariableService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/IBaseTemplateVariableService.java index de8132e2..a1b90e53 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/IBaseTemplateVariableService.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/IBaseTemplateVariableService.java @@ -1,6 +1,5 @@ package org.dromara.oa.base.service; -import org.dromara.oa.base.domain.BaseTemplateVariable; import org.dromara.oa.base.domain.vo.BaseTemplateVariableVo; import org.dromara.oa.base.domain.bo.BaseTemplateVariableBo; import org.dromara.common.mybatis.core.page.TableDataInfo; diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/ITemplateVariableAssignService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/ITemplateVariableAssignService.java new file mode 100644 index 00000000..37f48b7b --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/ITemplateVariableAssignService.java @@ -0,0 +1,25 @@ +package org.dromara.oa.base.service; + +import org.dromara.oa.base.domain.bo.TemplateVariableAssignRequest; +import org.dromara.oa.base.domain.vo.TemplateVariableAssignVo; + +import java.util.List; + +/** + * 模板变量赋值Service接口 + * + * @author Yinq + * @date 2025-01-XX + */ +public interface ITemplateVariableAssignService { + + /** + * 根据模板类型为模板变量赋值 + * 模板类型:1=合同,2=发货单 + * + * @param request 赋值请求(包含变量名称数组、模板类型、业务ID等) + * @return 赋值后的模板变量列表 + */ + List assignTemplateVariables(TemplateVariableAssignRequest request); +} + diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/impl/BaseTemplateVariableServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/impl/BaseTemplateVariableServiceImpl.java index 957162d3..c7c16748 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/impl/BaseTemplateVariableServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/impl/BaseTemplateVariableServiceImpl.java @@ -2,12 +2,11 @@ package org.dromara.oa.base.service.impl; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; - import org.dromara.common.mybatis.core.page.TableDataInfo; - import org.dromara.common.mybatis.core.page.PageQuery; - import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.wrapper.MPJLambdaWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.dromara.oa.base.domain.bo.BaseTemplateVariableBo; @@ -16,9 +15,8 @@ import org.dromara.oa.base.domain.BaseTemplateVariable; import org.dromara.oa.base.mapper.BaseTemplateVariableMapper; import org.dromara.oa.base.service.IBaseTemplateVariableService; -import java.util.List; -import java.util.Map; import java.util.Collection; +import java.util.List; /** * 模板变量信息Service业务层处理 @@ -39,23 +37,23 @@ public class BaseTemplateVariableServiceImpl implements IBaseTemplateVariableSer * @return 模板变量信息 */ @Override - public BaseTemplateVariableVo queryById(Long variableId){ + public BaseTemplateVariableVo queryById(Long variableId) { return baseMapper.selectVoById(variableId); } - /** - * 分页查询模板变量信息列表 - * - * @param bo 查询条件 - * @param pageQuery 分页参数 - * @return 模板变量信息分页列表 - */ - @Override - public TableDataInfo queryPageList(BaseTemplateVariableBo bo, PageQuery pageQuery) { - MPJLambdaWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } + /** + * 分页查询模板变量信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 模板变量信息分页列表 + */ + @Override + public TableDataInfo queryPageList(BaseTemplateVariableBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } /** * 查询符合条件的模板变量信息列表 @@ -70,20 +68,18 @@ public class BaseTemplateVariableServiceImpl implements IBaseTemplateVariableSer } private MPJLambdaWrapper buildQueryWrapper(BaseTemplateVariableBo bo) { - Map params = bo.getParams(); MPJLambdaWrapper lqw = JoinWrappers.lambda(BaseTemplateVariable.class) - .selectAll(BaseTemplateVariable.class) - .eq(StringUtils.isNotBlank(bo.getVarLabel()), BaseTemplateVariable::getVarLabel, bo.getVarLabel()) - .like(StringUtils.isNotBlank(bo.getVarName()), BaseTemplateVariable::getVarName, bo.getVarName()) - .eq(StringUtils.isNotBlank(bo.getTemplateType()), BaseTemplateVariable::getTemplateType, bo.getTemplateType()) - .eq(StringUtils.isNotBlank(bo.getDataSource()), BaseTemplateVariable::getDataSource, bo.getDataSource()) - .eq(StringUtils.isNotBlank(bo.getDataField()), BaseTemplateVariable::getDataField, bo.getDataField()) - .eq(StringUtils.isNotBlank(bo.getVarType()), BaseTemplateVariable::getVarType, bo.getVarType()) - .eq(StringUtils.isNotBlank(bo.getDefaultValue()), BaseTemplateVariable::getDefaultValue, bo.getDefaultValue()) - .eq(bo.getSortOrder() != null, BaseTemplateVariable::getSortOrder, bo.getSortOrder()) - .eq(bo.getTemplateId() != null, BaseTemplateVariable::getTemplateId, bo.getTemplateId()) - .eq(StringUtils.isNotBlank(bo.getActiveFlag()), BaseTemplateVariable::getActiveFlag, bo.getActiveFlag()) -; + .selectAll(BaseTemplateVariable.class) + .eq(StringUtils.isNotBlank(bo.getVarLabel()), BaseTemplateVariable::getVarLabel, bo.getVarLabel()) + .like(StringUtils.isNotBlank(bo.getVarName()), BaseTemplateVariable::getVarName, bo.getVarName()) + .eq(StringUtils.isNotBlank(bo.getTemplateType()), BaseTemplateVariable::getTemplateType, bo.getTemplateType()) + .eq(StringUtils.isNotBlank(bo.getDataSource()), BaseTemplateVariable::getDataSource, bo.getDataSource()) + .eq(StringUtils.isNotBlank(bo.getDataField()), BaseTemplateVariable::getDataField, bo.getDataField()) + .eq(StringUtils.isNotBlank(bo.getVarType()), BaseTemplateVariable::getVarType, bo.getVarType()) + .eq(StringUtils.isNotBlank(bo.getDefaultValue()), BaseTemplateVariable::getDefaultValue, bo.getDefaultValue()) + .eq(bo.getSortOrder() != null, BaseTemplateVariable::getSortOrder, bo.getSortOrder()) + .eq(bo.getTemplateId() != null, BaseTemplateVariable::getTemplateId, bo.getTemplateId()) + .eq(StringUtils.isNotBlank(bo.getActiveFlag()), BaseTemplateVariable::getActiveFlag, bo.getActiveFlag()); return lqw; } @@ -120,7 +116,7 @@ public class BaseTemplateVariableServiceImpl implements IBaseTemplateVariableSer /** * 保存前的数据校验 */ - private void validEntityBeforeSave(BaseTemplateVariable entity){ + private void validEntityBeforeSave(BaseTemplateVariable entity) { //TODO 做一些数据校验,如唯一约束 } @@ -133,7 +129,7 @@ public class BaseTemplateVariableServiceImpl implements IBaseTemplateVariableSer */ @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if(isValid){ + if (isValid) { //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteByIds(ids) > 0; diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/impl/TemplateVariableAssignServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/impl/TemplateVariableAssignServiceImpl.java new file mode 100644 index 00000000..f87701de --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/base/service/impl/TemplateVariableAssignServiceImpl.java @@ -0,0 +1,403 @@ +package org.dromara.oa.base.service.impl; + +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.oa.base.domain.bo.BaseTemplateVariableBo; +import org.dromara.oa.base.domain.bo.TemplateVariableAssignRequest; +import org.dromara.oa.base.domain.vo.BaseTemplateVariableVo; +import org.dromara.oa.base.domain.vo.TemplateVariableAssignVo; +import org.dromara.oa.base.service.IBaseTemplateVariableService; +import org.dromara.oa.base.service.ITemplateVariableAssignService; +import org.dromara.oa.erp.domain.bo.ErpContractInfoBo; +import org.dromara.oa.erp.domain.bo.ErpContractMaterialBo; +import org.dromara.oa.erp.domain.vo.ErpContractInfoVo; +import org.dromara.oa.erp.domain.vo.ErpContractMaterialVo; +import org.dromara.oa.erp.service.IErpContractInfoService; +import org.dromara.oa.erp.service.IErpContractMaterialService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 模板变量赋值Service业务层处理 + * + * @author Yinq + * @date 2025-01-XX + */ +@RequiredArgsConstructor +@Service +public class TemplateVariableAssignServiceImpl implements ITemplateVariableAssignService { + + private final IBaseTemplateVariableService baseTemplateVariableService; + private final IErpContractInfoService erpContractInfoService; + private final IErpContractMaterialService erpContractMaterialService; + + /** + * 根据模板类型为模板变量赋值 + * 模板类型:1=合同,2=发货单 + * + * @param request 赋值请求(包含变量名称数组、模板类型、业务ID等) + * @return 赋值后的模板变量列表 + */ + @Override + public List assignTemplateVariables(TemplateVariableAssignRequest request) { + // 根据模板类型选择不同的处理逻辑 + String templateType = request.getTemplateType(); + if ("1".equals(templateType)) { + // 合同类型 + return assignContractTemplateVariables(request); + } else if ("2".equals(templateType)) { + // 发货单类型 + return assignDeliveryTemplateVariables(request); + } else { + throw new ServiceException("不支持的模板类型:" + templateType); + } + } + + /** + * 为合同模板变量赋值 + * + * @param request 赋值请求 + * @return 赋值后的模板变量列表 + */ + private List assignContractTemplateVariables(TemplateVariableAssignRequest request) { + // 1. 根据模板类型查询所有模板变量配置 + BaseTemplateVariableBo queryBo = new BaseTemplateVariableBo(); + queryBo.setTemplateType(request.getTemplateType()); + List allTemplateVariables = baseTemplateVariableService.queryList(queryBo); + + // 构建变量名到配置的映射 + Map variableMap = buildVariableMap(allTemplateVariables); + + // 2. 查询合同信息 + ErpContractInfoBo bo = new ErpContractInfoBo(); + bo.setContractId(request.getContractId()); + List contractInfoVoList = erpContractInfoService.queryList(bo); + if (contractInfoVoList.isEmpty()) { + throw new ServiceException("合同信息不存在,合同ID:" + request.getContractId()); + } + ErpContractInfoVo contractInfo = contractInfoVoList.get(0); + + // 3. 查询合同物料列表(如果存在需要物料数据的变量) + List contractMaterials = null; + boolean needMaterialData = allTemplateVariables.stream() + .anyMatch(var -> "erp_contract_material".equalsIgnoreCase(var.getDataSource())); + if (needMaterialData) { + ErpContractMaterialBo materialBo = new ErpContractMaterialBo(); + materialBo.setContractId(request.getContractId()); + contractMaterials = erpContractMaterialService.queryList(materialBo); + for (int i = 0; i < contractMaterials.size(); i++) { + contractMaterials.get(i).setSeq(i + 1L); + } + } + + // 4. 为所有模板变量赋值 + return buildAssignResultList(allTemplateVariables, variableMap, contractInfo, contractMaterials); + } + + /** + * 为发货单模板变量赋值 + * + * @param request 赋值请求 + * @return 赋值后的模板变量列表 + */ + private List assignDeliveryTemplateVariables(TemplateVariableAssignRequest request) { + // TODO: 实现发货单模板变量赋值逻辑 + throw new ServiceException("发货单模板变量赋值功能暂未实现"); + } + + /** + * 构建赋值结果列表 + * + * @param allTemplateVariables 所有模板变量配置 + * @param variableMap 变量配置映射 + * @param contractInfo 合同信息 + * @param contractMaterials 合同物料列表 + * @return 赋值结果列表 + */ + private List buildAssignResultList( + List allTemplateVariables, + Map variableMap, + ErpContractInfoVo contractInfo, + List contractMaterials) { + + List resultList = new ArrayList<>(); + for (BaseTemplateVariableVo variable : allTemplateVariables) { + if (variable == null || StringUtils.isBlank(variable.getVarName())) { + continue; + } + + // 根据 dataSource 决定数据源 + Object value = getValueFromDataSource(variable, contractInfo, contractMaterials); + + // 如果获取不到值,使用默认值 + if (value == null && StringUtils.isNotBlank(variable.getDefaultValue())) { + value = variable.getDefaultValue(); + } + + // 根据变量类型决定返回类型(4表示数组类型) + boolean shouldReturnArray = "4".equals(variable.getVarType()); + Object finalValue = convertValueToTargetType(value, shouldReturnArray); + + // 构建返回对象 + TemplateVariableAssignVo assignVo = new TemplateVariableAssignVo(); + assignVo.setVarName(variable.getVarName()); + assignVo.setVarLabel(variable.getVarLabel()); + assignVo.setVarValue(finalValue); + assignVo.setVarType(variable.getVarType()); + resultList.add(assignVo); + } + + return resultList; + } + + /** + * 解析变量名称格式 + * #{变量名} 表示字符串类型 + * ^{变量名} 表示数组类型 + * + * @param varNameWithFormat 带格式的变量名,如 #{客户名称} 或 ^{产品名称} + * @return 变量名信息 + */ + private VariableNameInfo parseVariableName(String varNameWithFormat) { + if (StringUtils.isBlank(varNameWithFormat)) { + return new VariableNameInfo(varNameWithFormat, false); + } + + // 检查是否是 #{变量名} 格式(字符串) + if (varNameWithFormat.startsWith("#{") && varNameWithFormat.endsWith("}")) { + String actualName = varNameWithFormat.substring(2, varNameWithFormat.length() - 1); + return new VariableNameInfo(actualName, false); + } + + // 检查是否是 ^{变量名} 格式(数组) + if (varNameWithFormat.startsWith("^{") && varNameWithFormat.endsWith("}")) { + String actualName = varNameWithFormat.substring(2, varNameWithFormat.length() - 1); + return new VariableNameInfo(actualName, true); + } + + // 默认格式,返回原值 + return new VariableNameInfo(varNameWithFormat, false); + } + + /** + * 变量名信息内部类 + */ + private static class VariableNameInfo { + private final String actualName; + private final boolean arrayType; + + public VariableNameInfo(String actualName, boolean arrayType) { + this.actualName = actualName; + this.arrayType = arrayType; + } + + public String getActualName() { + return actualName; + } + + public boolean isArrayType() { + return arrayType; + } + } + + /** + * 构建变量名到配置的映射 + * 支持带占位符(#{变量名}或^{变量名})和不带占位符的匹配 + * + * @param templateVariables 所有模板变量配置 + * @return 变量名到配置的映射 + */ + private Map buildVariableMap( + List templateVariables) { + Map variableMap = new HashMap<>(); + + for (BaseTemplateVariableVo variable : templateVariables) { + String varName = variable.getVarName(); + if (StringUtils.isBlank(varName)) { + continue; + } + + // 提取变量名(去除占位符) + String normalizedName = normalizeVariableName(varName); + + // 添加到映射中(使用规范化后的变量名作为key) + variableMap.put(normalizedName, variable); + } + + return variableMap; + } + + /** + * 规范化变量名(去除占位符格式) + * + * @param varName 变量名(可能包含#{或^{}) + * @return 规范化后的变量名 + */ + private String normalizeVariableName(String varName) { + if (StringUtils.isBlank(varName)) { + return varName; + } + + // 去除 #{变量名} 或 ^{变量名} 格式 + if ((varName.startsWith("#{") || varName.startsWith("^{")) && varName.endsWith("}")) { + return varName.substring(2, varName.length() - 1); + } + + return varName; + } + + /** + * 根据数据源获取字段值 + * + * @param variable 变量配置 + * @param contractInfo 合同信息 + * @param contractMaterials 合同物料列表(可能为null) + * @return 字段值 + */ + private Object getValueFromDataSource(BaseTemplateVariableVo variable, + ErpContractInfoVo contractInfo, + List contractMaterials) { + if (StringUtils.isBlank(variable.getDataField())) { + return null; + } + + String dataSource = variable.getDataSource(); + + // 根据数据源类型获取值 + if ("erp_contract_material".equalsIgnoreCase(dataSource)) { + // 从合同物料列表中提取字段值 + return getFieldValueFromMaterialList(contractMaterials, variable.getDataField()); + } else { + // 默认从合同信息中获取 + return getFieldValueFromContract(contractInfo, variable.getDataField()); + } + } + + /** + * 从合同物料列表中提取指定字段的值列表 + * + * @param contractMaterials 合同物料列表 + * @param fieldName 字段名 + * @return 字段值列表 + */ + private List getFieldValueFromMaterialList(List contractMaterials, String fieldName) { + if (contractMaterials == null || contractMaterials.isEmpty() || StringUtils.isBlank(fieldName)) { + return new ArrayList<>(); + } + + List values = new ArrayList<>(); + for (ErpContractMaterialVo material : contractMaterials) { + Object value = getFieldValueFromObject(material, fieldName); + // 如果值为null,用空字符串代替 + values.add(value != null ? value : ""); + } + return values; + } + + /** + * 使用反射从对象中根据字段名获取值 + * + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值 + */ + private Object getFieldValueFromObject(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 先尝试使用反射获取字段值 + Field field = obj.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + return field.get(obj); + } catch (NoSuchFieldException e) { + // 如果字段不存在,尝试使用 getter 方法 + try { + String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); + return obj.getClass().getMethod(methodName).invoke(obj); + } catch (Exception ex) { + // 如果都获取不到,返回 null + return null; + } + } catch (Exception e) { + return null; + } + } + + /** + * 使用反射从合同信息中根据字段名获取值 + * + * @param contractInfo 合同信息 + * @param fieldName 字段名 + * @return 字段值 + */ + private Object getFieldValueFromContract(ErpContractInfoVo contractInfo, String fieldName) { + return getFieldValueFromObject(contractInfo, fieldName); + } + + /** + * 将值转换为目标类型 + * + * @param value 原始值 + * @param shouldReturnArray 是否应该返回数组类型 + * @return 转换后的值 + */ + private Object convertValueToTargetType(Object value, boolean shouldReturnArray) { + if (shouldReturnArray) { + // 转换为数组类型 + if (value instanceof List) { + return value; + } else if (value instanceof Collection) { + return new ArrayList<>((Collection) value); + } else if (value != null) { + // 单个值,转换为列表 + List arrayValue = new ArrayList<>(); + arrayValue.add(value); + return arrayValue; + } else { + return new ArrayList<>(); + } + } else { + // 转换为字符串类型 + if (value instanceof List) { + List list = (List) value; + if (!list.isEmpty()) { + return list.get(0).toString(); + } else { + return ""; + } + } else if (value instanceof Collection) { + Collection collection = (Collection) value; + if (!collection.isEmpty()) { + return collection.iterator().next().toString(); + } else { + return ""; + } + } else if (value != null) { + return value.toString(); + } else { + return ""; + } + } + } + + /** + * 根据类型获取默认值 + * + * @param isArrayType 是否为数组类型 + * @return 默认值 + */ + private Object getDefaultValueByType(boolean isArrayType) { + return isArrayType ? new ArrayList<>() : ""; + } +} + diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/controller/CrmSupplierInfoController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/controller/CrmSupplierInfoController.java new file mode 100644 index 00000000..707b0988 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/controller/CrmSupplierInfoController.java @@ -0,0 +1,116 @@ +package org.dromara.oa.crm.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.oa.crm.domain.vo.CrmSupplierInfoVo; +import org.dromara.oa.crm.domain.bo.CrmSupplierInfoBo; +import org.dromara.oa.crm.service.ICrmSupplierInfoService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 供应商信息 + * 前端访问路由地址为:/oa/crm/crmSupplierInfo + * + * @author Yinq + * @date 2025-11-05 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/crm/crmSupplierInfo") +public class CrmSupplierInfoController extends BaseController { + + private final ICrmSupplierInfoService crmSupplierInfoService; + + /** + * 查询供应商信息列表 + */ + @SaCheckPermission("oa/crm:crmSupplierInfo:list") + @GetMapping("/list") + public TableDataInfo list(CrmSupplierInfoBo bo, PageQuery pageQuery) { + return crmSupplierInfoService.queryPageList(bo, pageQuery); + } + + /** + * 导出供应商信息列表 + */ + @SaCheckPermission("oa/crm:crmSupplierInfo:export") + @Log(title = "供应商信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(CrmSupplierInfoBo bo, HttpServletResponse response) { + List list = crmSupplierInfoService.queryList(bo); + ExcelUtil.exportExcel(list, "供应商信息", CrmSupplierInfoVo.class, response); + } + + /** + * 获取供应商信息详细信息 + * + * @param supplierId 主键 + */ + @SaCheckPermission("oa/crm:crmSupplierInfo:query") + @GetMapping("/{supplierId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable("supplierId") Long supplierId) { + return R.ok(crmSupplierInfoService.queryById(supplierId)); + } + + /** + * 新增供应商信息 + */ + @SaCheckPermission("oa/crm:crmSupplierInfo:add") + @Log(title = "供应商信息", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody CrmSupplierInfoBo bo) { + return toAjax(crmSupplierInfoService.insertByBo(bo)); + } + + /** + * 修改供应商信息 + */ + @SaCheckPermission("oa/crm:crmSupplierInfo:edit") + @Log(title = "供应商信息", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody CrmSupplierInfoBo bo) { + return toAjax(crmSupplierInfoService.updateByBo(bo)); + } + + /** + * 删除供应商信息 + * + * @param supplierIds 主键串 + */ + @SaCheckPermission("oa/crm:crmSupplierInfo:remove") + @Log(title = "供应商信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{supplierIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable("supplierIds") Long[] supplierIds) { + return toAjax(crmSupplierInfoService.deleteWithValidByIds(List.of(supplierIds), true)); + } + + /** + * 下拉框查询供应商信息列表 + */ + @GetMapping("/getCrmSupplierInfoList") + public R> getCrmSupplierInfoList(CrmSupplierInfoBo bo) { + List list = crmSupplierInfoService.queryList(bo); + return R.ok(list); + } + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/CrmSupplierInfo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/CrmSupplierInfo.java new file mode 100644 index 00000000..af9fc8b0 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/CrmSupplierInfo.java @@ -0,0 +1,178 @@ +package org.dromara.oa.crm.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 供应商信息对象 crm_supplier_info + * + * @author Yinq + * @date 2025-11-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("crm_supplier_info") +public class CrmSupplierInfo extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 供应商ID + */ + @TableId(value = "supplier_id", type = IdType.AUTO) + private Long supplierId; + + /** + * 供应商名称 + */ + private String supplierName; + + /** + * 助记名称 + */ + private String mnemonicName; + + /** + * 供应商类型(1企业 2个体户 3其他) + */ + private String supplierType; + + /** + * 注册资本(万元) + */ + private BigDecimal registeredCapital; + + /** + * 成立日期 + */ + private Date establishmentDate; + + /** + * 经营范围 + */ + private String businessScope; + + /** + * 主营行业 + */ + private String mainIndustry; + + /** + * 法定代表人 + */ + private String legalRepresentative; + + /** + * 营业执照号码 + */ + private String businessLicenseNumber; + + /** + * 税号 + */ + private String taxNumber; + + /** + * 开户银行 + */ + private String bankAccountOpening; + + /** + * 银行账号 + */ + private String bankNumber; + + /** + * 注册地址 + */ + private String registeredAddress; + + /** + * 经营地址 + */ + private String businessAddress; + + /** + * 联系人 + */ + private String contactPerson; + + /** + * 联系电话 + */ + private String contactPhone; + + /** + * 联系手机 + */ + private String contactMobile; + + /** + * 联系邮箱 + */ + private String contactEmail; + + /** + * 传真 + */ + private String contactFax; + + /** + * 网址 + */ + private String website; + + /** + * 归属人员ID + */ + private Long ownerId; + + /** + * 详细地址 + */ + private String detailedAddress; + + /** + * 附件ID + */ + private String ossId; + + /** + * 备注 + */ + private String remark; + + /** + * 激活标识(1是 0否) + */ + private String activeFlag; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @TableLogic + private String delFlag; + + + /** + * 归属人员名称 + */ + @TableField(exist = false) + private String ownerName; + + /** + * 归属人员部门名称 + */ + @TableField(exist = false) + private String ownerDeptName; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/bo/CrmSupplierInfoBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/bo/CrmSupplierInfoBo.java new file mode 100644 index 00000000..4d8b903b --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/bo/CrmSupplierInfoBo.java @@ -0,0 +1,158 @@ +package org.dromara.oa.crm.domain.bo; + +import org.dromara.oa.crm.domain.CrmSupplierInfo; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 供应商信息业务对象 crm_supplier_info + * + * @author Yinq + * @date 2025-11-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = CrmSupplierInfo.class, reverseConvertGenerate = false) +public class CrmSupplierInfoBo extends BaseEntity { + + /** + * 供应商ID + */ + @NotNull(message = "供应商ID不能为空", groups = { EditGroup.class }) + private Long supplierId; + + /** + * 供应商名称 + */ + private String supplierName; + + /** + * 助记名称 + */ + private String mnemonicName; + + /** + * 供应商类型(1企业 2个体户 3其他) + */ + private String supplierType; + + /** + * 注册资本(万元) + */ + private BigDecimal registeredCapital; + + /** + * 成立日期 + */ + private Date establishmentDate; + + /** + * 经营范围 + */ + private String businessScope; + + /** + * 主营行业 + */ + private String mainIndustry; + + /** + * 法定代表人 + */ + private String legalRepresentative; + + /** + * 营业执照号码 + */ + private String businessLicenseNumber; + + /** + * 税号 + */ + private String taxNumber; + + /** + * 开户银行 + */ + private String bankAccountOpening; + + /** + * 银行账号 + */ + private String bankNumber; + + /** + * 注册地址 + */ + private String registeredAddress; + + /** + * 经营地址 + */ + private String businessAddress; + + /** + * 联系人 + */ + private String contactPerson; + + /** + * 联系电话 + */ + private String contactPhone; + + /** + * 联系手机 + */ + private String contactMobile; + + /** + * 联系邮箱 + */ + private String contactEmail; + + /** + * 传真 + */ + private String contactFax; + + /** + * 网址 + */ + private String website; + + /** + * 归属人员ID + */ + private Long ownerId; + + /** + * 详细地址 + */ + private String detailedAddress; + + /** + * 附件ID + */ + private String ossId; + + /** + * 备注 + */ + private String remark; + + /** + * 激活标识(1是 0否) + */ + private String activeFlag; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/vo/CrmSupplierInfoVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/vo/CrmSupplierInfoVo.java new file mode 100644 index 00000000..e76123f4 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/domain/vo/CrmSupplierInfoVo.java @@ -0,0 +1,209 @@ +package org.dromara.oa.crm.domain.vo; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.oa.crm.domain.CrmSupplierInfo; +import cn.idev.excel.annotation.ExcelIgnore; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.resource.api.domain.RemoteFile; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + + + +/** + * 供应商信息视图对象 crm_supplier_info + * + * @author Yinq + * @date 2025-11-05 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = CrmSupplierInfo.class) +public class CrmSupplierInfoVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 供应商ID + */ + @ExcelProperty(value = "供应商ID") + private Long supplierId; + + /** + * 供应商名称 + */ + @ExcelProperty(value = "供应商名称") + private String supplierName; + + /** + * 助记名称 + */ + @ExcelProperty(value = "助记名称") + private String mnemonicName; + + /** + * 供应商类型(1企业 2个体户 3其他) + */ + @ExcelProperty(value = "供应商类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "supplier_type") + private String supplierType; + + /** + * 注册资本(万元) + */ + @ExcelProperty(value = "注册资本", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "万=元") + private BigDecimal registeredCapital; + + /** + * 成立日期 + */ + @ExcelProperty(value = "成立日期") + private Date establishmentDate; + + /** + * 经营范围 + */ + @ExcelProperty(value = "经营范围") + private String businessScope; + + /** + * 主营行业 + */ + @ExcelProperty(value = "主营行业") + private String mainIndustry; + + /** + * 法定代表人 + */ + @ExcelProperty(value = "法定代表人") + private String legalRepresentative; + + /** + * 营业执照号码 + */ + @ExcelProperty(value = "营业执照号码") + private String businessLicenseNumber; + + /** + * 税号 + */ + @ExcelProperty(value = "税号") + private String taxNumber; + + /** + * 开户银行 + */ + @ExcelProperty(value = "开户银行") + private String bankAccountOpening; + + /** + * 银行账号 + */ + @ExcelProperty(value = "银行账号") + private String bankNumber; + + /** + * 注册地址 + */ + @ExcelProperty(value = "注册地址") + private String registeredAddress; + + /** + * 经营地址 + */ + @ExcelProperty(value = "经营地址") + private String businessAddress; + + /** + * 联系人 + */ + @ExcelProperty(value = "联系人") + private String contactPerson; + + /** + * 联系电话 + */ + @ExcelProperty(value = "联系电话") + private String contactPhone; + + /** + * 联系手机 + */ + @ExcelProperty(value = "联系手机") + private String contactMobile; + + /** + * 联系邮箱 + */ + @ExcelProperty(value = "联系邮箱") + private String contactEmail; + + /** + * 传真 + */ + @ExcelProperty(value = "传真") + private String contactFax; + + /** + * 网址 + */ + @ExcelProperty(value = "网址") + private String website; + + /** + * 归属人员ID + */ + @ExcelProperty(value = "归属人员ID") + private Long ownerId; + + /** + * 详细地址 + */ + @ExcelProperty(value = "详细地址") + private String detailedAddress; + + /** + * 附件ID + */ + @ExcelProperty(value = "附件ID") + private String ossId; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 激活标识(1是 0否) + */ + @ExcelProperty(value = "激活标识", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "active_flag") + private String activeFlag; + + /** + * 归属人员名称(从 sys_user 关联得到,不落库) + */ + @ExcelProperty(value = "归属人员名称") + private String ownerName; + + /** + * 附件信息 + */ + @ExcelIgnore + private List attachmentList; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/mapper/CrmSupplierInfoMapper.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/mapper/CrmSupplierInfoMapper.java new file mode 100644 index 00000000..4e76a100 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/mapper/CrmSupplierInfoMapper.java @@ -0,0 +1,113 @@ +package org.dromara.oa.crm.mapper; + +import java.util.List; +import java.util.Collection; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.dromara.oa.crm.domain.CrmSupplierInfo; +import org.dromara.oa.crm.domain.vo.CrmSupplierInfoVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 供应商信息Mapper接口 + * + * @author Yinq + * @date 2025-11-05 + */ +public interface CrmSupplierInfoMapper extends BaseMapperPlus { + + /** + * 查询供应商信息列表 + * + * @param page 分页 + * @param queryWrapper 条件 + * @return 供应商信息集合 + */ + public Page selectCustomCrmSupplierInfoVoList(@Param("page") Page page, @Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 查询供应商信息列表 + * + * @param queryWrapper 条件 + * @return 供应商信息集合 + */ + public List selectCustomCrmSupplierInfoVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 根据ID查询供应商信息详情 + * + * @param supplierId 主键ID + * @return 供应商信息对象 + */ + CrmSupplierInfoVo selectCustomCrmSupplierInfoVoById(@Param("supplierId") Long supplierId); + + /** + * 根据ID列表批量查询供应商信息 + * + * @param ids ID集合 + * @return 供应商信息集合 + */ + List selectCustomCrmSupplierInfoVoByIds(@Param("ids") Collection ids); + + /** + * 统计供应商信息记录数 + * + * @param queryWrapper 查询条件 + * @return 记录总数 + */ + Long countCustomCrmSupplierInfo(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 分页查询供应商信息(自定义条件) + * + * @param page 分页对象 + * @param queryWrapper 查询条件 + * @return 分页结果 + */ + Page selectCustomCrmSupplierInfoVoPage(@Param("page") Page page, @Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 批量插入供应商信息 + * + * @param list 供应商信息对象集合 + * @return 影响行数 + */ + int batchInsertCrmSupplierInfo(@Param("list") List list); + + /** + * 批量更新供应商信息 + * + * @param list 供应商信息对象集合 + * @return 影响行数 + */ + int batchUpdateCrmSupplierInfo(@Param("list") List list); + + /** + * 根据自定义条件删除供应商信息 + * + * @param queryWrapper 删除条件 + * @return 影响行数 + */ + int deleteCustomCrmSupplierInfo(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 根据ID列表批量删除供应商信息 + * + * @param ids ID集合 + * @return 影响行数 + */ + int deleteCustomCrmSupplierInfoByIds(@Param("ids") Collection ids); + + /** + * 检查供应商信息是否存在 + * + * @param queryWrapper 查询条件 + * @return 是否存在 + */ + Boolean existsCrmSupplierInfo(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/ICrmSupplierInfoService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/ICrmSupplierInfoService.java new file mode 100644 index 00000000..bf525dbd --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/ICrmSupplierInfoService.java @@ -0,0 +1,69 @@ +package org.dromara.oa.crm.service; + +import org.dromara.oa.crm.domain.CrmSupplierInfo; +import org.dromara.oa.crm.domain.vo.CrmSupplierInfoVo; +import org.dromara.oa.crm.domain.bo.CrmSupplierInfoBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 供应商信息Service接口 + * + * @author Yinq + * @date 2025-11-05 + */ +public interface ICrmSupplierInfoService { + + /** + * 查询供应商信息 + * + * @param supplierId 主键 + * @return 供应商信息 + */ + CrmSupplierInfoVo queryById(Long supplierId); + + /** + * 分页查询供应商信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 供应商信息分页列表 + */ + TableDataInfo queryPageList(CrmSupplierInfoBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的供应商信息列表 + * + * @param bo 查询条件 + * @return 供应商信息列表 + */ + List queryList(CrmSupplierInfoBo bo); + + /** + * 新增供应商信息 + * + * @param bo 供应商信息 + * @return 是否新增成功 + */ + Boolean insertByBo(CrmSupplierInfoBo bo); + + /** + * 修改供应商信息 + * + * @param bo 供应商信息 + * @return 是否修改成功 + */ + Boolean updateByBo(CrmSupplierInfoBo bo); + + /** + * 校验并批量删除供应商信息信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmCustomerContactServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmCustomerContactServiceImpl.java index 3f57b2ae..f675bd53 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmCustomerContactServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmCustomerContactServiceImpl.java @@ -75,7 +75,7 @@ public class CrmCustomerContactServiceImpl implements ICrmCustomerContactService MPJLambdaWrapper lqw = JoinWrappers.lambda(CrmCustomerContact.class) .selectAll(CrmCustomerContact.class) .select(CrmCustomerInfo::getCustomerName) - .leftJoin(CrmCustomerInfo.class, CrmCustomerInfo::getCustomerId, CrmCustomerContact::getContactId) + .leftJoin(CrmCustomerInfo.class, CrmCustomerInfo::getCustomerId, CrmCustomerContact::getCustomerId) .eq(bo.getCustomerId() != null, CrmCustomerContact::getCustomerId, bo.getCustomerId()) .like(StringUtils.isNotBlank(bo.getContactName()), CrmCustomerContact::getContactName, bo.getContactName()) .eq(StringUtils.isNotBlank(bo.getSexType()), CrmCustomerContact::getSexType, bo.getSexType()) diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmSupplierInfoServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmSupplierInfoServiceImpl.java new file mode 100644 index 00000000..484b634e --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmSupplierInfoServiceImpl.java @@ -0,0 +1,217 @@ +package org.dromara.oa.crm.service.impl; + +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.yulichang.toolkit.JoinWrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.stereotype.Service; +import org.dromara.oa.crm.domain.bo.CrmSupplierInfoBo; +import org.dromara.oa.crm.domain.vo.CrmSupplierInfoVo; +import org.dromara.oa.crm.domain.CrmSupplierInfo; +import org.dromara.oa.crm.mapper.CrmSupplierInfoMapper; +import org.dromara.oa.crm.service.ICrmSupplierInfoService; +import org.dromara.resource.api.RemoteFileService; +import org.dromara.resource.api.domain.RemoteFile; + +import java.util.List; +import java.util.Map; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; +import java.util.LinkedHashSet; +import java.util.HashMap; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +/** + * 供应商信息Service业务层处理 + * + * @author Yinq + * @date 2025-11-05 + */ +@RequiredArgsConstructor +@Service +public class CrmSupplierInfoServiceImpl implements ICrmSupplierInfoService { + + private final CrmSupplierInfoMapper baseMapper; + @DubboReference(mock = "true") + private RemoteFileService remoteFileService; + + /** + * 查询供应商信息 + * + * @param supplierId 主键 + * @return 供应商信息 + */ + @Override + public CrmSupplierInfoVo queryById(Long supplierId){ + CrmSupplierInfoVo vo = baseMapper.selectVoById(supplierId); + fillAttachmentInfo(Collections.singletonList(vo)); + return vo; + } + + /** + * 分页查询供应商信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 供应商信息分页列表 + */ + @Override + public TableDataInfo queryPageList(CrmSupplierInfoBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + fillAttachmentInfo(result.getRecords()); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的供应商信息列表 + * + * @param bo 查询条件 + * @return 供应商信息列表 + */ + @Override + public List queryList(CrmSupplierInfoBo bo) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + List list = baseMapper.selectVoList(lqw); + fillAttachmentInfo(list); + return list; + } + + private MPJLambdaWrapper buildQueryWrapper(CrmSupplierInfoBo bo) { + Map params = bo.getParams(); + MPJLambdaWrapper lqw = JoinWrappers.lambda(CrmSupplierInfo.class) + .selectAll(CrmSupplierInfo.class) +// // 左连接 sys_user 表获取归属人员名称 +// .selectAs(SysUser::getNickName, CrmSupplierInfo::getOwnerName) +// .leftJoin(SysUser.class, SysUser::getUserId, CrmSupplierInfo::getOwnerId) + .eq(CrmSupplierInfo::getDelFlag, "0") + .like(StringUtils.isNotBlank(bo.getSupplierName()), CrmSupplierInfo::getSupplierName, bo.getSupplierName()) + .like(StringUtils.isNotBlank(bo.getMnemonicName()), CrmSupplierInfo::getMnemonicName, bo.getMnemonicName()) + .eq(StringUtils.isNotBlank(bo.getSupplierType()), CrmSupplierInfo::getSupplierType, bo.getSupplierType()) + .eq(bo.getRegisteredCapital() != null, CrmSupplierInfo::getRegisteredCapital, bo.getRegisteredCapital()) + .eq(bo.getEstablishmentDate() != null, CrmSupplierInfo::getEstablishmentDate, bo.getEstablishmentDate()) + .eq(StringUtils.isNotBlank(bo.getBusinessScope()), CrmSupplierInfo::getBusinessScope, bo.getBusinessScope()) + .eq(StringUtils.isNotBlank(bo.getMainIndustry()), CrmSupplierInfo::getMainIndustry, bo.getMainIndustry()) + .eq(StringUtils.isNotBlank(bo.getLegalRepresentative()), CrmSupplierInfo::getLegalRepresentative, bo.getLegalRepresentative()) + .eq(StringUtils.isNotBlank(bo.getBusinessLicenseNumber()), CrmSupplierInfo::getBusinessLicenseNumber, bo.getBusinessLicenseNumber()) + .eq(StringUtils.isNotBlank(bo.getTaxNumber()), CrmSupplierInfo::getTaxNumber, bo.getTaxNumber()) + .eq(StringUtils.isNotBlank(bo.getBankAccountOpening()), CrmSupplierInfo::getBankAccountOpening, bo.getBankAccountOpening()) + .eq(StringUtils.isNotBlank(bo.getBankNumber()), CrmSupplierInfo::getBankNumber, bo.getBankNumber()) + .eq(StringUtils.isNotBlank(bo.getRegisteredAddress()), CrmSupplierInfo::getRegisteredAddress, bo.getRegisteredAddress()) + .eq(StringUtils.isNotBlank(bo.getBusinessAddress()), CrmSupplierInfo::getBusinessAddress, bo.getBusinessAddress()) + .eq(StringUtils.isNotBlank(bo.getContactPerson()), CrmSupplierInfo::getContactPerson, bo.getContactPerson()) + .eq(StringUtils.isNotBlank(bo.getContactPhone()), CrmSupplierInfo::getContactPhone, bo.getContactPhone()) + .eq(StringUtils.isNotBlank(bo.getContactMobile()), CrmSupplierInfo::getContactMobile, bo.getContactMobile()) + .eq(StringUtils.isNotBlank(bo.getContactEmail()), CrmSupplierInfo::getContactEmail, bo.getContactEmail()) + .eq(StringUtils.isNotBlank(bo.getContactFax()), CrmSupplierInfo::getContactFax, bo.getContactFax()) + .eq(StringUtils.isNotBlank(bo.getWebsite()), CrmSupplierInfo::getWebsite, bo.getWebsite()) + .eq(bo.getOwnerId() != null, CrmSupplierInfo::getOwnerId, bo.getOwnerId()) + .eq(StringUtils.isNotBlank(bo.getDetailedAddress()), CrmSupplierInfo::getDetailedAddress, bo.getDetailedAddress()) + .eq(StringUtils.isNotBlank(bo.getOssId()), CrmSupplierInfo::getOssId, bo.getOssId()) + .eq(StringUtils.isNotBlank(bo.getActiveFlag()), CrmSupplierInfo::getActiveFlag, bo.getActiveFlag()); + return lqw; + } + + private void fillAttachmentInfo(List voList) { + if (voList == null || voList.isEmpty()) { + return; + } + Set ossIdSet = new LinkedHashSet<>(); + Map> voOssMapping = new HashMap<>(); + for (CrmSupplierInfoVo vo : voList) { + if (vo == null || StringUtils.isBlank(vo.getOssId())) { + continue; + } + List ids = List.of(StringUtils.split(vo.getOssId(), ",")); + if (ids.isEmpty()) { + continue; + } + voOssMapping.put(vo, ids); + ossIdSet.addAll(ids); + } + if (ossIdSet.isEmpty()) { + return; + } + try { + List files = remoteFileService.selectByIds(String.join(",", ossIdSet)); + Map fileMap = files.stream() + .filter(item -> item.getOssId() != null) + .collect(Collectors.toMap(RemoteFile::getOssId, item -> item, (a, b) -> a)); + for (Entry> entry : voOssMapping.entrySet()) { + List voFiles = entry.getValue().stream() + .map(id -> { + if (!StringUtils.isNumeric(id)) { + return null; + } + Long key = Long.parseLong(id); + return fileMap.get(key); + }) + .filter(item -> item != null) + .collect(Collectors.toList()); + entry.getKey().setAttachmentList(voFiles); + } + } catch (Exception ignored) { + // 远程文件服务异常时忽略附件 + } + } + + /** + * 新增供应商信息 + * + * @param bo 供应商信息 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(CrmSupplierInfoBo bo) { + CrmSupplierInfo add = MapstructUtils.convert(bo, CrmSupplierInfo.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setSupplierId(add.getSupplierId()); + } + return flag; + } + + /** + * 修改供应商信息 + * + * @param bo 供应商信息 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(CrmSupplierInfoBo bo) { + CrmSupplierInfo update = MapstructUtils.convert(bo, CrmSupplierInfo.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(CrmSupplierInfo entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除供应商信息信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectInfoController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectInfoController.java index 42c4b82f..c2eb1932 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectInfoController.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectInfoController.java @@ -80,6 +80,19 @@ public class ErpProjectInfoController extends BaseController { return toAjax(erpProjectInfoService.insertByBo(bo)); } + /** + * 提交项目信息并提交流程 + * @param bo + * @return + */ + @SaCheckPermission("oa/erp:projectInfo:add") + @Log(title = "项目信息", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/submitAndFlowStart") + public R submitAndFlowStart(@Validated(AddGroup.class) @RequestBody ErpProjectInfoBo bo) { + return R.ok(erpProjectInfoService.projectSubmitAndFlowStart(bo)); + } + /** * 修改项目信息 */ diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectPlanController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectPlanController.java new file mode 100644 index 00000000..4e9b3c25 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectPlanController.java @@ -0,0 +1,130 @@ +package org.dromara.oa.erp.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.oa.erp.domain.vo.ErpProjectPlanVo; +import org.dromara.oa.erp.domain.bo.ErpProjectPlanBo; +import org.dromara.oa.erp.service.IErpProjectPlanService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 项目计划 + * 前端访问路由地址为:/oa/erp/erpProjectPlan + * + * @author Yinq + * @date 2025-10-30 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/erp/erpProjectPlan") +public class ErpProjectPlanController extends BaseController { + + private final IErpProjectPlanService erpProjectPlanService; + + /** + * 查询项目计划列表 + */ + @SaCheckPermission("oa/erp:erpProjectPlan:list") + @GetMapping("/list") + public TableDataInfo list(ErpProjectPlanBo bo, PageQuery pageQuery) { + return erpProjectPlanService.queryPageList(bo, pageQuery); + } + + /** + * 导出项目计划列表 + */ + @SaCheckPermission("oa/erp:erpProjectPlan:export") + @Log(title = "项目计划", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(ErpProjectPlanBo bo, HttpServletResponse response) { + List list = erpProjectPlanService.queryList(bo); + ExcelUtil.exportExcel(list, "项目计划", ErpProjectPlanVo.class, response); + } + + /** + * 获取项目计划详细信息 + * + * @param projectPlanId 主键 + */ + @SaCheckPermission("oa/erp:erpProjectPlan:query") + @GetMapping("/{projectPlanId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable("projectPlanId") Long projectPlanId) { + return R.ok(erpProjectPlanService.queryById(projectPlanId)); + } + + /** + * 新增项目计划 + */ + @SaCheckPermission("oa/erp:erpProjectPlan:add") + @Log(title = "项目计划", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody ErpProjectPlanBo bo) { + erpProjectPlanService.insertByBo(bo); + return R.ok(erpProjectPlanService.queryById(bo.getProjectPlanId())); + } + + /** + * 修改项目计划 + */ + @SaCheckPermission("oa/erp:erpProjectPlan:edit") + @Log(title = "项目计划", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody ErpProjectPlanBo bo) { + return toAjax(erpProjectPlanService.updateByBo(bo)); + } + + /** + * 删除项目计划 + * + * @param projectPlanIds 主键串 + */ + @SaCheckPermission("oa/erp:erpProjectPlan:remove") + @Log(title = "项目计划", businessType = BusinessType.DELETE) + @DeleteMapping("/{projectPlanIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable("projectPlanIds") Long[] projectPlanIds) { + return toAjax(erpProjectPlanService.deleteWithValidByIds(List.of(projectPlanIds), true)); + } + + /** + * 下拉框查询项目计划列表 + */ + @GetMapping("/getErpProjectPlanList") + public R> getErpProjectPlanList(ErpProjectPlanBo bo) { + List list = erpProjectPlanService.queryList(bo); + return R.ok(list); + } + + /** + * 提交项目计划并发起流程 + * @param bo 项目计划 + * @return 项目计划 + */ + @SaCheckPermission("oa/erp:erpProjectPlan:add") + @Log(title = "项目计划", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/projectPlanSubmitAndFlowStart") + public R projectPlanSubmitAndFlowStart(@Validated(AddGroup.class) @RequestBody ErpProjectPlanBo bo) { + return R.ok(erpProjectPlanService.projectPlanSubmitAndFlowStart(bo)); + } + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectPlanStageController.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectPlanStageController.java new file mode 100644 index 00000000..cd1ac5e6 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/controller/ErpProjectPlanStageController.java @@ -0,0 +1,116 @@ +package org.dromara.oa.erp.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.oa.erp.domain.vo.ErpProjectPlanStageVo; +import org.dromara.oa.erp.domain.bo.ErpProjectPlanStageBo; +import org.dromara.oa.erp.service.IErpProjectPlanStageService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 项目计划阶段 + * 前端访问路由地址为:/oa/erp/erpProjectPlanStage + * + * @author Yinq + * @date 2025-10-30 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/erp/erpProjectPlanStage") +public class ErpProjectPlanStageController extends BaseController { + + private final IErpProjectPlanStageService erpProjectPlanStageService; + + /** + * 查询项目计划阶段列表 + */ + @SaCheckPermission("oa/erp:erpProjectPlanStage:list") + @GetMapping("/list") + public TableDataInfo list(ErpProjectPlanStageBo bo, PageQuery pageQuery) { + return erpProjectPlanStageService.queryPageList(bo, pageQuery); + } + + /** + * 导出项目计划阶段列表 + */ + @SaCheckPermission("oa/erp:erpProjectPlanStage:export") + @Log(title = "项目计划阶段", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(ErpProjectPlanStageBo bo, HttpServletResponse response) { + List list = erpProjectPlanStageService.queryList(bo); + ExcelUtil.exportExcel(list, "项目计划阶段", ErpProjectPlanStageVo.class, response); + } + + /** + * 获取项目计划阶段详细信息 + * + * @param planStageId 主键 + */ + @SaCheckPermission("oa/erp:erpProjectPlanStage:query") + @GetMapping("/{planStageId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable("planStageId") Long planStageId) { + return R.ok(erpProjectPlanStageService.queryById(planStageId)); + } + + /** + * 新增项目计划阶段 + */ + @SaCheckPermission("oa/erp:erpProjectPlanStage:add") + @Log(title = "项目计划阶段", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody ErpProjectPlanStageBo bo) { + return toAjax(erpProjectPlanStageService.insertByBo(bo)); + } + + /** + * 修改项目计划阶段 + */ + @SaCheckPermission("oa/erp:erpProjectPlanStage:edit") + @Log(title = "项目计划阶段", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody ErpProjectPlanStageBo bo) { + return toAjax(erpProjectPlanStageService.updateByBo(bo)); + } + + /** + * 删除项目计划阶段 + * + * @param planStageIds 主键串 + */ + @SaCheckPermission("oa/erp:erpProjectPlanStage:remove") + @Log(title = "项目计划阶段", businessType = BusinessType.DELETE) + @DeleteMapping("/{planStageIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable("planStageIds") Long[] planStageIds) { + return toAjax(erpProjectPlanStageService.deleteWithValidByIds(List.of(planStageIds), true)); + } + + /** + * 下拉框查询项目计划阶段列表 + */ + @GetMapping("/getErpProjectPlanStageList") + public R> getErpProjectPlanStageList(ErpProjectPlanStageBo bo) { + List list = erpProjectPlanStageService.queryList(bo); + return R.ok(list); + } + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectPlan.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectPlan.java new file mode 100644 index 00000000..27e3d0de --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectPlan.java @@ -0,0 +1,87 @@ +package org.dromara.oa.erp.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 项目计划对象 erp_project_plan + * + * @author Yinq + * @date 2025-10-30 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("erp_project_plan") +public class ErpProjectPlan extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 项目计划ID + */ + @TableId(value = "project_plan_id", type = IdType.ASSIGN_ID) + private Long projectPlanId; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 项目经理 + */ + private Long managerId; + + /** + * 部门负责人 + */ + private Long chargeId; + + /** + * 付款方式 + */ + private String paymentMethod; + + /** + * 项目计划状态(1暂存 2审批中 3可用) + */ + private String projectPlanStatus; + + /** + * 流程状态 + */ + private String flowStatus; + + /** + * 排序号 + */ + private Long sortOrder; + + /** + * 合同ID(预留) + */ + private Long contractId; + + /** + * 备注 + */ + private String remark; + + /** + * 激活标识(1是 0否) + */ + private String activeFlag; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @TableLogic + private String delFlag; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectPlanStage.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectPlanStage.java new file mode 100644 index 00000000..2a89b4a1 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/ErpProjectPlanStage.java @@ -0,0 +1,129 @@ +package org.dromara.oa.erp.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 项目计划阶段对象 erp_project_plan_stage + * + * @author Yinq + * @date 2025-10-30 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("erp_project_plan_stage") +public class ErpProjectPlanStage extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 计划阶段ID + */ + @TableId(value = "plan_stage_id", type = IdType.AUTO) + private Long planStageId; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 项目计划ID + */ + private Long projectPlanId; + + /** + * 项目阶段 + */ + private String projectPhases; + + /** + * 计划开始时间 + */ + private Date planStartTime; + + /** + * 计划结束时间 + */ + private Date planEndTime; + + /** + * 回款阶段 + */ + private String collectionStage; + + /** + * 预计回款比例(%) + */ + private Long repaymentRate; + + /** + * 预计回款金额 + */ + private Long repaymentAmount; + + /** + * 预计回款时间 + */ + private Date repaymentTime; + + /** + * 回款延期天数 + */ + private Long delayDay; + + /** + * 应收款日期 + */ + private Date receivableDate; + + /** + * 原因说明 + */ + private String reasonsExplanation; + + /** + * 进度备注 + */ + private String scheduleRemark; + + /** + * 实际开始时间 + */ + private Date realStartTime; + + /** + * 实际结束时间 + */ + private Date realEndTime; + + /** + * 排序号 + */ + private Long sortOrder; + + /** + * 备注 + */ + private String remark; + + /** + * 激活标识(1是 0否) + */ + private String activeFlag; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @TableLogic + private String delFlag; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectInfoBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectInfoBo.java index d2cdd2d7..655a6d64 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectInfoBo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectInfoBo.java @@ -9,6 +9,9 @@ import lombok.Data; import lombok.EqualsAndHashCode; import jakarta.validation.constraints.*; import java.math.BigDecimal; +import java.util.*; +import cn.hutool.core.util.ObjectUtil; +import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt; /** * 项目信息业务对象 erp_project_info @@ -131,5 +134,39 @@ public class ErpProjectInfoBo extends BaseEntity { */ private String activeFlag; + /** + * 流程定义编码 + */ + private String flowCode; + + /** + * 办理人(可不填 用于覆盖当前节点办理人) + */ + private String handler; + + /** + * 流程变量,前端会提交一个元素{'entity': {业务详情数据对象}} + */ + private Map variables; + + /** + * 流程业务扩展信息 + */ + private RemoteFlowInstanceBizExt bizExt; + + public Map getVariables() { + if (variables == null) { + return new HashMap<>(16); + } + variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue())); + return variables; + } + + public RemoteFlowInstanceBizExt getBizExt() { + if (ObjectUtil.isNull(bizExt)) { + bizExt = new RemoteFlowInstanceBizExt(); + } + return bizExt; + } } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectPlanBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectPlanBo.java new file mode 100644 index 00000000..04bd18bb --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectPlanBo.java @@ -0,0 +1,144 @@ +package org.dromara.oa.erp.domain.bo; + +import cn.hutool.core.util.ObjectUtil; +import org.dromara.oa.erp.domain.ErpProjectPlan; +import org.dromara.oa.erp.domain.ErpProjectPlanStage; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt; +// import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt; + +import java.util.*; + +/** + * 项目计划业务对象 erp_project_plan + * + * @author Yinq + * @date 2025-10-30 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ErpProjectPlan.class, reverseConvertGenerate = false) +public class ErpProjectPlanBo extends BaseEntity { + + /** + * 项目计划ID + */ + @NotNull(message = "项目计划ID不能为空", groups = { EditGroup.class }) + private Long projectPlanId; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 项目经理 + */ + private Long managerId; + + /** + * 部门负责人 + */ + private Long chargeId; + + /** + * 付款方式 + */ + private String paymentMethod; + + /** + * 项目计划状态(1暂存 2审批中 3可用) + */ + private String projectPlanStatus; + + /** + * 流程状态 + */ + private String flowStatus; + + /** + * 排序号 + */ + private Long sortOrder; + + /** + * 合同ID(预留) + */ + private Long contractId; + + /** + * 备注 + */ + private String remark; + + /** + * 激活标识(1是 0否) + */ + private String activeFlag; + + /** + * 项目计划阶段列表 + */ + private List planStageList; + + /** + * 项目名称 + */ + private String projectName; + + /** + * 项目经理名称 + */ + private String managerName; + + /** + * 部门负责人名称 + */ + private String chargeName; + + /** + * 合同名称 + */ + private String contractName; + + /** + * 流程定义编码 + */ + private String flowCode; + + /** + * 办理人(可不填 用于覆盖当前节点办理人) + */ + private String handler; + + /** + * 流程变量,前端会提交一个元素{'entity': {业务详情数据对象}} + */ + private Map variables; + + /** + * 流程业务扩展信息 + */ + private RemoteFlowInstanceBizExt bizExt; + + public Map getVariables() { + if (variables == null) { + return new HashMap<>(16); + } + variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue())); + return variables; + } + + public RemoteFlowInstanceBizExt getBizExt() { + if (ObjectUtil.isNull(bizExt)) { + bizExt = new RemoteFlowInstanceBizExt(); + } + return bizExt; + } +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectPlanStageBo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectPlanStageBo.java new file mode 100644 index 00000000..687f4c7f --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/bo/ErpProjectPlanStageBo.java @@ -0,0 +1,122 @@ +package org.dromara.oa.erp.domain.bo; + +import org.dromara.oa.erp.domain.ErpProjectPlanStage; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 项目计划阶段业务对象 erp_project_plan_stage + * + * @author Yinq + * @date 2025-10-30 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ErpProjectPlanStage.class, reverseConvertGenerate = false) +public class ErpProjectPlanStageBo extends BaseEntity { + + /** + * 计划阶段ID + */ + @NotNull(message = "计划阶段ID不能为空", groups = { EditGroup.class }) + private Long planStageId; + + /** + * 项目ID + */ + private Long projectId; + + /** + * 项目计划ID + */ + private Long projectPlanId; + + /** + * 项目阶段 + */ + private String projectPhases; + + /** + * 计划开始时间 + */ + private Date planStartTime; + + /** + * 计划结束时间 + */ + private Date planEndTime; + + /** + * 回款阶段 + */ + private String collectionStage; + + /** + * 预计回款比例(%) + */ + private Long repaymentRate; + + /** + * 预计回款金额 + */ + private Long repaymentAmount; + + /** + * 预计回款时间 + */ + private Date repaymentTime; + + /** + * 回款延期天数 + */ + private Long delayDay; + + /** + * 应收款日期 + */ + private Date receivableDate; + + /** + * 原因说明 + */ + private String reasonsExplanation; + + /** + * 进度备注 + */ + private String scheduleRemark; + + /** + * 实际开始时间 + */ + private Date realStartTime; + + /** + * 实际结束时间 + */ + private Date realEndTime; + + /** + * 排序号 + */ + private Long sortOrder; + + /** + * 备注 + */ + private String remark; + + /** + * 激活标识(1是 0否) + */ + private String activeFlag; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpContractMaterialVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpContractMaterialVo.java index 762350d0..92e3d3cc 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpContractMaterialVo.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpContractMaterialVo.java @@ -160,6 +160,13 @@ public class ErpContractMaterialVo implements Serializable { /** * 计量单位名称 */ - @ExcelProperty(value = "计量单位名称") + @ExcelProperty(value = "单位") private String unitName; + + /** + * 序号 + */ + @ExcelProperty(value = "序号") + private Long seq; + } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectPlanStageVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectPlanStageVo.java new file mode 100644 index 00000000..8c915889 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectPlanStageVo.java @@ -0,0 +1,151 @@ +package org.dromara.oa.erp.domain.vo; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.oa.erp.domain.ErpProjectPlanStage; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 项目计划阶段视图对象 erp_project_plan_stage + * + * @author Yinq + * @date 2025-10-30 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ErpProjectPlanStage.class) +public class ErpProjectPlanStageVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 计划阶段ID + */ + @ExcelProperty(value = "计划阶段ID") + private Long planStageId; + + /** + * 项目ID + */ + @ExcelProperty(value = "项目ID") + private Long projectId; + + /** + * 项目计划ID + */ + @ExcelProperty(value = "项目计划ID") + private Long projectPlanId; + + /** + * 项目阶段 + */ + @ExcelProperty(value = "项目阶段") + @ExcelDictFormat(dictType = " project_phases") + private String projectPhases; + + /** + * 计划开始时间 + */ + @ExcelProperty(value = "计划开始时间") + private Date planStartTime; + + /** + * 计划结束时间 + */ + @ExcelProperty(value = "计划结束时间") + private Date planEndTime; + + /** + * 回款阶段 + */ + @ExcelProperty(value = "回款阶段") + @ExcelDictFormat(dictType = " collection_stage") + private String collectionStage; + + /** + * 预计回款比例(%) + */ + @ExcelProperty(value = "预计回款比例(%)") + private Long repaymentRate; + + /** + * 预计回款金额 + */ + @ExcelProperty(value = "预计回款金额") + private Long repaymentAmount; + + /** + * 预计回款时间 + */ + @ExcelProperty(value = "预计回款时间") + private Date repaymentTime; + + /** + * 回款延期天数 + */ + @ExcelProperty(value = "回款延期天数") + private Long delayDay; + + /** + * 应收款日期 + */ + @ExcelProperty(value = "应收款日期") + private Date receivableDate; + + /** + * 原因说明 + */ + @ExcelProperty(value = "原因说明") + private String reasonsExplanation; + + /** + * 进度备注 + */ + @ExcelProperty(value = "进度备注") + private String scheduleRemark; + + /** + * 实际开始时间 + */ + @ExcelProperty(value = "实际开始时间") + private Date realStartTime; + + /** + * 实际结束时间 + */ + @ExcelProperty(value = "实际结束时间") + private Date realEndTime; + + /** + * 排序号 + */ + @ExcelProperty(value = "排序号") + private Long sortOrder; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 激活标识(1是 0否) + */ + @ExcelProperty(value = "激活标识", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "active_flag") + private String activeFlag; + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectPlanVo.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectPlanVo.java new file mode 100644 index 00000000..57ecddb4 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/domain/vo/ErpProjectPlanVo.java @@ -0,0 +1,129 @@ +package org.dromara.oa.erp.domain.vo; + +import org.dromara.oa.erp.domain.ErpProjectPlan; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + + + +/** + * 项目计划视图对象 erp_project_plan + * + * @author Yinq + * @date 2025-10-30 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ErpProjectPlan.class) +public class ErpProjectPlanVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 项目计划ID + */ + @ExcelProperty(value = "项目计划ID") + private Long projectPlanId; + + /** + * 项目ID + */ + @ExcelProperty(value = "项目ID") + private Long projectId; + + /** + * 项目经理 + */ + @ExcelProperty(value = "项目经理") + private Long managerId; + + /** + * 部门负责人 + */ + @ExcelProperty(value = "部门负责人") + private Long chargeId; + + /** + * 付款方式 + */ + @ExcelProperty(value = "付款方式") + private String paymentMethod; + + /** + * 项目计划状态(1暂存 2审批中 3可用) + */ + @ExcelProperty(value = "项目计划状态(1暂存 2审批中 3可用)", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "project_plan_status") + private String projectPlanStatus; + + /** + * 流程状态 + */ + @ExcelProperty(value = "流程状态") + private String flowStatus; + + /** + * 排序号 + */ + @ExcelProperty(value = "排序号") + private Long sortOrder; + + /** + * 合同ID(预留) + */ + @ExcelProperty(value = "合同ID(预留)") + private Long contractId; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 激活标识(1是 0否) + */ + @ExcelProperty(value = "激活标识", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "active_flag") + private String activeFlag; + + /** + * 项目计划阶段列表 + */ + private List planStageList; + + /** + * 项目名称 + */ + @ExcelProperty(value = "项目名称") + private String projectName; + + /** + * 项目经理名称 + */ + @ExcelProperty(value = "项目经理名称") + private String managerName; + + /** + * 部门负责人名称 + */ + @ExcelProperty(value = "部门负责人名称") + private String chargeName; + + /** + * 合同名称 + */ + @ExcelProperty(value = "合同名称") + private String contractName; + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectPlanMapper.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectPlanMapper.java new file mode 100644 index 00000000..a850b4de --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectPlanMapper.java @@ -0,0 +1,113 @@ +package org.dromara.oa.erp.mapper; + +import java.util.List; +import java.util.Collection; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.dromara.oa.erp.domain.ErpProjectPlan; +import org.dromara.oa.erp.domain.vo.ErpProjectPlanVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 项目计划Mapper接口 + * + * @author Yinq + * @date 2025-10-30 + */ +public interface ErpProjectPlanMapper extends BaseMapperPlus { + + /** + * 查询项目计划列表 + * + * @param page 分页 + * @param queryWrapper 条件 + * @return 项目计划集合 + */ + public Page selectCustomErpProjectPlanVoList(@Param("page") Page page, @Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 查询项目计划列表 + * + * @param queryWrapper 条件 + * @return 项目计划集合 + */ + public List selectCustomErpProjectPlanVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 根据ID查询项目计划详情 + * + * @param projectPlanId 主键ID + * @return 项目计划对象 + */ + ErpProjectPlanVo selectCustomErpProjectPlanVoById(@Param("projectPlanId") Long projectPlanId); + + /** + * 根据ID列表批量查询项目计划 + * + * @param ids ID集合 + * @return 项目计划集合 + */ + List selectCustomErpProjectPlanVoByIds(@Param("ids") Collection ids); + + /** + * 统计项目计划记录数 + * + * @param queryWrapper 查询条件 + * @return 记录总数 + */ + Long countCustomErpProjectPlan(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 分页查询项目计划(自定义条件) + * + * @param page 分页对象 + * @param queryWrapper 查询条件 + * @return 分页结果 + */ + Page selectCustomErpProjectPlanVoPage(@Param("page") Page page, @Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 批量插入项目计划 + * + * @param list 项目计划对象集合 + * @return 影响行数 + */ + int batchInsertErpProjectPlan(@Param("list") List list); + + /** + * 批量更新项目计划 + * + * @param list 项目计划对象集合 + * @return 影响行数 + */ + int batchUpdateErpProjectPlan(@Param("list") List list); + + /** + * 根据自定义条件删除项目计划 + * + * @param queryWrapper 删除条件 + * @return 影响行数 + */ + int deleteCustomErpProjectPlan(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 根据ID列表批量删除项目计划 + * + * @param ids ID集合 + * @return 影响行数 + */ + int deleteCustomErpProjectPlanByIds(@Param("ids") Collection ids); + + /** + * 检查项目计划是否存在 + * + * @param queryWrapper 查询条件 + * @return 是否存在 + */ + Boolean existsErpProjectPlan(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectPlanStageMapper.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectPlanStageMapper.java new file mode 100644 index 00000000..f5ae02cf --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/mapper/ErpProjectPlanStageMapper.java @@ -0,0 +1,113 @@ +package org.dromara.oa.erp.mapper; + +import java.util.List; +import java.util.Collection; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Param; +import org.dromara.oa.erp.domain.ErpProjectPlanStage; +import org.dromara.oa.erp.domain.vo.ErpProjectPlanStageVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 项目计划阶段Mapper接口 + * + * @author Yinq + * @date 2025-10-30 + */ +public interface ErpProjectPlanStageMapper extends BaseMapperPlus { + + /** + * 查询项目计划阶段列表 + * + * @param page 分页 + * @param queryWrapper 条件 + * @return 项目计划阶段集合 + */ + public Page selectCustomErpProjectPlanStageVoList(@Param("page") Page page, @Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 查询项目计划阶段列表 + * + * @param queryWrapper 条件 + * @return 项目计划阶段集合 + */ + public List selectCustomErpProjectPlanStageVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper queryWrapper); + + /** + * 根据ID查询项目计划阶段详情 + * + * @param planStageId 主键ID + * @return 项目计划阶段对象 + */ + ErpProjectPlanStageVo selectCustomErpProjectPlanStageVoById(@Param("planStageId") Long planStageId); + + /** + * 根据ID列表批量查询项目计划阶段 + * + * @param ids ID集合 + * @return 项目计划阶段集合 + */ + List selectCustomErpProjectPlanStageVoByIds(@Param("ids") Collection ids); + + /** + * 统计项目计划阶段记录数 + * + * @param queryWrapper 查询条件 + * @return 记录总数 + */ + Long countCustomErpProjectPlanStage(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 分页查询项目计划阶段(自定义条件) + * + * @param page 分页对象 + * @param queryWrapper 查询条件 + * @return 分页结果 + */ + Page selectCustomErpProjectPlanStageVoPage(@Param("page") Page page, @Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 批量插入项目计划阶段 + * + * @param list 项目计划阶段对象集合 + * @return 影响行数 + */ + int batchInsertErpProjectPlanStage(@Param("list") List list); + + /** + * 批量更新项目计划阶段 + * + * @param list 项目计划阶段对象集合 + * @return 影响行数 + */ + int batchUpdateErpProjectPlanStage(@Param("list") List list); + + /** + * 根据自定义条件删除项目计划阶段 + * + * @param queryWrapper 删除条件 + * @return 影响行数 + */ + int deleteCustomErpProjectPlanStage(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + /** + * 根据ID列表批量删除项目计划阶段 + * + * @param ids ID集合 + * @return 影响行数 + */ + int deleteCustomErpProjectPlanStageByIds(@Param("ids") Collection ids); + + /** + * 检查项目计划阶段是否存在 + * + * @param queryWrapper 查询条件 + * @return 是否存在 + */ + Boolean existsErpProjectPlanStage(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectInfoService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectInfoService.java index dd879d0f..09074d6d 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectInfoService.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectInfoService.java @@ -66,4 +66,11 @@ public interface IErpProjectInfoService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 提交项目信息并提交流程 + * @param bo + * @return + */ + ErpProjectInfoVo projectSubmitAndFlowStart(ErpProjectInfoBo bo); } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectPlanService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectPlanService.java new file mode 100644 index 00000000..319ae2ba --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectPlanService.java @@ -0,0 +1,76 @@ +package org.dromara.oa.erp.service; + +import org.dromara.oa.erp.domain.ErpProjectPlan; +import org.dromara.oa.erp.domain.vo.ErpProjectPlanVo; +import org.dromara.oa.erp.domain.bo.ErpProjectPlanBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 项目计划Service接口 + * + * @author Yinq + * @date 2025-10-30 + */ +public interface IErpProjectPlanService { + + /** + * 查询项目计划 + * + * @param projectPlanId 主键 + * @return 项目计划 + */ + ErpProjectPlanVo queryById(Long projectPlanId); + + /** + * 分页查询项目计划列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目计划分页列表 + */ + TableDataInfo queryPageList(ErpProjectPlanBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的项目计划列表 + * + * @param bo 查询条件 + * @return 项目计划列表 + */ + List queryList(ErpProjectPlanBo bo); + + /** + * 新增项目计划 + * + * @param bo 项目计划 + * @return 是否新增成功 + */ + Boolean insertByBo(ErpProjectPlanBo bo); + + /** + * 修改项目计划 + * + * @param bo 项目计划 + * @return 是否修改成功 + */ + Boolean updateByBo(ErpProjectPlanBo bo); + + /** + * 校验并批量删除项目计划信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 提交项目计划并发起流程 + * @param bo 项目计划 + * @return 项目计划 + */ + ErpProjectPlanVo projectPlanSubmitAndFlowStart(ErpProjectPlanBo bo); +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectPlanStageService.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectPlanStageService.java new file mode 100644 index 00000000..08f598d1 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/IErpProjectPlanStageService.java @@ -0,0 +1,69 @@ +package org.dromara.oa.erp.service; + +import org.dromara.oa.erp.domain.ErpProjectPlanStage; +import org.dromara.oa.erp.domain.vo.ErpProjectPlanStageVo; +import org.dromara.oa.erp.domain.bo.ErpProjectPlanStageBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 项目计划阶段Service接口 + * + * @author Yinq + * @date 2025-10-30 + */ +public interface IErpProjectPlanStageService { + + /** + * 查询项目计划阶段 + * + * @param planStageId 主键 + * @return 项目计划阶段 + */ + ErpProjectPlanStageVo queryById(Long planStageId); + + /** + * 分页查询项目计划阶段列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目计划阶段分页列表 + */ + TableDataInfo queryPageList(ErpProjectPlanStageBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的项目计划阶段列表 + * + * @param bo 查询条件 + * @return 项目计划阶段列表 + */ + List queryList(ErpProjectPlanStageBo bo); + + /** + * 新增项目计划阶段 + * + * @param bo 项目计划阶段 + * @return 是否新增成功 + */ + Boolean insertByBo(ErpProjectPlanStageBo bo); + + /** + * 修改项目计划阶段 + * + * @param bo 项目计划阶段 + * @return 是否修改成功 + */ + Boolean updateByBo(ErpProjectPlanStageBo bo); + + /** + * 校验并批量删除项目计划阶段信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractInfoServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractInfoServiceImpl.java index fd6cdb62..9e0219bc 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractInfoServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractInfoServiceImpl.java @@ -64,7 +64,8 @@ public class ErpContractInfoServiceImpl implements IErpContractInfoService { ErpContractInfoVo contractInfoVo = baseMapper.selectVoById(contractId); MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpContractMaterial.class) .selectAll(ErpContractMaterial.class) - .eq(contractId != null, ErpContractMaterial::getContractId, contractId); + .eq(contractId != null, ErpContractMaterial::getContractId, contractId) + .eq("t.del_flag", "0");; List contractMaterialList = contractMaterialMapper.selectCustomErpContractMaterialVoList(lqw); contractInfoVo.setContractMaterialList(contractMaterialList); return contractInfoVo; @@ -117,6 +118,7 @@ public class ErpContractInfoServiceImpl implements IErpContractInfoService { .eq(bo.getSignatureAppendix() != null, ErpContractInfo::getSignatureAppendix, bo.getSignatureAppendix()) .eq(bo.getTaxRate() != null, ErpContractInfo::getTaxRate, bo.getTaxRate()) .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpContractInfo::getActiveFlag, bo.getActiveFlag()) + .eq("t.del_flag", "0") .orderByDesc(ErpContractInfo::getCreateTime); return lqw; } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractMaterialServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractMaterialServiceImpl.java index 823534b3..7af08b78 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractMaterialServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpContractMaterialServiceImpl.java @@ -66,7 +66,7 @@ public class ErpContractMaterialServiceImpl implements IErpContractMaterialServi @Override public List queryList(ErpContractMaterialBo bo) { MPJLambdaWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); + return baseMapper.selectCustomErpContractMaterialVoList(lqw); } private MPJLambdaWrapper buildQueryWrapper(ErpContractMaterialBo bo) { @@ -86,6 +86,7 @@ public class ErpContractMaterialServiceImpl implements IErpContractMaterialServi .eq(bo.getIncludingPrice() != null, ErpContractMaterial::getIncludingPrice, bo.getIncludingPrice()) .eq(bo.getSubtotal() != null, ErpContractMaterial::getSubtotal, bo.getSubtotal()) .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpContractMaterial::getActiveFlag, bo.getActiveFlag()) + .eq("t.del_flag", "0") .orderByAsc(ErpContractMaterial::getContractMaterialId); return lqw; } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectContractsServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectContractsServiceImpl.java index 9e7dfa6f..9eea9bd0 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectContractsServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectContractsServiceImpl.java @@ -76,7 +76,8 @@ public class ErpProjectContractsServiceImpl implements IErpProjectContractsServi .eq(bo.getProjectId() != null, ErpProjectContracts::getProjectId, bo.getProjectId()) .eq(bo.getContractId() != null, ErpProjectContracts::getContractId, bo.getContractId()) .eq(bo.getSortOrder() != null, ErpProjectContracts::getSortOrder, bo.getSortOrder()) - .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectContracts::getActiveFlag, bo.getActiveFlag()); + .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectContracts::getActiveFlag, bo.getActiveFlag()) + .eq("t.del_flag", "0"); return lqw; } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectInfoServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectInfoServiceImpl.java index 4c79c278..d116b31f 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectInfoServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectInfoServiceImpl.java @@ -7,7 +7,6 @@ import org.dromara.common.mybatis.core.page.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.wrapper.MPJLambdaWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.dromara.oa.erp.domain.bo.ErpProjectInfoBo; @@ -15,6 +14,11 @@ import org.dromara.oa.erp.domain.vo.ErpProjectInfoVo; import org.dromara.oa.erp.domain.ErpProjectInfo; import org.dromara.oa.erp.mapper.ErpProjectInfoMapper; import org.dromara.oa.erp.service.IErpProjectInfoService; +import org.apache.dubbo.config.annotation.DubboReference; +import org.apache.seata.spring.annotation.GlobalTransactional; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.workflow.api.RemoteWorkflowService; +import org.dromara.workflow.api.domain.RemoteStartProcess; import java.util.List; import java.util.Map; @@ -32,6 +36,9 @@ public class ErpProjectInfoServiceImpl implements IErpProjectInfoService { private final ErpProjectInfoMapper baseMapper; + @DubboReference(timeout = 30000) + private RemoteWorkflowService remoteWorkflowService; + /** * 查询项目信息 * @@ -70,7 +77,6 @@ public class ErpProjectInfoServiceImpl implements IErpProjectInfoService { } private MPJLambdaWrapper buildQueryWrapper(ErpProjectInfoBo bo) { - Map params = bo.getParams(); MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpProjectInfo.class) .selectAll(ErpProjectInfo.class) .eq(StringUtils.isNotBlank(bo.getContractFlag()), ErpProjectInfo::getContractFlag, bo.getContractFlag()) @@ -91,7 +97,9 @@ public class ErpProjectInfoServiceImpl implements IErpProjectInfoService { .eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpProjectInfo::getFlowStatus, bo.getFlowStatus()) .eq(bo.getSortOrder() != null, ErpProjectInfo::getSortOrder, bo.getSortOrder()) .eq(bo.getContractId() != null, ErpProjectInfo::getContractId, bo.getContractId()) - .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectInfo::getActiveFlag, bo.getActiveFlag()); + .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectInfo::getActiveFlag, bo.getActiveFlag()) + .eq("t.del_flag", "0") + .orderByDesc(ErpProjectInfo::getCreateTime); return lqw; } @@ -146,4 +154,35 @@ public class ErpProjectInfoServiceImpl implements IErpProjectInfoService { } return baseMapper.deleteByIds(ids) > 0; } + + /** + * 提交项目信息并提交流程 + * + * @param bo + * @return + */ + @Override + @GlobalTransactional(rollbackFor = Exception.class) + public ErpProjectInfoVo projectSubmitAndFlowStart(ErpProjectInfoBo bo) { + ErpProjectInfo add = MapstructUtils.convert(bo, ErpProjectInfo.class); + validEntityBeforeSave(add); + if (StringUtils.isNull(bo.getProjectId())) { + this.insertByBo(bo); + } else { + this.updateByBo(bo); + } + // 后端发起需要忽略权限 + bo.getVariables().put("ignore", true); + RemoteStartProcess startProcess = new RemoteStartProcess(); + startProcess.setBusinessId(bo.getProjectId().toString()); + startProcess.setFlowCode(bo.getFlowCode()); + startProcess.setVariables(bo.getVariables()); + startProcess.setBizExt(bo.getBizExt()); + bo.getBizExt().setBusinessId(startProcess.getBusinessId()); + boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess); + if (!flagOne) { + throw new ServiceException("流程发起异常"); + } + return MapstructUtils.convert(add, ErpProjectInfoVo.class); + } } diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectPlanServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectPlanServiceImpl.java new file mode 100644 index 00000000..70aa5826 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectPlanServiceImpl.java @@ -0,0 +1,322 @@ +package org.dromara.oa.erp.service.impl; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.map.MapUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.apache.seata.spring.annotation.GlobalTransactional; +import org.dromara.common.core.enums.BusinessStatusEnum; +import org.dromara.common.core.enums.OAStatusEnum; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.yulichang.toolkit.JoinWrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.dromara.common.tenant.helper.TenantHelper; +import org.dromara.oa.erp.domain.ErpProjectInfo; +import org.dromara.oa.erp.domain.ErpProjectPlanStage; +import org.dromara.oa.erp.domain.vo.ErpProjectPlanStageVo; +import org.dromara.oa.erp.mapper.ErpProjectPlanStageMapper; +import org.dromara.workflow.api.RemoteWorkflowService; +import org.dromara.workflow.api.domain.RemoteStartProcess; +import org.dromara.workflow.api.event.ProcessEvent; +import org.springframework.context.event.EventListener; +import org.dromara.common.satoken.utils.LoginHelper; +import org.springframework.stereotype.Service; +import org.dromara.oa.erp.domain.bo.ErpProjectPlanBo; +import org.dromara.oa.erp.domain.vo.ErpProjectPlanVo; +import org.dromara.oa.erp.domain.ErpProjectPlan; +import org.dromara.oa.erp.mapper.ErpProjectPlanMapper; +import org.dromara.oa.erp.service.IErpProjectPlanService; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 项目计划Service业务层处理 + * + * @author Yinq + * @date 2025-10-30 + */ +@RequiredArgsConstructor +@Service +@Slf4j +public class ErpProjectPlanServiceImpl implements IErpProjectPlanService { + + private final ErpProjectPlanMapper baseMapper; + + private final ErpProjectPlanStageMapper planStageMapper; + + @DubboReference(timeout = 30000) + private RemoteWorkflowService remoteWorkflowService; + + /** + * 查询项目计划 + * + * @param projectPlanId 主键 + * @return 项目计划 + */ + @Override + public ErpProjectPlanVo queryById(Long projectPlanId){ + // 使用自定义方法查询,包含关联数据 + ErpProjectPlanVo projectPlanVo = baseMapper.selectCustomErpProjectPlanVoById(projectPlanId); + // 查询项目计划阶段列表 + MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpProjectPlanStage.class) + .selectAll(ErpProjectPlanStage.class) + .eq("t.del_flag", "0") + .eq(projectPlanId != null, ErpProjectPlanStage::getProjectPlanId, projectPlanId); + List planStageList = planStageMapper.selectVoList(lqw); + projectPlanVo.setPlanStageList(planStageList); + return projectPlanVo; + } + + /** + * 分页查询项目计划列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目计划分页列表 + */ + @Override + public TableDataInfo queryPageList(ErpProjectPlanBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + // 使用自定义分页查询方法获取包含关联数据的结果 + Page result = baseMapper.selectCustomErpProjectPlanVoList(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的项目计划列表 + * + * @param bo 查询条件 + * @return 项目计划列表 + */ + @Override + public List queryList(ErpProjectPlanBo bo) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + // 使用自定义查询方法获取包含关联数据的列表 + return baseMapper.selectCustomErpProjectPlanVoList(lqw); + } + + private MPJLambdaWrapper buildQueryWrapper(ErpProjectPlanBo bo) { + Map params = bo.getParams(); + MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpProjectPlan.class) + .selectAll(ErpProjectPlan.class) + .eq(ErpProjectPlan::getDelFlag, "0") + // 关联项目信息 + .select(ErpProjectInfo::getProjectName) + .leftJoin(ErpProjectInfo.class,ErpProjectInfo::getProjectId, ErpProjectPlan::getProjectId) + .eq(bo.getProjectId() != null, ErpProjectPlan::getProjectId, bo.getProjectId()) + .eq(bo.getManagerId() != null, ErpProjectPlan::getManagerId, bo.getManagerId()) + .eq(bo.getChargeId() != null, ErpProjectPlan::getChargeId, bo.getChargeId()) + .eq(StringUtils.isNotBlank(bo.getPaymentMethod()), ErpProjectPlan::getPaymentMethod, bo.getPaymentMethod()) + .eq(StringUtils.isNotBlank(bo.getProjectPlanStatus()), ErpProjectPlan::getProjectPlanStatus, bo.getProjectPlanStatus()) + .eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpProjectPlan::getFlowStatus, bo.getFlowStatus()) + .eq(bo.getSortOrder() != null, ErpProjectPlan::getSortOrder, bo.getSortOrder()) + .eq(bo.getContractId() != null, ErpProjectPlan::getContractId, bo.getContractId()) + .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectPlan::getActiveFlag, bo.getActiveFlag()); + return lqw; + } + + /** + * 新增项目计划 + * + * @param bo 项目计划 + * @return 是否新增成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(ErpProjectPlanBo bo) { + ErpProjectPlan add = MapstructUtils.convert(bo, ErpProjectPlan.class); + validEntityBeforeSave(add); + // 权限校验:只有项目经理才能提交 + validateProjectManager(bo.getManagerId()); + List planStageList = bo.getPlanStageList(); + boolean flag = baseMapper.insert(add) > 0; + if (flag && planStageList != null && !planStageList.isEmpty()) { + bo.setProjectPlanId(add.getProjectPlanId()); + for (ErpProjectPlanStage planStage : planStageList) { + planStage.setProjectPlanId(add.getProjectPlanId()); + planStage.setProjectId(add.getProjectId()); + planStageMapper.insert(planStage); + } + } + return flag; + } + + /** + * 修改项目计划 + * + * @param bo 项目计划 + * @return 是否修改成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateByBo(ErpProjectPlanBo bo) { + // 获取原有数据 + ErpProjectPlan existingPlan = baseMapper.selectById(bo.getProjectPlanId()); + if (existingPlan == null) { + throw new ServiceException("项目计划不存在"); + } + + // 权限校验:只有项目经理才能修改 + validateProjectManager(existingPlan.getManagerId()); + + // 如果不是草稿状态,只允许更新阶段的delayDay和scheduleRemark + if (!"1".equals(existingPlan.getProjectPlanStatus())) { + // 非草稿状态,只更新阶段的特定字段 + List planStageList = bo.getPlanStageList(); + if (planStageList != null && !planStageList.isEmpty()) { + for (ErpProjectPlanStage newStage : planStageList) { + if (newStage.getPlanStageId() != null) { + // 只更新delayDay、scheduleRemark和receivableDate + ErpProjectPlanStage existingStage = planStageMapper.selectById(newStage.getPlanStageId()); + if (existingStage != null) { + existingStage.setDelayDay(newStage.getDelayDay()); + existingStage.setScheduleRemark(newStage.getScheduleRemark()); + existingStage.setReceivableDate(newStage.getReceivableDate()); + planStageMapper.updateById(existingStage); + } + } + } + } + // 不更新主表数据 + return true; + } + + // 草稿状态,允许全面更新 + ErpProjectPlan update = MapstructUtils.convert(bo, ErpProjectPlan.class); + validEntityBeforeSave(update); + List planStageList = bo.getPlanStageList(); + MPJLambdaWrapper lqwRecord = JoinWrappers.lambda(ErpProjectPlanStage.class); + lqwRecord.eq(ErpProjectPlanStage::getProjectPlanId, bo.getProjectPlanId()); + List planStageOldList = planStageMapper.selectList(lqwRecord); + // 如果计划阶段列表不为空且不为空列表,则进行处理 + if (planStageList != null && !planStageList.isEmpty()) { + // 遍历计划阶段列表,设置项目ID并插入或更新数据库记录 + for (ErpProjectPlanStage planStage : planStageList) { + planStage.setProjectId(update.getProjectId()); + planStageMapper.insertOrUpdate(planStage); + } + + // 收集当前计划阶段列表中已存在的计划阶段ID集合 + Set existingPlanStageIds = planStageList.stream() + .map(ErpProjectPlanStage::getPlanStageId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 从旧的计划阶段列表中筛选出需要删除的记录(即不在当前列表中的记录) + List filterPlanStageIds = planStageOldList.stream() + .filter(stage -> !existingPlanStageIds.contains(stage.getPlanStageId())) + .toList(); + + // 删除需要移除的计划阶段记录 + for (ErpProjectPlanStage filterPlanStageId : filterPlanStageIds) { + planStageMapper.deleteById(filterPlanStageId.getPlanStageId()); + } + } + + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(ErpProjectPlan entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验项目经理权限:只有项目经理才能提交项目计划 + * + * @param managerId 项目经理ID + */ + private void validateProjectManager(Long managerId) { + // 超级管理员跳过校验 + if (LoginHelper.isSuperAdmin()) { + return; + } + // 普通用户判断当前用户ID是否等于项目经理ID + Long currentUserId = LoginHelper.getUserId(); + if (!currentUserId.equals(managerId)) { + throw new ServiceException("只有项目经理才能提交项目计划"); + } + } + + /** + * 校验并批量删除项目计划信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + /** + * 提交项目计划并发起流程 + * + * @param bo 项目计划 + * @return 项目计划 + */ + @Override + @GlobalTransactional(rollbackFor = Exception.class) + public ErpProjectPlanVo projectPlanSubmitAndFlowStart(ErpProjectPlanBo bo) { + ErpProjectPlan add = MapstructUtils.convert(bo, ErpProjectPlan.class); + validEntityBeforeSave(add); + // 权限校验:只有项目经理才能提交 + validateProjectManager(bo.getManagerId()); + if (StringUtils.isNull(bo.getProjectPlanId())) { + this.insertByBo(bo); + } else { + this.updateByBo(bo); + } + // 后端发起需要忽略权限 + bo.getVariables().put("ignore", true); + RemoteStartProcess startProcess = new RemoteStartProcess(); + startProcess.setBusinessId(bo.getProjectPlanId().toString()); + startProcess.setFlowCode(bo.getFlowCode()); + startProcess.setVariables(bo.getVariables()); + startProcess.setBizExt(bo.getBizExt()); + bo.getBizExt().setBusinessId(startProcess.getBusinessId()); + boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess); + if (!flagOne) { + throw new ServiceException("流程发起异常"); + } + return MapstructUtils.convert(add, ErpProjectPlanVo.class); + } + + /** + * 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成等) + * + * @param processEvent 参数 + */ + @EventListener(condition = "#processEvent.flowCode =='OAPS'") + public void processHandler(ProcessEvent processEvent) { + TenantHelper.dynamic(processEvent.getTenantId(), () -> { + log.info("当前任务执行了{}", processEvent.toString()); + ErpProjectPlan projectPlan = baseMapper.selectById(Convert.toLong(processEvent.getBusinessId())); + projectPlan.setFlowStatus(processEvent.getStatus()); + Map params = processEvent.getParams(); + if (MapUtil.isNotEmpty(params)) { + // 办理人 + String handler = Convert.toStr(params.get("handler")); + } + if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) { + projectPlan.setProjectPlanStatus(OAStatusEnum.COMPLETED.getStatus()); + } + baseMapper.updateById(projectPlan); + }); + } +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectPlanStageServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectPlanStageServiceImpl.java new file mode 100644 index 00000000..07da663f --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/erp/service/impl/ErpProjectPlanStageServiceImpl.java @@ -0,0 +1,149 @@ +package org.dromara.oa.erp.service.impl; + +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; + import org.dromara.common.mybatis.core.page.TableDataInfo; + import org.dromara.common.mybatis.core.page.PageQuery; + import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.yulichang.toolkit.JoinWrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.dromara.oa.erp.domain.bo.ErpProjectPlanStageBo; +import org.dromara.oa.erp.domain.vo.ErpProjectPlanStageVo; +import org.dromara.oa.erp.domain.ErpProjectPlanStage; +import org.dromara.oa.erp.mapper.ErpProjectPlanStageMapper; +import org.dromara.oa.erp.service.IErpProjectPlanStageService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 项目计划阶段Service业务层处理 + * + * @author Yinq + * @date 2025-10-30 + */ +@RequiredArgsConstructor +@Service +public class ErpProjectPlanStageServiceImpl implements IErpProjectPlanStageService { + + private final ErpProjectPlanStageMapper baseMapper; + + /** + * 查询项目计划阶段 + * + * @param planStageId 主键 + * @return 项目计划阶段 + */ + @Override + public ErpProjectPlanStageVo queryById(Long planStageId){ + return baseMapper.selectVoById(planStageId); + } + + /** + * 分页查询项目计划阶段列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 项目计划阶段分页列表 + */ + @Override + public TableDataInfo queryPageList(ErpProjectPlanStageBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的项目计划阶段列表 + * + * @param bo 查询条件 + * @return 项目计划阶段列表 + */ + @Override + public List queryList(ErpProjectPlanStageBo bo) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private MPJLambdaWrapper buildQueryWrapper(ErpProjectPlanStageBo bo) { + Map params = bo.getParams(); + MPJLambdaWrapper lqw = JoinWrappers.lambda(ErpProjectPlanStage.class) + .selectAll(ErpProjectPlanStage.class) + .eq(ErpProjectPlanStage::getDelFlag, "0") + .eq(bo.getProjectId() != null, ErpProjectPlanStage::getProjectId, bo.getProjectId()) + .eq(bo.getProjectPlanId() != null, ErpProjectPlanStage::getProjectPlanId, bo.getProjectPlanId()) + .eq(StringUtils.isNotBlank(bo.getProjectPhases()), ErpProjectPlanStage::getProjectPhases, bo.getProjectPhases()) + .eq(bo.getPlanStartTime() != null, ErpProjectPlanStage::getPlanStartTime, bo.getPlanStartTime()) + .eq(bo.getPlanEndTime() != null, ErpProjectPlanStage::getPlanEndTime, bo.getPlanEndTime()) + .eq(StringUtils.isNotBlank(bo.getCollectionStage()), ErpProjectPlanStage::getCollectionStage, bo.getCollectionStage()) + .eq(bo.getRepaymentRate() != null, ErpProjectPlanStage::getRepaymentRate, bo.getRepaymentRate()) + .eq(bo.getRepaymentAmount() != null, ErpProjectPlanStage::getRepaymentAmount, bo.getRepaymentAmount()) + .eq(bo.getRepaymentTime() != null, ErpProjectPlanStage::getRepaymentTime, bo.getRepaymentTime()) + .eq(bo.getDelayDay() != null, ErpProjectPlanStage::getDelayDay, bo.getDelayDay()) + .eq(bo.getReceivableDate() != null, ErpProjectPlanStage::getReceivableDate, bo.getReceivableDate()) + .eq(StringUtils.isNotBlank(bo.getReasonsExplanation()), ErpProjectPlanStage::getReasonsExplanation, bo.getReasonsExplanation()) + .eq(StringUtils.isNotBlank(bo.getScheduleRemark()), ErpProjectPlanStage::getScheduleRemark, bo.getScheduleRemark()) + .eq(bo.getRealStartTime() != null, ErpProjectPlanStage::getRealStartTime, bo.getRealStartTime()) + .eq(bo.getRealEndTime() != null, ErpProjectPlanStage::getRealEndTime, bo.getRealEndTime()) + .eq(bo.getSortOrder() != null, ErpProjectPlanStage::getSortOrder, bo.getSortOrder()) + .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectPlanStage::getActiveFlag, bo.getActiveFlag()) +; + return lqw; + } + + /** + * 新增项目计划阶段 + * + * @param bo 项目计划阶段 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(ErpProjectPlanStageBo bo) { + ErpProjectPlanStage add = MapstructUtils.convert(bo, ErpProjectPlanStage.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setPlanStageId(add.getPlanStageId()); + } + return flag; + } + + /** + * 修改项目计划阶段 + * + * @param bo 项目计划阶段 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(ErpProjectPlanStageBo bo) { + ErpProjectPlanStage update = MapstructUtils.convert(bo, ErpProjectPlanStage.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(ErpProjectPlanStage entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除项目计划阶段信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/crm/CrmSupplierInfoMapper.xml b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/crm/CrmSupplierInfoMapper.xml new file mode 100644 index 00000000..b67e1875 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/crm/CrmSupplierInfoMapper.xml @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + insert into crm_supplier_info( + tenant_id, + + supplier_name, + + mnemonic_name, + + supplier_type, + + registered_capital, + + establishment_date, + + business_scope, + + main_industry, + + legal_representative, + + business_license_number, + + tax_number, + + bank_account_opening, + + bank_number, + + registered_address, + + business_address, + + contact_person, + + contact_phone, + + contact_mobile, + + contact_email, + + contact_fax, + + website, + + owner_id, + + detailed_address, + + oss_id, + + remark, + + active_flag, + + del_flag, + + create_dept, + + create_by, + + create_time, + + update_by, + + update_time + + ) + values + + ( + #{item.tenantId}, + + #{item.supplierName}, + + #{item.mnemonicName}, + + #{item.supplierType}, + + #{item.registeredCapital}, + + #{item.establishmentDate}, + + #{item.businessScope}, + + #{item.mainIndustry}, + + #{item.legalRepresentative}, + + #{item.businessLicenseNumber}, + + #{item.taxNumber}, + + #{item.bankAccountOpening}, + + #{item.bankNumber}, + + #{item.registeredAddress}, + + #{item.businessAddress}, + + #{item.contactPerson}, + + #{item.contactPhone}, + + #{item.contactMobile}, + + #{item.contactEmail}, + + #{item.contactFax}, + + #{item.website}, + + #{item.ownerId}, + + #{item.detailedAddress}, + + #{item.ossId}, + + #{item.remark}, + + #{item.activeFlag}, + + #{item.delFlag}, + + #{item.createDept}, + + #{item.createBy}, + + #{item.createTime}, + + #{item.updateBy}, + + #{item.updateTime} + + ) + + + + + + + update crm_supplier_info + + + tenant_id = #{item.tenantId}, + + + supplier_name = #{item.supplierName}, + + + mnemonic_name = #{item.mnemonicName}, + + + supplier_type = #{item.supplierType}, + + + registered_capital = #{item.registeredCapital}, + + + establishment_date = #{item.establishmentDate}, + + + business_scope = #{item.businessScope}, + + + main_industry = #{item.mainIndustry}, + + + legal_representative = #{item.legalRepresentative}, + + + business_license_number = #{item.businessLicenseNumber}, + + + tax_number = #{item.taxNumber}, + + + bank_account_opening = #{item.bankAccountOpening}, + + + bank_number = #{item.bankNumber}, + + + registered_address = #{item.registeredAddress}, + + + business_address = #{item.businessAddress}, + + + contact_person = #{item.contactPerson}, + + + contact_phone = #{item.contactPhone}, + + + contact_mobile = #{item.contactMobile}, + + + contact_email = #{item.contactEmail}, + + + contact_fax = #{item.contactFax}, + + + website = #{item.website}, + + + owner_id = #{item.ownerId}, + + + detailed_address = #{item.detailedAddress}, + + + oss_id = #{item.ossId}, + + + remark = #{item.remark}, + + + active_flag = #{item.activeFlag}, + + + del_flag = #{item.delFlag}, + + + create_dept = #{item.createDept}, + + + create_by = #{item.createBy}, + + + create_time = #{item.createTime}, + + + update_by = #{item.updateBy}, + + + update_time = #{item.updateTime} + + + where supplier_id = #{item.supplierId} + + + + + + delete from crm_supplier_info + ${ew.getCustomSqlSegment} + + + + + delete from crm_supplier_info + where supplier_id in + + #{id} + + + + + + + + diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectPlanMapper.xml b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectPlanMapper.xml new file mode 100644 index 00000000..3e86bb18 --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectPlanMapper.xml @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + insert into erp_project_plan( + tenant_id, + + project_id, + + manager_id, + + charge_id, + + payment_method, + + project_plan_status, + + flow_status, + + sort_order, + + contract_id, + + remark, + + active_flag, + + del_flag, + + create_dept, + + create_by, + + create_time, + + update_by, + + update_time + + ) + values + + ( + #{item.tenantId}, + + #{item.projectId}, + + #{item.managerId}, + + #{item.chargeId}, + + #{item.paymentMethod}, + + #{item.projectPlanStatus}, + + #{item.flowStatus}, + + #{item.sortOrder}, + + #{item.contractId}, + + #{item.remark}, + + #{item.activeFlag}, + + #{item.delFlag}, + + #{item.createDept}, + + #{item.createBy}, + + #{item.createTime}, + + #{item.updateBy}, + + #{item.updateTime} + + ) + + + + + + + update erp_project_plan + + + tenant_id = #{item.tenantId}, + + + project_id = #{item.projectId}, + + + manager_id = #{item.managerId}, + + + charge_id = #{item.chargeId}, + + + payment_method = #{item.paymentMethod}, + + + project_plan_status = #{item.projectPlanStatus}, + + + flow_status = #{item.flowStatus}, + + + sort_order = #{item.sortOrder}, + + + contract_id = #{item.contractId}, + + + remark = #{item.remark}, + + + active_flag = #{item.activeFlag}, + + + del_flag = #{item.delFlag}, + + + create_dept = #{item.createDept}, + + + create_by = #{item.createBy}, + + + create_time = #{item.createTime}, + + + update_by = #{item.updateBy}, + + + update_time = #{item.updateTime} + + + where project_plan_id = #{item.projectPlanId} + + + + + + delete from erp_project_plan + ${ew.getCustomSqlSegment} + + + + + delete from erp_project_plan + where project_plan_id in + + #{id} + + + + + + + + diff --git a/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectPlanStageMapper.xml b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectPlanStageMapper.xml new file mode 100644 index 00000000..da485b3e --- /dev/null +++ b/ruoyi-modules/ruoyi-oa/src/main/resources/mapper/oa/erp/ErpProjectPlanStageMapper.xml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + insert into erp_project_plan_stage( + tenant_id, + + project_id, + + project_plan_id, + + project_phases, + + plan_start_time, + + plan_end_time, + + collection_stage, + + repayment_rate, + + repayment_amount, + + repayment_time, + + delay_day, + + receivable_date, + + reasons_explanation, + + schedule_remark, + + real_start_time, + + real_end_time, + + sort_order, + + remark, + + active_flag, + + del_flag, + + create_dept, + + create_by, + + create_time, + + update_by, + + update_time + + ) + values + + ( + #{item.tenantId}, + + #{item.projectId}, + + #{item.projectPlanId}, + + #{item.projectPhases}, + + #{item.planStartTime}, + + #{item.planEndTime}, + + #{item.collectionStage}, + + #{item.repaymentRate}, + + #{item.repaymentAmount}, + + #{item.repaymentTime}, + + #{item.delayDay}, + + #{item.receivableDate}, + + #{item.reasonsExplanation}, + + #{item.scheduleRemark}, + + #{item.realStartTime}, + + #{item.realEndTime}, + + #{item.sortOrder}, + + #{item.remark}, + + #{item.activeFlag}, + + #{item.delFlag}, + + #{item.createDept}, + + #{item.createBy}, + + #{item.createTime}, + + #{item.updateBy}, + + #{item.updateTime} + + ) + + + + + + + update erp_project_plan_stage + + + tenant_id = #{item.tenantId}, + + + project_id = #{item.projectId}, + + + project_plan_id = #{item.projectPlanId}, + + + project_phases = #{item.projectPhases}, + + + plan_start_time = #{item.planStartTime}, + + + plan_end_time = #{item.planEndTime}, + + + collection_stage = #{item.collectionStage}, + + + repayment_rate = #{item.repaymentRate}, + + + repayment_amount = #{item.repaymentAmount}, + + + repayment_time = #{item.repaymentTime}, + + + delay_day = #{item.delayDay}, + + + receivable_date = #{item.receivableDate}, + + + reasons_explanation = #{item.reasonsExplanation}, + + + schedule_remark = #{item.scheduleRemark}, + + + real_start_time = #{item.realStartTime}, + + + real_end_time = #{item.realEndTime}, + + + sort_order = #{item.sortOrder}, + + + remark = #{item.remark}, + + + active_flag = #{item.activeFlag}, + + + del_flag = #{item.delFlag}, + + + create_dept = #{item.createDept}, + + + create_by = #{item.createBy}, + + + create_time = #{item.createTime}, + + + update_by = #{item.updateBy}, + + + update_time = #{item.updateTime} + + + where plan_stage_id = #{item.planStageId} + + + + + + delete from erp_project_plan_stage + ${ew.getCustomSqlSegment} + + + + + delete from erp_project_plan_stage + where plan_stage_id in + + #{id} + + + + + + + + diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index b06c152c..acc867a6 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -22,6 +22,7 @@ import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.system.domain.SysUser; import org.dromara.system.domain.SysUserPost; import org.dromara.system.domain.SysUserRole; +import org.dromara.system.domain.SysRole; import org.dromara.system.domain.bo.SysUserBo; import org.dromara.system.domain.vo.SysPostVo; import org.dromara.system.domain.vo.SysRoleVo; @@ -59,6 +60,32 @@ public class SysUserServiceImpl implements ISysUserService { @Override public TableDataInfo selectPageUserList(SysUserBo user, PageQuery pageQuery) { Page page = baseMapper.selectVoPage(pageQuery.build(), this.buildQueryWrapper(user)); + // 批量填充角色信息 + if (CollUtil.isNotEmpty(page.getRecords())) { + List userIds = StreamUtils.toList(page.getRecords(), SysUserVo::getUserId); + // 批量查询用户角色关联关系 + List userRoles = userRoleMapper.selectList( + new LambdaQueryWrapper().in(SysUserRole::getUserId, userIds)); + // 获取所有角色ID + List roleIds = StreamUtils.toList(userRoles, SysUserRole::getRoleId); + // 批量查询角色信息 + List allRoles = CollUtil.isEmpty(roleIds) ? new ArrayList<>() : + roleMapper.selectVoList(new LambdaQueryWrapper().in(SysRole::getRoleId, roleIds)); + Map roleMap = StreamUtils.toIdentityMap(allRoles, SysRoleVo::getRoleId); + // 按用户ID分组用户角色关联关系 + Map> userRoleMap = StreamUtils.groupByKey(userRoles, SysUserRole::getUserId); + // 为每个用户填充角色信息 + page.getRecords().forEach(userVo -> { + List userRoleList = userRoleMap.get(userVo.getUserId()); + if (CollUtil.isNotEmpty(userRoleList)) { + List userRoleVoList = StreamUtils.toList(userRoleList, ur -> roleMap.get(ur.getRoleId())) + .stream().filter(ObjectUtil::isNotNull).toList(); + userVo.setRoles(userRoleVoList); + } else { + userVo.setRoles(new ArrayList<>()); + } + }); + } return TableDataInfo.build(page); }