1.0.35.0:

后端封装工作流:包括工作流的执行和工作流的监听
dev
xs 3 months ago
parent 3ba19aa3ed
commit 38f4d4c0ab

@ -3,6 +3,7 @@ package org.dromara.workflow.api.domain;
import cn.hutool.core.util.ObjectUtil;
import lombok.Data;
import org.dromara.common.core.utils.StringUtils;
import java.io.Serial;
import java.io.Serializable;
@ -46,6 +47,7 @@ public class RemoteStartProcess implements Serializable {
*/
private RemoteFlowInstanceBizExt bizExt;
public Map<String, Object> getVariables() {
if (variables == null) {
return new HashMap<>(16);
@ -61,4 +63,17 @@ public class RemoteStartProcess implements Serializable {
return bizExt;
}
public void setFlowConfig(String flowCode,String businessTitle,String businessCode){
// 后端发起需要忽略权限
this.getVariables().put("ignore", true);
this.setFlowCode(flowCode);
RemoteFlowInstanceBizExt bizExt = new RemoteFlowInstanceBizExt();
bizExt.setBusinessTitle(businessTitle);
bizExt.setBusinessId(this.getBusinessId());
if(StringUtils.isNotEmpty(businessCode)){
bizExt.setBusinessCode(businessCode);
}
this.setBizExt(bizExt);
}
}

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common</artifactId>
<version>2.5.0</version>
</parent>
<artifactId>hwbm-common-workflow</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api-workflow</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-bus</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,88 @@
package org.dromara.workflow.enums;
import lombok.Getter;
import org.dromara.common.core.enums.OAStatusEnum;
/**
* @description
*
*
* @author xins
* @date 2025/11/4 9:41
*/
@Getter
public enum FlowConfigEnum {
/**
*
*/
BUDGET("HWOABudget", "erp_budget_info", "budget_status", OAStatusEnum.COMPLETED.getStatus(), "flow_status","预算审批","budget_id");
/**
*
*/
private final String flowCode;
/**
*
*/
private final String tableName;
/**
*
*/
private final String businessStatusField;
/**
*
*/
private final String completedBusinessStatus;
/**
*
*/
private final String flowStatusField;
/**
*
*/
private final String businessTitle;
/**
*
*/
private final String businessPk;
FlowConfigEnum(String flowCode, String tableName, String businessStatusField,
String completedBusinessStatus, String flowStatusField, String businessTitle, String businessPk) {
this.flowCode = flowCode;
this.tableName = tableName;
this.businessStatusField = businessStatusField;
this.completedBusinessStatus = completedBusinessStatus;
this.flowStatusField = flowStatusField;
this.businessTitle = businessTitle;
this.businessPk = businessPk;
}
/**
*
*/
public static FlowConfigEnum getByFlowCode(String flowCode) {
for (FlowConfigEnum config : values()) {
if (config.getFlowCode().equals(flowCode)) {
return config;
}
}
return null;
}
/**
*
*/
public static boolean supports(String flowCode) {
return getByFlowCode(flowCode) != null;
}
}

@ -0,0 +1,182 @@
package org.dromara.workflow.event;
import cn.hutool.core.convert.Convert;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.workflow.api.event.ProcessEvent;
import org.dromara.workflow.enums.FlowConfigEnum;
import java.util.HashMap;
import java.util.Map;
/**
* @Author xins
* @Date 2025/11/10 10:16
* @Description: *
*
*/
@Slf4j
public abstract class AbstractProcessEventHandler implements IProcessEventHandler {
/**
*
*
*/
public abstract void onProcessEvent(ProcessEvent processEvent);
/**
* -
*/
@Override
public final int handleProcessEvent(ProcessEvent processEvent) {
// 步骤1: 参数校验
validateParameters(processEvent);
String flowCode = processEvent.getFlowCode();
String businessId = processEvent.getBusinessId();
log.info("开始处理流程事件: flowCode={}, businessId={}, status={}",
flowCode, businessId, processEvent.getStatus());
// 检查是否支持该流程编码
FlowConfigEnum flowConfig = FlowConfigEnum.getByFlowCode(flowCode);
// 步骤2: 构建更新字段
Map<String, Object> setFields = buildSetFields(flowConfig,processEvent);
// 步骤3: 构建查询条件
Map<String, Object> conditions = buildConditions(flowConfig,processEvent);
// 步骤4: 执行更新
int updateCount = doUpdate(flowConfig, setFields, conditions);
// 步骤5: 验证更新结果
validateUpdateResult(processEvent, updateCount);
return updateCount;
}
/**
* -
*/
protected void validateParameters(ProcessEvent processEvent) {
if (processEvent == null) {
throw new IllegalArgumentException("流程事件不能为空");
}
String flowCode = processEvent.getFlowCode();
// 检查是否支持该流程编码
FlowConfigEnum flowConfig = FlowConfigEnum.getByFlowCode(flowCode);
if (flowConfig == null) {
throw new IllegalArgumentException("不支持的流程编码: "+flowCode+", 忽略处理");
}
// if (flowConfig == null) {
// throw new IllegalArgumentException("流程配置不能为空");
// }
if (StringUtils.isBlank(processEvent.getBusinessId())) {
throw new IllegalArgumentException("业务ID不能为空");
}
log.debug("参数校验通过: flowCode={}, businessId={}",
processEvent.getFlowCode(), processEvent.getBusinessId());
}
/**
*
*/
protected Map<String, Object> buildSetFields(FlowConfigEnum flowConfig, ProcessEvent processEvent) {
Map<String, Object> setFields = new HashMap<>();
// 设置流程状态
setFields.put(flowConfig.getFlowStatusField(), processEvent.getStatus());
// 如果流程完成,更新业务状态
if (BusinessStatusEnum.FINISH.getStatus().equals(processEvent.getStatus())) {
setFields.put(flowConfig.getBusinessStatusField(), flowConfig.getCompletedBusinessStatus());
}
// 处理特殊状态转换
// handleSpecialStatus(flowConfig, processEvent, setFields);
// 设置更新时间(如果表中有这个字段)
setFields.put("update_time", new java.util.Date());
return setFields;
}
/**
*
*/
protected Map<String, Object> buildConditions(FlowConfigEnum flowConfig, ProcessEvent processEvent) {
Map<String, Object> conditions = new HashMap<>();
// 主键条件
conditions.put(flowConfig.getBusinessPk(), Convert.toLong(processEvent.getBusinessId()));
// 可以添加其他条件如租户ID等
// conditions.put("tenant_id", processEvent.getTenantId());
return conditions;
}
/**
* -
*/
protected abstract int doUpdate(FlowConfigEnum flowConfig,
Map<String, Object> setFields, Map<String, Object> conditions);
/**
* -
*/
protected void validateUpdateResult(ProcessEvent processEvent, int updateCount) {
if (updateCount == 0) {
log.warn("未更新到任何记录: flowCode={}, businessId={}",
processEvent.getFlowCode(), processEvent.getBusinessId());
} else if (updateCount > 1) {
log.warn("更新了多条记录: flowCode={}, businessId={}, updateCount={}",
processEvent.getFlowCode(), processEvent.getBusinessId(), updateCount);
}
}
/**
*
*/
protected void handleSpecialStatus(FlowConfigEnum flowConfig, ProcessEvent processEvent, Map<String, Object> setFields) {
// 可以根据需要添加特殊的状态转换逻辑
switch (processEvent.getStatus()) {
case "BACK": // 退回
setFields.put(flowConfig.getBusinessStatusField(), "REJECTED");
break;
case "CANCEL": // 取消
setFields.put(flowConfig.getBusinessStatusField(), "CANCELLED");
break;
case "TERMINATE": // 终止
setFields.put(flowConfig.getBusinessStatusField(), "TERMINATED");
break;
default:
// 默认不处理
break;
}
}
/**
*
*/
protected void handlePostProcess(FlowConfigEnum flowConfig, ProcessEvent processEvent, int updateCount) {
// 可以在这里添加后处理逻辑,如发送消息、记录日志等
switch (flowConfig) {
case BUDGET:
log.debug("预算流程处理完成, businessId: {}", processEvent.getBusinessId());
// 可以发送预算特定的领域事件
break;
default:
log.debug("流程处理完成, flowCode: {}, businessId: {}",
processEvent.getFlowCode(), processEvent.getBusinessId());
break;
}
}
}

@ -0,0 +1,17 @@
package org.dromara.workflow.event;
import org.dromara.workflow.api.event.ProcessEvent;
/**
* @Author xins
* @Date 2025/11/10 10:14
* @Description:
*/
public interface IProcessEventHandler {
/**
*
*/
public int handleProcessEvent(ProcessEvent processEvent);
}

@ -0,0 +1,52 @@
package org.dromara.workflow.strategy;//package org.dromara.workflow.strategy;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.dromara.workflow.enums.FlowConfigEnum;
/**
* @Author xins
* @Date 2025/11/10 13:48
* @Description:
*/
public abstract class AbstractWorkflowService<T> {
/**
* -
*/
protected final void executeWorkflow(T bo) {
WorkflowStrategy<T> strategy = getStrategy();
if (strategy != null && strategy.shouldStartWorkflow(bo)) {
startWorkFlow(bo, strategy);
}
}
/**
*
*/
protected void startWorkFlow(T bo, WorkflowStrategy<T> strategy) {
RemoteStartProcess startProcess = new RemoteStartProcess();
startProcess.setBusinessId(strategy.getBusinessId(bo));
startProcess.setVariables(strategy.getVariables(bo));
FlowConfigEnum flowConfigEnum = strategy.getFlowConfig(bo);
startProcess.setFlowConfig(flowConfigEnum.getFlowCode(), flowConfigEnum.getBusinessTitle(), "");
boolean flagOne = this.doStartWorkflow(startProcess);
if (!flagOne) {
throw new ServiceException("流程发起异常");
}
}
/**
* remoteWorkflowService.startCompleteTask(startProcess);
*/
protected abstract boolean doStartWorkflow(RemoteStartProcess startProcess);
/**
*
*/
protected abstract WorkflowStrategy<T> getStrategy();
}

@ -0,0 +1,21 @@
package org.dromara.workflow.strategy;
import org.dromara.workflow.enums.FlowConfigEnum;
import java.util.Map;
/**
* @Author xins
* @Date 2025/11/10 13:50
* @Description:
*/
public interface WorkflowStrategy<T> {
boolean shouldStartWorkflow(T bo);
String getBusinessId(T bo);
Map<String, Object> getVariables(T bo);
FlowConfigEnum getFlowConfig(T bo);
}

@ -0,0 +1,103 @@
package org.dromara.common.mybatis.utils;
/**
* @Author xins
* @Date 2025/11/3 16:27
* @Description:
*/
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.jdbc.SQL;
import java.util.Map;
/**
* SQL
* SQL
*/
public class UniversalSqlProvider {
/**
* SQL
*/
public String buildDynamicUpdate(@Param("tableName") String tableName,
@Param("setFields") Map<String, Object> setFields,
@Param("conditions") Map<String, Object> conditions) {
return new SQL() {{
UPDATE(tableName);
// 设置更新字段
if (setFields != null && !setFields.isEmpty()) {
for (Map.Entry<String, Object> entry : setFields.entrySet()) {
SET(entry.getKey() + " = #{setFields." + entry.getKey() + "}");
}
}
// 设置条件
if (conditions != null && !conditions.isEmpty()) {
for (Map.Entry<String, Object> entry : conditions.entrySet()) {
WHERE(entry.getKey() + " = #{conditions." + entry.getKey() + "}");
}
}
}}.toString();
}
/**
* SQL
*/
public String buildDynamicUpdateWithOperator(@Param("tableName") String tableName,
@Param("setFields") Map<String, Object> setFields,
@Param("conditions") Map<String, Object> conditions) {
return new SQL() {{
UPDATE(tableName);
// 设置更新字段
if (setFields != null && !setFields.isEmpty()) {
for (Map.Entry<String, Object> entry : setFields.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String && ((String) value).startsWith("+")) {
// 增量更新,如: set quantity = quantity + 1
SET(key + " = " + key + " + " + ((String) value).substring(1));
} else if (value instanceof String && ((String) value).startsWith("-")) {
// 减量更新
SET(key + " = " + key + " - " + ((String) value).substring(1));
} else {
// 普通赋值更新
SET(key + " = #{setFields." + key + "}");
}
}
}
// 设置条件
if (conditions != null && !conditions.isEmpty()) {
for (Map.Entry<String, Object> entry : conditions.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String) {
String strValue = (String) value;
if (strValue.startsWith(">=")) {
WHERE(key + " >= " + strValue.substring(2));
} else if (strValue.startsWith("<=")) {
WHERE(key + " <= " + strValue.substring(2));
} else if (strValue.startsWith(">")) {
WHERE(key + " > " + strValue.substring(1));
} else if (strValue.startsWith("<")) {
WHERE(key + " < " + strValue.substring(1));
} else if (strValue.startsWith("!=")) {
WHERE(key + " != " + strValue.substring(2));
} else if (strValue.startsWith("LIKE ")) {
WHERE(key + " LIKE '%" + strValue.substring(5) + "%'");
} else {
WHERE(key + " = #{conditions." + key + "}");
}
} else {
WHERE(key + " = #{conditions." + key + "}");
}
}
}
}}.toString();
}
}

@ -109,6 +109,12 @@
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-bus</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>hwbm-common-workflow</artifactId>
<version>2.5.0</version>
<scope>compile</scope>
</dependency>
</dependencies>

@ -0,0 +1,145 @@
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.dromara.oa.base.domain.bo.BaseMaterialInfoBo;
import org.dromara.oa.base.domain.vo.BaseMaterialInfoVo;
import org.dromara.oa.base.service.IBaseMaterialInfoService;
import org.dromara.oa.erp.domain.bo.ErpProjectInfoBo;
import org.dromara.oa.erp.domain.vo.ErpProjectInfoVo;
import org.dromara.oa.erp.service.IErpProjectInfoService;
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.ErpBudgetInfoVo;
import org.dromara.oa.erp.domain.bo.ErpBudgetInfoBo;
import org.dromara.oa.erp.service.IErpBudgetInfoService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
*
* 访:/oa/erp/budgetInfo
*
* @author xins
* @date 2025-10-28
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/erp/budgetInfo")
public class ErpBudgetInfoController extends BaseController {
private final IErpBudgetInfoService erpBudgetInfoService;
private final IErpProjectInfoService erpProjectInfoService;
private final IBaseMaterialInfoService baseMaterialInfoService;
/**
*
*/
@SaCheckPermission("oa:erp/budgetInfo:list")
@GetMapping("/list")
public TableDataInfo<ErpBudgetInfoVo> list(ErpBudgetInfoBo bo, PageQuery pageQuery) {
return erpBudgetInfoService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("oa:erp/budgetInfo:export")
@Log(title = "项目预算", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ErpBudgetInfoBo bo, HttpServletResponse response) {
List<ErpBudgetInfoVo> list = erpBudgetInfoService.queryList(bo);
ExcelUtil.exportExcel(list, "项目预算", ErpBudgetInfoVo.class, response);
}
/**
*
*
* @param budgetId
*/
@SaCheckPermission("oa:erp/budgetInfo:query")
@GetMapping("/{budgetId}")
public R<ErpBudgetInfoVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("budgetId") Long budgetId) {
return R.ok(erpBudgetInfoService.queryById(budgetId));
}
/**
*
*/
@SaCheckPermission("oa:erp/budgetInfo:add")
@Log(title = "项目预算", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ErpBudgetInfoBo bo) {
return toAjax(erpBudgetInfoService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("oa:erp/budgetInfo:edit")
@Log(title = "项目预算", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ErpBudgetInfoBo bo) {
return toAjax(erpBudgetInfoService.updateByBo(bo));
}
/**
*
*
* @param budgetIds
*/
@SaCheckPermission("oa:erp/budgetInfo:remove")
@Log(title = "项目预算", businessType = BusinessType.DELETE)
@DeleteMapping("/{budgetIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("budgetIds") Long[] budgetIds) {
return toAjax(erpBudgetInfoService.deleteWithValidByIds(List.of(budgetIds), true));
}
/**
*
*/
@GetMapping("/getErpBudgetInfoList")
public R<List<ErpBudgetInfoVo>> getErpBudgetInfoList(ErpBudgetInfoBo bo) {
List<ErpBudgetInfoVo> list = erpBudgetInfoService.queryList(bo);
return R.ok(list);
}
/**
*
*/
@SaCheckPermission("oa:erp/budgetInfo:list")
@GetMapping("/listProjectInfo")
public TableDataInfo<ErpProjectInfoVo> listProjectInfo(ErpProjectInfoBo bo, PageQuery pageQuery) {
return erpProjectInfoService.queryPageList(bo, pageQuery);
}
/**
* SAP
*/
@SaCheckPermission("oa:erp/budgetInfo:list")
@GetMapping("/listMaterialInfo")
public TableDataInfo<BaseMaterialInfoVo> listMaterialInfo(BaseMaterialInfoBo bo, PageQuery pageQuery) {
return baseMaterialInfoService.queryPageList(bo, pageQuery);
}
}

@ -0,0 +1,65 @@
package org.dromara.oa.erp.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* erp_budget_detail
*
* @author xins
* @date 2025-10-28
*/
@Data
@TableName("erp_budget_detail")
public class ErpBudgetDetail{
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "budget_detail_id", type = IdType.AUTO)
private Long budgetDetailId;
/**
* ID
*/
private Long budgetId;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String budgetItem;
/**
* ()
*/
private Long budgetCost;
/**
* ()
*/
private Long reduceBudgetCost;
/**
* ID
*/
private Long referenceProjectId;
/**
*
*/
private String referenceProjectName;
}

@ -0,0 +1,167 @@
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_budget_info
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_budget_info")
public class ErpBudgetInfo extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "budget_id", type = IdType.AUTO)
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* ID使
*/
private Long approvedFlag;
/**
* +1
*/
private Long budgetVersion;
/**
* 1 2 3
*/
private String projectCategory;
/**
*
*/
private String projectCode;
/**
*
*/
private String projectName;
/**
* sys_user
*/
private Long managerId;
/**
*
*/
private String managerName;
/**
* sys_user
*/
private Long productManagerId;
/**
*
*/
private String productManagerName;
/**
* ()IDsys_user
*/
private Long approveUserId;
/**
* ()
*/
private String approveUserName;
/**
* ()
*/
private Long contractAmount;
/**
* ()
*/
private Long netContractAmount;
/**
* ()
*/
private Long budgetCost;
/**
* 1001%,1
*/
private Long budgetRate;
/**
* ()
*/
private Long reduceBudgetCost;
/**
*
*/
private Long reduceBudgetRate;
/**
*
*/
private String duringOperation;
/**
* ID,base_unit_info
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
* 1 0
*/
private String exportFlag;
/**
* (1 2 3)
*/
private String budgetStatus;
/**
*
*/
private String flowStatus;
/**
* ID()
*/
private Long contractId;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,117 @@
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_budget_install_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_budget_install_cost")
public class ErpBudgetInstallCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "install_cost_id", type = IdType.AUTO)
private Long installCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String personnelCategory;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long cumulativeTime;
/**
* %
*/
private Long monthRate;
/**
* /
*/
private Long artificialStandard;
/**
*
*/
private Long price;
/**
*
*/
private Long reducePeopleNumber;
/**
*
*/
private Long reduceCumulativeTime;
/**
* %
*/
private Long reduceMonthRate;
/**
* /
*/
private Long reduceArtificialStandard;
/**
*
*/
private Long reducePrice;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String reduceProposal;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,122 @@
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_budget_labor_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_budget_labor_cost")
public class ErpBudgetLaborCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "labor_cost_id", type = IdType.AUTO)
private Long laborCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* ,sys_dict_datadict_value
*/
private String personnelCategory;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long cumulativeTime;
/**
* %100
*/
private Long monthRate;
/**
* /
*/
private Long artificialStandard;
/**
*
*/
private Long price;
/**
* ,sys_dict_datadict_value
*/
private String reducePersonnelCategory;
/**
*
*/
private Long reducePeopleNumber;
/**
*
*/
private Long reduceCumulativeTime;
/**
* %
*/
private Long reduceMonthRate;
/**
* /
*/
private Long reduceArtificialStandard;
/**
*
*/
private Long reducePrice;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String reduceProposal;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,122 @@
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_budget_material_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_budget_material_cost")
public class ErpBudgetMaterialCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "material_cost_id", type = IdType.AUTO)
private Long materialCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* IDbase_material_info
*/
private Long materielId;
/**
* SAP
*/
private String materielCode;
/**
* SAP
*/
private String materielName;
/**
* ID?
*/
private Long relationMaterielId;
/**
* ,base_unit_info
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
* ()
*/
private Long unitPrice;
/**
*
*/
private Long amount;
/**
*
*/
private Long price;
/**
* ()
*/
private Long reduceUnitPrice;
/**
*
*/
private Long reduceAmount;
/**
*
*/
private Long reducePrice;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String reduceProposal;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,82 @@
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_budget_other_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_budget_other_cost")
public class ErpBudgetOtherCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "other_cost_id", type = IdType.AUTO)
private Long otherCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String itemDesc;
/**
*
*/
private Long price;
/**
*
*/
private String reduceItemDesc;
/**
*
*/
private Long reducePrice;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String reduceProposal;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,152 @@
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_budget_travel_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_budget_travel_cost")
public class ErpBudgetTravelCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "travel_cost_id", type = IdType.AUTO)
private Long travelCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String tripLocation;
/**
*
*/
private String reason;
/**
*
*/
private Long frequency;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long days;
/**
* 宿
*/
private Long stayStandard;
/**
*
*/
private Long travelExpenses;
/**
* 宿
*/
private Long stayCosts;
/**
*
*/
private Long subsidyCosts;
/**
*
*/
private Long subtotalCosts;
/**
*
*/
private Long reduceFrequency;
/**
*
*/
private Long reducePeopleNumber;
/**
*
*/
private Long reduceDayNumber;
/**
* 宿
*/
private Long reduceStayStandard;
/**
*
*/
private Long reduceTravelExpenses;
/**
* 宿
*/
private Long reduceStayCosts;
/**
*
*/
private Long reduceSubsidyCosts;
/**
*
*/
private Long reduceSubtotalCosts;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String reduceProposal;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,82 @@
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_rd_budget_equipment_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_rd_budget_equipment_cost")
public class ErpRdBudgetEquipmentCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "equipment_cost_id", type = IdType.AUTO)
private Long equipmentCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String equipmentName;
/**
*
*/
private String equipmentSpec;
/**
* (/)
*/
private Long unitPrice;
/**
* ()
*/
private Long amount;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,97 @@
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_rd_budget_exchange_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_rd_budget_exchange_cost")
public class ErpRdBudgetExchangeCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "exchange_cost_id", type = IdType.AUTO)
private Long exchangeCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* ()
*/
private String communicationType;
/**
*
*/
private String countryRegion;
/**
*
*/
private String institution;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long days;
/**
* 宿()
*/
private Long travelAccommodationExpense;
/**
*
*/
private Long subsidy;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,97 @@
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_rd_budget_labor_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_rd_budget_labor_cost")
public class ErpRdBudgetLaborCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "labor_cost_id", type = IdType.AUTO)
private Long laborCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* (12)
*/
private String laborType;
/**
* ,sys_dict_datadict_value
*/
private String personnelCategory;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long cumulativeTime;
/**
* %
*/
private Long monthRate;
/**
* /
*/
private Long artificialStandard;
/**
*
*/
private Long price;
/**
* ,
*/
private String projectPersonnel;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,72 @@
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_rd_budget_literature_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_rd_budget_literature_cost")
public class ErpRdBudgetLiteratureCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "literature_cost_id", type = IdType.AUTO)
private Long literatureCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* 123
*/
private String literatureType;
/**
*
*/
private String itemDesc;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -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_rd_budget_material_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_rd_budget_material_cost")
public class ErpRdBudgetMaterialCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "material_cost_id", type = IdType.AUTO)
private Long materialCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String materialName;
/**
* ,base_unit_info
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
* (/)
*/
private Long unitPrice;
/**
*
*/
private Long amount;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,102 @@
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_rd_budget_meeting_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_rd_budget_meeting_cost")
public class ErpRdBudgetMeetingCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "meeting_cost_id", type = IdType.AUTO)
private Long meetingCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String meetingType;
/**
*
*/
private String meetingContent;
/**
* ()
*/
private Long rentalFee;
/**
* ()
*/
private Long dailyExpense;
/**
*
*/
private Long days;
/**
* 宿()
*/
private Long expertExpense;
/**
*
*/
private Long peopleNumber;
/**
* ()
*/
private Long perPersonExpense;
/**
*
*/
private Long meetingPrice;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,67 @@
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_rd_budget_other_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_rd_budget_other_cost")
public class ErpRdBudgetOtherCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "other_cost_id", type = IdType.AUTO)
private Long otherCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String itemDesc;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,97 @@
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_rd_budget_tech_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_rd_budget_tech_cost")
public class ErpRdBudgetTechCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "tech_cost_id", type = IdType.AUTO)
private Long techCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* (12-3-)
*/
private String techType;
/**
*
*/
private String techContent;
/**
* base_unit_info
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long days;
/**
*
*/
private Long frequency;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,92 @@
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_rd_budget_testing_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_rd_budget_testing_cost")
public class ErpRdBudgetTestingCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "testing_cost_id", type = IdType.AUTO)
private Long testingCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String testingContent;
/**
*
*/
private String testingUnitName;
/**
* ,base_unit_info
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
* (/)
*/
private Long unitPrice;
/**
*
*/
private Long amount;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,107 @@
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_rd_budget_travel_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_rd_budget_travel_cost")
public class ErpRdBudgetTravelCost extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "travel_cost_id", type = IdType.AUTO)
private Long travelCostId;
/**
* IDerp_budget_info
*/
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String tripLocation;
/**
*
*/
private String reason;
/**
*
*/
private Long frequency;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long days;
/**
* 宿
*/
private Long stayStandard;
/**
*
*/
private Long travelExpenses;
/**
* 宿
*/
private Long stayCosts;
/**
*
*/
private Long subsidyCosts;
/**
*
*/
private Long subtotalCosts;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,67 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpBudgetDetail;
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.*;
/**
* erp_budget_detail
*
* @author xins
* @date 2025-10-28
*/
@Data
@AutoMapper(target = ErpBudgetDetail.class, reverseConvertGenerate = false)
public class ErpBudgetDetailBo {
/**
* ID
*/
@NotNull(message = "预算详情ID不能为空", groups = { EditGroup.class })
private Long budgetDetailId;
/**
* ID
*/
@NotNull(message = "预算ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
*
*/
@NotNull(message = "排序号不能为空", groups = { AddGroup.class, EditGroup.class })
private Long sortOrder;
/**
*
*/
@NotBlank(message = "预算科目不能为空", groups = { AddGroup.class, EditGroup.class })
private String budgetItem;
/**
* ()
*/
private Long budgetCost;
/**
* ()
*/
private Long reduceBudgetCost;
/**
* ID
*/
private Long referenceProjectId;
/**
*
*/
private String referenceProjectName;
}

@ -0,0 +1,171 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpBudgetDetail;
import org.dromara.oa.erp.domain.ErpBudgetInfo;
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.oa.erp.domain.ErpBudgetMaterialCost;
import java.util.List;
/**
* erp_budget_info
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpBudgetInfo.class, reverseConvertGenerate = false)
public class ErpBudgetInfoBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "预算ID不能为空", groups = { EditGroup.class })
private Long budgetId;
/**
* ID
*/
@NotNull(message = "项目ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long projectId;
/**
* ID使
*/
private Long approvedFlag;
/**
* +1
*/
private Long budgetVersion;
/**
* 1 2 3
*/
@NotBlank(message = "冗余项目类别1销售 2研发 3预投不能为空", groups = { AddGroup.class, EditGroup.class })
private String projectCategory;
/**
*
*/
@NotBlank(message = "项目号不能为空", groups = { AddGroup.class, EditGroup.class })
private String projectCode;
/**
*
*/
@NotBlank(message = "项目名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String projectName;
/**
* sys_user
*/
private Long managerId;
/**
*
*/
private String managerName;
/**
* sys_user
*/
private Long productManagerId;
/**
*
*/
private String productManagerName;
/**
* ()IDsys_user
*/
private Long approveUserId;
/**
* ()
*/
private String approveUserName;
/**
* ()
*/
private Long contractAmount;
/**
* ()
*/
private Long netContractAmount;
/**
* ()
*/
private Long budgetCost;
/**
* 1001%,1
*/
private Long budgetRate;
/**
* ()
*/
private Long reduceBudgetCost;
/**
*
*/
private Long reduceBudgetRate;
/**
*
*/
private String duringOperation;
/**
* ID,base_unit_info
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
* 1 0
*/
private String exportFlag;
/**
* (1 2 3)
*/
private String budgetStatus;
/**
*
*/
private String flowStatus;
/**
* ID()
*/
private Long contractId;
/**
*
*/
private String remark;
private List<ErpBudgetDetail> erpBudgetDetailList;
private List<ErpBudgetMaterialCost> erpBudgetMaterialCostList;
}

@ -0,0 +1,111 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpBudgetInstallCost;
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.*;
/**
* erp_budget_install_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpBudgetInstallCost.class, reverseConvertGenerate = false)
public class ErpBudgetInstallCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "安装费ID不能为空", groups = { EditGroup.class })
private Long installCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String personnelCategory;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long cumulativeTime;
/**
* %
*/
private Long monthRate;
/**
* /
*/
private Long artificialStandard;
/**
*
*/
private Long price;
/**
*
*/
private Long reducePeopleNumber;
/**
*
*/
private Long reduceCumulativeTime;
/**
* %
*/
private Long reduceMonthRate;
/**
* /
*/
private Long reduceArtificialStandard;
/**
*
*/
private Long reducePrice;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String reduceProposal;
/**
*
*/
private String remark;
}

@ -0,0 +1,116 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpBudgetLaborCost;
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.*;
/**
* erp_budget_labor_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpBudgetLaborCost.class, reverseConvertGenerate = false)
public class ErpBudgetLaborCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "人工费ID不能为空", groups = { EditGroup.class })
private Long laborCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* ,sys_dict_datadict_value
*/
private String personnelCategory;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long cumulativeTime;
/**
* %100
*/
private Long monthRate;
/**
* /
*/
private Long artificialStandard;
/**
*
*/
private Long price;
/**
* ,sys_dict_datadict_value
*/
private String reducePersonnelCategory;
/**
*
*/
private Long reducePeopleNumber;
/**
*
*/
private Long reduceCumulativeTime;
/**
* %
*/
private Long reduceMonthRate;
/**
* /
*/
private Long reduceArtificialStandard;
/**
*
*/
private Long reducePrice;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String reduceProposal;
/**
*
*/
private String remark;
}

@ -0,0 +1,116 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpBudgetMaterialCost;
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.*;
/**
* erp_budget_material_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpBudgetMaterialCost.class, reverseConvertGenerate = false)
public class ErpBudgetMaterialCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "材料费ID不能为空", groups = { EditGroup.class })
private Long materialCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* IDbase_material_info
*/
private Long materielId;
/**
* SAP
*/
private String materielCode;
/**
* SAP
*/
private String materielName;
/**
* ID?
*/
private Long relationMaterielId;
/**
* ,base_unit_info
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
* ()
*/
private Long unitPrice;
/**
*
*/
private Long amount;
/**
*
*/
private Long price;
/**
* ()
*/
private Long reduceUnitPrice;
/**
*
*/
private Long reduceAmount;
/**
*
*/
private Long reducePrice;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String reduceProposal;
/**
*
*/
private String remark;
}

@ -0,0 +1,76 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpBudgetOtherCost;
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.*;
/**
* erp_budget_other_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpBudgetOtherCost.class, reverseConvertGenerate = false)
public class ErpBudgetOtherCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "其他费用ID不能为空", groups = { EditGroup.class })
private Long otherCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String itemDesc;
/**
*
*/
private Long price;
/**
*
*/
private String reduceItemDesc;
/**
*
*/
private Long reducePrice;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String reduceProposal;
/**
*
*/
private String remark;
}

@ -0,0 +1,146 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpBudgetTravelCost;
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.*;
/**
* erp_budget_travel_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpBudgetTravelCost.class, reverseConvertGenerate = false)
public class ErpBudgetTravelCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "差旅费ID不能为空", groups = { EditGroup.class })
private Long travelCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String tripLocation;
/**
*
*/
private String reason;
/**
*
*/
private Long frequency;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long days;
/**
* 宿
*/
private Long stayStandard;
/**
*
*/
private Long travelExpenses;
/**
* 宿
*/
private Long stayCosts;
/**
*
*/
private Long subsidyCosts;
/**
*
*/
private Long subtotalCosts;
/**
*
*/
private Long reduceFrequency;
/**
*
*/
private Long reducePeopleNumber;
/**
*
*/
private Long reduceDayNumber;
/**
* 宿
*/
private Long reduceStayStandard;
/**
*
*/
private Long reduceTravelExpenses;
/**
* 宿
*/
private Long reduceStayCosts;
/**
*
*/
private Long reduceSubsidyCosts;
/**
*
*/
private Long reduceSubtotalCosts;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String reduceProposal;
/**
*
*/
private String remark;
}

@ -0,0 +1,76 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpRdBudgetEquipmentCost;
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.*;
/**
* erp_rd_budget_equipment_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpRdBudgetEquipmentCost.class, reverseConvertGenerate = false)
public class ErpRdBudgetEquipmentCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "设备费ID不能为空", groups = { EditGroup.class })
private Long equipmentCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String equipmentName;
/**
*
*/
private String equipmentSpec;
/**
* (/)
*/
private Long unitPrice;
/**
* ()
*/
private Long amount;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

@ -0,0 +1,91 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpRdBudgetExchangeCost;
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.*;
/**
* erp_rd_budget_exchange_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpRdBudgetExchangeCost.class, reverseConvertGenerate = false)
public class ErpRdBudgetExchangeCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "交流费ID不能为空", groups = { EditGroup.class })
private Long exchangeCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* ()
*/
private String communicationType;
/**
*
*/
private String countryRegion;
/**
*
*/
private String institution;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long days;
/**
* 宿()
*/
private Long travelAccommodationExpense;
/**
*
*/
private Long subsidy;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

@ -0,0 +1,93 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpRdBudgetLaborCost;
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.*;
/**
* erp_rd_budget_labor_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpRdBudgetLaborCost.class, reverseConvertGenerate = false)
public class ErpRdBudgetLaborCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "人工费ID不能为空", groups = { EditGroup.class })
private Long laborCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
@NotNull(message = "项目ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long projectId;
/**
* (12)
*/
@NotBlank(message = "类型(1人工费2劳务费)不能为空", groups = { AddGroup.class, EditGroup.class })
private String laborType;
/**
* ,sys_dict_datadict_value
*/
private String personnelCategory;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long cumulativeTime;
/**
* %
*/
private Long monthRate;
/**
* /
*/
private Long artificialStandard;
/**
*
*/
private Long price;
/**
* ,
*/
private String projectPersonnel;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

@ -0,0 +1,66 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpRdBudgetLiteratureCost;
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.*;
/**
* erp_rd_budget_literature_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpRdBudgetLiteratureCost.class, reverseConvertGenerate = false)
public class ErpRdBudgetLiteratureCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "资料文献费ID不能为空", groups = { EditGroup.class })
private Long literatureCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* 123
*/
private String literatureType;
/**
*
*/
private String itemDesc;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

@ -0,0 +1,81 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpRdBudgetMaterialCost;
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.*;
/**
* erp_rd_budget_material_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpRdBudgetMaterialCost.class, reverseConvertGenerate = false)
public class ErpRdBudgetMaterialCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "材料费ID不能为空", groups = { EditGroup.class })
private Long materialCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String materialName;
/**
* ,base_unit_info
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
* (/)
*/
private Long unitPrice;
/**
*
*/
private Long amount;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

@ -0,0 +1,96 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpRdBudgetMeetingCost;
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.*;
/**
* erp_rd_budget_meeting_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpRdBudgetMeetingCost.class, reverseConvertGenerate = false)
public class ErpRdBudgetMeetingCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "会议费ID不能为空", groups = { EditGroup.class })
private Long meetingCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String meetingType;
/**
*
*/
private String meetingContent;
/**
* ()
*/
private Long rentalFee;
/**
* ()
*/
private Long dailyExpense;
/**
*
*/
private Long days;
/**
* 宿()
*/
private Long expertExpense;
/**
*
*/
private Long peopleNumber;
/**
* ()
*/
private Long perPersonExpense;
/**
*
*/
private Long meetingPrice;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

@ -0,0 +1,61 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpRdBudgetOtherCost;
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.*;
/**
* erp_rd_budget_other_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpRdBudgetOtherCost.class, reverseConvertGenerate = false)
public class ErpRdBudgetOtherCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "其他费用ID不能为空", groups = { EditGroup.class })
private Long otherCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String itemDesc;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

@ -0,0 +1,92 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpRdBudgetTechCost;
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.*;
/**
* erp_rd_budget_tech_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpRdBudgetTechCost.class, reverseConvertGenerate = false)
public class ErpRdBudgetTechCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "技术服务费ID不能为空", groups = { EditGroup.class })
private Long techCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
* (12-3-)
*/
@NotBlank(message = "技术服务费类型(1、技术咨询开发2、专家咨询-会议形式3、专家咨询-通讯形式)不能为空", groups = { AddGroup.class, EditGroup.class })
private String techType;
/**
*
*/
private String techContent;
/**
* base_unit_info
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long days;
/**
*
*/
private Long frequency;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

@ -0,0 +1,86 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpRdBudgetTestingCost;
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.*;
/**
* erp_rd_budget_testing_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpRdBudgetTestingCost.class, reverseConvertGenerate = false)
public class ErpRdBudgetTestingCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "测试化验费ID不能为空", groups = { EditGroup.class })
private Long testingCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String testingContent;
/**
*
*/
private String testingUnitName;
/**
* ,base_unit_info
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
* (/)
*/
private Long unitPrice;
/**
*
*/
private Long amount;
/**
*
*/
private Long price;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

@ -0,0 +1,101 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpRdBudgetTravelCost;
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.*;
/**
* erp_rd_budget_travel_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpRdBudgetTravelCost.class, reverseConvertGenerate = false)
public class ErpRdBudgetTravelCostBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "差旅费ID不能为空", groups = { EditGroup.class })
private Long travelCostId;
/**
* IDerp_budget_info
*/
@NotNull(message = "预算ID关联erp_budget_info不能为空", groups = { AddGroup.class, EditGroup.class })
private Long budgetId;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String tripLocation;
/**
*
*/
private String reason;
/**
*
*/
private Long frequency;
/**
*
*/
private Long peopleNumber;
/**
*
*/
private Long days;
/**
* 宿
*/
private Long stayStandard;
/**
*
*/
private Long travelExpenses;
/**
* 宿
*/
private Long stayCosts;
/**
*
*/
private Long subsidyCosts;
/**
*
*/
private Long subtotalCosts;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String remark;
}

@ -0,0 +1,80 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpBudgetDetail;
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_budget_detail
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpBudgetDetail.class)
public class ErpBudgetDetailVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "预算详情ID")
private Long budgetDetailId;
/**
* ID
*/
@ExcelProperty(value = "预算ID")
private Long budgetId;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "预算科目")
private String budgetItem;
/**
* ()
*/
@ExcelProperty(value = "预算成本(元)")
private Long budgetCost;
/**
* ()
*/
@ExcelProperty(value = "降成本预算成本(元)")
private Long reduceBudgetCost;
/**
* ID
*/
@ExcelProperty(value = "参考项目ID")
private Long referenceProjectId;
/**
*
*/
@ExcelProperty(value = "参考项目名称")
private String referenceProjectName;
}

@ -0,0 +1,198 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpBudgetInfo;
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_budget_info
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpBudgetInfo.class)
public class ErpBudgetInfoVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "预算ID")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
* ID使
*/
@ExcelProperty(value = "等同于项目ID做唯一索引使用在作废时此值要清空")
private Long approvedFlag;
/**
* +1
*/
@ExcelProperty(value = "版本,新版本+1")
private Long budgetVersion;
/**
* 1 2 3
*/
@ExcelProperty(value = "冗余,项目类别", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "1=销售,2=研发,3=预投")
private String projectCategory;
/**
*
*/
@ExcelProperty(value = "项目号")
private String projectCode;
/**
*
*/
@ExcelProperty(value = "项目名称")
private String projectName;
/**
* sys_user
*/
@ExcelProperty(value = "项目经理", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "市=场预算表的项目经理,研发预算表中的编制")
private Long managerId;
/**
*
*/
@ExcelProperty(value = "项目经理姓名")
private String managerName;
/**
* sys_user
*/
@ExcelProperty(value = "产品经理关联sys_user")
private Long productManagerId;
/**
*
*/
@ExcelProperty(value = "产品经理姓名")
private String productManagerName;
/**
* ()IDsys_user
*/
@ExcelProperty(value = "审核(评审组长)ID关联sys_user")
private Long approveUserId;
/**
* ()
*/
@ExcelProperty(value = "审核(评审组长)姓名")
private String approveUserName;
/**
* ()
*/
@ExcelProperty(value = "合同额(元)")
private Long contractAmount;
/**
* ()
*/
@ExcelProperty(value = "合同净额(元)")
private Long netContractAmount;
/**
* ()
*/
@ExcelProperty(value = "预算成本(元)")
private Long budgetCost;
/**
* 1001%,1
*/
@ExcelProperty(value = "预算毛利率乘以100保存", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "如=1%,保存1")
private Long budgetRate;
/**
* ()
*/
@ExcelProperty(value = "降成本后预算成本(元)")
private Long reduceBudgetCost;
/**
*
*/
@ExcelProperty(value = "降成本后预算毛利率")
private Long reduceBudgetRate;
/**
*
*/
@ExcelProperty(value = "项目预算期间")
private String duringOperation;
/**
* ID,base_unit_info
*/
@ExcelProperty(value = "单位ID,关联base_unit_info")
private Long unitId;
/**
*
*/
@ExcelProperty(value = "单位名称")
private String unitName;
/**
* 1 0
*/
@ExcelProperty(value = "是否出口", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "1=是,0=否")
private String exportFlag;
/**
* (1 2 3)
*/
@ExcelProperty(value = "预算状态(1暂存 2审批中 3可用)")
private String budgetStatus;
/**
*
*/
@ExcelProperty(value = "流程状态")
private String flowStatus;
/**
* ID()
*/
@ExcelProperty(value = "合同ID(预留)")
private Long contractId;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,142 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpBudgetInstallCost;
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_budget_install_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpBudgetInstallCost.class)
public class ErpBudgetInstallCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "安装费ID")
private Long installCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "人员类别")
private String personnelCategory;
/**
*
*/
@ExcelProperty(value = "人数")
private Long peopleNumber;
/**
*
*/
@ExcelProperty(value = "累计时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "月=")
private Long cumulativeTime;
/**
* %
*/
@ExcelProperty(value = "月平均投入比例", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "%=")
private Long monthRate;
/**
* /
*/
@ExcelProperty(value = "人工标准", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=/人月")
private Long artificialStandard;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
*
*/
@ExcelProperty(value = "降成本人数")
private Long reducePeopleNumber;
/**
*
*/
@ExcelProperty(value = "降成本累计时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "月=")
private Long reduceCumulativeTime;
/**
* %
*/
@ExcelProperty(value = "降成本月平均投入比例", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "%=")
private Long reduceMonthRate;
/**
* /
*/
@ExcelProperty(value = "降成本人工标准", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=/人月")
private Long reduceArtificialStandard;
/**
*
*/
@ExcelProperty(value = "降成本降成本金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long reducePrice;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "降成本方案")
private String reduceProposal;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,148 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpBudgetLaborCost;
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_budget_labor_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpBudgetLaborCost.class)
public class ErpBudgetLaborCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "人工费ID")
private Long laborCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
* ,sys_dict_datadict_value
*/
@ExcelProperty(value = "人员类别,关联sys_dict_data的dict_value")
private String personnelCategory;
/**
*
*/
@ExcelProperty(value = "人数")
private Long peopleNumber;
/**
*
*/
@ExcelProperty(value = "累计时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "月=")
private Long cumulativeTime;
/**
* %100
*/
@ExcelProperty(value = "月平均投入比例", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "%=")
private Long monthRate;
/**
* /
*/
@ExcelProperty(value = "人工标准", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=/人月")
private Long artificialStandard;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
* ,sys_dict_datadict_value
*/
@ExcelProperty(value = "降成本人员类别,关联sys_dict_data的dict_value")
private String reducePersonnelCategory;
/**
*
*/
@ExcelProperty(value = "降成本人数")
private Long reducePeopleNumber;
/**
*
*/
@ExcelProperty(value = "降成本累计时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "月=")
private Long reduceCumulativeTime;
/**
* %
*/
@ExcelProperty(value = "降成本月平均投入比例", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "%=")
private Long reduceMonthRate;
/**
* /
*/
@ExcelProperty(value = "降成本人工标准", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=/人月")
private Long reduceArtificialStandard;
/**
*
*/
@ExcelProperty(value = "降成本金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long reducePrice;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "降成本方案")
private String reduceProposal;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,142 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpBudgetMaterialCost;
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_budget_material_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpBudgetMaterialCost.class)
public class ErpBudgetMaterialCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "材料费ID")
private Long materialCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
* IDbase_material_info
*/
@ExcelProperty(value = "物料ID关联base_material_info")
private Long materielId;
/**
* SAP
*/
@ExcelProperty(value = "SAP物料编码")
private String materielCode;
/**
* SAP
*/
@ExcelProperty(value = "SAP物料名称")
private String materielName;
/**
* ID?
*/
@ExcelProperty(value = "销售物料ID?")
private Long relationMaterielId;
/**
* ,base_unit_info
*/
@ExcelProperty(value = "单位,关联base_unit_info")
private Long unitId;
/**
*
*/
@ExcelProperty(value = "单位名称")
private String unitName;
/**
* ()
*/
@ExcelProperty(value = "单价(元)")
private Long unitPrice;
/**
*
*/
@ExcelProperty(value = "购置数量")
private Long amount;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
* ()
*/
@ExcelProperty(value = "降成本单价(元)")
private Long reduceUnitPrice;
/**
*
*/
@ExcelProperty(value = "降成本数量")
private Long reduceAmount;
/**
*
*/
@ExcelProperty(value = "降成本金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long reducePrice;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "降成本方案")
private String reduceProposal;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,94 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpBudgetOtherCost;
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_budget_other_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpBudgetOtherCost.class)
public class ErpBudgetOtherCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "其他费用ID")
private Long otherCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "项目描述")
private String itemDesc;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
*
*/
@ExcelProperty(value = "降成本项目描述")
private String reduceItemDesc;
/**
*
*/
@ExcelProperty(value = "降成本金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long reducePrice;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "降成本方案")
private String reduceProposal;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,186 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpBudgetTravelCost;
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_budget_travel_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpBudgetTravelCost.class)
public class ErpBudgetTravelCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "差旅费ID")
private Long travelCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "出差地点")
private String tripLocation;
/**
*
*/
@ExcelProperty(value = "事由")
private String reason;
/**
*
*/
@ExcelProperty(value = "次数")
private Long frequency;
/**
*
*/
@ExcelProperty(value = "人数")
private Long peopleNumber;
/**
*
*/
@ExcelProperty(value = "天数")
private Long days;
/**
* 宿
*/
@ExcelProperty(value = "住宿标准", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long stayStandard;
/**
*
*/
@ExcelProperty(value = "往返路费", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long travelExpenses;
/**
* 宿
*/
@ExcelProperty(value = "住宿费", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long stayCosts;
/**
*
*/
@ExcelProperty(value = "补贴", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long subsidyCosts;
/**
*
*/
@ExcelProperty(value = "小计", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long subtotalCosts;
/**
*
*/
@ExcelProperty(value = "降成本次数")
private Long reduceFrequency;
/**
*
*/
@ExcelProperty(value = "降成本人数")
private Long reducePeopleNumber;
/**
*
*/
@ExcelProperty(value = "降成本天数")
private Long reduceDayNumber;
/**
* 宿
*/
@ExcelProperty(value = "降成本住宿标准", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long reduceStayStandard;
/**
*
*/
@ExcelProperty(value = "降成本往返路费", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long reduceTravelExpenses;
/**
* 宿
*/
@ExcelProperty(value = "降成本住宿费", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long reduceStayCosts;
/**
*
*/
@ExcelProperty(value = "降成本补贴", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long reduceSubsidyCosts;
/**
*
*/
@ExcelProperty(value = "降成本小计", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long reduceSubtotalCosts;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "降成本方案")
private String reduceProposal;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,93 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpRdBudgetEquipmentCost;
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_rd_budget_equipment_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpRdBudgetEquipmentCost.class)
public class ErpRdBudgetEquipmentCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "设备费ID")
private Long equipmentCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "设备名称")
private String equipmentName;
/**
*
*/
@ExcelProperty(value = "设备型号")
private String equipmentSpec;
/**
* (/)
*/
@ExcelProperty(value = "单价(元/台件)")
private Long unitPrice;
/**
* ()
*/
@ExcelProperty(value = "数量(台件)")
private Long amount;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,114 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpRdBudgetExchangeCost;
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_rd_budget_exchange_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpRdBudgetExchangeCost.class)
public class ErpRdBudgetExchangeCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "交流费ID")
private Long exchangeCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
* ()
*/
@ExcelProperty(value = "合作交流类型(下拉列表选择,也可以直接输入)")
private String communicationType;
/**
*
*/
@ExcelProperty(value = "国家和地区")
private String countryRegion;
/**
*
*/
@ExcelProperty(value = "机构")
private String institution;
/**
*
*/
@ExcelProperty(value = "人数", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "人=")
private Long peopleNumber;
/**
*
*/
@ExcelProperty(value = "时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "天=")
private Long days;
/**
* 宿()
*/
@ExcelProperty(value = "往返路费及住宿费(元)")
private Long travelAccommodationExpense;
/**
*
*/
@ExcelProperty(value = "补贴", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long subsidy;
/**
*
*/
@ExcelProperty(value = "小计", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,114 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpRdBudgetLaborCost;
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_rd_budget_labor_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpRdBudgetLaborCost.class)
public class ErpRdBudgetLaborCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "人工费ID")
private Long laborCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
* (12)
*/
@ExcelProperty(value = "类型(1人工费2劳务费)")
private String laborType;
/**
* ,sys_dict_datadict_value
*/
@ExcelProperty(value = "人员类别,关联sys_dict_data的dict_value")
private String personnelCategory;
/**
*
*/
@ExcelProperty(value = "人数")
private Long peopleNumber;
/**
*
*/
@ExcelProperty(value = "累计时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "月=")
private Long cumulativeTime;
/**
* %
*/
@ExcelProperty(value = "月平均投入比例", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "%=")
private Long monthRate;
/**
* /
*/
@ExcelProperty(value = "人工标准", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=/人月")
private Long artificialStandard;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
* ,
*/
@ExcelProperty(value = "投入人员,多个以,隔开")
private String projectPersonnel;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,82 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpRdBudgetLiteratureCost;
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_rd_budget_literature_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpRdBudgetLiteratureCost.class)
public class ErpRdBudgetLiteratureCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "资料文献费ID")
private Long literatureCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
* 123
*/
@ExcelProperty(value = "类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "1=、资料费2文献检索费3专用软件购买费")
private String literatureType;
/**
*
*/
@ExcelProperty(value = "项目描述")
private String itemDesc;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,99 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpRdBudgetMaterialCost;
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_rd_budget_material_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpRdBudgetMaterialCost.class)
public class ErpRdBudgetMaterialCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "材料费ID")
private Long materialCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "材料名称")
private String materialName;
/**
* ,base_unit_info
*/
@ExcelProperty(value = "单位,关联base_unit_info")
private Long unitId;
/**
*
*/
@ExcelProperty(value = "单位名称")
private String unitName;
/**
* (/)
*/
@ExcelProperty(value = "单价(元/台件)")
private Long unitPrice;
/**
*
*/
@ExcelProperty(value = "数量")
private Long amount;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,117 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpRdBudgetMeetingCost;
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_rd_budget_meeting_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpRdBudgetMeetingCost.class)
public class ErpRdBudgetMeetingCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "会议费ID")
private Long meetingCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "会议类型")
private String meetingType;
/**
*
*/
@ExcelProperty(value = "会议内容")
private String meetingContent;
/**
* ()
*/
@ExcelProperty(value = "场地日租金(元)")
private Long rentalFee;
/**
* ()
*/
@ExcelProperty(value = "日均杂费(元)")
private Long dailyExpense;
/**
*
*/
@ExcelProperty(value = "天数")
private Long days;
/**
* 宿()
*/
@ExcelProperty(value = "专家交通住宿费(元)")
private Long expertExpense;
/**
*
*/
@ExcelProperty(value = "人数")
private Long peopleNumber;
/**
* ()
*/
@ExcelProperty(value = "人均花费(元)")
private Long perPersonExpense;
/**
*
*/
@ExcelProperty(value = "会议费", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long meetingPrice;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,75 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpRdBudgetOtherCost;
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_rd_budget_other_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpRdBudgetOtherCost.class)
public class ErpRdBudgetOtherCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "其他费用ID")
private Long otherCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "项目描述")
private String itemDesc;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,111 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpRdBudgetTechCost;
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_rd_budget_tech_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpRdBudgetTechCost.class)
public class ErpRdBudgetTechCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "技术服务费ID")
private Long techCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
* (12-3-)
*/
@ExcelProperty(value = "技术服务费类型(1、技术咨询开发2、专家咨询-会议形式3、专家咨询-通讯形式)")
private String techType;
/**
*
*/
@ExcelProperty(value = "内容")
private String techContent;
/**
* base_unit_info
*/
@ExcelProperty(value = "单位关联base_unit_info")
private Long unitId;
/**
*
*/
@ExcelProperty(value = "单位名称")
private String unitName;
/**
*
*/
@ExcelProperty(value = "人数")
private Long peopleNumber;
/**
*
*/
@ExcelProperty(value = "天数")
private Long days;
/**
*
*/
@ExcelProperty(value = "次数")
private Long frequency;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,105 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpRdBudgetTestingCost;
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_rd_budget_testing_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpRdBudgetTestingCost.class)
public class ErpRdBudgetTestingCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "测试化验费ID")
private Long testingCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "测试化验的内容")
private String testingContent;
/**
*
*/
@ExcelProperty(value = "测试化验单位")
private String testingUnitName;
/**
* ,base_unit_info
*/
@ExcelProperty(value = "单位,关联base_unit_info")
private Long unitId;
/**
*
*/
@ExcelProperty(value = "单位名称")
private String unitName;
/**
* (/)
*/
@ExcelProperty(value = "单价(元/单位数量)")
private Long unitPrice;
/**
*
*/
@ExcelProperty(value = "数量")
private Long amount;
/**
*
*/
@ExcelProperty(value = "金额", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long price;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,127 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpRdBudgetTravelCost;
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_rd_budget_travel_cost
*
* @author xins
* @date 2025-10-28
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpRdBudgetTravelCost.class)
public class ErpRdBudgetTravelCostVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "差旅费ID")
private Long travelCostId;
/**
* IDerp_budget_info
*/
@ExcelProperty(value = "预算ID关联erp_budget_info")
private Long budgetId;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "出差地点")
private String tripLocation;
/**
*
*/
@ExcelProperty(value = "事由")
private String reason;
/**
*
*/
@ExcelProperty(value = "次数")
private Long frequency;
/**
*
*/
@ExcelProperty(value = "人数")
private Long peopleNumber;
/**
*
*/
@ExcelProperty(value = "天数")
private Long days;
/**
* 宿
*/
@ExcelProperty(value = "住宿标准", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long stayStandard;
/**
*
*/
@ExcelProperty(value = "往返路费", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long travelExpenses;
/**
* 宿
*/
@ExcelProperty(value = "住宿费", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long stayCosts;
/**
*
*/
@ExcelProperty(value = "补贴", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long subsidyCosts;
/**
*
*/
@ExcelProperty(value = "小计", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "元=")
private Long subtotalCosts;
/**
*
*/
@ExcelProperty(value = "排序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,40 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpBudgetDetail;
import org.dromara.oa.erp.domain.vo.ErpBudgetDetailVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
@InterceptorIgnore(dataPermission = "true", tenantLine = "true")
public interface ErpBudgetDetailMapper extends BaseMapperPlus<ErpBudgetDetail, ErpBudgetDetailVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpBudgetDetailVo> selectCustomErpBudgetDetailVoList(@Param("page") Page<ErpBudgetDetailVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetDetail> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpBudgetDetailVo> selectCustomErpBudgetDetailVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetDetail> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpBudgetInfo;
import org.dromara.oa.erp.domain.vo.ErpBudgetInfoVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpBudgetInfoMapper extends BaseMapperPlus<ErpBudgetInfo, ErpBudgetInfoVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpBudgetInfoVo> selectCustomErpBudgetInfoVoList(@Param("page") Page<ErpBudgetInfoVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetInfo> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpBudgetInfoVo> selectCustomErpBudgetInfoVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetInfo> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpBudgetInstallCost;
import org.dromara.oa.erp.domain.vo.ErpBudgetInstallCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpBudgetInstallCostMapper extends BaseMapperPlus<ErpBudgetInstallCost, ErpBudgetInstallCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpBudgetInstallCostVo> selectCustomErpBudgetInstallCostVoList(@Param("page") Page<ErpBudgetInstallCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetInstallCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpBudgetInstallCostVo> selectCustomErpBudgetInstallCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetInstallCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpBudgetLaborCost;
import org.dromara.oa.erp.domain.vo.ErpBudgetLaborCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpBudgetLaborCostMapper extends BaseMapperPlus<ErpBudgetLaborCost, ErpBudgetLaborCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpBudgetLaborCostVo> selectCustomErpBudgetLaborCostVoList(@Param("page") Page<ErpBudgetLaborCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetLaborCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpBudgetLaborCostVo> selectCustomErpBudgetLaborCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetLaborCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpBudgetMaterialCost;
import org.dromara.oa.erp.domain.vo.ErpBudgetMaterialCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpBudgetMaterialCostMapper extends BaseMapperPlus<ErpBudgetMaterialCost, ErpBudgetMaterialCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpBudgetMaterialCostVo> selectCustomErpBudgetMaterialCostVoList(@Param("page") Page<ErpBudgetMaterialCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetMaterialCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpBudgetMaterialCostVo> selectCustomErpBudgetMaterialCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetMaterialCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpBudgetOtherCost;
import org.dromara.oa.erp.domain.vo.ErpBudgetOtherCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpBudgetOtherCostMapper extends BaseMapperPlus<ErpBudgetOtherCost, ErpBudgetOtherCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpBudgetOtherCostVo> selectCustomErpBudgetOtherCostVoList(@Param("page") Page<ErpBudgetOtherCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetOtherCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpBudgetOtherCostVo> selectCustomErpBudgetOtherCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetOtherCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpBudgetTravelCost;
import org.dromara.oa.erp.domain.vo.ErpBudgetTravelCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpBudgetTravelCostMapper extends BaseMapperPlus<ErpBudgetTravelCost, ErpBudgetTravelCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpBudgetTravelCostVo> selectCustomErpBudgetTravelCostVoList(@Param("page") Page<ErpBudgetTravelCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetTravelCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpBudgetTravelCostVo> selectCustomErpBudgetTravelCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpBudgetTravelCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpRdBudgetEquipmentCost;
import org.dromara.oa.erp.domain.vo.ErpRdBudgetEquipmentCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpRdBudgetEquipmentCostMapper extends BaseMapperPlus<ErpRdBudgetEquipmentCost, ErpRdBudgetEquipmentCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpRdBudgetEquipmentCostVo> selectCustomErpRdBudgetEquipmentCostVoList(@Param("page") Page<ErpRdBudgetEquipmentCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetEquipmentCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpRdBudgetEquipmentCostVo> selectCustomErpRdBudgetEquipmentCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetEquipmentCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpRdBudgetExchangeCost;
import org.dromara.oa.erp.domain.vo.ErpRdBudgetExchangeCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpRdBudgetExchangeCostMapper extends BaseMapperPlus<ErpRdBudgetExchangeCost, ErpRdBudgetExchangeCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpRdBudgetExchangeCostVo> selectCustomErpRdBudgetExchangeCostVoList(@Param("page") Page<ErpRdBudgetExchangeCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetExchangeCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpRdBudgetExchangeCostVo> selectCustomErpRdBudgetExchangeCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetExchangeCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpRdBudgetLaborCost;
import org.dromara.oa.erp.domain.vo.ErpRdBudgetLaborCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpRdBudgetLaborCostMapper extends BaseMapperPlus<ErpRdBudgetLaborCost, ErpRdBudgetLaborCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpRdBudgetLaborCostVo> selectCustomErpRdBudgetLaborCostVoList(@Param("page") Page<ErpRdBudgetLaborCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetLaborCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpRdBudgetLaborCostVo> selectCustomErpRdBudgetLaborCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetLaborCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpRdBudgetLiteratureCost;
import org.dromara.oa.erp.domain.vo.ErpRdBudgetLiteratureCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpRdBudgetLiteratureCostMapper extends BaseMapperPlus<ErpRdBudgetLiteratureCost, ErpRdBudgetLiteratureCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpRdBudgetLiteratureCostVo> selectCustomErpRdBudgetLiteratureCostVoList(@Param("page") Page<ErpRdBudgetLiteratureCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetLiteratureCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpRdBudgetLiteratureCostVo> selectCustomErpRdBudgetLiteratureCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetLiteratureCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpRdBudgetMaterialCost;
import org.dromara.oa.erp.domain.vo.ErpRdBudgetMaterialCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpRdBudgetMaterialCostMapper extends BaseMapperPlus<ErpRdBudgetMaterialCost, ErpRdBudgetMaterialCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpRdBudgetMaterialCostVo> selectCustomErpRdBudgetMaterialCostVoList(@Param("page") Page<ErpRdBudgetMaterialCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetMaterialCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpRdBudgetMaterialCostVo> selectCustomErpRdBudgetMaterialCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetMaterialCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpRdBudgetMeetingCost;
import org.dromara.oa.erp.domain.vo.ErpRdBudgetMeetingCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpRdBudgetMeetingCostMapper extends BaseMapperPlus<ErpRdBudgetMeetingCost, ErpRdBudgetMeetingCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpRdBudgetMeetingCostVo> selectCustomErpRdBudgetMeetingCostVoList(@Param("page") Page<ErpRdBudgetMeetingCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetMeetingCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpRdBudgetMeetingCostVo> selectCustomErpRdBudgetMeetingCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetMeetingCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpRdBudgetOtherCost;
import org.dromara.oa.erp.domain.vo.ErpRdBudgetOtherCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpRdBudgetOtherCostMapper extends BaseMapperPlus<ErpRdBudgetOtherCost, ErpRdBudgetOtherCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpRdBudgetOtherCostVo> selectCustomErpRdBudgetOtherCostVoList(@Param("page") Page<ErpRdBudgetOtherCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetOtherCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpRdBudgetOtherCostVo> selectCustomErpRdBudgetOtherCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetOtherCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpRdBudgetTechCost;
import org.dromara.oa.erp.domain.vo.ErpRdBudgetTechCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpRdBudgetTechCostMapper extends BaseMapperPlus<ErpRdBudgetTechCost, ErpRdBudgetTechCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpRdBudgetTechCostVo> selectCustomErpRdBudgetTechCostVoList(@Param("page") Page<ErpRdBudgetTechCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetTechCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpRdBudgetTechCostVo> selectCustomErpRdBudgetTechCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetTechCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpRdBudgetTestingCost;
import org.dromara.oa.erp.domain.vo.ErpRdBudgetTestingCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpRdBudgetTestingCostMapper extends BaseMapperPlus<ErpRdBudgetTestingCost, ErpRdBudgetTestingCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpRdBudgetTestingCostVo> selectCustomErpRdBudgetTestingCostVoList(@Param("page") Page<ErpRdBudgetTestingCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetTestingCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpRdBudgetTestingCostVo> selectCustomErpRdBudgetTestingCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetTestingCost> queryWrapper);
}

@ -0,0 +1,37 @@
package org.dromara.oa.erp.mapper;
import java.util.List;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.ErpRdBudgetTravelCost;
import org.dromara.oa.erp.domain.vo.ErpRdBudgetTravelCostVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author xins
* @date 2025-10-28
*/
public interface ErpRdBudgetTravelCostMapper extends BaseMapperPlus<ErpRdBudgetTravelCost, ErpRdBudgetTravelCostVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpRdBudgetTravelCostVo> selectCustomErpRdBudgetTravelCostVoList(@Param("page") Page<ErpRdBudgetTravelCostVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetTravelCost> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpRdBudgetTravelCostVo> selectCustomErpRdBudgetTravelCostVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpRdBudgetTravelCost> queryWrapper);
}

@ -0,0 +1,29 @@
package org.dromara.oa.erp.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.UpdateProvider;
import org.dromara.common.mybatis.utils.UniversalSqlProvider;
import java.util.Map;
/**
* Mapper
* SQL
*/
@Mapper
public interface OaUniversalMapper {
/**
*
*
* @param tableName
* @param setFields
* @param conditions
* @return
*/
@UpdateProvider(type = UniversalSqlProvider.class, method = "buildDynamicUpdate")
int dynamicUpdate(@Param("tableName") String tableName,
@Param("setFields") Map<String, Object> setFields,
@Param("conditions") Map<String, Object> conditions);
}

@ -0,0 +1,69 @@
package org.dromara.oa.erp.service;
import org.dromara.oa.erp.domain.ErpBudgetInfo;
import org.dromara.oa.erp.domain.vo.ErpBudgetInfoVo;
import org.dromara.oa.erp.domain.bo.ErpBudgetInfoBo;
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 xins
* @date 2025-10-28
*/
public interface IErpBudgetInfoService {
/**
*
*
* @param budgetId
* @return
*/
ErpBudgetInfoVo queryById(Long budgetId);
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
TableDataInfo<ErpBudgetInfoVo> queryPageList(ErpBudgetInfoBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
List<ErpBudgetInfoVo> queryList(ErpBudgetInfoBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(ErpBudgetInfoBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(ErpBudgetInfoBo bo);
/**
*
*
* @param ids
* @param isValid
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

@ -0,0 +1,222 @@
package org.dromara.oa.erp.service.impl;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.seata.spring.annotation.GlobalTransactional;
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 lombok.RequiredArgsConstructor;
import org.dromara.oa.erp.domain.ErpBudgetDetail;
import org.dromara.oa.erp.domain.ErpBudgetMaterialCost;
import org.dromara.oa.erp.mapper.ErpBudgetDetailMapper;
import org.dromara.oa.erp.mapper.ErpBudgetMaterialCostMapper;
import org.dromara.oa.workflow.strategy.BudgetWorkflowStrategy;
import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.dromara.workflow.strategy.AbstractWorkflowService;
import org.springframework.stereotype.Service;
import org.dromara.oa.erp.domain.bo.ErpBudgetInfoBo;
import org.dromara.oa.erp.domain.vo.ErpBudgetInfoVo;
import org.dromara.oa.erp.domain.ErpBudgetInfo;
import org.dromara.oa.erp.mapper.ErpBudgetInfoMapper;
import org.dromara.oa.erp.service.IErpBudgetInfoService;
import org.dromara.workflow.strategy.WorkflowStrategy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* Service
*
* @author xins
* @date 2025-10-28
*/
@RequiredArgsConstructor
@Service
public class ErpBudgetInfoServiceImpl extends AbstractWorkflowService<ErpBudgetInfoBo> implements IErpBudgetInfoService {
private final ErpBudgetInfoMapper baseMapper;
private final ErpBudgetDetailMapper erpBudgetDetailMapper;
private final ErpBudgetMaterialCostMapper erpBudgetMaterialCostMapper;
@DubboReference(timeout = 30000)
private RemoteWorkflowService remoteWorkflowService;
@Override
protected WorkflowStrategy<ErpBudgetInfoBo> getStrategy() {
return new BudgetWorkflowStrategy();
}
/**
* remoteWorkflowService.startCompleteTask(startProcess);
*/
@Override
protected boolean doStartWorkflow(RemoteStartProcess startProcess){
return remoteWorkflowService.startCompleteTask(startProcess);
}
/**
*
*
* @param budgetId
* @return
*/
@Override
public ErpBudgetInfoVo queryById(Long budgetId) {
return baseMapper.selectVoById(budgetId);
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<ErpBudgetInfoVo> queryPageList(ErpBudgetInfoBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpBudgetInfo> lqw = buildQueryWrapper(bo);
Page<ErpBudgetInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*
* @param bo
* @return
*/
@Override
public List<ErpBudgetInfoVo> queryList(ErpBudgetInfoBo bo) {
MPJLambdaWrapper<ErpBudgetInfo> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private MPJLambdaWrapper<ErpBudgetInfo> buildQueryWrapper(ErpBudgetInfoBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpBudgetInfo> lqw = JoinWrappers.lambda(ErpBudgetInfo.class)
.selectAll(ErpBudgetInfo.class)
.eq(bo.getProjectId() != null, ErpBudgetInfo::getProjectId, bo.getProjectId())
.eq(bo.getApprovedFlag() != null, ErpBudgetInfo::getApprovedFlag, bo.getApprovedFlag())
.eq(bo.getBudgetVersion() != null, ErpBudgetInfo::getBudgetVersion, bo.getBudgetVersion())
.eq(StringUtils.isNotBlank(bo.getProjectCategory()), ErpBudgetInfo::getProjectCategory, bo.getProjectCategory())
.eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpBudgetInfo::getProjectCode, bo.getProjectCode())
.like(StringUtils.isNotBlank(bo.getProjectName()), ErpBudgetInfo::getProjectName, bo.getProjectName())
.eq(bo.getManagerId() != null, ErpBudgetInfo::getManagerId, bo.getManagerId())
.like(StringUtils.isNotBlank(bo.getManagerName()), ErpBudgetInfo::getManagerName, bo.getManagerName())
.eq(bo.getProductManagerId() != null, ErpBudgetInfo::getProductManagerId, bo.getProductManagerId())
.like(StringUtils.isNotBlank(bo.getProductManagerName()), ErpBudgetInfo::getProductManagerName, bo.getProductManagerName())
.eq(bo.getApproveUserId() != null, ErpBudgetInfo::getApproveUserId, bo.getApproveUserId())
.like(StringUtils.isNotBlank(bo.getApproveUserName()), ErpBudgetInfo::getApproveUserName, bo.getApproveUserName())
.eq(bo.getContractAmount() != null, ErpBudgetInfo::getContractAmount, bo.getContractAmount())
.eq(bo.getNetContractAmount() != null, ErpBudgetInfo::getNetContractAmount, bo.getNetContractAmount())
.eq(bo.getBudgetCost() != null, ErpBudgetInfo::getBudgetCost, bo.getBudgetCost())
.eq(bo.getBudgetRate() != null, ErpBudgetInfo::getBudgetRate, bo.getBudgetRate())
.eq(bo.getReduceBudgetCost() != null, ErpBudgetInfo::getReduceBudgetCost, bo.getReduceBudgetCost())
.eq(bo.getReduceBudgetRate() != null, ErpBudgetInfo::getReduceBudgetRate, bo.getReduceBudgetRate())
.eq(StringUtils.isNotBlank(bo.getDuringOperation()), ErpBudgetInfo::getDuringOperation, bo.getDuringOperation())
.eq(bo.getUnitId() != null, ErpBudgetInfo::getUnitId, bo.getUnitId())
.like(StringUtils.isNotBlank(bo.getUnitName()), ErpBudgetInfo::getUnitName, bo.getUnitName())
.eq(StringUtils.isNotBlank(bo.getExportFlag()), ErpBudgetInfo::getExportFlag, bo.getExportFlag())
.eq(StringUtils.isNotBlank(bo.getBudgetStatus()), ErpBudgetInfo::getBudgetStatus, bo.getBudgetStatus())
.eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpBudgetInfo::getFlowStatus, bo.getFlowStatus())
.eq(bo.getContractId() != null, ErpBudgetInfo::getContractId, bo.getContractId());
return lqw;
}
/**
*
*
* @param bo
* @return
*/
@Override
@GlobalTransactional(rollbackFor = Exception.class)
public Boolean insertByBo(ErpBudgetInfoBo bo) {
ErpBudgetInfo add = MapstructUtils.convert(bo, ErpBudgetInfo.class);
validEntityBeforeSave(add);
add.setApprovedFlag(add.getProjectId());
add.setBudgetVersion(1L);
boolean flag = baseMapper.insert(add) > 0;
List<ErpBudgetDetail> erpBudgetDetailList = bo.getErpBudgetDetailList();
erpBudgetDetailList.forEach(erpBudgetDetail -> erpBudgetDetail.setBudgetId(add.getBudgetId()));
List<ErpBudgetMaterialCost> erpBudgetMaterialCostList = bo.getErpBudgetMaterialCostList();
erpBudgetMaterialCostList.forEach(erpBudgetMaterialCost -> erpBudgetMaterialCost.setBudgetId(add.getBudgetId()));
erpBudgetDetailMapper.insertBatch(erpBudgetDetailList);
erpBudgetMaterialCostMapper.insertBatch(erpBudgetMaterialCostList);
if (flag) {
bo.setBudgetId(add.getBudgetId());
}
this.executeWorkflow(bo);
return flag;
}
/**
*
* @param bo
*/
// private void startWorkFlow(ErpBudgetInfoBo bo){
// if (!bo.getBudgetStatus().equals(OAStatusEnum.DRAFT.getStatus())) {
// Map<String, Object> variables = new HashMap<>();
// variables.put("projectName", bo.getProjectName());
// RemoteStartProcess startProcess = new RemoteStartProcess();
// startProcess.setBusinessId(bo.getBudgetId().toString());
// startProcess.setVariables(variables);
// startProcess.setFlowConfig(FlowConfigEnum.BUDGET,"");
// boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess);
// if (!flagOne) {
// throw new ServiceException("流程发起异常");
// }
// }
// }
/**
*
*
* @param bo
* @return
*/
@Override
@GlobalTransactional(rollbackFor = Exception.class)
public Boolean updateByBo(ErpBudgetInfoBo bo) {
ErpBudgetInfo update = MapstructUtils.convert(bo, ErpBudgetInfo.class);
validEntityBeforeSave(update);
boolean isUpdated = baseMapper.updateById(update) > 0;
this.executeWorkflow(bo);
return isUpdated;
}
/**
*
*/
private void validEntityBeforeSave(ErpBudgetInfo entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
*
*
* @param ids
* @param isValid
* @return
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

@ -0,0 +1,54 @@
package org.dromara.oa.workflow.handler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.oa.erp.mapper.OaUniversalMapper;
import org.dromara.workflow.api.event.ProcessEvent;
import org.dromara.workflow.enums.FlowConfigEnum;
import org.dromara.workflow.event.AbstractProcessEventHandler;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
/**
* @Author xins
* @Date 2025/11/10 10:28
* @Description:
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class OaProcessEventHandler extends AbstractProcessEventHandler {
private final OaUniversalMapper oaUniversalMapper;
@EventListener(condition = "#processEvent.flowCode.startsWith('HWOA')")
@Transactional(rollbackFor = Exception.class)
@Override
public void onProcessEvent(ProcessEvent processEvent) {
String flowCode = processEvent.getFlowCode();
FlowConfigEnum flowConfig = FlowConfigEnum.getByFlowCode(flowCode);
if (flowConfig == null) {
log.warn("不支持的流程编码: {}, 忽略处理", flowCode);
return;
}
log.info("处理器开始处理流程事件: handler={}, flowCode={}, businessId={}",
this.getClass().getSimpleName(), flowCode, processEvent.getBusinessId());
int updateCount = handleProcessEvent(processEvent);
}
@Override
protected int doUpdate(FlowConfigEnum flowConfig, Map<String, Object> setFields, Map<String, Object> conditions) {
String tableName = flowConfig.getTableName();
log.debug("执行数据库更新: table={}, conditions={}", tableName, conditions);
return oaUniversalMapper.dynamicUpdate(tableName, setFields, conditions);
}
}

@ -0,0 +1,39 @@
package org.dromara.oa.workflow.strategy;
import org.dromara.common.core.enums.OAStatusEnum;
import org.dromara.oa.erp.domain.bo.ErpBudgetInfoBo;
import org.dromara.workflow.enums.FlowConfigEnum;
import org.dromara.workflow.strategy.WorkflowStrategy;
import java.util.HashMap;
import java.util.Map;
/**
* @Author xins
* @Date 2025/11/4 14:42
* @Description:
*/
public class BudgetWorkflowStrategy implements WorkflowStrategy<ErpBudgetInfoBo> {
@Override
public boolean shouldStartWorkflow(ErpBudgetInfoBo bo) {
return !bo.getBudgetStatus().equals(OAStatusEnum.DRAFT.getStatus());
}
@Override
public String getBusinessId(ErpBudgetInfoBo bo) {
return bo.getBudgetId().toString();
}
@Override
public Map<String, Object> getVariables(ErpBudgetInfoBo bo) {
Map<String, Object> variables = new HashMap<>();
variables.put("projectName", bo.getProjectName());
return variables;
}
@Override
public FlowConfigEnum getFlowConfig(ErpBudgetInfoBo bo) {
return FlowConfigEnum.BUDGET;
}
}

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpBudgetDetailMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpBudgetDetailVo" id="ErpBudgetDetailResult">
</resultMap>
<select id="selectCustomErpBudgetDetailVoList" resultMap="ErpBudgetDetailResult">
select budget_detail_id, budget_id, sort_order, budget_item, budget_cost, reduce_budget_cost, reference_project_id, reference_project_name from erp_budget_detail t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpBudgetInfoMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpBudgetInfoVo" id="ErpBudgetInfoResult">
</resultMap>
<select id="selectCustomErpBudgetInfoVoList" resultMap="ErpBudgetInfoResult">
select budget_id, tenant_id, project_id, approved_flag, budget_version, project_category, project_code, project_name, manager_id, manager_name, product_manager_id, product_manager_name, approve_user_id, approve_user_name, contract_amount, net_contract_amount, budget_cost, budget_rate, reduce_budget_cost, reduce_budget_rate, during_operation, unit_id, unit_name, export_flag, budget_status, flow_status, contract_id, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_budget_info t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpBudgetInstallCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpBudgetInstallCostVo" id="ErpBudgetInstallCostResult">
</resultMap>
<select id="selectCustomErpBudgetInstallCostVoList" resultMap="ErpBudgetInstallCostResult">
select install_cost_id, tenant_id, budget_id, project_id, personnel_category, people_number, cumulative_time, month_rate, artificial_standard, price, reduce_people_number, reduce_cumulative_time, reduce_month_rate, reduce_artificial_standard, reduce_price, sort_order, reduce_proposal, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_budget_install_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpBudgetLaborCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpBudgetLaborCostVo" id="ErpBudgetLaborCostResult">
</resultMap>
<select id="selectCustomErpBudgetLaborCostVoList" resultMap="ErpBudgetLaborCostResult">
select labor_cost_id, tenant_id, budget_id, project_id, personnel_category, people_number, cumulative_time, month_rate, artificial_standard, price, reduce_personnel_category, reduce_people_number, reduce_cumulative_time, reduce_month_rate, reduce_artificial_standard, reduce_price, sort_order, reduce_proposal, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_budget_labor_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpBudgetMaterialCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpBudgetMaterialCostVo" id="ErpBudgetMaterialCostResult">
</resultMap>
<select id="selectCustomErpBudgetMaterialCostVoList" resultMap="ErpBudgetMaterialCostResult">
select material_cost_id, tenant_id, budget_id, project_id, materiel_id, materiel_code, materiel_name, relation_materiel_id, unit_id, unit_name, unit_price, amount, price, reduce_unit_price, reduce_amount, reduce_price, sort_order, reduce_proposal, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_budget_material_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpBudgetOtherCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpBudgetOtherCostVo" id="ErpBudgetOtherCostResult">
</resultMap>
<select id="selectCustomErpBudgetOtherCostVoList" resultMap="ErpBudgetOtherCostResult">
select other_cost_id, tenant_id, budget_id, project_id, item_desc, price, reduce_item_desc, reduce_price, sort_order, reduce_proposal, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_budget_other_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpBudgetTravelCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpBudgetTravelCostVo" id="ErpBudgetTravelCostResult">
</resultMap>
<select id="selectCustomErpBudgetTravelCostVoList" resultMap="ErpBudgetTravelCostResult">
select travel_cost_id, tenant_id, budget_id, project_id, trip_location, reason, frequency, people_number, days, stay_standard, travel_expenses, stay_costs, subsidy_costs, subtotal_costs, reduce_frequency, reduce_people_number, reduce_day_number, reduce_stay_standard, reduce_travel_expenses, reduce_stay_costs, reduce_subsidy_costs, reduce_subtotal_costs, sort_order, reduce_proposal, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_budget_travel_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpRdBudgetEquipmentCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpRdBudgetEquipmentCostVo" id="ErpRdBudgetEquipmentCostResult">
</resultMap>
<select id="selectCustomErpRdBudgetEquipmentCostVoList" resultMap="ErpRdBudgetEquipmentCostResult">
select equipment_cost_id, tenant_id, budget_id, project_id, equipment_name, equipment_spec, unit_price, amount, price, sort_order, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_rd_budget_equipment_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpRdBudgetExchangeCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpRdBudgetExchangeCostVo" id="ErpRdBudgetExchangeCostResult">
</resultMap>
<select id="selectCustomErpRdBudgetExchangeCostVoList" resultMap="ErpRdBudgetExchangeCostResult">
select exchange_cost_id, tenant_id, budget_id, project_id, communication_type, country_region, institution, people_number, days, travel_accommodation_expense, subsidy, price, sort_order, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_rd_budget_exchange_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpRdBudgetLaborCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpRdBudgetLaborCostVo" id="ErpRdBudgetLaborCostResult">
</resultMap>
<select id="selectCustomErpRdBudgetLaborCostVoList" resultMap="ErpRdBudgetLaborCostResult">
select labor_cost_id, tenant_id, budget_id, project_id, labor_type, personnel_category, people_number, cumulative_time, month_rate, artificial_standard, price, project_personnel, sort_order, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_rd_budget_labor_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpRdBudgetLiteratureCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpRdBudgetLiteratureCostVo" id="ErpRdBudgetLiteratureCostResult">
</resultMap>
<select id="selectCustomErpRdBudgetLiteratureCostVoList" resultMap="ErpRdBudgetLiteratureCostResult">
select literature_cost_id, tenant_id, budget_id, project_id, literature_type, item_desc, price, sort_order, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_rd_budget_literature_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpRdBudgetMaterialCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpRdBudgetMaterialCostVo" id="ErpRdBudgetMaterialCostResult">
</resultMap>
<select id="selectCustomErpRdBudgetMaterialCostVoList" resultMap="ErpRdBudgetMaterialCostResult">
select material_cost_id, tenant_id, budget_id, project_id, material_name, unit_id, unit_name, unit_price, amount, price, sort_order, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_rd_budget_material_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpRdBudgetMeetingCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpRdBudgetMeetingCostVo" id="ErpRdBudgetMeetingCostResult">
</resultMap>
<select id="selectCustomErpRdBudgetMeetingCostVoList" resultMap="ErpRdBudgetMeetingCostResult">
select meeting_cost_id, tenant_id, budget_id, project_id, meeting_type, meeting_content, rental_fee, daily_expense, days, expert_expense, people_number, per_person_expense, meeting_price, sort_order, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_rd_budget_meeting_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpRdBudgetOtherCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpRdBudgetOtherCostVo" id="ErpRdBudgetOtherCostResult">
</resultMap>
<select id="selectCustomErpRdBudgetOtherCostVoList" resultMap="ErpRdBudgetOtherCostResult">
select other_cost_id, tenant_id, budget_id, project_id, item_desc, price, sort_order, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_rd_budget_other_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpRdBudgetTechCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpRdBudgetTechCostVo" id="ErpRdBudgetTechCostResult">
</resultMap>
<select id="selectCustomErpRdBudgetTechCostVoList" resultMap="ErpRdBudgetTechCostResult">
select tech_cost_id, tenant_id, budget_id, project_id, tech_type, tech_content, unit_id, unit_name, people_number, days, frequency, price, sort_order, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_rd_budget_tech_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpRdBudgetTestingCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpRdBudgetTestingCostVo" id="ErpRdBudgetTestingCostResult">
</resultMap>
<select id="selectCustomErpRdBudgetTestingCostVoList" resultMap="ErpRdBudgetTestingCostResult">
select testing_cost_id, tenant_id, budget_id, project_id, testing_content, testing_unit_name, unit_id, unit_name, unit_price, amount, price, sort_order, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_rd_budget_testing_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpRdBudgetTravelCostMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpRdBudgetTravelCostVo" id="ErpRdBudgetTravelCostResult">
</resultMap>
<select id="selectCustomErpRdBudgetTravelCostVoList" resultMap="ErpRdBudgetTravelCostResult">
select travel_cost_id, tenant_id, budget_id, project_id, trip_location, reason, frequency, people_number, days, stay_standard, travel_expenses, stay_costs, subsidy_costs, subtotal_costs, sort_order, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_rd_budget_travel_cost t
${ew.getCustomSqlSegment}
</select>
</mapper>
Loading…
Cancel
Save