Merge remote-tracking branch 'origin/dev' into dev

dev
wanghao 2 months ago
commit b9a5105734

@ -42,6 +42,11 @@ public class BaseRelationMaterial extends TenantEntity {
*/
private String saleMaterialName;
/**
*
*/
private String saleMaterialModel;
/**
*
*/

@ -42,6 +42,11 @@ public class BaseRelationMaterialBo extends BaseEntity {
*/
private String saleMaterialName;
/**
*
*/
private String saleMaterialModel;
/**
*
*/

@ -70,6 +70,12 @@ public class BaseRelationMaterialVo implements Serializable {
@ExcelProperty(value = "销售物料名称")
private String saleMaterialName;
/**
*
*/
@ExcelProperty(value = "销售物料型号")
private String saleMaterialModel;
/**
*
*/

@ -90,6 +90,7 @@ public class BaseRelationMaterialServiceImpl implements IBaseRelationMaterialSer
.like(StringUtils.isNotBlank(bo.getMaterialName()), BaseMaterialInfo::getMaterialName, bo.getMaterialName())
.like(StringUtils.isNotBlank(bo.getCustomerName()), CrmCustomerInfo::getCustomerName, bo.getCustomerName())
.like(StringUtils.isNotBlank(bo.getSaleMaterialName()), BaseRelationMaterial::getSaleMaterialName, bo.getSaleMaterialName())
.like(StringUtils.isNotBlank(bo.getSaleMaterialModel()), BaseRelationMaterial::getSaleMaterialModel, bo.getSaleMaterialModel())
.eq(StringUtils.isNotBlank(bo.getActiveFlag()), BaseRelationMaterial::getActiveFlag, bo.getActiveFlag());
return lqw;
}

@ -119,7 +119,7 @@ public class ErpProjectReportDetailController extends BaseController {
}
/**
*
*
* @param wrapper
* @return
*/
@ -132,4 +132,6 @@ public class ErpProjectReportDetailController extends BaseController {
ErpProjectReportDetailBo projectDetailReport = wrapper.getProjectDetailReport();
return R.ok(erpProjectReportDetailService.projectReportSubmitAndFlowStart(projectReport, projectDetailReport));
}
}

@ -0,0 +1,116 @@
package org.dromara.oa.erp.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.oa.erp.domain.vo.ErpTimesheetDeptVo;
import org.dromara.oa.erp.domain.bo.ErpTimesheetDeptBo;
import org.dromara.oa.erp.service.IErpTimesheetDeptService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
*
* 访:/oa/erp/timesheetDept
*
* @author Yangk
* @date 2025-12-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/erp/timesheetDept")
public class ErpTimesheetDeptController extends BaseController {
private final IErpTimesheetDeptService erpTimesheetDeptService;
/**
*
*/
@SaCheckPermission("oa/erp:timesheetDept:list")
@GetMapping("/list")
public TableDataInfo<ErpTimesheetDeptVo> list(ErpTimesheetDeptBo bo, PageQuery pageQuery) {
return erpTimesheetDeptService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("oa/erp:timesheetDept:export")
@Log(title = "部门工作明细", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ErpTimesheetDeptBo bo, HttpServletResponse response) {
List<ErpTimesheetDeptVo> list = erpTimesheetDeptService.queryList(bo);
ExcelUtil.exportExcel(list, "部门工作明细", ErpTimesheetDeptVo.class, response);
}
/**
*
*
* @param timesheetDeptId
*/
@SaCheckPermission("oa/erp:timesheetDept:query")
@GetMapping("/{timesheetDeptId}")
public R<ErpTimesheetDeptVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("timesheetDeptId") Long timesheetDeptId) {
return R.ok(erpTimesheetDeptService.queryById(timesheetDeptId));
}
/**
*
*/
@SaCheckPermission("oa/erp:timesheetDept:add")
@Log(title = "部门工作明细", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ErpTimesheetDeptBo bo) {
return toAjax(erpTimesheetDeptService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("oa/erp:timesheetDept:edit")
@Log(title = "部门工作明细", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ErpTimesheetDeptBo bo) {
return toAjax(erpTimesheetDeptService.updateByBo(bo));
}
/**
*
*
* @param timesheetDeptIds
*/
@SaCheckPermission("oa/erp:timesheetDept:remove")
@Log(title = "部门工作明细", businessType = BusinessType.DELETE)
@DeleteMapping("/{timesheetDeptIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("timesheetDeptIds") Long[] timesheetDeptIds) {
return toAjax(erpTimesheetDeptService.deleteWithValidByIds(List.of(timesheetDeptIds), true));
}
/**
*
*/
@GetMapping("/getErpTimesheetDeptList")
public R<List<ErpTimesheetDeptVo>> getErpTimesheetDeptList(ErpTimesheetDeptBo bo) {
List<ErpTimesheetDeptVo> list = erpTimesheetDeptService.queryList(bo);
return R.ok(list);
}
}

@ -0,0 +1,116 @@
package org.dromara.oa.erp.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.oa.erp.domain.vo.ErpTimesheetInfoVo;
import org.dromara.oa.erp.domain.bo.ErpTimesheetInfoBo;
import org.dromara.oa.erp.service.IErpTimesheetInfoService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
*
* 访:/oa/erp/timesheetInfo
*
* @author Yangk
* @date 2025-12-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/erp/timesheetInfo")
public class ErpTimesheetInfoController extends BaseController {
private final IErpTimesheetInfoService erpTimesheetInfoService;
/**
*
*/
@SaCheckPermission("oa/erp:timesheetInfo:list")
@GetMapping("/list")
public TableDataInfo<ErpTimesheetInfoVo> list(ErpTimesheetInfoBo bo, PageQuery pageQuery) {
return erpTimesheetInfoService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("oa/erp:timesheetInfo:export")
@Log(title = "工时填报", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ErpTimesheetInfoBo bo, HttpServletResponse response) {
List<ErpTimesheetInfoVo> list = erpTimesheetInfoService.queryList(bo);
ExcelUtil.exportExcel(list, "工时填报", ErpTimesheetInfoVo.class, response);
}
/**
*
*
* @param timesheetId
*/
@SaCheckPermission("oa/erp:timesheetInfo:query")
@GetMapping("/{timesheetId}")
public R<ErpTimesheetInfoVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("timesheetId") Long timesheetId) {
return R.ok(erpTimesheetInfoService.queryById(timesheetId));
}
/**
*
*/
@SaCheckPermission("oa/erp:timesheetInfo:add")
@Log(title = "工时填报", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ErpTimesheetInfoBo bo) {
return toAjax(erpTimesheetInfoService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("oa/erp:timesheetInfo:edit")
@Log(title = "工时填报", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ErpTimesheetInfoBo bo) {
return toAjax(erpTimesheetInfoService.updateByBo(bo));
}
/**
*
*
* @param timesheetIds
*/
@SaCheckPermission("oa/erp:timesheetInfo:remove")
@Log(title = "工时填报", businessType = BusinessType.DELETE)
@DeleteMapping("/{timesheetIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("timesheetIds") Long[] timesheetIds) {
return toAjax(erpTimesheetInfoService.deleteWithValidByIds(List.of(timesheetIds), true));
}
/**
*
*/
@GetMapping("/getErpTimesheetInfoList")
public R<List<ErpTimesheetInfoVo>> getErpTimesheetInfoList(ErpTimesheetInfoBo bo) {
List<ErpTimesheetInfoVo> list = erpTimesheetInfoService.queryList(bo);
return R.ok(list);
}
}

@ -0,0 +1,116 @@
package org.dromara.oa.erp.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.oa.erp.domain.vo.ErpTimesheetProjectVo;
import org.dromara.oa.erp.domain.bo.ErpTimesheetProjectBo;
import org.dromara.oa.erp.service.IErpTimesheetProjectService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
*
* 访:/oa/erp/timesheetProject
*
* @author Yangk
* @date 2025-12-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/erp/timesheetProject")
public class ErpTimesheetProjectController extends BaseController {
private final IErpTimesheetProjectService erpTimesheetProjectService;
/**
*
*/
@SaCheckPermission("oa/erp:timesheetProject:list")
@GetMapping("/list")
public TableDataInfo<ErpTimesheetProjectVo> list(ErpTimesheetProjectBo bo, PageQuery pageQuery) {
return erpTimesheetProjectService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("oa/erp:timesheetProject:export")
@Log(title = "项目工作明细", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ErpTimesheetProjectBo bo, HttpServletResponse response) {
List<ErpTimesheetProjectVo> list = erpTimesheetProjectService.queryList(bo);
ExcelUtil.exportExcel(list, "项目工作明细", ErpTimesheetProjectVo.class, response);
}
/**
*
*
* @param timesheetProjectId
*/
@SaCheckPermission("oa/erp:timesheetProject:query")
@GetMapping("/{timesheetProjectId}")
public R<ErpTimesheetProjectVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("timesheetProjectId") Long timesheetProjectId) {
return R.ok(erpTimesheetProjectService.queryById(timesheetProjectId));
}
/**
*
*/
@SaCheckPermission("oa/erp:timesheetProject:add")
@Log(title = "项目工作明细", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ErpTimesheetProjectBo bo) {
return toAjax(erpTimesheetProjectService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("oa/erp:timesheetProject:edit")
@Log(title = "项目工作明细", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ErpTimesheetProjectBo bo) {
return toAjax(erpTimesheetProjectService.updateByBo(bo));
}
/**
*
*
* @param timesheetProjectIds
*/
@SaCheckPermission("oa/erp:timesheetProject:remove")
@Log(title = "项目工作明细", businessType = BusinessType.DELETE)
@DeleteMapping("/{timesheetProjectIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("timesheetProjectIds") Long[] timesheetProjectIds) {
return toAjax(erpTimesheetProjectService.deleteWithValidByIds(List.of(timesheetProjectIds), true));
}
/**
*
*/
@GetMapping("/getErpTimesheetProjectList")
public R<List<ErpTimesheetProjectVo>> getErpTimesheetProjectList(ErpTimesheetProjectBo bo) {
List<ErpTimesheetProjectVo> list = erpTimesheetProjectService.queryList(bo);
return R.ok(list);
}
}

@ -79,7 +79,7 @@ public class ErpProjectReportDetail extends TenantEntity {
/**
*
*/
private Long plannedCompletionRate;
private Double plannedCompletionRate;
/**
*

@ -0,0 +1,68 @@
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;
import java.math.BigDecimal;
/**
* erp_timesheet_dept
*
* @author Yangk
* @date 2025-12-09
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_timesheet_dept")
public class ErpTimesheetDept extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "timesheet_dept_id", type = IdType.ASSIGN_ID)
private Long timesheetDeptId;
/**
* ID
*/
private Long timesheetId;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String workDescription;
/**
* ID
*/
private Long deptId;
/**
* 线ID
*/
private Long deptManagerId;
/**
*
*/
private BigDecimal hours;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,96 @@
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.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* erp_timesheet_info
*
* @author Yangk
* @date 2025-12-09
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_timesheet_info")
public class ErpTimesheetInfo extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "timesheet_id", type = IdType.ASSIGN_ID)
private Long timesheetId;
/**
*
*/
private String timesheetCode;
/**
* ID
*/
private Long userId;
/**
* ID
*/
private Long deptId;
/**
*
*/
private Date startTime;
/**
*
*/
private Date endTime;
/**
*
*/
private BigDecimal totalHours;
/**
*
*/
private BigDecimal deptHours;
/**
*
*/
private BigDecimal projectHours;
/**
* 1 2 3 4
*/
private String timesheetStatus;
/**
*
*/
private String flowStatus;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,78 @@
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;
import java.math.BigDecimal;
/**
* erp_timesheet_project
*
* @author Yangk
* @date 2025-12-09
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("erp_timesheet_project")
public class ErpTimesheetProject extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "timesheet_project_id", type = IdType.ASSIGN_ID)
private Long timesheetProjectId;
/**
* ID
*/
private Long timesheetId;
/**
*
*/
private Long sortOrder;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String projectCode;
/**
*
*/
private String projectName;
/**
* ID
*/
private Long projectManagerId;
/**
* ID
*/
private Long deptId;
/**
*
*/
private BigDecimal hours;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -172,13 +172,11 @@ public class ErpAfterSalesBo extends BaseEntity {
/**
*
* JSON "laborCostsList": [...]
*/
private List<ErpAfterSalesLaborCostsBo> laborCostsList;
/**
*
* JSON "materialCostsList": [...]
*/
private List<ErpAfterSalesMaterialCostsBo> materialCostsList;
@ -188,7 +186,7 @@ public class ErpAfterSalesBo extends BaseEntity {
private String flowCode;
/**
* {'entity': {}}
*
*/
private Map<String, Object> variables;

@ -80,7 +80,7 @@ public class ErpProjectReportDetailBo extends BaseEntity {
/**
*
*/
private Long plannedCompletionRate;
private Double plannedCompletionRate;
/**
*

@ -0,0 +1,61 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpTimesheetDept;
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_timesheet_dept
*
* @author Yangk
* @date 2025-12-09
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpTimesheetDept.class, reverseConvertGenerate = false)
public class ErpTimesheetDeptBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "部门工作ID不能为空", groups = { EditGroup.class })
private Long timesheetDeptId;
/**
* ID
*/
@NotNull(message = "工时填报ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long timesheetId;
/**
*
*/
private Long sortOrder;
/**
*
*/
private String workDescription;
/**
* ID
*/
private Long deptId;
/**
* 线ID
*/
private Long deptManagerId;
/**
*
*/
private Long hours;
}

@ -0,0 +1,120 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpTimesheetInfo;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt;
/**
* erp_timesheet_info
*
* @author Yangk
* @date 2025-12-09
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpTimesheetInfo.class, reverseConvertGenerate = false)
public class ErpTimesheetInfoBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "工时填报ID不能为空", groups = { EditGroup.class })
private Long timesheetId;
/**
*
*/
@NotBlank(message = "工时填报编号不能为空", groups = { AddGroup.class, EditGroup.class })
private String timesheetCode;
/**
* ID
*/
@NotNull(message = "人员ID填报人不能为空", groups = { AddGroup.class, EditGroup.class })
private Long userId;
/**
* ID
*/
private Long deptId;
/**
*
*/
@NotNull(message = "起始时间(自然周的周一)不能为空", groups = { AddGroup.class, EditGroup.class })
private Date startTime;
/**
*
*/
@NotNull(message = "结束时间(自然周的周日)不能为空", groups = { AddGroup.class, EditGroup.class })
private Date endTime;
/**
*
*/
private Long totalHours;
/**
*
*/
private Long deptHours;
/**
*
*/
private Long projectHours;
/**
* 1 2 3 4
*/
private String timesheetStatus;
/**
*
*/
private String flowStatus;
/**
*
*/
private String remark;
/**
*
*/
private List<ErpTimesheetDeptBo> timesheetDeptList;
/**
*
*/
private List<ErpTimesheetProjectBo> timesheetProjectList;
/**
*
*/
private String flowCode;
/**
*
*/
private Map<String, Object> variables;
/**
*
*/
private RemoteFlowInstanceBizExt bizExt;
}

@ -0,0 +1,71 @@
package org.dromara.oa.erp.domain.bo;
import org.dromara.oa.erp.domain.ErpTimesheetProject;
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_timesheet_project
*
* @author Yangk
* @date 2025-12-09
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ErpTimesheetProject.class, reverseConvertGenerate = false)
public class ErpTimesheetProjectBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "项目工作ID不能为空", groups = { EditGroup.class })
private Long timesheetProjectId;
/**
* ID
*/
@NotNull(message = "工时填报ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long timesheetId;
/**
*
*/
private Long sortOrder;
/**
* ID
*/
private Long projectId;
/**
*
*/
private String projectCode;
/**
*
*/
private String projectName;
/**
* ID
*/
private Long projectManagerId;
/**
* ID
*/
private Long deptId;
/**
*
*/
private Long hours;
}

@ -1,7 +1,11 @@
package org.dromara.oa.erp.domain.vo;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.List;
import java.io.Serial;
import java.io.Serializable;
import org.dromara.oa.erp.domain.ErpAfterSales;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
@ -9,14 +13,6 @@ import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.oa.erp.domain.vo.ErpAfterSalesLaborCostsVo;
import org.dromara.oa.erp.domain.vo.ErpAfterSalesMaterialCostsVo;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* erp_after_sales
@ -35,7 +31,6 @@ public class ErpAfterSalesVo implements Serializable {
/**
* ID
*/
@ExcelProperty(value = "售后ID")
private Long afterSalesId;
/**
@ -50,29 +45,14 @@ public class ErpAfterSalesVo implements Serializable {
@ExcelProperty(value = "售后主题")
private String afterSalesSubject;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "项目编号")
private String projectCode;
/**
*
*/
@ExcelProperty(value = "项目名称")
private String projectName;
/**
* ID
*/
@ExcelProperty(value = "客户ID")
private Long customerId;
private Long projectId;
private String projectCode;
/**
*
@ -80,6 +60,8 @@ public class ErpAfterSalesVo implements Serializable {
@ExcelProperty(value = "客户名称")
private String customerName;
private Long customerId;
/**
*
*/
@ -98,18 +80,14 @@ public class ErpAfterSalesVo implements Serializable {
@ExcelProperty(value = "售后日期")
private Date afterSalesDate;
/**
* ID
*/
@ExcelProperty(value = "合同ID")
private Long contractId;
/**
*
*/
@ExcelProperty(value = "合同号")
private String contractCode;
private Long contractId;
/**
*
*/
@ -118,19 +96,27 @@ public class ErpAfterSalesVo implements Serializable {
private String afterSalesType;
/**
* ID
* ID
*/
@ExcelProperty(value = "客户干系人ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=联客户联系人表")
private String stakeholderId;
/**
* ID
*
*/
@ExcelProperty(value = "客户干系人")
private String stakeholderName;
/**
* ID
*/
@ExcelProperty(value = "处理人ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=联用户表")
private String handlerId;
/**
*
*/
@ExcelProperty(value = "处理人")
private String handlerName;
/**
*
*/
@ -141,18 +127,18 @@ public class ErpAfterSalesVo implements Serializable {
*
*/
@ExcelProperty(value = "售后总工时")
private Long totalWorkHours;
private BigDecimal totalWorkHours;
/**
*
*/
@ExcelProperty(value = "售后总成本")
private Long totalCost;
private BigDecimal totalCost;
/**
* 0 1 2
*
*/
@ExcelProperty(value = "售后问题是否解决", converter = ExcelDictConvert.class)
@ExcelProperty(value = "解决状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "solve_status")
private String solveStatus;
@ -169,7 +155,7 @@ public class ErpAfterSalesVo implements Serializable {
private String processingResult;
/**
* 0 1 2
*
*/
@ExcelProperty(value = "售后状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "after_sales_status")
@ -178,15 +164,12 @@ public class ErpAfterSalesVo implements Serializable {
/**
*
*/
@ExcelProperty(value = "流程状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "flow_status")
@ExcelProperty(value = "流程状态")
private String flowStatus;
/**
* 1 0
*
*/
@ExcelProperty(value = "激活标识", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "active_flag")
private String activeFlag;
/**
@ -200,16 +183,4 @@ public class ErpAfterSalesVo implements Serializable {
*/
private List<ErpAfterSalesLaborCostsVo> laborCostsList;
private List<ErpAfterSalesMaterialCostsVo> materialCostsList;
/**
*
*/
private String stakeholderName;
/**
*
*/
private String handlerName;
}

@ -2,6 +2,7 @@ package org.dromara.oa.erp.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat;
@ -30,7 +31,7 @@ public class ErpProjectReportDetailVo implements Serializable {
/**
* ID
*/
@ExcelProperty(value = "项目周报明细ID")
// @ExcelProperty(value = "项目周报明细ID")
private Long reportDetailId;
/**
@ -44,11 +45,34 @@ public class ErpProjectReportDetailVo implements Serializable {
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
// @ExcelProperty(value = "部门名称")
private String deptName;
/**
*
*/
// @ExcelProperty(value = "项目经理名称")
private String managerName;
/**
*
*/
// @ExcelProperty(value = "部门负责人名称")
private String chargeName;
/**
*
*/
// @ExcelProperty(value = "分管副总名称")
private String deputyName;
/**
*
*/
@ExcelProperty(value = "填写日期")
@ColumnWidth(20) // 设置列宽为20个字符
private Date fillTime;
/**
@ -91,7 +115,7 @@ public class ErpProjectReportDetailVo implements Serializable {
*
*/
@ExcelProperty(value = "计划完成率")
private Long plannedCompletionRate;
private Double plannedCompletionRate;
/**
*
@ -109,7 +133,8 @@ public class ErpProjectReportDetailVo implements Serializable {
/**
* (1 2 3)
*/
@ExcelProperty(value = "周报状态(1暂存 2审批中 3可用)")
@ExcelProperty(value = "周报状态(1暂存 2审批中 3可用)", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "1=暂存,2=审批中,3=可用")
private String projectReportStatus;
/**
@ -121,7 +146,7 @@ public class ErpProjectReportDetailVo implements Serializable {
/**
*
*/
@ExcelProperty(value = "排序号")
// @ExcelProperty(value = "排序号")
private Long sortOrder;
/**
@ -151,32 +176,10 @@ public class ErpProjectReportDetailVo implements Serializable {
/**
* 1 0
*/
@ExcelProperty(value = "激活标识", converter = ExcelDictConvert.class)
// @ExcelProperty(value = "激活标识", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "1=是,0=否")
private String activeFlag;
/**
*
*/
@ExcelProperty(value = "部门名称")
private String deptName;
/**
*
*/
@ExcelProperty(value = "项目经理名称")
private String managerName;
/**
*
*/
@ExcelProperty(value = "部门负责人名称")
private String chargeName;
/**
*
*/
@ExcelProperty(value = "分管副总名称")
private String deputyName;
}

@ -0,0 +1,74 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpTimesheetDept;
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_timesheet_dept
*
* @author Yangk
* @date 2025-12-09
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpTimesheetDept.class)
public class ErpTimesheetDeptVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "部门工作ID")
private Long timesheetDeptId;
/**
* ID
*/
@ExcelProperty(value = "工时填报ID")
private Long timesheetId;
/**
*
*/
@ExcelProperty(value = "序号")
private Long sortOrder;
/**
*
*/
@ExcelProperty(value = "部门工作描述")
private String workDescription;
/**
* ID
*/
@ExcelProperty(value = "部门ID")
private Long deptId;
/**
* 线ID
*/
@ExcelProperty(value = "部门直线经理ID")
private Long deptManagerId;
/**
*
*/
@ExcelProperty(value = "工时")
private Long hours;
}

@ -0,0 +1,120 @@
package org.dromara.oa.erp.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.dromara.oa.erp.domain.ErpTimesheetInfo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* erp_timesheet_info
*
* @author Yangk
* @date 2025-12-09
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpTimesheetInfo.class)
public class ErpTimesheetInfoVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "工时填报ID")
private Long timesheetId;
/**
*
*/
@ExcelProperty(value = "工时填报编号")
private String timesheetCode;
/**
* ID
*/
@ExcelProperty(value = "人员ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "填=报人")
private Long userId;
/**
* ID
*/
@ExcelProperty(value = "部门ID")
private Long deptId;
/**
*
*/
@ExcelProperty(value = "起始时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "自=然周的周一")
private Date startTime;
/**
*
*/
@ExcelProperty(value = "结束时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "自=然周的周日")
private Date endTime;
/**
*
*/
@ExcelProperty(value = "总工时", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "自=动累计")
private Long totalHours;
/**
*
*/
@ExcelProperty(value = "部门工时", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "根=据部门工作自动累计")
private Long deptHours;
/**
*
*/
@ExcelProperty(value = "项目工时", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "根=据项目工作自动累计")
private Long projectHours;
/**
* 1 2 3 4
*/
@ExcelProperty(value = "工时填报状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "timesheet_status")
private String timesheetStatus;
/**
*
*/
@ExcelProperty(value = "流程状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "flow_status")
private String flowStatus;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
/**
*
*/
private List<ErpTimesheetDeptVo> timesheetDeptList;
private List<ErpTimesheetProjectVo> timesheetProjectList;
}

@ -0,0 +1,86 @@
package org.dromara.oa.erp.domain.vo;
import org.dromara.oa.erp.domain.ErpTimesheetProject;
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_timesheet_project
*
* @author Yangk
* @date 2025-12-09
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ErpTimesheetProject.class)
public class ErpTimesheetProjectVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "项目工作ID")
private Long timesheetProjectId;
/**
* ID
*/
@ExcelProperty(value = "工时填报ID")
private Long timesheetId;
/**
*
*/
@ExcelProperty(value = "序号")
private Long sortOrder;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
*
*/
@ExcelProperty(value = "项目号")
private String projectCode;
/**
*
*/
@ExcelProperty(value = "项目名称")
private String projectName;
/**
* ID
*/
@ExcelProperty(value = "项目经理ID")
private Long projectManagerId;
/**
* ID
*/
@ExcelProperty(value = "部门ID")
private Long deptId;
/**
*
*/
@ExcelProperty(value = "工时")
private Long hours;
}

@ -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.ErpTimesheetDept;
import org.dromara.oa.erp.domain.vo.ErpTimesheetDeptVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author Yangk
* @date 2025-12-09
*/
public interface ErpTimesheetDeptMapper extends BaseMapperPlus<ErpTimesheetDept, ErpTimesheetDeptVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpTimesheetDeptVo> selectCustomErpTimesheetDeptVoList(@Param("page") Page<ErpTimesheetDeptVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpTimesheetDept> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpTimesheetDeptVo> selectCustomErpTimesheetDeptVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpTimesheetDept> 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.ErpTimesheetInfo;
import org.dromara.oa.erp.domain.vo.ErpTimesheetInfoVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author Yangk
* @date 2025-12-09
*/
public interface ErpTimesheetInfoMapper extends BaseMapperPlus<ErpTimesheetInfo, ErpTimesheetInfoVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpTimesheetInfoVo> selectCustomErpTimesheetInfoVoList(@Param("page") Page<ErpTimesheetInfoVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpTimesheetInfo> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpTimesheetInfoVo> selectCustomErpTimesheetInfoVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpTimesheetInfo> 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.ErpTimesheetProject;
import org.dromara.oa.erp.domain.vo.ErpTimesheetProjectVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* Mapper
*
* @author Yangk
* @date 2025-12-09
*/
public interface ErpTimesheetProjectMapper extends BaseMapperPlus<ErpTimesheetProject, ErpTimesheetProjectVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<ErpTimesheetProjectVo> selectCustomErpTimesheetProjectVoList(@Param("page") Page<ErpTimesheetProjectVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpTimesheetProject> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<ErpTimesheetProjectVo> selectCustomErpTimesheetProjectVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpTimesheetProject> queryWrapper);
}

@ -71,9 +71,10 @@ public interface IErpProjectReportDetailService {
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
*
*
* @param
* @return
*/
ErpProjectReportDetailVo projectReportSubmitAndFlowStart(ErpProjectReportBo projectReport, ErpProjectReportDetailBo projectDetailReport);
}

@ -0,0 +1,70 @@
package org.dromara.oa.erp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.oa.erp.domain.ErpTimesheetDept;
import org.dromara.oa.erp.domain.vo.ErpTimesheetDeptVo;
import org.dromara.oa.erp.domain.bo.ErpTimesheetDeptBo;
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 Yangk
* @date 2025-12-09
*/
public interface IErpTimesheetDeptService extends IService<ErpTimesheetDept> {
/**
*
*
* @param timesheetDeptId
* @return
*/
ErpTimesheetDeptVo queryById(Long timesheetDeptId);
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
TableDataInfo<ErpTimesheetDeptVo> queryPageList(ErpTimesheetDeptBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
List<ErpTimesheetDeptVo> queryList(ErpTimesheetDeptBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(ErpTimesheetDeptBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(ErpTimesheetDeptBo bo);
/**
*
*
* @param ids
* @param isValid
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

@ -0,0 +1,79 @@
package org.dromara.oa.erp.service;
import org.dromara.oa.erp.domain.ErpTimesheetInfo;
import org.dromara.oa.erp.domain.bo.ErpAfterSalesBo;
import org.dromara.oa.erp.domain.vo.ErpAfterSalesVo;
import org.dromara.oa.erp.domain.vo.ErpTimesheetDeptVo;
import org.dromara.oa.erp.domain.vo.ErpTimesheetInfoVo;
import org.dromara.oa.erp.domain.bo.ErpTimesheetInfoBo;
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 Yangk
* @date 2025-12-09
*/
public interface IErpTimesheetInfoService {
/**
*
*
* @param timesheetId
* @return
*/
ErpTimesheetInfoVo queryById(Long timesheetId);
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
TableDataInfo<ErpTimesheetInfoVo> queryPageList(ErpTimesheetInfoBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
List<ErpTimesheetInfoVo> queryList(ErpTimesheetInfoBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(ErpTimesheetInfoBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(ErpTimesheetInfoBo bo);
/**
*
*
* @param ids
* @param isValid
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
*
* @param bo
* @return
*/
ErpTimesheetInfoVo submitAndFlowStart(ErpTimesheetInfoBo bo);
}

@ -0,0 +1,70 @@
package org.dromara.oa.erp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.oa.erp.domain.ErpTimesheetProject;
import org.dromara.oa.erp.domain.vo.ErpTimesheetProjectVo;
import org.dromara.oa.erp.domain.bo.ErpTimesheetProjectBo;
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 Yangk
* @date 2025-12-09
*/
public interface IErpTimesheetProjectService extends IService<ErpTimesheetProject> {
/**
*
*
* @param timesheetProjectId
* @return
*/
ErpTimesheetProjectVo queryById(Long timesheetProjectId);
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
TableDataInfo<ErpTimesheetProjectVo> queryPageList(ErpTimesheetProjectBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
List<ErpTimesheetProjectVo> queryList(ErpTimesheetProjectBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(ErpTimesheetProjectBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(ErpTimesheetProjectBo bo);
/**
*
*
* @param ids
* @param isValid
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

@ -159,7 +159,7 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class) // 【重要】开启事务!如果子表保存失败,主表也要回滚,防止数据不一致
@Transactional(rollbackFor = Exception.class) // 开启事务!如果子表保存失败,主表也要回滚,防止数据不一致
public Boolean insertByBo(ErpAfterSalesBo bo) {
ErpAfterSales add = MapstructUtils.convert(bo, ErpAfterSales.class);
@ -195,7 +195,7 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class) // 【重要】开启事务
@Transactional(rollbackFor = Exception.class) // 开启事务
public Boolean updateByBo(ErpAfterSalesBo bo) {
ErpAfterSales update = MapstructUtils.convert(bo, ErpAfterSales.class);
validEntityBeforeSave(update);
@ -216,7 +216,7 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
// 遍历列表,清空 ID
laborList.forEach(item -> {
item.setLaborCostsId(null); // 关键:清空ID让MP重新生成雪花ID避免和逻辑删除的数据冲突
item.setLaborCostsId(null); // 清空ID让MP重新生成雪花ID避免和逻辑删除的数据冲突
item.setAfterSalesId(afterSalesId);
});
@ -232,7 +232,7 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
List<ErpAfterSalesMaterialCosts> materialList = MapstructUtils.convert(materialBoList, ErpAfterSalesMaterialCosts.class);
materialList.forEach(item -> {
item.setMaterialCostsId(null); // 关键清空ID
item.setMaterialCostsId(null);
item.setAfterSalesId(afterSalesId);
});

@ -84,6 +84,7 @@ public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetai
@Override
public TableDataInfo<ErpProjectReportDetailVo> queryPageList(ErpProjectReportDetailBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpProjectReportDetail> lqw = buildQueryWrapper(bo);
lqw.orderByDesc(ErpProjectReportDetail::getFillTime);
Page<ErpProjectReportDetailVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@ -179,8 +180,7 @@ public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetai
}
/**
*
*
*
* @param projectReport
* @param projectDetailReport
* @return
@ -194,9 +194,13 @@ public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetai
erpProjectReportService.updateByBo(projectReport);
} else {
erpProjectReportService.insertByBo(projectReport);
projectDetailReport.setReportId(projectReport.getReportId());
projectDetailReport.setProjectId(projectReport.getProjectId());
}
} else {
erpProjectReportService.insertByBo(projectReport);
projectDetailReport.setReportId(projectReport.getReportId());
projectDetailReport.setProjectId(projectReport.getProjectId());
}
ErpProjectReportDetail erpProjectReportDetail = MapstructUtils.convert(projectDetailReport, ErpProjectReportDetail.class);
validEntityBeforeSave(erpProjectReportDetail);

@ -10,11 +10,15 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.oa.erp.domain.ErpProjectContracts;
import org.dromara.oa.erp.domain.ErpProjectReport;
import org.dromara.oa.erp.domain.ErpProjectReportDetail;
import org.dromara.oa.erp.domain.bo.ErpProjectReportBo;
import org.dromara.oa.erp.domain.vo.ErpProjectReportVo;
import org.dromara.oa.erp.mapper.ErpProjectReportDetailMapper;
import org.dromara.oa.erp.mapper.ErpProjectReportMapper;
import org.dromara.oa.erp.service.IErpProjectReportDetailService;
import org.dromara.oa.erp.service.IErpProjectReportService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
@ -32,6 +36,9 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService {
private final ErpProjectReportMapper baseMapper;
private final ErpProjectReportDetailMapper erpProjectReportDetailMapper;
/**
*
*
@ -78,7 +85,6 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService {
MPJLambdaWrapper<ErpProjectReport> lqw = JoinWrappers.lambda(ErpProjectReport.class)
.selectAll(ErpProjectReport.class)
.eq(bo.getProjectId() != null, ErpProjectReport::getProjectId, bo.getProjectId())
.eq(StringUtils.isNotBlank(bo.getMilestonePlan()), ErpProjectReport::getMilestonePlan, bo.getMilestonePlan())
.eq(bo.getManagerId() != null, ErpProjectReport::getManagerId, bo.getManagerId())
.eq(bo.getDeptId() != null, ErpProjectReport::getDeptId, bo.getDeptId())
.eq(bo.getChargeId() != null, ErpProjectReport::getChargeId, bo.getChargeId())
@ -88,6 +94,7 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService {
.eq(StringUtils.isNotBlank(bo.getOssId()), ErpProjectReport::getOssId, bo.getOssId())
.eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectReport::getActiveFlag, bo.getActiveFlag())
.eq("t.del_flag", "0")
.like(StringUtils.isNotBlank(bo.getMilestonePlan()), ErpProjectReport::getMilestonePlan, bo.getMilestonePlan())
.like(StringUtils.isNotBlank(bo.getProjectName()), ErpProjectReport::getProjectName, bo.getProjectName())
.like(StringUtils.isNotBlank(bo.getProjectCode()), ErpProjectReport::getProjectCode, bo.getProjectCode())
.apply(StringUtils.isNotBlank(bo.getDeptName()), "d.dept_name LIKE CONCAT('%', {0}, '%')", bo.getDeptName())
@ -143,10 +150,16 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService {
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
boolean p = baseMapper.deleteByIds(ids) > 0;
// 构建删除条件根据reportIds删除所有相关的明细
MPJLambdaWrapper<ErpProjectReportDetail> wrapper = JoinWrappers.lambda(ErpProjectReportDetail.class)
.in(ErpProjectReportDetail::getReportId, ids);
boolean pd = erpProjectReportDetailMapper.delete(wrapper) > 0;
return p && pd;
}
}

@ -0,0 +1,141 @@
package org.dromara.oa.erp.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.oa.erp.domain.bo.ErpTimesheetDeptBo;
import org.dromara.oa.erp.domain.vo.ErpTimesheetDeptVo;
import org.dromara.oa.erp.domain.ErpTimesheetDept;
import org.dromara.oa.erp.mapper.ErpTimesheetDeptMapper;
import org.dromara.oa.erp.service.IErpTimesheetDeptService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* Service
*
* @author Yangk
* @date 2025-12-09
*/
@RequiredArgsConstructor
@Service
public class ErpTimesheetDeptServiceImpl
extends ServiceImpl<ErpTimesheetDeptMapper, ErpTimesheetDept>
implements IErpTimesheetDeptService {
private final ErpTimesheetDeptMapper baseMapper;
/**
*
*
* @param timesheetDeptId
* @return
*/
@Override
public ErpTimesheetDeptVo queryById(Long timesheetDeptId){
return baseMapper.selectVoById(timesheetDeptId);
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<ErpTimesheetDeptVo> queryPageList(ErpTimesheetDeptBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpTimesheetDept> lqw = buildQueryWrapper(bo);
Page<ErpTimesheetDeptVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*
* @param bo
* @return
*/
@Override
public List<ErpTimesheetDeptVo> queryList(ErpTimesheetDeptBo bo) {
MPJLambdaWrapper<ErpTimesheetDept> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private MPJLambdaWrapper<ErpTimesheetDept> buildQueryWrapper(ErpTimesheetDeptBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpTimesheetDept> lqw = JoinWrappers.lambda(ErpTimesheetDept.class)
.selectAll(ErpTimesheetDept.class)
.eq(ErpTimesheetDept::getDelFlag, "0")
.eq(bo.getTimesheetId() != null, ErpTimesheetDept::getTimesheetId, bo.getTimesheetId())
.eq(bo.getSortOrder() != null, ErpTimesheetDept::getSortOrder, bo.getSortOrder())
.eq(StringUtils.isNotBlank(bo.getWorkDescription()), ErpTimesheetDept::getWorkDescription, bo.getWorkDescription())
.eq(bo.getDeptId() != null, ErpTimesheetDept::getDeptId, bo.getDeptId())
.eq(bo.getDeptManagerId() != null, ErpTimesheetDept::getDeptManagerId, bo.getDeptManagerId())
.eq(bo.getHours() != null, ErpTimesheetDept::getHours, bo.getHours())
;
return lqw;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean insertByBo(ErpTimesheetDeptBo bo) {
ErpTimesheetDept add = MapstructUtils.convert(bo, ErpTimesheetDept.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setTimesheetDeptId(add.getTimesheetDeptId());
}
return flag;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean updateByBo(ErpTimesheetDeptBo bo) {
ErpTimesheetDept update = MapstructUtils.convert(bo, ErpTimesheetDept.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
*
*/
private void validEntityBeforeSave(ErpTimesheetDept 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,281 @@
package org.dromara.oa.erp.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.oa.erp.domain.ErpTimesheetDept;
import org.dromara.oa.erp.domain.ErpTimesheetProject;
import org.dromara.oa.erp.domain.bo.ErpTimesheetDeptBo;
import org.dromara.oa.erp.domain.bo.ErpTimesheetProjectBo;
import org.dromara.oa.erp.domain.vo.ErpTimesheetDeptVo;
import org.dromara.oa.erp.domain.vo.ErpTimesheetProjectVo;
import org.dromara.oa.erp.service.IErpTimesheetDeptService;
import org.dromara.oa.erp.service.IErpTimesheetProjectService;
import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.springframework.stereotype.Service;
import org.dromara.oa.erp.domain.bo.ErpTimesheetInfoBo;
import org.dromara.oa.erp.domain.vo.ErpTimesheetInfoVo;
import org.dromara.oa.erp.domain.ErpTimesheetInfo;
import org.dromara.oa.erp.mapper.ErpTimesheetInfoMapper;
import org.dromara.oa.erp.service.IErpTimesheetInfoService;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* Service
*
* @author Yangk
* @date 2025-12-09
*/
@RequiredArgsConstructor
@Service
public class ErpTimesheetInfoServiceImpl implements IErpTimesheetInfoService {
private final ErpTimesheetInfoMapper baseMapper;
@DubboReference(timeout = 30000)
private RemoteWorkflowService remoteWorkflowService;
private final IErpTimesheetDeptService timesheetDeptService;
private final IErpTimesheetProjectService timesheetProjectService;
/**
*
*
* @param timesheetId
* @return
*/
@Override
public ErpTimesheetInfoVo queryById(Long timesheetId) {
ErpTimesheetInfoVo vo = baseMapper.selectVoById(timesheetId);
if (vo != null) {
// 回显部门工时
List<ErpTimesheetDept> deptList = timesheetDeptService.list(
new LambdaQueryWrapper<ErpTimesheetDept>().eq(ErpTimesheetDept::getTimesheetId, timesheetId)
);
vo.setTimesheetDeptList(MapstructUtils.convert(deptList, ErpTimesheetDeptVo.class));
// 回显项目工时
List<ErpTimesheetProject> projectList = timesheetProjectService.list(
new LambdaQueryWrapper<ErpTimesheetProject>().eq(ErpTimesheetProject::getTimesheetId, timesheetId)
);
vo.setTimesheetProjectList(MapstructUtils.convert(projectList, ErpTimesheetProjectVo.class));
}
return vo;
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<ErpTimesheetInfoVo> queryPageList(ErpTimesheetInfoBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpTimesheetInfo> lqw = buildQueryWrapper(bo);
Page<ErpTimesheetInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*
* @param bo
* @return
*/
@Override
public List<ErpTimesheetInfoVo> queryList(ErpTimesheetInfoBo bo) {
MPJLambdaWrapper<ErpTimesheetInfo> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private MPJLambdaWrapper<ErpTimesheetInfo> buildQueryWrapper(ErpTimesheetInfoBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpTimesheetInfo> lqw = JoinWrappers.lambda(ErpTimesheetInfo.class)
.selectAll(ErpTimesheetInfo.class)
.eq(ErpTimesheetInfo::getDelFlag, "0")
.eq(StringUtils.isNotBlank(bo.getTimesheetCode()), ErpTimesheetInfo::getTimesheetCode, bo.getTimesheetCode())
.eq(bo.getUserId() != null, ErpTimesheetInfo::getUserId, bo.getUserId())
.eq(bo.getDeptId() != null, ErpTimesheetInfo::getDeptId, bo.getDeptId())
.eq(bo.getStartTime() != null, ErpTimesheetInfo::getStartTime, bo.getStartTime())
.eq(bo.getEndTime() != null, ErpTimesheetInfo::getEndTime, bo.getEndTime())
.eq(bo.getTotalHours() != null, ErpTimesheetInfo::getTotalHours, bo.getTotalHours())
.eq(bo.getDeptHours() != null, ErpTimesheetInfo::getDeptHours, bo.getDeptHours())
.eq(bo.getProjectHours() != null, ErpTimesheetInfo::getProjectHours, bo.getProjectHours())
.eq(StringUtils.isNotBlank(bo.getTimesheetStatus()), ErpTimesheetInfo::getTimesheetStatus, bo.getTimesheetStatus())
.eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpTimesheetInfo::getFlowStatus, bo.getFlowStatus())
;
return lqw;
}
/**
*
*
* @param bo
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(ErpTimesheetInfoBo bo) {
ErpTimesheetInfo add = MapstructUtils.convert(bo, ErpTimesheetInfo.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
// 回填 ID 给 BO
bo.setTimesheetId(add.getTimesheetId());
Long timesheetId = add.getTimesheetId();
// 保存部门工时子表
List<ErpTimesheetDeptBo> deptBoList = bo.getTimesheetDeptList();
if (CollUtil.isNotEmpty(deptBoList)) {
List<ErpTimesheetDept> list = MapstructUtils.convert(deptBoList, ErpTimesheetDept.class);
list.forEach(item -> item.setTimesheetId(timesheetId));
timesheetDeptService.saveBatch(list);
}
// 保存项目工时子表
List<ErpTimesheetProjectBo> projectBoList = bo.getTimesheetProjectList();
if (CollUtil.isNotEmpty(projectBoList)) {
List<ErpTimesheetProject> list = MapstructUtils.convert(projectBoList, ErpTimesheetProject.class);
list.forEach(item -> item.setTimesheetId(timesheetId));
timesheetProjectService.saveBatch(list);
}
}
return flag;
}
/**
*
*
* @param bo
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateByBo(ErpTimesheetInfoBo bo) {
ErpTimesheetInfo update = MapstructUtils.convert(bo, ErpTimesheetInfo.class);
validEntityBeforeSave(update);
int row = baseMapper.updateById(update);
if (row > 0) {
Long timesheetId = bo.getTimesheetId();
// 更新部门工时 (先删后增)
timesheetDeptService.remove(new LambdaQueryWrapper<ErpTimesheetDept>()
.eq(ErpTimesheetDept::getTimesheetId, timesheetId));
List<ErpTimesheetDeptBo> deptBoList = bo.getTimesheetDeptList();
if (CollUtil.isNotEmpty(deptBoList)) {
List<ErpTimesheetDept> list = MapstructUtils.convert(deptBoList, ErpTimesheetDept.class);
list.forEach(item -> {
item.setTimesheetDeptId(null); // 清空子表ID防止逻辑删除冲突
item.setTimesheetId(timesheetId);
});
timesheetDeptService.saveBatch(list);
}
// 更新项目工时 (先删后增)
timesheetProjectService.remove(new LambdaQueryWrapper<ErpTimesheetProject>()
.eq(ErpTimesheetProject::getTimesheetId, timesheetId));
List<ErpTimesheetProjectBo> projectBoList = bo.getTimesheetProjectList();
if (CollUtil.isNotEmpty(projectBoList)) {
List<ErpTimesheetProject> list = MapstructUtils.convert(projectBoList, ErpTimesheetProject.class);
list.forEach(item -> {
item.setTimesheetProjectId(null);
item.setTimesheetId(timesheetId);
});
timesheetProjectService.saveBatch(list);
}
}
return row > 0;
}
/**
*
*/
private void validEntityBeforeSave(ErpTimesheetInfo entity){
//TODO 做一些数据校验,如唯一约束
}
/**
*
*
* @param ids
* @param isValid
* @return
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
*
*
* @param bo
* @return
*/
@Override
@GlobalTransactional(rollbackFor = Exception.class) // 开启全局事务
public ErpTimesheetInfoVo submitAndFlowStart(ErpTimesheetInfoBo bo) {
ErpTimesheetInfo add = MapstructUtils.convert(bo, ErpTimesheetInfo.class);
validEntityBeforeSave(add);
if (bo.getTimesheetId() == null) {
this.insertByBo(bo);
} else {
this.updateByBo(bo);
}
// 准备启动流程参数
// 后端发起需要忽略权限
if (bo.getVariables() == null) {
bo.setVariables(new HashMap<>());
}
bo.getVariables().put("ignore", true);
RemoteStartProcess startProcess = new RemoteStartProcess();
startProcess.setBusinessId(bo.getTimesheetId().toString());
startProcess.setFlowCode(bo.getFlowCode());
startProcess.setVariables(bo.getVariables());
startProcess.setBizExt(bo.getBizExt());
// 确保 BizExt 里也有 BusinessId
if (bo.getBizExt() != null) {
bo.getBizExt().setBusinessId(startProcess.getBusinessId());
}
// 调用远程服务启动流程
// startCompleteTask 表示“启动并自动完成第一个发起节点”,直接流转到下一个审批人
boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess);
if (!flagOne) {
throw new ServiceException("流程发起异常");
}
return MapstructUtils.convert(add, ErpTimesheetInfoVo.class);
}
}

@ -0,0 +1,143 @@
package org.dromara.oa.erp.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.oa.erp.domain.bo.ErpTimesheetProjectBo;
import org.dromara.oa.erp.domain.vo.ErpTimesheetProjectVo;
import org.dromara.oa.erp.domain.ErpTimesheetProject;
import org.dromara.oa.erp.mapper.ErpTimesheetProjectMapper;
import org.dromara.oa.erp.service.IErpTimesheetProjectService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* Service
*
* @author Yangk
* @date 2025-12-09
*/
@RequiredArgsConstructor
@Service
public class ErpTimesheetProjectServiceImpl
extends ServiceImpl<ErpTimesheetProjectMapper, ErpTimesheetProject>
implements IErpTimesheetProjectService {
private final ErpTimesheetProjectMapper baseMapper;
/**
*
*
* @param timesheetProjectId
* @return
*/
@Override
public ErpTimesheetProjectVo queryById(Long timesheetProjectId){
return baseMapper.selectVoById(timesheetProjectId);
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<ErpTimesheetProjectVo> queryPageList(ErpTimesheetProjectBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpTimesheetProject> lqw = buildQueryWrapper(bo);
Page<ErpTimesheetProjectVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*
* @param bo
* @return
*/
@Override
public List<ErpTimesheetProjectVo> queryList(ErpTimesheetProjectBo bo) {
MPJLambdaWrapper<ErpTimesheetProject> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private MPJLambdaWrapper<ErpTimesheetProject> buildQueryWrapper(ErpTimesheetProjectBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpTimesheetProject> lqw = JoinWrappers.lambda(ErpTimesheetProject.class)
.selectAll(ErpTimesheetProject.class)
.eq(ErpTimesheetProject::getDelFlag, "0")
.eq(bo.getTimesheetId() != null, ErpTimesheetProject::getTimesheetId, bo.getTimesheetId())
.eq(bo.getSortOrder() != null, ErpTimesheetProject::getSortOrder, bo.getSortOrder())
.eq(bo.getProjectId() != null, ErpTimesheetProject::getProjectId, bo.getProjectId())
.eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpTimesheetProject::getProjectCode, bo.getProjectCode())
.like(StringUtils.isNotBlank(bo.getProjectName()), ErpTimesheetProject::getProjectName, bo.getProjectName())
.eq(bo.getProjectManagerId() != null, ErpTimesheetProject::getProjectManagerId, bo.getProjectManagerId())
.eq(bo.getDeptId() != null, ErpTimesheetProject::getDeptId, bo.getDeptId())
.eq(bo.getHours() != null, ErpTimesheetProject::getHours, bo.getHours())
;
return lqw;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean insertByBo(ErpTimesheetProjectBo bo) {
ErpTimesheetProject add = MapstructUtils.convert(bo, ErpTimesheetProject.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setTimesheetProjectId(add.getTimesheetProjectId());
}
return flag;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean updateByBo(ErpTimesheetProjectBo bo) {
ErpTimesheetProject update = MapstructUtils.convert(bo, ErpTimesheetProject.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
*
*/
private void validEntityBeforeSave(ErpTimesheetProject entity){
//TODO 做一些数据校验,如唯一约束
}
/**
*
*
* @param ids
* @param isValid
* @return
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

@ -12,6 +12,7 @@
material_id,
customer_id,
sale_material_name,
sale_material_model,
remark,
active_flag,
del_flag,

@ -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.ErpTimesheetDeptMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpTimesheetDeptVo" id="ErpTimesheetDeptResult">
</resultMap>
<select id="selectCustomErpTimesheetDeptVoList" resultMap="ErpTimesheetDeptResult">
select timesheet_dept_id, tenant_id, timesheet_id, sort_order, work_description, dept_id, dept_manager_id, hours, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_timesheet_dept 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.ErpTimesheetInfoMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpTimesheetInfoVo" id="ErpTimesheetInfoResult">
</resultMap>
<select id="selectCustomErpTimesheetInfoVoList" resultMap="ErpTimesheetInfoResult">
select timesheet_id, tenant_id, timesheet_code, user_id, dept_id, start_time, end_time, total_hours, dept_hours, project_hours, timesheet_status, flow_status, remark, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_timesheet_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.ErpTimesheetProjectMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpTimesheetProjectVo" id="ErpTimesheetProjectResult">
</resultMap>
<select id="selectCustomErpTimesheetProjectVoList" resultMap="ErpTimesheetProjectResult">
select timesheet_project_id, tenant_id, timesheet_id, sort_order, project_id, project_code, project_name, project_manager_id, dept_id, hours, del_flag, create_dept, create_by, create_time, update_by, update_time from erp_timesheet_project t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -1,6 +1,7 @@
package org.dromara.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ArrayUtil;
@ -39,6 +40,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
*
@ -314,4 +316,14 @@ public class SysUserController extends BaseController {
List<SysUserVo> list = userService.selectUserList();
return R.ok(list);
}
/**
* ID
* @return
*/
@SaCheckPermission("system:user:list")
@GetMapping("/listByDeptAndRole")
public R<List<SysUserVo>> listByDeptAndRole(@RequestParam Long deptId, @RequestParam(required = false) String roleName) {
return R.ok(userService.selectUserListByDeptAndRole(deptId, roleName));
}
}

@ -128,4 +128,12 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
})
int updateById(@Param(Constants.ENTITY) SysUser user);
/**
* ID
*
* @param deptId ID
* @param roleName
* @return
*/
List<SysUserVo> selectUserListByDeptAndRole(@Param("deptId") Long deptId, @Param("roleName") String roleName);
}

@ -1,5 +1,6 @@
package org.dromara.system.service;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.domain.bo.SysUserBo;
@ -280,5 +281,13 @@ public interface ISysUserService {
* @return
*/
public List<SysUserVo> selectUserList();
/**
* ID
*
* @param deptId ID
* @param roleName "项目经理"
* @return
*/
List<SysUserVo> selectUserListByDeptAndRole(@Param("roleName") Long deptId, @Param("roleName") String roleName);
}

@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.exception.ServiceException;
@ -692,5 +693,15 @@ public class SysUserServiceImpl implements ISysUserService {
lqw.orderByAsc(SysUser::getNickName);
return baseMapper.selectVoList(lqw);
}
/**
* ID
*
* @param deptId ID
* @param roleName "项目经理"
* @return
*/
@Override
public List<SysUserVo> selectUserListByDeptAndRole(@Param("deptId") Long deptId, @Param("roleName") String roleName) {
return baseMapper.selectUserListByDeptAndRole(deptId, roleName);
}
}

@ -38,5 +38,27 @@
left join sys_role r on r.role_id = sur.role_id
${ew.getCustomSqlSegment}
</select>
<select id="selectUserListByDeptAndRole" resultType="org.dromara.system.domain.vo.SysUserVo">
SELECT
u.user_id,
u.dept_id,
u.nick_name,
r.role_id,
r.role_name
FROM sys_user u
INNER JOIN sys_user_role ur ON u.user_id = ur.user_id
INNER JOIN sys_role r ON ur.role_id = r.role_id
WHERE u.del_flag = '0'
AND u.status = '0'
AND r.del_flag = '0'
AND r.status = '0'
<if test="deptId != null">
AND u.dept_id = #{deptId}
</if>
<if test="roleName != null and roleName != ''">
AND r.role_name = #{roleName}
</if>
ORDER BY u.user_id
</select>
</mapper>

@ -0,0 +1,128 @@
package org.dromara.wms.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
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.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.wms.domain.bo.WmsShippingBillBo;
import org.dromara.wms.domain.vo.WmsShippingBillVo;
import org.dromara.wms.service.IWmsShippingBillService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
* 访:/wms/wmsShippingBill
*
* @author Yinq
* @date 2025-12-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/wmsShippingBill")
public class WmsShippingBillController extends BaseController {
private final IWmsShippingBillService wmsShippingBillService;
/**
*
*/
@SaCheckPermission("wms:wmsShippingBill:list")
@GetMapping("/list")
public TableDataInfo<WmsShippingBillVo> list(WmsShippingBillBo bo, PageQuery pageQuery) {
return wmsShippingBillService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("wms:wmsShippingBill:export")
@Log(title = "发货单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(WmsShippingBillBo bo, HttpServletResponse response) {
List<WmsShippingBillVo> list = wmsShippingBillService.queryList(bo);
ExcelUtil.exportExcel(list, "发货单", WmsShippingBillVo.class, response);
}
/**
*
*
* @param shippingBillId
*/
@SaCheckPermission("wms:wmsShippingBill:query")
@GetMapping("/{shippingBillId}")
public R<WmsShippingBillVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("shippingBillId") Long shippingBillId) {
return R.ok(wmsShippingBillService.queryById(shippingBillId));
}
/**
*
*/
@SaCheckPermission("wms:wmsShippingBill:add")
@Log(title = "发货单", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody WmsShippingBillBo bo) {
return toAjax(wmsShippingBillService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("wms:wmsShippingBill:edit")
@Log(title = "发货单", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WmsShippingBillBo bo) {
return toAjax(wmsShippingBillService.updateByBo(bo));
}
/**
*
*
* @param shippingBillIds
*/
@SaCheckPermission("wms:wmsShippingBill:remove")
@Log(title = "发货单", businessType = BusinessType.DELETE)
@DeleteMapping("/{shippingBillIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("shippingBillIds") Long[] shippingBillIds) {
return toAjax(wmsShippingBillService.deleteWithValidByIds(List.of(shippingBillIds), true));
}
/**
*
*/
@GetMapping("/getWmsShippingBillList")
public R<List<WmsShippingBillVo>> getWmsShippingBillList(WmsShippingBillBo bo) {
List<WmsShippingBillVo> list = wmsShippingBillService.queryList(bo);
return R.ok(list);
}
/**
*
*/
@SaCheckPermission("wms:wmsShippingBill:edit")
@Log(title = "发货单", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/shippingBillSubmitAndFlowStart")
public R<WmsShippingBillVo> shippingBillSubmitAndFlowStart(@RequestBody WmsShippingBillBo bo) {
return R.ok(wmsShippingBillService.shippingBillSubmitAndFlowStart(bo));
}
}

@ -0,0 +1,117 @@
package org.dromara.wms.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
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.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.wms.domain.bo.WmsShippingDetailsBo;
import org.dromara.wms.domain.vo.WmsShippingDetailsVo;
import org.dromara.wms.service.IWmsShippingDetailsService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
* 访:/wms/wmsShippingDetails
*
* @author Yinq
* @date 2025-12-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/wmsShippingDetails")
public class WmsShippingDetailsController extends BaseController {
private final IWmsShippingDetailsService wmsShippingDetailsService;
/**
*
*/
@SaCheckPermission("wms:wmsShippingDetails:list")
@GetMapping("/list")
public TableDataInfo<WmsShippingDetailsVo> list(WmsShippingDetailsBo bo, PageQuery pageQuery) {
return wmsShippingDetailsService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("wms:wmsShippingDetails:export")
@Log(title = "发货单明细", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(WmsShippingDetailsBo bo, HttpServletResponse response) {
List<WmsShippingDetailsVo> list = wmsShippingDetailsService.queryList(bo);
ExcelUtil.exportExcel(list, "发货单明细", WmsShippingDetailsVo.class, response);
}
/**
*
*
* @param shippingDetailsId
*/
@SaCheckPermission("wms:wmsShippingDetails:query")
@GetMapping("/{shippingDetailsId}")
public R<WmsShippingDetailsVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable("shippingDetailsId") Long shippingDetailsId) {
return R.ok(wmsShippingDetailsService.queryById(shippingDetailsId));
}
/**
*
*/
@SaCheckPermission("wms:wmsShippingDetails:add")
@Log(title = "发货单明细", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody WmsShippingDetailsBo bo) {
return toAjax(wmsShippingDetailsService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("wms:wmsShippingDetails:edit")
@Log(title = "发货单明细", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WmsShippingDetailsBo bo) {
return toAjax(wmsShippingDetailsService.updateByBo(bo));
}
/**
*
*
* @param shippingDetailsIds
*/
@SaCheckPermission("wms:wmsShippingDetails:remove")
@Log(title = "发货单明细", businessType = BusinessType.DELETE)
@DeleteMapping("/{shippingDetailsIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable("shippingDetailsIds") Long[] shippingDetailsIds) {
return toAjax(wmsShippingDetailsService.deleteWithValidByIds(List.of(shippingDetailsIds), true));
}
/**
*
*/
@GetMapping("/getWmsShippingDetailsList")
public R<List<WmsShippingDetailsVo>> getWmsShippingDetailsList(WmsShippingDetailsBo bo) {
List<WmsShippingDetailsVo> list = wmsShippingDetailsService.queryList(bo);
return R.ok(list);
}
}

@ -0,0 +1,235 @@
package org.dromara.wms.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.tenant.core.TenantEntity;
import java.io.Serial;
import java.util.Date;
import java.util.List;
/**
* wms_shipping_bill
*
* @author Yinq
* @date 2025-12-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("wms_shipping_bill")
public class WmsShippingBill extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "shipping_bill_id", type = IdType.ASSIGN_ID)
private Long shippingBillId;
/**
*
*/
private String shippingCode;
/**
*
*/
private String shippingType;
/**
* 1 2
*/
private String shippingMode;
/**
* 1 2
*/
private String bindType;
/**
* ID
*/
private Long projectId;
/**
* 便
*/
private String projectCode;
/**
* 便
*/
private String projectName;
/**
* ID
*/
private Long customerId;
/**
* 便
*/
private String customerName;
/**
*
*/
private String shippingAddress;
/**
*
*/
private String inventoryAmount;
/**
* POSOPR
*/
private String sourceBillType;
/**
* ID
*/
private Long sourceBillId;
/**
*
*/
private String sourceBillCode;
/**
* ID
*/
private Long contractId;
/**
* 便
*/
private String contractCode;
/**
* 便
*/
private String contractName;
/**
* SAP
*/
@TableField(exist = false)
private String orderContractCode;
/**
*
*/
private String supplier;
/**
* ID
*/
private Long supplierId;
/**
*
*/
private String contactUser;
/**
*
*/
private String contactNumber;
/**
*
*/
private String receiverName;
/**
*
*/
private String receiverPhone;
/**
*
*/
private String logisticsCompany;
/**
*
*/
private String trackingNo;
/**
*
*/
private String logisticsPhone;
/**
*
*/
private String directions;
/**
*
*/
private Date planArrivalTime;
/**
*
*/
private Date shippingTime;
/**
*
*/
private Date receivedTime;
/**
* SAP /
*/
private Date completedTime;
/**
* (1 2 3)
*/
private String outStockBillStatus;
/**
*
*/
private String flowStatus;
/**
* shipping_status1 2 3 4
*/
private String shippingStatus;
/**
* ID
*/
private Long warehouseId;
/**
* 便
*/
private String warehouseName;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
/**
*
*/
@TableField(exist = false)
private List<WmsShippingDetails> detailsList;
}

@ -0,0 +1,131 @@
package org.dromara.wms.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.tenant.core.TenantEntity;
import java.io.Serial;
import java.math.BigDecimal;
/**
* wms_shipping_details
*
* @author Yinq
* @date 2025-12-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("wms_shipping_details")
public class WmsShippingDetails extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "shipping_details_id", type = IdType.AUTO)
private Long shippingDetailsId;
/**
* ID
*/
private Long shippingBillId;
/**
* 1-ERP(base_material_info) 2-WMS() 3-
*/
private String materialSourceType;
/**
* ERPIDbase_material_info.material_id
*/
private Long erpMaterialId;
/**
* WMSIDID
*/
private Long wmsMaterialId;
/**
* CONTRACT_DETAILPURCHASE_DETAIL
*/
private String sourceDetailType;
/**
* ID
*/
private Long sourceDetailId;
/**
* ID
*/
private Long warehouseId;
/**
* ID
*/
private Long materielId;
/**
* 便
*/
private String materialCode;
/**
* 便
*/
private String materialName;
/**
*
*/
private String materielSpecification;
/**
*
*/
private String batchNumber;
/**
*
*/
private BigDecimal unitPrice;
/**
*
*/
private BigDecimal shippingStockAmount;
/**
* ID
*/
private Long unitId;
/**
* 便
*/
private String unitName;
/**
*
*/
private BigDecimal totalPrice;
/**
*
*/
private String remark;
/**
* 0 1
*/
@TableLogic
private String delFlag;
}

@ -0,0 +1,259 @@
package org.dromara.wms.domain.bo;
import cn.hutool.core.util.ObjectUtil;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.wms.domain.WmsShippingBill;
import org.dromara.wms.domain.WmsShippingDetails;
import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt;
import java.util.*;
/**
* wms_shipping_bill
*
* @author Yinq
* @date 2025-12-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = WmsShippingBill.class, reverseConvertGenerate = false)
public class WmsShippingBillBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "发货单ID不能为空", groups = { EditGroup.class })
private Long shippingBillId;
/**
*
*/
private String shippingCode;
/**
*
*/
private String shippingType;
/**
* 1 2
*/
private String shippingMode;
/**
* 1 2
*/
private String bindType;
/**
* ID
*/
private Long projectId;
/**
* 便
*/
private String projectCode;
/**
* 便
*/
private String projectName;
/**
* ID
*/
private Long customerId;
/**
* 便
*/
private String customerName;
/**
*
*/
private String shippingAddress;
/**
*
*/
private String inventoryAmount;
/**
* POSOPR
*/
private String sourceBillType;
/**
* ID
*/
private Long sourceBillId;
/**
*
*/
private String sourceBillCode;
/**
* ID
*/
private Long contractId;
/**
* 便
*/
private String contractCode;
/**
* 便
*/
private String contractName;
/**
* SAP
*/
private String orderContractCode;
/**
*
*/
private String supplier;
/**
* ID
*/
private Long supplierId;
/**
*
*/
private String contactUser;
/**
*
*/
private String contactNumber;
/**
*
*/
private String receiverName;
/**
*
*/
private String receiverPhone;
/**
*
*/
private String logisticsCompany;
/**
*
*/
private String trackingNo;
/**
*
*/
private String logisticsPhone;
/**
*
*/
private String directions;
/**
*
*/
private Date planArrivalTime;
/**
*
*/
private Date shippingTime;
/**
*
*/
private Date receivedTime;
/**
* SAP /
*/
private Date completedTime;
/**
* (1 2 3)
*/
private String outStockBillStatus;
/**
*
*/
private String flowStatus;
/**
* shipping_status1 2 3 4
*/
private String shippingStatus;
/**
* ID
*/
private Long warehouseId;
/**
* 便
*/
private String warehouseName;
/**
*
*/
private String remark;
/**
*
*/
private List<WmsShippingDetails> detailsList;
/**
*
*/
private String flowCode;
/**
* {'entity': {}}
*/
private Map<String, Object> variables;
/**
*
*/
private RemoteFlowInstanceBizExt bizExt;
public Map<String, Object> getVariables() {
if (variables == null) {
return new HashMap<>(16);
}
variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
return variables;
}
public RemoteFlowInstanceBizExt getBizExt() {
if (ObjectUtil.isNull(bizExt)) {
bizExt = new RemoteFlowInstanceBizExt();
}
return bizExt;
}
}

@ -0,0 +1,121 @@
package org.dromara.wms.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.wms.domain.WmsShippingDetails;
import java.math.BigDecimal;
/**
* wms_shipping_details
*
* @author Yinq
* @date 2025-12-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = WmsShippingDetails.class, reverseConvertGenerate = false)
public class WmsShippingDetailsBo extends BaseEntity {
/**
* ID
*/
@NotNull(message = "发货单明细ID不能为空", groups = { EditGroup.class })
private Long shippingDetailsId;
/**
* ID
*/
private Long shippingBillId;
/**
* 1-ERP(base_material_info) 2-WMS() 3-
*/
private String materialSourceType;
/**
* ERPIDbase_material_info.material_id
*/
private Long erpMaterialId;
/**
* WMSIDID
*/
private Long wmsMaterialId;
/**
* CONTRACT_DETAILPURCHASE_DETAIL
*/
private String sourceDetailType;
/**
* ID
*/
private Long sourceDetailId;
/**
* ID
*/
private Long warehouseId;
/**
* ID
*/
private Long materielId;
/**
* 便
*/
private String materialCode;
/**
* 便
*/
private String materialName;
/**
*
*/
private String materielSpecification;
/**
*
*/
private String batchNumber;
/**
*
*/
private BigDecimal unitPrice;
/**
*
*/
private BigDecimal shippingStockAmount;
/**
* ID
*/
private Long unitId;
/**
* 便
*/
private String unitName;
/**
*
*/
private BigDecimal totalPrice;
/**
*
*/
private String remark;
}

@ -0,0 +1,285 @@
package org.dromara.wms.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import org.dromara.wms.domain.WmsShippingBill;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* wms_shipping_bill
*
* @author Yinq
* @date 2025-12-08
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = WmsShippingBill.class)
public class WmsShippingBillVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "发货单ID")
private Long shippingBillId;
/**
*
*/
@ExcelProperty(value = "发货单号")
private String shippingCode;
/**
*
*/
@ExcelProperty(value = "发货单类型")
private String shippingType;
/**
* 1 2
*/
@ExcelProperty(value = "发货方式1公司仓库发货 2供应商代发货")
private String shippingMode;
/**
* 1 2
*/
@ExcelProperty(value = "绑定类型1项目 2合同")
private String bindType;
/**
* ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
* 便
*/
@ExcelProperty(value = "项目编号", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余,方便导出")
private String projectCode;
/**
* 便
*/
@ExcelProperty(value = "项目名称", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余,方便导出")
private String projectName;
/**
* ID
*/
@ExcelProperty(value = "客户ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "逻=辑外键")
private Long customerId;
/**
* 便
*/
@ExcelProperty(value = "客户名称", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余,方便导出")
private String customerName;
/**
*
*/
@ExcelProperty(value = "收货地址")
private String shippingAddress;
/**
*
*/
@ExcelProperty(value = "关联单号")
private String inventoryAmount;
/**
* POSOPR
*/
@ExcelProperty(value = "来源单据类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "如=PO采购订单、SO销售订单、PR项目采购申请等")
private String sourceBillType;
/**
* ID
*/
@ExcelProperty(value = "来源单据ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "逻=辑外键,不建物理外键")
private Long sourceBillId;
/**
*
*/
@ExcelProperty(value = "来源单据编号")
private String sourceBillCode;
/**
* ID
*/
@ExcelProperty(value = "合同ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "逻=辑外键")
private Long contractId;
/**
* 便
*/
@ExcelProperty(value = "合同编号", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余,方便导出")
private String contractCode;
/**
* 便
*/
@ExcelProperty(value = "合同名称", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余,方便导出")
private String contractName;
/**
* SAP
*/
@ExcelProperty(value = "SAP订单号")
private String orderContractCode;
/**
*
*/
@ExcelProperty(value = "供应商")
private String supplier;
/**
* ID
*/
@ExcelProperty(value = "供应商ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "逻=辑外键")
private Long supplierId;
/**
*
*/
@ExcelProperty(value = "联系人")
private String contactUser;
/**
*
*/
@ExcelProperty(value = "联系电话")
private String contactNumber;
/**
*
*/
@ExcelProperty(value = "收货联系人")
private String receiverName;
/**
*
*/
@ExcelProperty(value = "收货联系电话")
private String receiverPhone;
/**
*
*/
@ExcelProperty(value = "物流公司")
private String logisticsCompany;
/**
*
*/
@ExcelProperty(value = "运单号")
private String trackingNo;
/**
*
*/
@ExcelProperty(value = "物流联系电话")
private String logisticsPhone;
/**
*
*/
@ExcelProperty(value = "发货说明")
private String directions;
/**
*
*/
@ExcelProperty(value = "计划到货时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余,用于未按时发货台账")
private Date planArrivalTime;
/**
*
*/
@ExcelProperty(value = "实际发货时间")
private Date shippingTime;
/**
*
*/
@ExcelProperty(value = "客户收货时间")
private Date receivedTime;
/**
* SAP /
*/
@ExcelProperty(value = "业务完成时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "如=SAP投料,/=,内=部流程完成")
private Date completedTime;
/**
* (1 2 3)
*/
@ExcelProperty(value = "发货单状态(1暂存 2审批中 3完成)")
private String outStockBillStatus;
/**
*
*/
@ExcelProperty(value = "流程状态")
private String flowStatus;
/**
* shipping_status1 2 3 4
*/
@ExcelProperty(value = "发货状态字典shipping_status1待发货 2已发货 3已收货 4已完成")
private String shippingStatus;
/**
* ID
*/
@ExcelProperty(value = "仓库ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "预=留")
private Long warehouseId;
/**
* 便
*/
@ExcelProperty(value = "仓库名称", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余,方便导出")
private String warehouseName;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
/**
*
*/
private List<WmsShippingDetailsVo> itemsVo;
}

@ -0,0 +1,152 @@
package org.dromara.wms.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import org.dromara.wms.domain.WmsShippingDetails;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* wms_shipping_details
*
* @author Yinq
* @date 2025-12-08
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = WmsShippingDetails.class)
public class WmsShippingDetailsVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ExcelProperty(value = "发货单明细ID")
private Long shippingDetailsId;
/**
* ID
*/
@ExcelProperty(value = "发货单ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "逻=辑外键")
private Long shippingBillId;
/**
* 1-ERP(base_material_info) 2-WMS() 3-
*/
@ExcelProperty(value = "物料来源类型1-ERP物料(base_material_info) 2-WMS物料(仓储物料) 3-手工录入")
private String materialSourceType;
/**
* ERPIDbase_material_info.material_id
*/
@ExcelProperty(value = "ERP物料ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "b=ase_material_info.material_id")
private Long erpMaterialId;
/**
* WMSIDID
*/
@ExcelProperty(value = "WMS物料ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "仓=储物料表ID预留")
private Long wmsMaterialId;
/**
* CONTRACT_DETAILPURCHASE_DETAIL
*/
@ExcelProperty(value = "来源明细类型如CONTRACT_DETAIL、PURCHASE_DETAIL等")
private String sourceDetailType;
/**
* ID
*/
@ExcelProperty(value = "来源明细ID")
private Long sourceDetailId;
/**
* ID
*/
@ExcelProperty(value = "仓库ID")
private Long warehouseId;
/**
* ID
*/
@ExcelProperty(value = "物料ID")
private Long materielId;
/**
* 便
*/
@ExcelProperty(value = "物料编码", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余,方便导出")
private String materialCode;
/**
* 便
*/
@ExcelProperty(value = "物料名称", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余,方便导出")
private String materialName;
/**
*
*/
@ExcelProperty(value = "物料规格")
private String materielSpecification;
/**
*
*/
@ExcelProperty(value = "批次号")
private String batchNumber;
/**
*
*/
@ExcelProperty(value = "单价")
private BigDecimal unitPrice;
/**
*
*/
@ExcelProperty(value = "发货数量")
private BigDecimal shippingStockAmount;
/**
* ID
*/
@ExcelProperty(value = "单位ID")
private Long unitId;
/**
* 便
*/
@ExcelProperty(value = "计量单位名称", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余,方便导出")
private String unitName;
/**
*
*/
@ExcelProperty(value = "总价")
private BigDecimal totalPrice;
/**
*
*/
@ExcelProperty(value = "备注")
private String remark;
}

@ -0,0 +1,128 @@
package org.dromara.wms.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.annotation.DataColumn;
import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.wms.domain.WmsShippingBill;
import org.dromara.wms.domain.vo.WmsShippingBillVo;
import java.util.Collection;
import java.util.List;
/**
* Mapper
*
* @author Yinq
* @date 2025-12-08
*/
public interface WmsShippingBillMapper extends BaseMapperPlus<WmsShippingBill, WmsShippingBillVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Page<WmsShippingBillVo> selectCustomWmsShippingBillVoList(@Param("page") Page<WmsShippingBillVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<WmsShippingBill> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
List<WmsShippingBillVo> selectCustomWmsShippingBillVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<WmsShippingBill> queryWrapper);
/**
* ID
*
* @param shippingBillId ID
* @return
*/
WmsShippingBillVo selectCustomWmsShippingBillVoById(@Param("shippingBillId") Long shippingBillId);
/**
* ID
*
* @param ids ID
* @return
*/
List<WmsShippingBillVo> selectCustomWmsShippingBillVoByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
Long countCustomWmsShippingBill(@Param(Constants.WRAPPER) Wrapper<WmsShippingBill> queryWrapper);
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
@DataPermission({
@DataColumn(key = "deptName", value = "t.create_dept"),
@DataColumn(key = "userName", value = "t.create_by")
})
Page<WmsShippingBillVo> selectCustomWmsShippingBillVoPage(@Param("page") Page<WmsShippingBillVo> page, @Param(Constants.WRAPPER) Wrapper<WmsShippingBill> queryWrapper);
/**
*
*
* @param list
* @return
*/
int batchInsertWmsShippingBill(@Param("list") List<WmsShippingBill> list);
/**
*
*
* @param list
* @return
*/
int batchUpdateWmsShippingBill(@Param("list") List<WmsShippingBill> list);
/**
*
*
* @param queryWrapper
* @return
*/
int deleteCustomWmsShippingBill(@Param(Constants.WRAPPER) Wrapper<WmsShippingBill> queryWrapper);
/**
* ID
*
* @param ids ID
* @return
*/
int deleteCustomWmsShippingBillByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
Boolean existsWmsShippingBill(@Param(Constants.WRAPPER) Wrapper<WmsShippingBill> queryWrapper);
}

@ -0,0 +1,114 @@
package org.dromara.wms.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.wms.domain.WmsShippingDetails;
import org.dromara.wms.domain.vo.WmsShippingDetailsVo;
import java.util.Collection;
import java.util.List;
/**
* Mapper
*
* @author Yinq
* @date 2025-12-08
*/
public interface WmsShippingDetailsMapper extends BaseMapperPlus<WmsShippingDetails, WmsShippingDetailsVo> {
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
public Page<WmsShippingDetailsVo> selectCustomWmsShippingDetailsVoList(@Param("page") Page<WmsShippingDetailsVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<WmsShippingDetails> queryWrapper);
/**
*
*
* @param queryWrapper
* @return
*/
public List<WmsShippingDetailsVo> selectCustomWmsShippingDetailsVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<WmsShippingDetails> queryWrapper);
/**
* ID
*
* @param shippingDetailsId ID
* @return
*/
WmsShippingDetailsVo selectCustomWmsShippingDetailsVoById(@Param("shippingDetailsId") Long shippingDetailsId);
/**
* ID
*
* @param ids ID
* @return
*/
List<WmsShippingDetailsVo> selectCustomWmsShippingDetailsVoByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
Long countCustomWmsShippingDetails(@Param(Constants.WRAPPER) Wrapper<WmsShippingDetails> queryWrapper);
/**
*
*
* @param page
* @param queryWrapper
* @return
*/
Page<WmsShippingDetailsVo> selectCustomWmsShippingDetailsVoPage(@Param("page") Page<WmsShippingDetailsVo> page, @Param(Constants.WRAPPER) Wrapper<WmsShippingDetails> queryWrapper);
/**
*
*
* @param list
* @return
*/
int batchInsertWmsShippingDetails(@Param("list") List<WmsShippingDetails> list);
/**
*
*
* @param list
* @return
*/
int batchUpdateWmsShippingDetails(@Param("list") List<WmsShippingDetails> list);
/**
*
*
* @param queryWrapper
* @return
*/
int deleteCustomWmsShippingDetails(@Param(Constants.WRAPPER) Wrapper<WmsShippingDetails> queryWrapper);
/**
* ID
*
* @param ids ID
* @return
*/
int deleteCustomWmsShippingDetailsByIds(@Param("ids") Collection<Long> ids);
/**
*
*
* @param queryWrapper
* @return
*/
Boolean existsWmsShippingDetails(@Param(Constants.WRAPPER) Wrapper<WmsShippingDetails> queryWrapper);
}

@ -0,0 +1,76 @@
package org.dromara.wms.service;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.wms.domain.bo.WmsShippingBillBo;
import org.dromara.wms.domain.vo.WmsShippingBillVo;
import java.util.Collection;
import java.util.List;
/**
* Service
*
* @author Yinq
* @date 2025-12-08
*/
public interface IWmsShippingBillService {
/**
*
*
* @param shippingBillId
* @return
*/
WmsShippingBillVo queryById(Long shippingBillId);
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
TableDataInfo<WmsShippingBillVo> queryPageList(WmsShippingBillBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
List<WmsShippingBillVo> queryList(WmsShippingBillBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(WmsShippingBillBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(WmsShippingBillBo bo);
/**
*
*
* @param ids
* @param isValid
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
*
*
* @param bo
* @return VO
*/
WmsShippingBillVo shippingBillSubmitAndFlowStart(WmsShippingBillBo bo);
}

@ -0,0 +1,68 @@
package org.dromara.wms.service;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.wms.domain.bo.WmsShippingDetailsBo;
import org.dromara.wms.domain.vo.WmsShippingDetailsVo;
import java.util.Collection;
import java.util.List;
/**
* Service
*
* @author Yinq
* @date 2025-12-08
*/
public interface IWmsShippingDetailsService {
/**
*
*
* @param shippingDetailsId
* @return
*/
WmsShippingDetailsVo queryById(Long shippingDetailsId);
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
TableDataInfo<WmsShippingDetailsVo> queryPageList(WmsShippingDetailsBo bo, PageQuery pageQuery);
/**
*
*
* @param bo
* @return
*/
List<WmsShippingDetailsVo> queryList(WmsShippingDetailsBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean insertByBo(WmsShippingDetailsBo bo);
/**
*
*
* @param bo
* @return
*/
Boolean updateByBo(WmsShippingDetailsBo bo);
/**
*
*
* @param ids
* @param isValid
* @return
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

@ -0,0 +1,339 @@
package org.dromara.wms.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.enums.OAStatusEnum;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.wms.domain.WmsShippingBill;
import org.dromara.wms.domain.WmsShippingDetails;
import org.dromara.wms.domain.bo.WmsShippingBillBo;
import org.dromara.wms.domain.vo.WmsShippingBillVo;
import org.dromara.wms.domain.vo.WmsShippingDetailsVo;
import org.dromara.wms.mapper.WmsShippingBillMapper;
import org.dromara.wms.mapper.WmsShippingDetailsMapper;
import org.dromara.wms.service.IWmsShippingBillService;
import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.dromara.workflow.api.event.ProcessEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Service
*
* @author Yinq
* @date 2025-12-08
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class WmsShippingBillServiceImpl implements IWmsShippingBillService {
private final WmsShippingBillMapper baseMapper;
private final WmsShippingDetailsMapper detailsMapper;
@DubboReference(timeout = 30000)
private RemoteWorkflowService remoteWorkflowService;
/**
*
*
* @param shippingBillId
* @return
*/
@Override
public WmsShippingBillVo queryById(Long shippingBillId) {
// 使用 Mapper.xml 中自定义 SQL联查合同表获取发货单及 SAP 订单号
WmsShippingBillVo vo = baseMapper.selectCustomWmsShippingBillVoById(shippingBillId);
if (vo != null) {
// 查询当前发货单下的明细列表
LambdaQueryWrapper<WmsShippingDetails> detailsLqw = Wrappers.<WmsShippingDetails>lambdaQuery()
.eq(WmsShippingDetails::getDelFlag, "0")
.eq(WmsShippingDetails::getShippingBillId, shippingBillId);
List<WmsShippingDetailsVo> detailsVoList = detailsMapper.selectVoList(detailsLqw);
vo.setItemsVo(detailsVoList);
}
return vo;
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<WmsShippingBillVo> queryPageList(WmsShippingBillBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<WmsShippingBill> lqw = buildQueryWrapper(bo);
// 使用 Mapper.xml 中分页自定义 SQL 接口selectCustomWmsShippingBillVoPage联查合同表获取 SAP 订单号
Page<WmsShippingBillVo> page = baseMapper.selectCustomWmsShippingBillVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(page);
}
/**
*
*
* @param bo
* @return
*/
@Override
public List<WmsShippingBillVo> queryList(WmsShippingBillBo bo) {
MPJLambdaWrapper<WmsShippingBill> lqw = buildQueryWrapper(bo);
// 使用 Mapper.xml 中自定义 SQL联查合同表获取 SAP 订单号)
return baseMapper.selectCustomWmsShippingBillVoList(lqw);
}
private MPJLambdaWrapper<WmsShippingBill> buildQueryWrapper(WmsShippingBillBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<WmsShippingBill> lqw = JoinWrappers.lambda(WmsShippingBill.class)
.selectAll(WmsShippingBill.class)
.eq(WmsShippingBill::getDelFlag, "0")
.eq(StringUtils.isNotBlank(bo.getShippingCode()), WmsShippingBill::getShippingCode, bo.getShippingCode())
.eq(StringUtils.isNotBlank(bo.getShippingType()), WmsShippingBill::getShippingType, bo.getShippingType())
.eq(StringUtils.isNotBlank(bo.getShippingMode()), WmsShippingBill::getShippingMode, bo.getShippingMode())
.eq(StringUtils.isNotBlank(bo.getBindType()), WmsShippingBill::getBindType, bo.getBindType())
.eq(bo.getProjectId() != null, WmsShippingBill::getProjectId, bo.getProjectId())
.eq(StringUtils.isNotBlank(bo.getProjectCode()), WmsShippingBill::getProjectCode, bo.getProjectCode())
.like(StringUtils.isNotBlank(bo.getProjectName()), WmsShippingBill::getProjectName, bo.getProjectName())
.eq(bo.getCustomerId() != null, WmsShippingBill::getCustomerId, bo.getCustomerId())
.like(StringUtils.isNotBlank(bo.getCustomerName()), WmsShippingBill::getCustomerName, bo.getCustomerName())
.eq(StringUtils.isNotBlank(bo.getShippingAddress()), WmsShippingBill::getShippingAddress, bo.getShippingAddress())
.eq(StringUtils.isNotBlank(bo.getInventoryAmount()), WmsShippingBill::getInventoryAmount, bo.getInventoryAmount())
.eq(StringUtils.isNotBlank(bo.getSourceBillType()), WmsShippingBill::getSourceBillType, bo.getSourceBillType())
.eq(bo.getSourceBillId() != null, WmsShippingBill::getSourceBillId, bo.getSourceBillId())
.eq(StringUtils.isNotBlank(bo.getSourceBillCode()), WmsShippingBill::getSourceBillCode, bo.getSourceBillCode())
.eq(bo.getContractId() != null, WmsShippingBill::getContractId, bo.getContractId())
.eq(StringUtils.isNotBlank(bo.getContractCode()), WmsShippingBill::getContractCode, bo.getContractCode())
.like(StringUtils.isNotBlank(bo.getContractName()), WmsShippingBill::getContractName, bo.getContractName())
.eq(StringUtils.isNotBlank(bo.getSupplier()), WmsShippingBill::getSupplier, bo.getSupplier())
.eq(bo.getSupplierId() != null, WmsShippingBill::getSupplierId, bo.getSupplierId())
.eq(StringUtils.isNotBlank(bo.getContactUser()), WmsShippingBill::getContactUser, bo.getContactUser())
.eq(StringUtils.isNotBlank(bo.getContactNumber()), WmsShippingBill::getContactNumber, bo.getContactNumber())
.like(StringUtils.isNotBlank(bo.getReceiverName()), WmsShippingBill::getReceiverName, bo.getReceiverName())
.eq(StringUtils.isNotBlank(bo.getReceiverPhone()), WmsShippingBill::getReceiverPhone, bo.getReceiverPhone())
.eq(StringUtils.isNotBlank(bo.getLogisticsCompany()), WmsShippingBill::getLogisticsCompany, bo.getLogisticsCompany())
.eq(StringUtils.isNotBlank(bo.getTrackingNo()), WmsShippingBill::getTrackingNo, bo.getTrackingNo())
.eq(StringUtils.isNotBlank(bo.getLogisticsPhone()), WmsShippingBill::getLogisticsPhone, bo.getLogisticsPhone())
.eq(StringUtils.isNotBlank(bo.getDirections()), WmsShippingBill::getDirections, bo.getDirections())
.eq(bo.getPlanArrivalTime() != null, WmsShippingBill::getPlanArrivalTime, bo.getPlanArrivalTime())
.eq(bo.getShippingTime() != null, WmsShippingBill::getShippingTime, bo.getShippingTime())
.eq(bo.getReceivedTime() != null, WmsShippingBill::getReceivedTime, bo.getReceivedTime())
.eq(bo.getCompletedTime() != null, WmsShippingBill::getCompletedTime, bo.getCompletedTime())
.eq(StringUtils.isNotBlank(bo.getOutStockBillStatus()), WmsShippingBill::getOutStockBillStatus, bo.getOutStockBillStatus())
.eq(StringUtils.isNotBlank(bo.getFlowStatus()), WmsShippingBill::getFlowStatus, bo.getFlowStatus())
.eq(StringUtils.isNotBlank(bo.getShippingStatus()), WmsShippingBill::getShippingStatus, bo.getShippingStatus())
.eq(bo.getWarehouseId() != null, WmsShippingBill::getWarehouseId, bo.getWarehouseId())
.like(StringUtils.isNotBlank(bo.getWarehouseName()), WmsShippingBill::getWarehouseName, bo.getWarehouseName())
;
return lqw;
}
/**
*
*
* @param bo
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(WmsShippingBillBo bo) {
WmsShippingBill add = MapstructUtils.convert(bo, WmsShippingBill.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setShippingBillId(add.getShippingBillId());
// 同步保存明细列表
List<WmsShippingDetails> detailsList = bo.getDetailsList();
if (CollUtil.isNotEmpty(detailsList)) {
for (WmsShippingDetails detail : detailsList) {
detail.setShippingBillId(add.getShippingBillId());
}
detailsMapper.insertBatch(detailsList);
}
}
return flag;
}
/**
*
*
* @param bo
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateByBo(WmsShippingBillBo bo) {
WmsShippingBill update = MapstructUtils.convert(bo, WmsShippingBill.class);
validEntityBeforeSave(update);
boolean flag = baseMapper.updateById(update) > 0;
// 处理明细列表的增删改
List<WmsShippingDetails> detailsList = bo.getDetailsList();
Long shippingBillId = bo.getShippingBillId();
if (detailsList != null) {
// 1. 获取前端提交的明细ID集合
List<Long> submittedIds = detailsList.stream()
.filter(d -> d.getShippingDetailsId() != null)
.map(WmsShippingDetails::getShippingDetailsId)
.collect(Collectors.toList());
// 2. 删除前端未提交的旧明细(即数据库中存在但前端不再提交的记录)
if (CollUtil.isNotEmpty(submittedIds)) {
detailsMapper.delete(Wrappers.<WmsShippingDetails>lambdaUpdate()
.eq(WmsShippingDetails::getShippingBillId, shippingBillId)
.notIn(WmsShippingDetails::getShippingDetailsId, submittedIds));
} else {
// 如果前端提交的明细都没有ID全为新增则删除该发货单下所有旧明细
detailsMapper.delete(Wrappers.<WmsShippingDetails>lambdaUpdate()
.eq(WmsShippingDetails::getShippingBillId, shippingBillId));
}
// 3. 新增或更新明细
for (WmsShippingDetails detail : detailsList) {
detail.setShippingBillId(shippingBillId);
if (detail.getShippingDetailsId() != null) {
detailsMapper.updateById(detail);
} else {
detailsMapper.insert(detail);
}
}
}
return flag;
}
/**
*
*/
private void validEntityBeforeSave(WmsShippingBill entity) {
// 发货单号唯一性校验(新增时校验)
if (entity.getShippingBillId() == null && StringUtils.isNotBlank(entity.getShippingCode())) {
Long count = baseMapper.selectCount(Wrappers.<WmsShippingBill>lambdaQuery()
.eq(WmsShippingBill::getShippingCode, entity.getShippingCode())
.eq(WmsShippingBill::getDelFlag, "0"));
if (count > 0) {
throw new ServiceException("发货单号【" + entity.getShippingCode() + "】已存在");
}
}
// 必须绑定项目或合同
if (entity.getProjectId() == null && entity.getContractId() == null) {
throw new ServiceException("发货单必须绑定项目或合同");
}
}
/**
*
*
* @param ids
* @param isValid
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
// 先删除子表明细
detailsMapper.delete(Wrappers.<WmsShippingDetails>lambdaUpdate()
.in(WmsShippingDetails::getShippingBillId, ids));
// 再删除主表
return baseMapper.deleteByIds(ids) > 0;
}
/**
*
*
* @param bo
* @return VO
*/
@Override
@Transactional(rollbackFor = Exception.class)
public WmsShippingBillVo shippingBillSubmitAndFlowStart(WmsShippingBillBo bo) {
WmsShippingBill add = MapstructUtils.convert(bo, WmsShippingBill.class);
validEntityBeforeSave(add);
if (StringUtils.isNull(bo.getShippingBillId())) {
this.insertByBo(bo);
} else {
this.updateByBo(bo);
}
// 后端发起需要忽略权限
bo.getVariables().put("ignore", true);
RemoteStartProcess startProcess = new RemoteStartProcess();
startProcess.setBusinessId(bo.getShippingBillId().toString());
startProcess.setFlowCode(bo.getFlowCode());
startProcess.setVariables(bo.getVariables());
startProcess.setBizExt(bo.getBizExt());
bo.getBizExt().setBusinessId(startProcess.getBusinessId());
boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess);
if (!flagOne) {
throw new ServiceException("流程发起异常");
}
return MapstructUtils.convert(add, WmsShippingBillVo.class);
}
/**
* 稿退
* WMSSP
*
* @param processEvent
*/
@EventListener(condition = "#processEvent.flowCode == 'WMSSP'")
public void processHandler(ProcessEvent processEvent) {
TenantHelper.dynamic(processEvent.getTenantId(), () -> {
log.info("发货单流程事件: {}", processEvent.toString());
WmsShippingBill shippingBill = baseMapper.selectById(Convert.toLong(processEvent.getBusinessId()));
if (shippingBill == null) {
log.warn("发货单不存在businessId: {}", processEvent.getBusinessId());
return;
}
// 更新流程状态
shippingBill.setFlowStatus(processEvent.getStatus());
Map<String, Object> params = processEvent.getParams();
if (MapUtil.isNotEmpty(params)) {
// 可获取办理人等信息
String handler = Convert.toStr(params.get("handler"));
}
// 根据流程状态更新业务状态
if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.WAITING.getStatus())) {
// 审批中
shippingBill.setOutStockBillStatus(OAStatusEnum.APPROVING.getStatus());
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) {
// 审批完成 → 业务状态变为可用/待发货
shippingBill.setOutStockBillStatus(OAStatusEnum.COMPLETED.getStatus());
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.INVALID.getStatus())
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.TERMINATION.getStatus())) {
// 作废或终止 → 业务状态变为作废
shippingBill.setOutStockBillStatus(OAStatusEnum.INVALID.getStatus());
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.BACK.getStatus())
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.CANCEL.getStatus())) {
// 退回或撤销 → 业务状态变为草稿
shippingBill.setOutStockBillStatus(OAStatusEnum.DRAFT.getStatus());
}
baseMapper.updateById(shippingBill);
});
}
}

@ -0,0 +1,148 @@
package org.dromara.wms.service.impl;
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.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.wms.domain.WmsShippingDetails;
import org.dromara.wms.domain.bo.WmsShippingDetailsBo;
import org.dromara.wms.domain.vo.WmsShippingDetailsVo;
import org.dromara.wms.mapper.WmsShippingDetailsMapper;
import org.dromara.wms.service.IWmsShippingDetailsService;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* Service
*
* @author Yinq
* @date 2025-12-08
*/
@RequiredArgsConstructor
@Service
public class WmsShippingDetailsServiceImpl implements IWmsShippingDetailsService {
private final WmsShippingDetailsMapper baseMapper;
/**
*
*
* @param shippingDetailsId
* @return
*/
@Override
public WmsShippingDetailsVo queryById(Long shippingDetailsId){
return baseMapper.selectVoById(shippingDetailsId);
}
/**
*
*
* @param bo
* @param pageQuery
* @return
*/
@Override
public TableDataInfo<WmsShippingDetailsVo> queryPageList(WmsShippingDetailsBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<WmsShippingDetails> lqw = buildQueryWrapper(bo);
Page<WmsShippingDetailsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*
* @param bo
* @return
*/
@Override
public List<WmsShippingDetailsVo> queryList(WmsShippingDetailsBo bo) {
MPJLambdaWrapper<WmsShippingDetails> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private MPJLambdaWrapper<WmsShippingDetails> buildQueryWrapper(WmsShippingDetailsBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<WmsShippingDetails> lqw = JoinWrappers.lambda(WmsShippingDetails.class)
.selectAll(WmsShippingDetails.class)
.eq(WmsShippingDetails::getDelFlag, "0")
.eq(bo.getShippingBillId() != null, WmsShippingDetails::getShippingBillId, bo.getShippingBillId())
.eq(StringUtils.isNotBlank(bo.getMaterialSourceType()), WmsShippingDetails::getMaterialSourceType, bo.getMaterialSourceType())
.eq(bo.getErpMaterialId() != null, WmsShippingDetails::getErpMaterialId, bo.getErpMaterialId())
.eq(bo.getWmsMaterialId() != null, WmsShippingDetails::getWmsMaterialId, bo.getWmsMaterialId())
.eq(StringUtils.isNotBlank(bo.getSourceDetailType()), WmsShippingDetails::getSourceDetailType, bo.getSourceDetailType())
.eq(bo.getSourceDetailId() != null, WmsShippingDetails::getSourceDetailId, bo.getSourceDetailId())
.eq(bo.getWarehouseId() != null, WmsShippingDetails::getWarehouseId, bo.getWarehouseId())
.eq(bo.getMaterielId() != null, WmsShippingDetails::getMaterielId, bo.getMaterielId())
.eq(StringUtils.isNotBlank(bo.getMaterialCode()), WmsShippingDetails::getMaterialCode, bo.getMaterialCode())
.like(StringUtils.isNotBlank(bo.getMaterialName()), WmsShippingDetails::getMaterialName, bo.getMaterialName())
.eq(StringUtils.isNotBlank(bo.getMaterielSpecification()), WmsShippingDetails::getMaterielSpecification, bo.getMaterielSpecification())
.eq(StringUtils.isNotBlank(bo.getBatchNumber()), WmsShippingDetails::getBatchNumber, bo.getBatchNumber())
.eq(bo.getUnitPrice() != null, WmsShippingDetails::getUnitPrice, bo.getUnitPrice())
.eq(bo.getShippingStockAmount() != null, WmsShippingDetails::getShippingStockAmount, bo.getShippingStockAmount())
.eq(bo.getUnitId() != null, WmsShippingDetails::getUnitId, bo.getUnitId())
.like(StringUtils.isNotBlank(bo.getUnitName()), WmsShippingDetails::getUnitName, bo.getUnitName())
.eq(bo.getTotalPrice() != null, WmsShippingDetails::getTotalPrice, bo.getTotalPrice())
;
return lqw;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean insertByBo(WmsShippingDetailsBo bo) {
WmsShippingDetails add = MapstructUtils.convert(bo, WmsShippingDetails.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setShippingDetailsId(add.getShippingDetailsId());
}
return flag;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean updateByBo(WmsShippingDetailsBo bo) {
WmsShippingDetails update = MapstructUtils.convert(bo, WmsShippingDetails.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
*
*/
private void validEntityBeforeSave(WmsShippingDetails 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,400 @@
<?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.wms.mapper.WmsShippingBillMapper">
<resultMap type="org.dromara.wms.domain.vo.WmsShippingBillVo" id="WmsShippingBillResult">
</resultMap>
<select id="selectCustomWmsShippingBillVoList" resultMap="WmsShippingBillResult">
select t.shipping_bill_id, t.tenant_id, t.shipping_code, t.shipping_type, t.shipping_mode, t.bind_type, t.project_id, t.project_code, t.project_name, t.customer_id, t.customer_name, t.shipping_address, t.inventory_amount, t.source_bill_type, t.source_bill_id, t.source_bill_code, t.contract_id, t.contract_code, t.contract_name, c.order_contract_code as orderContractCode, t.supplier, t.supplier_id, t.contact_user, t.contact_number, t.receiver_name, t.receiver_phone, t.logistics_company, t.tracking_no, t.logistics_phone, t.directions, t.plan_arrival_time, t.shipping_time, t.received_time, t.completed_time, t.out_stock_bill_status, t.flow_status, t.shipping_status, t.warehouse_id, t.warehouse_name, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from wms_shipping_bill t
left join erp_contract_info c on t.contract_id = c.contract_id
${ew.getCustomSqlSegment}
</select>
<!-- 根据ID查询详情联查合同获取SAP订单号 -->
<select id="selectCustomWmsShippingBillVoById" resultMap="WmsShippingBillResult">
select t.shipping_bill_id, t.tenant_id, t.shipping_code, t.shipping_type, t.shipping_mode, t.bind_type, t.project_id, t.project_code, t.project_name, t.customer_id, t.customer_name, t.shipping_address, t.inventory_amount, t.source_bill_type, t.source_bill_id, t.source_bill_code, t.contract_id, t.contract_code, t.contract_name, c.order_contract_code as orderContractCode, t.supplier, t.supplier_id, t.contact_user, t.contact_number, t.receiver_name, t.receiver_phone, t.logistics_company, t.tracking_no, t.logistics_phone, t.directions, t.plan_arrival_time, t.shipping_time, t.received_time, t.completed_time, t.out_stock_bill_status, t.flow_status, t.shipping_status, t.warehouse_id, t.warehouse_name, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from wms_shipping_bill t
left join erp_contract_info c on t.contract_id = c.contract_id
where t.shipping_bill_id = #{shippingBillId}
</select>
<!-- 批量查询 - 根据ID列表联查合同获取SAP订单号 -->
<select id="selectCustomWmsShippingBillVoByIds" resultMap="WmsShippingBillResult">
select t.shipping_bill_id, t.tenant_id, t.shipping_code, t.shipping_type, t.shipping_mode, t.bind_type, t.project_id, t.project_code, t.project_name, t.customer_id, t.customer_name, t.shipping_address, t.inventory_amount, t.source_bill_type, t.source_bill_id, t.source_bill_code, t.contract_id, t.contract_code, t.contract_name, c.order_contract_code as orderContractCode, t.supplier, t.supplier_id, t.contact_user, t.contact_number, t.receiver_name, t.receiver_phone, t.logistics_company, t.tracking_no, t.logistics_phone, t.directions, t.plan_arrival_time, t.shipping_time, t.received_time, t.completed_time, t.out_stock_bill_status, t.flow_status, t.shipping_status, t.warehouse_id, t.warehouse_name, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from wms_shipping_bill t
left join erp_contract_info c on t.contract_id = c.contract_id
where t.shipping_bill_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 统计查询 -->
<select id="countCustomWmsShippingBill" resultType="java.lang.Long">
select count(1) from wms_shipping_bill t
${ew.getCustomSqlSegment}
</select>
<!-- 分页查询带自定义条件联查合同获取SAP订单号 -->
<select id="selectCustomWmsShippingBillVoPage" resultMap="WmsShippingBillResult">
select t.shipping_bill_id, t.tenant_id, t.shipping_code, t.shipping_type, t.shipping_mode, t.bind_type, t.project_id, t.project_code, t.project_name, t.customer_id, t.customer_name, t.shipping_address, t.inventory_amount, t.source_bill_type, t.source_bill_id, t.source_bill_code, t.contract_id, t.contract_code, t.contract_name, c.order_contract_code as orderContractCode, t.supplier, t.supplier_id, t.contact_user, t.contact_number, t.receiver_name, t.receiver_phone, t.logistics_company, t.tracking_no, t.logistics_phone, t.directions, t.plan_arrival_time, t.shipping_time, t.received_time, t.completed_time, t.out_stock_bill_status, t.flow_status, t.shipping_status, t.warehouse_id, t.warehouse_name, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from wms_shipping_bill t
left join erp_contract_info c on t.contract_id = c.contract_id
${ew.getCustomSqlSegment}
</select>
<!-- 批量插入 -->
<insert id="batchInsertWmsShippingBill">
insert into wms_shipping_bill(
tenant_id,
shipping_code,
shipping_type,
shipping_mode,
bind_type,
project_id,
project_code,
project_name,
customer_id,
customer_name,
shipping_address,
inventory_amount,
source_bill_type,
source_bill_id,
source_bill_code,
contract_id,
contract_code,
contract_name,
supplier,
supplier_id,
contact_user,
contact_number,
receiver_name,
receiver_phone,
logistics_company,
tracking_no,
logistics_phone,
directions,
plan_arrival_time,
shipping_time,
received_time,
completed_time,
out_stock_bill_status,
flow_status,
shipping_status,
warehouse_id,
warehouse_name,
remark,
del_flag,
create_dept,
create_by,
create_time,
update_by,
update_time
)
values
<foreach collection="list" item="item" separator=",">
(
#{item.tenantId},
#{item.shippingCode},
#{item.shippingType},
#{item.shippingMode},
#{item.bindType},
#{item.projectId},
#{item.projectCode},
#{item.projectName},
#{item.customerId},
#{item.customerName},
#{item.shippingAddress},
#{item.inventoryAmount},
#{item.sourceBillType},
#{item.sourceBillId},
#{item.sourceBillCode},
#{item.contractId},
#{item.contractCode},
#{item.contractName},
#{item.supplier},
#{item.supplierId},
#{item.contactUser},
#{item.contactNumber},
#{item.receiverName},
#{item.receiverPhone},
#{item.logisticsCompany},
#{item.trackingNo},
#{item.logisticsPhone},
#{item.directions},
#{item.planArrivalTime},
#{item.shippingTime},
#{item.receivedTime},
#{item.completedTime},
#{item.outStockBillStatus},
#{item.flowStatus},
#{item.shippingStatus},
#{item.warehouseId},
#{item.warehouseName},
#{item.remark},
#{item.delFlag},
#{item.createDept},
#{item.createBy},
#{item.createTime},
#{item.updateBy},
#{item.updateTime}
)
</foreach>
</insert>
<!-- 批量更新 -->
<update id="batchUpdateWmsShippingBill">
<foreach collection="list" item="item" separator=";">
update wms_shipping_bill t
<set>
<if test="item.tenantId != null and item.tenantId != ''">
t.tenant_id = #{item.tenantId},
</if>
<if test="item.shippingCode != null and item.shippingCode != ''">
t.shipping_code = #{item.shippingCode},
</if>
<if test="item.shippingType != null and item.shippingType != ''">
t.shipping_type = #{item.shippingType},
</if>
<if test="item.shippingMode != null and item.shippingMode != ''">
t.shipping_mode = #{item.shippingMode},
</if>
<if test="item.bindType != null and item.bindType != ''">
t.bind_type = #{item.bindType},
</if>
<if test="item.projectId != null">
t.project_id = #{item.projectId},
</if>
<if test="item.projectCode != null and item.projectCode != ''">
t.project_code = #{item.projectCode},
</if>
<if test="item.projectName != null and item.projectName != ''">
t.project_name = #{item.projectName},
</if>
<if test="item.customerId != null">
t.customer_id = #{item.customerId},
</if>
<if test="item.customerName != null and item.customerName != ''">
t.customer_name = #{item.customerName},
</if>
<if test="item.shippingAddress != null and item.shippingAddress != ''">
t.shipping_address = #{item.shippingAddress},
</if>
<if test="item.inventoryAmount != null and item.inventoryAmount != ''">
t.inventory_amount = #{item.inventoryAmount},
</if>
<if test="item.sourceBillType != null and item.sourceBillType != ''">
t.source_bill_type = #{item.sourceBillType},
</if>
<if test="item.sourceBillId != null">
t.source_bill_id = #{item.sourceBillId},
</if>
<if test="item.sourceBillCode != null and item.sourceBillCode != ''">
t.source_bill_code = #{item.sourceBillCode},
</if>
<if test="item.contractId != null">
t.contract_id = #{item.contractId},
</if>
<if test="item.contractCode != null and item.contractCode != ''">
t.contract_code = #{item.contractCode},
</if>
<if test="item.contractName != null and item.contractName != ''">
t.contract_name = #{item.contractName},
</if>
<if test="item.supplier != null and item.supplier != ''">
t.supplier = #{item.supplier},
</if>
<if test="item.supplierId != null">
t.supplier_id = #{item.supplierId},
</if>
<if test="item.contactUser != null and item.contactUser != ''">
t.contact_user = #{item.contactUser},
</if>
<if test="item.contactNumber != null and item.contactNumber != ''">
t.contact_number = #{item.contactNumber},
</if>
<if test="item.receiverName != null and item.receiverName != ''">
t.receiver_name = #{item.receiverName},
</if>
<if test="item.receiverPhone != null and item.receiverPhone != ''">
t.receiver_phone = #{item.receiverPhone},
</if>
<if test="item.logisticsCompany != null and item.logisticsCompany != ''">
t.logistics_company = #{item.logisticsCompany},
</if>
<if test="item.trackingNo != null and item.trackingNo != ''">
t.tracking_no = #{item.trackingNo},
</if>
<if test="item.logisticsPhone != null and item.logisticsPhone != ''">
t.logistics_phone = #{item.logisticsPhone},
</if>
<if test="item.directions != null and item.directions != ''">
t.directions = #{item.directions},
</if>
<if test="item.planArrivalTime != null">
t.plan_arrival_time = #{item.planArrivalTime},
</if>
<if test="item.shippingTime != null">
t.shipping_time = #{item.shippingTime},
</if>
<if test="item.receivedTime != null">
t.received_time = #{item.receivedTime},
</if>
<if test="item.completedTime != null">
t.completed_time = #{item.completedTime},
</if>
<if test="item.outStockBillStatus != null and item.outStockBillStatus != ''">
t.out_stock_bill_status = #{item.outStockBillStatus},
</if>
<if test="item.flowStatus != null and item.flowStatus != ''">
t.flow_status = #{item.flowStatus},
</if>
<if test="item.shippingStatus != null and item.shippingStatus != ''">
t.shipping_status = #{item.shippingStatus},
</if>
<if test="item.warehouseId != null">
t.warehouse_id = #{item.warehouseId},
</if>
<if test="item.warehouseName != null and item.warehouseName != ''">
t.warehouse_name = #{item.warehouseName},
</if>
<if test="item.remark != null and item.remark != ''">
t.remark = #{item.remark},
</if>
<if test="item.delFlag != null and item.delFlag != ''">
t.del_flag = #{item.delFlag},
</if>
<if test="item.createDept != null">
t.create_dept = #{item.createDept},
</if>
<if test="item.createBy != null">
t.create_by = #{item.createBy},
</if>
<if test="item.createTime != null">
t.create_time = #{item.createTime},
</if>
<if test="item.updateBy != null">
t.update_by = #{item.updateBy},
</if>
<if test="item.updateTime != null">
t.update_time = #{item.updateTime}
</if>
</set>
where t.shipping_bill_id = #{item.shippingBillId}
</foreach>
</update>
<!-- 根据自定义条件删除 -->
<delete id="deleteCustomWmsShippingBill">
delete from wms_shipping_bill t
${ew.getCustomSqlSegment}
</delete>
<!-- 根据ID列表批量删除 -->
<delete id="deleteCustomWmsShippingBillByIds">
delete from wms_shipping_bill t
where t.shipping_bill_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 检查是否存在 -->
<select id="existsWmsShippingBill" resultType="java.lang.Boolean">
select count(1) > 0 from wms_shipping_bill t
${ew.getCustomSqlSegment}
</select>
</mapper>

@ -0,0 +1,262 @@
<?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.wms.mapper.WmsShippingDetailsMapper">
<resultMap type="org.dromara.wms.domain.vo.WmsShippingDetailsVo" id="WmsShippingDetailsResult">
</resultMap>
<select id="selectCustomWmsShippingDetailsVoList" resultMap="WmsShippingDetailsResult">
select t.shipping_details_id, t.tenant_id, t.shipping_bill_id, t.material_source_type, t.erp_material_id, t.wms_material_id, t.source_detail_type, t.source_detail_id, t.warehouse_id, t.materiel_id, t.material_code, t.material_name, t.materiel_specification, t.batch_number, t.unit_price, t.shipping_stock_amount, t.unit_id, t.unit_name, t.total_price, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time from wms_shipping_details t
${ew.getCustomSqlSegment}
</select>
<!-- 根据ID查询详情 -->
<select id="selectCustomWmsShippingDetailsVoById" resultMap="WmsShippingDetailsResult">
select t.shipping_details_id, t.tenant_id, t.shipping_bill_id, t.material_source_type, t.erp_material_id, t.wms_material_id, t.source_detail_type, t.source_detail_id, t.warehouse_id, t.materiel_id, t.material_code, t.material_name, t.materiel_specification, t.batch_number, t.unit_price, t.shipping_stock_amount, t.unit_id, t.unit_name, t.total_price, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from wms_shipping_details t
where t.shipping_details_id = #{shippingDetailsId}
</select>
<!-- 批量查询 - 根据ID列表 -->
<select id="selectCustomWmsShippingDetailsVoByIds" resultMap="WmsShippingDetailsResult">
select t.shipping_details_id, t.tenant_id, t.shipping_bill_id, t.material_source_type, t.erp_material_id, t.wms_material_id, t.source_detail_type, t.source_detail_id, t.warehouse_id, t.materiel_id, t.material_code, t.material_name, t.materiel_specification, t.batch_number, t.unit_price, t.shipping_stock_amount, t.unit_id, t.unit_name, t.total_price, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from wms_shipping_details t
where t.shipping_details_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 统计查询 -->
<select id="countCustomWmsShippingDetails" resultType="java.lang.Long">
select count(1) from wms_shipping_details t
${ew.getCustomSqlSegment}
</select>
<!-- 分页查询(带自定义条件) -->
<select id="selectCustomWmsShippingDetailsVoPage" resultMap="WmsShippingDetailsResult">
select t.shipping_details_id, t.tenant_id, t.shipping_bill_id, t.material_source_type, t.erp_material_id, t.wms_material_id, t.source_detail_type, t.source_detail_id, t.warehouse_id, t.materiel_id, t.material_code, t.material_name, t.materiel_specification, t.batch_number, t.unit_price, t.shipping_stock_amount, t.unit_id, t.unit_name, t.total_price, t.remark, t.del_flag, t.create_dept, t.create_by, t.create_time, t.update_by, t.update_time
from wms_shipping_details t
${ew.getCustomSqlSegment}
</select>
<!-- 批量插入 -->
<insert id="batchInsertWmsShippingDetails">
insert into wms_shipping_details(
tenant_id,
shipping_bill_id,
material_source_type,
erp_material_id,
wms_material_id,
source_detail_type,
source_detail_id,
warehouse_id,
materiel_id,
material_code,
material_name,
materiel_specification,
batch_number,
unit_price,
shipping_stock_amount,
unit_id,
unit_name,
total_price,
remark,
del_flag,
create_dept,
create_by,
create_time,
update_by,
update_time
)
values
<foreach collection="list" item="item" separator=",">
(
#{item.tenantId},
#{item.shippingBillId},
#{item.materialSourceType},
#{item.erpMaterialId},
#{item.wmsMaterialId},
#{item.sourceDetailType},
#{item.sourceDetailId},
#{item.warehouseId},
#{item.materielId},
#{item.materialCode},
#{item.materialName},
#{item.materielSpecification},
#{item.batchNumber},
#{item.unitPrice},
#{item.shippingStockAmount},
#{item.unitId},
#{item.unitName},
#{item.totalPrice},
#{item.remark},
#{item.delFlag},
#{item.createDept},
#{item.createBy},
#{item.createTime},
#{item.updateBy},
#{item.updateTime}
)
</foreach>
</insert>
<!-- 批量更新 -->
<update id="batchUpdateWmsShippingDetails">
<foreach collection="list" item="item" separator=";">
update wms_shipping_details t
<set>
<if test="item.tenantId != null and item.tenantId != ''">
t.tenant_id = #{item.tenantId},
</if>
<if test="item.shippingBillId != null">
t.shipping_bill_id = #{item.shippingBillId},
</if>
<if test="item.materialSourceType != null and item.materialSourceType != ''">
t.material_source_type = #{item.materialSourceType},
</if>
<if test="item.erpMaterialId != null">
t.erp_material_id = #{item.erpMaterialId},
</if>
<if test="item.wmsMaterialId != null">
t.wms_material_id = #{item.wmsMaterialId},
</if>
<if test="item.sourceDetailType != null and item.sourceDetailType != ''">
t.source_detail_type = #{item.sourceDetailType},
</if>
<if test="item.sourceDetailId != null">
t.source_detail_id = #{item.sourceDetailId},
</if>
<if test="item.warehouseId != null">
t.warehouse_id = #{item.warehouseId},
</if>
<if test="item.materielId != null">
t.materiel_id = #{item.materielId},
</if>
<if test="item.materialCode != null and item.materialCode != ''">
t.material_code = #{item.materialCode},
</if>
<if test="item.materialName != null and item.materialName != ''">
t.material_name = #{item.materialName},
</if>
<if test="item.materielSpecification != null and item.materielSpecification != ''">
t.materiel_specification = #{item.materielSpecification},
</if>
<if test="item.batchNumber != null and item.batchNumber != ''">
t.batch_number = #{item.batchNumber},
</if>
<if test="item.unitPrice != null">
t.unit_price = #{item.unitPrice},
</if>
<if test="item.shippingStockAmount != null">
t.shipping_stock_amount = #{item.shippingStockAmount},
</if>
<if test="item.unitId != null">
t.unit_id = #{item.unitId},
</if>
<if test="item.unitName != null and item.unitName != ''">
t.unit_name = #{item.unitName},
</if>
<if test="item.totalPrice != null">
t.total_price = #{item.totalPrice},
</if>
<if test="item.remark != null and item.remark != ''">
t.remark = #{item.remark},
</if>
<if test="item.delFlag != null and item.delFlag != ''">
t.del_flag = #{item.delFlag},
</if>
<if test="item.createDept != null">
t.create_dept = #{item.createDept},
</if>
<if test="item.createBy != null">
t.create_by = #{item.createBy},
</if>
<if test="item.createTime != null">
t.create_time = #{item.createTime},
</if>
<if test="item.updateBy != null">
t.update_by = #{item.updateBy},
</if>
<if test="item.updateTime != null">
t.update_time = #{item.updateTime}
</if>
</set>
where t.shipping_details_id = #{item.shippingDetailsId}
</foreach>
</update>
<!-- 根据自定义条件删除 -->
<delete id="deleteCustomWmsShippingDetails">
delete from wms_shipping_details t
${ew.getCustomSqlSegment}
</delete>
<!-- 根据ID列表批量删除 -->
<delete id="deleteCustomWmsShippingDetailsByIds">
delete from wms_shipping_details t
where t.shipping_details_id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 检查是否存在 -->
<select id="existsWmsShippingDetails" resultType="java.lang.Boolean">
select count(1) > 0 from wms_shipping_details t
${ew.getCustomSqlSegment}
</select>
</mapper>
Loading…
Cancel
Save