修改物资逻辑

This commit is contained in:
lcj
2025-08-22 18:46:36 +08:00
parent 8d460b418e
commit 476c19019e
38 changed files with 1201 additions and 116 deletions

View File

@ -21,15 +21,15 @@ public class SaPermissionImpl implements StpInterface {
*/
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
// LoginUser loginUser = LoginHelper.getLoginUser();
// UserType userType = UserType.getUserType(loginUser.getUserType());
// if (userType == UserType.SYS_USER) {
// return new ArrayList<>(loginUser.getMenuPermission());
// } else if (userType == UserType.APP_USER) {
// // 其他端 自行根据业务编写
// }
// return new ArrayList<>();
return Collections.singletonList("*");
LoginUser loginUser = LoginHelper.getLoginUser();
UserType userType = UserType.getUserType(loginUser.getUserType());
if (userType == UserType.SYS_USER) {
return new ArrayList<>(loginUser.getMenuPermission());
} else if (userType == UserType.APP_USER) {
// 其他端 自行根据业务编写
}
return new ArrayList<>();
// return Collections.singletonList("*");
}
/**

View File

@ -1,14 +1,12 @@
package org.dromara.bigscreen.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.bigscreen.domain.vo.*;
import org.dromara.bigscreen.service.MoneyBigScreenService;
import org.dromara.common.core.domain.R;
import org.dromara.project.domain.vo.project.BusProjectGisVo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.ctr.domain.CtrExpensesContract;
import org.dromara.ctr.domain.CtrIncomeContract;
import org.dromara.ctr.service.ICtrExpensesContractService;
@ -17,18 +15,23 @@ import org.dromara.out.domain.OutSettlementValueOwner;
import org.dromara.out.domain.OutSettlementValueSubcontract;
import org.dromara.out.service.IOutSettlementValueOwnerService;
import org.dromara.out.service.IOutSettlementValueSubcontractService;
import org.dromara.project.domain.vo.project.BusProjectGisVo;
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.YearMonth;
import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@ -59,7 +62,7 @@ public class MoneyBigScreenController {
* 查询项目位置列表
*/
@SaCheckPermission("money:bigScreen:projectGis")
@RequestMapping("/project/gis")
@GetMapping("/project/gis")
public R<List<BusProjectGisVo>> getProjectGis() {
return R.ok(moneyBigScreenService.getProjectGis());
}
@ -103,15 +106,15 @@ public class MoneyBigScreenController {
)
));
BigDecimal actualAmount =BigDecimal.ZERO;
BigDecimal actualAmount = BigDecimal.ZERO;
for (Long projectId : projectMonthlyAmountMap.keySet()) {
CtrIncomeContract contract = incomeContractService.getOne(Wrappers.lambdaQuery(CtrIncomeContract.class)
CtrIncomeContract contract = incomeContractService.getOne(Wrappers.lambdaQuery(CtrIncomeContract.class)
.eq(CtrIncomeContract::getProjectId, projectId)
.last("limit 1")
);
if(contract != null){
if (contract != null) {
actualAmount = actualAmount.add(projectMonthlyAmountMap.get(projectId).multiply(contract.getPayRatio()).divide(HUNDRED));
}
@ -157,16 +160,16 @@ public class MoneyBigScreenController {
)
));
BigDecimal actualAmount =BigDecimal.ZERO;
BigDecimal actualAmount = BigDecimal.ZERO;
for (String contractCode: projectAmountMap.keySet()) {
for (String contractCode : projectAmountMap.keySet()) {
CtrExpensesContract contract = expensesContractService.getOne(Wrappers.lambdaQuery(CtrExpensesContract.class)
CtrExpensesContract contract = expensesContractService.getOne(Wrappers.lambdaQuery(CtrExpensesContract.class)
.eq(CtrExpensesContract::getContractCode, contractCode)
.last("limit 1")
);
if(contract != null){
if (contract != null) {
actualAmount = actualAmount.add(projectAmountMap.get(contractCode).multiply(contract.getPayRatio()).divide(HUNDRED));
}
@ -176,7 +179,6 @@ public class MoneyBigScreenController {
}
/**
* 收入合同分析
*/
@ -187,23 +189,23 @@ public class MoneyBigScreenController {
List<CtrIncomeContract> list = incomeContractService.list();
// 按金额区间统计数量
Integer lessThan1M = (int)list.stream()
Integer lessThan1M = (int) list.stream()
.filter(contract -> contract.getAmount() != null && contract.getAmount().compareTo(FIRST_PHASE) < 0)
.count();
Integer between1MAnd5M = (int)list.stream()
Integer between1MAnd5M = (int) list.stream()
.filter(contract -> contract.getAmount() != null
&& contract.getAmount().compareTo(FIRST_PHASE) >= 0
&& contract.getAmount().compareTo(SECOND_PHASE) < 0)
.count();
Integer between5MAnd10M = (int)list.stream()
Integer between5MAnd10M = (int) list.stream()
.filter(contract -> contract.getAmount() != null
&& contract.getAmount().compareTo(SECOND_PHASE) >= 0
&& contract.getAmount().compareTo(THIRD_PHASE) < 0)
.count();
Integer greaterThanOrEqualTo10M = (int)list.stream()
Integer greaterThanOrEqualTo10M = (int) list.stream()
.filter(contract -> contract.getAmount() != null && contract.getAmount().compareTo(THIRD_PHASE) >= 0)
.count();
@ -221,23 +223,23 @@ public class MoneyBigScreenController {
List<CtrExpensesContract> list = expensesContractService.list();
// 按金额区间统计数量
Integer lessThan1M = (int)list.stream()
Integer lessThan1M = (int) list.stream()
.filter(contract -> contract.getAmount() != null && contract.getAmount().compareTo(FIRST_PHASE) < 0)
.count();
Integer between1MAnd5M = (int)list.stream()
Integer between1MAnd5M = (int) list.stream()
.filter(contract -> contract.getAmount() != null
&& contract.getAmount().compareTo(FIRST_PHASE) >= 0
&& contract.getAmount().compareTo(SECOND_PHASE) < 0)
.count();
Integer between5MAnd10M = (int)list.stream()
Integer between5MAnd10M = (int) list.stream()
.filter(contract -> contract.getAmount() != null
&& contract.getAmount().compareTo(SECOND_PHASE) >= 0
&& contract.getAmount().compareTo(THIRD_PHASE) < 0)
.count();
Integer greaterThanOrEqualTo10M = (int)list.stream()
Integer greaterThanOrEqualTo10M = (int) list.stream()
.filter(contract -> contract.getAmount() != null && contract.getAmount().compareTo(THIRD_PHASE) >= 0)
.count();
@ -272,7 +274,7 @@ public class MoneyBigScreenController {
//todo: 工程变更计算 不清楚逻辑 给定个假值
BigDecimal changeAmount = new BigDecimal("0.236");
return R.ok(new MoneyTotalAmountVo(incomeTotalAmount, expensesTotalAmount,profitAmount,changeAmount));
return R.ok(new MoneyTotalAmountVo(incomeTotalAmount, expensesTotalAmount, profitAmount, changeAmount));
}
@ -295,7 +297,7 @@ public class MoneyBigScreenController {
BigDecimal LaborCost = new BigDecimal("16304.89");
BigDecimal manageCost = new BigDecimal("8623.61");
return R.ok(new MoneyCostVo(materialCost, subcontractCost,LaborCost,manageCost));
return R.ok(new MoneyCostVo(materialCost, subcontractCost, LaborCost, manageCost));
}
@ -340,15 +342,15 @@ public class MoneyBigScreenController {
)
));
BigDecimal incomeAmount =BigDecimal.ZERO;
BigDecimal incomeAmount = BigDecimal.ZERO;
for (Long projectId : incomeGroupedByProject.keySet()) {
CtrIncomeContract contract = incomeContractService.getOne(Wrappers.lambdaQuery(CtrIncomeContract.class)
CtrIncomeContract contract = incomeContractService.getOne(Wrappers.lambdaQuery(CtrIncomeContract.class)
.eq(CtrIncomeContract::getProjectId, projectId)
.last("limit 1")
);
if(contract != null){
if (contract != null) {
incomeAmount = incomeAmount.add(incomeGroupedByProject.get(projectId).multiply(contract.getPayRatio()).divide(HUNDRED));
}
@ -371,16 +373,16 @@ public class MoneyBigScreenController {
)
));
BigDecimal expensesAmount =BigDecimal.ZERO;
BigDecimal expensesAmount = BigDecimal.ZERO;
for (String contractCode: expenseGroupedByContract.keySet()) {
for (String contractCode : expenseGroupedByContract.keySet()) {
CtrExpensesContract contract = expensesContractService.getOne(Wrappers.lambdaQuery(CtrExpensesContract.class)
CtrExpensesContract contract = expensesContractService.getOne(Wrappers.lambdaQuery(CtrExpensesContract.class)
.eq(CtrExpensesContract::getContractCode, contractCode)
.last("limit 1")
);
if(contract != null){
if (contract != null) {
expensesAmount = expensesAmount.add(expenseGroupedByContract.get(contractCode).multiply(contract.getPayRatio()).divide(HUNDRED));
}
@ -442,15 +444,15 @@ public class MoneyBigScreenController {
)
));
BigDecimal incomeAmount =BigDecimal.ZERO;
BigDecimal incomeAmount = BigDecimal.ZERO;
for (Long projectId : incomeGroupedByProject.keySet()) {
CtrIncomeContract contract = incomeContractService.getOne(Wrappers.lambdaQuery(CtrIncomeContract.class)
CtrIncomeContract contract = incomeContractService.getOne(Wrappers.lambdaQuery(CtrIncomeContract.class)
.eq(CtrIncomeContract::getProjectId, projectId)
.last("limit 1")
);
if(contract != null){
if (contract != null) {
incomeAmount = incomeAmount.add(incomeGroupedByProject.get(projectId).multiply(contract.getPayRatio()).divide(HUNDRED));
}
@ -473,16 +475,16 @@ public class MoneyBigScreenController {
)
));
BigDecimal expensesAmount =BigDecimal.ZERO;
BigDecimal expensesAmount = BigDecimal.ZERO;
for (String contractCode: expenseGroupedByContract.keySet()) {
for (String contractCode : expenseGroupedByContract.keySet()) {
CtrExpensesContract contract = expensesContractService.getOne(Wrappers.lambdaQuery(CtrExpensesContract.class)
CtrExpensesContract contract = expensesContractService.getOne(Wrappers.lambdaQuery(CtrExpensesContract.class)
.eq(CtrExpensesContract::getContractCode, contractCode)
.last("limit 1")
);
if(contract != null){
if (contract != null) {
expensesAmount = expensesAmount.add(expenseGroupedByContract.get(contractCode).multiply(contract.getPayRatio()).divide(HUNDRED));
}
@ -534,9 +536,10 @@ public class MoneyBigScreenController {
/**
* 获取当前月份的开始时间和结束时间
*
* @return
*/
public Map<String, LocalDate> getMonthStartAndEnd() {
public Map<String, LocalDate> getMonthStartAndEnd() {
LocalDate now = LocalDate.now();
LocalDate start = now.with(TemporalAdjusters.firstDayOfMonth());
LocalDate end = now.with(TemporalAdjusters.lastDayOfMonth());
@ -545,4 +548,24 @@ public class MoneyBigScreenController {
put("end", end);
}};
}
/**
* 查询项目天气
*/
@SaCheckPermission("project:bigScreen:weather")
@GetMapping("/weather/{projectId}")
public R<List<BusProjectWeatherVo>> getProjectWeather(@NotNull(message = "主键不能为空")
@PathVariable Long projectId) {
return R.ok(moneyBigScreenService.getProjectWeather(projectId));
}
/**
* 查询项目安全天数
*/
@SaCheckPermission("project:bigScreen:safetyDay")
@GetMapping("/safetyDay/{projectId}")
public R<BusProjectSafetyDayVo> getProjectSafetyDay(@NotNull(message = "主键不能为空")
@PathVariable Long projectId) {
return R.ok(moneyBigScreenService.getProjectSafetyDay(projectId));
}
}

View File

@ -1,33 +1,26 @@
package org.dromara.bigscreen.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import org.dromara.bigscreen.service.ProjectBigScreenService;
import org.dromara.common.core.domain.R;
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
import org.dromara.project.domain.vo.projectnews.BusProjectNewsVo;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.bigscreen.domain.vo.ProjectLandVo;
import org.dromara.bigscreen.service.ProjectBigScreenService;
import org.dromara.common.core.domain.R;
import org.dromara.land.domain.BusLandBlock;
import org.dromara.land.domain.BusLandTransferLedger;
import org.dromara.land.service.IBusLandBlockService;
import org.dromara.land.service.IBusLandTransferLedgerService;
import org.dromara.message.service.IMsgNotifyTargetDetailService;
import org.dromara.tender.domain.vo.BusBiddingPlanAnnexVo;
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
import org.dromara.project.domain.vo.projectnews.BusProjectNewsVo;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@ -53,10 +46,13 @@ public class ProjectBigScreenController {
private final IBusLandBlockService busLandBlockService;
/**
* 查询项目土地统计
*/
@GetMapping("/{projectId}")
public R<List<ProjectLandVo>> landCount(@NotNull(message = "主键不能为空")
@PathVariable Long projectId) {
List<BusLandTransferLedger> levelList = busLandTransferLedgerService.list(Wrappers.lambdaQuery(BusLandTransferLedger.class)
List<BusLandTransferLedger> levelList = busLandTransferLedgerService.list(Wrappers.lambdaQuery(BusLandTransferLedger.class)
.eq(BusLandTransferLedger::getProjectId, projectId));
// 根据 landBlockId 分组,并对 designArea 和 transferAea 进行求和
@ -86,8 +82,8 @@ public class ProjectBigScreenController {
));
List<ProjectLandVo> result = new ArrayList<>();
for(Long landBlockId : groupedResult.keySet()){
List<ProjectLandVo> result = new ArrayList<>();
for (Long landBlockId : groupedResult.keySet()) {
ProjectLandVo projectLandVo = new ProjectLandVo();
BusLandBlock landBlock = busLandBlockService.getById(landBlockId);
projectLandVo.setLandName(landBlock.getLandName());

View File

@ -1,6 +1,8 @@
package org.dromara.bigscreen.service;
import org.dromara.project.domain.vo.project.BusProjectGisVo;
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
import java.util.List;
@ -17,4 +19,20 @@ public interface MoneyBigScreenService {
*/
List<BusProjectGisVo> getProjectGis();
/**
* 获取项目天气
*
* @param projectId 项目id
* @return 项目天气
*/
List<BusProjectWeatherVo> getProjectWeather(Long projectId);
/**
* 获取项目安全天数
*
* @param projectId 项目id
* @return 项目安全天数
*/
BusProjectSafetyDayVo getProjectSafetyDay(Long projectId);
}

View File

@ -2,7 +2,12 @@ package org.dromara.bigscreen.service.impl;
import jakarta.annotation.Resource;
import org.dromara.bigscreen.service.MoneyBigScreenService;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.project.domain.BusProject;
import org.dromara.project.domain.vo.project.BusProjectGisVo;
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
import org.dromara.project.service.IBusProjectService;
import org.springframework.stereotype.Service;
@ -27,4 +32,40 @@ public class MoneyBigScreenServiceImpl implements MoneyBigScreenService {
public List<BusProjectGisVo> getProjectGis() {
return projectService.getGisList();
}
/**
* 获取项目天气
*
* @param projectId 项目id
* @return 项目天气
*/
@Override
public List<BusProjectWeatherVo> getProjectWeather(Long projectId) {
checkProject(projectId);
return projectService.getWeather(projectId);
}
/**
* 获取项目安全天数
*
* @param projectId 项目id
* @return 项目安全天数
*/
@Override
public BusProjectSafetyDayVo getProjectSafetyDay(Long projectId) {
checkProject(projectId);
return projectService.getSafetyDay(projectId);
}
/**
* 检查项目是否存在
*
* @param projectId 项目id
*/
private void checkProject(Long projectId) {
BusProject project = projectService.getById(projectId);
if (project == null) {
throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND);
}
}
}

View File

@ -19,8 +19,9 @@ import org.dromara.materials.domain.dto.materials.MatMaterialsCreateReq;
import org.dromara.materials.domain.dto.materials.MatMaterialsGisReq;
import org.dromara.materials.domain.dto.materials.MatMaterialsQueryReq;
import org.dromara.materials.domain.dto.materials.MatMaterialsUpdateReq;
import org.dromara.materials.domain.vo.materials.MatMaterialsVo;
import org.dromara.materials.domain.vo.materials.MatMaterialsGisVo;
import org.dromara.materials.domain.vo.materials.MatMaterialsNumberVo;
import org.dromara.materials.domain.vo.materials.MatMaterialsVo;
import org.dromara.materials.service.IMatMaterialsService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -70,6 +71,16 @@ public class MatMaterialsController extends BaseController {
return R.ok(materialsService.queryGisList(req));
}
/**
* 查询库存数量
*/
@SaCheckPermission("materials:materials:inventoryNumber")
@GetMapping("/inventoryNumber/{projectId}")
public R<List<MatMaterialsNumberVo>> queryInventoryList(@NotNull(message = "项目id不能为空")
@PathVariable Long projectId) {
return R.ok(materialsService.queryInventoryList(projectId));
}
/**
* 获取材料详细信息
*

View File

@ -0,0 +1,93 @@
package org.dromara.materials.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.dromara.common.core.domain.R;
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.materials.domain.dto.materialsuserecord.MatMaterialsUseRecordCreateReq;
import org.dromara.materials.domain.dto.materialsuserecord.MatMaterialsUseRecordQueryReq;
import org.dromara.materials.domain.dto.materialsuserecord.MatMaterialsUseRecordUpdateReq;
import org.dromara.materials.domain.vo.materialsuserecord.MatMaterialsUseRecordVo;
import org.dromara.materials.service.IMatMaterialsUseRecordService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 材料使用登记
*
* @author lilemy
* @date 2025-08-22
*/
@Validated
@RestController
@RequestMapping("/materials/materialsUseRecord")
public class MatMaterialsUseRecordController extends BaseController {
@Resource
private IMatMaterialsUseRecordService matMaterialsUseRecordService;
/**
* 查询材料使用登记列表
*/
@SaCheckPermission("materials:materialsUseRecord:list")
@GetMapping("/list")
public TableDataInfo<MatMaterialsUseRecordVo> list(MatMaterialsUseRecordQueryReq req, PageQuery pageQuery) {
return matMaterialsUseRecordService.queryPageList(req, pageQuery);
}
/**
* 获取材料使用登记详细信息
*
* @param id 主键
*/
@SaCheckPermission("materials:materialsUseRecord:query")
@GetMapping("/{id}")
public R<MatMaterialsUseRecordVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(matMaterialsUseRecordService.queryById(id));
}
/**
* 新增材料使用登记
*/
@SaCheckPermission("materials:materialsUseRecord:add")
@Log(title = "材料使用登记", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated @RequestBody MatMaterialsUseRecordCreateReq req) {
return toAjax(matMaterialsUseRecordService.insertByBo(req));
}
/**
* 修改材料使用登记
*/
@SaCheckPermission("materials:materialsUseRecord:edit")
@Log(title = "材料使用登记", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated @RequestBody MatMaterialsUseRecordUpdateReq req) {
return toAjax(matMaterialsUseRecordService.updateByBo(req));
}
/**
* 删除材料使用登记
*
* @param ids 主键串
*/
@SaCheckPermission("materials:materialsUseRecord:remove")
@Log(title = "材料使用登记", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(matMaterialsUseRecordService.deleteByIds(List.of(ids)));
}
}

View File

@ -74,11 +74,6 @@ public class MatMaterialsInventory extends BaseEntity {
*/
private String disposition;
/**
* 使用部位
*/
private String usePart;
/**
* 交接单位(班组)
*/

View File

@ -0,0 +1,62 @@
package org.dromara.materials.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
import java.math.BigDecimal;
/**
* 材料使用登记对象 mat_materials_use_record
*
* @author lilemy
* @date 2025-08-22
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("mat_materials_use_record")
public class MatMaterialsUseRecord extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 项目ID
*/
private Long projectId;
/**
* 库存ID
*/
private Long inventoryId;
/**
* 使用部位
*/
private String usePart;
/**
* 使用数量
*/
private BigDecimal useNumber;
/**
* 剩余量
*/
private BigDecimal residueNumber;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,65 @@
package org.dromara.materials.domain.bo;
import org.dromara.materials.domain.MatMaterialsUseRecord;
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.*;
/**
* 材料使用登记业务对象 mat_materials_use_record
*
* @author lilemy
* @date 2025-08-22
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = MatMaterialsUseRecord.class, reverseConvertGenerate = false)
public class MatMaterialsUseRecordBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 项目ID
*/
@NotNull(message = "项目ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long projectId;
/**
* 库存ID
*/
@NotNull(message = "库存ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long inventoryId;
/**
* 使用部位
*/
@NotBlank(message = "使用部位不能为空", groups = { AddGroup.class, EditGroup.class })
private String usePart;
/**
* 使用数量
*/
@NotNull(message = "使用数量不能为空", groups = { AddGroup.class, EditGroup.class })
private Long useNumber;
/**
* 剩余量
*/
@NotNull(message = "剩余量不能为空", groups = { AddGroup.class, EditGroup.class })
private Long residueNumber;
/**
* 备注
*/
private String remark;
}

View File

@ -1,5 +1,7 @@
package org.dromara.materials.domain.dto.materialissue;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.dromara.materials.domain.dto.materialissueitem.MatMaterialIssueItemDto;
@ -17,24 +19,22 @@ public class MatMaterialIssueCreateReq implements Serializable {
@Serial
private static final long serialVersionUID = 2742974667799153892L;
/**
* 主键id
*/
private Long id;
/**
* 项目id
*/
@NotNull(message = "项目id不能为空")
private Long projectId;
/**
* 材料来源(1甲供 2乙供)
*/
@NotBlank(message = "材料来源不能为空")
private String materialSource;
/**
* 表单编号
*/
@NotNull(message = "表单编号不能为空")
private String formCode;
/**
@ -60,6 +60,7 @@ public class MatMaterialIssueCreateReq implements Serializable {
/**
* 领料单位
*/
@NotBlank(message = "领料单位不能为空")
private String issueUnit;
/**

View File

@ -1,5 +1,7 @@
package org.dromara.materials.domain.dto.materialissueitem;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -20,34 +22,46 @@ public class MatMaterialIssueItemDto {
*/
private Long id;
/**
* 材料id
*/
@NotNull(message = "材料id不能为空")
private Long materialsId;
/**
* 名称
*/
@NotBlank(message = "名称不能为空")
private String name;
/**
* 规格
*/
@NotBlank(message = "规格不能为空")
private String specification;
/**
* 单位
*/
@NotBlank(message = "单位不能为空")
private String unit;
/**
* 库存
*/
@NotNull(message = "库存数量不能为空")
private BigDecimal stockQuantity;
/**
* 领取
*/
@NotNull(message = "领取数量不能为空")
private BigDecimal issuedQuantity;
/**
* 剩余
*/
@NotNull(message = "剩余数量不能为空")
private BigDecimal remainingQuantity;
/**

View File

@ -61,11 +61,6 @@ public class MatMaterialsInventoryCreateReq implements Serializable {
*/
private String recipient;
/**
* 使用部位
*/
private String usePart;
/**
* 领用人
*/

View File

@ -4,7 +4,6 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* @author lilemy
@ -61,9 +60,4 @@ public class MatMaterialsInventoryQueryReq implements Serializable {
*/
private String shipper;
/**
* 使用部位
*/
private String usePart;
}

View File

@ -46,11 +46,6 @@ public class MatMaterialsInventoryUpdateReq implements Serializable {
*/
private String path;
/**
* 使用部位
*/
private String usePart;
/**
* 处理方式
*/

View File

@ -0,0 +1,50 @@
package org.dromara.materials.domain.dto.materialsuserecord;
import com.baomidou.mybatisplus.annotation.TableId;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author lilemy
* @date 2025-08-22 15:36
*/
@Data
public class MatMaterialsUseRecordCreateReq implements Serializable {
@Serial
private static final long serialVersionUID = -5040208122865660213L;
/**
* 项目ID
*/
@NotNull(message = "项目ID不能为空")
private Long projectId;
/**
* 库存ID
*/
@NotNull(message = "库存ID不能为空")
private Long inventoryId;
/**
* 使用部位
*/
@NotBlank(message = "使用部位不能为空")
private String usePart;
/**
* 使用数量
*/
@NotNull(message = "使用数量不能为空")
private BigDecimal useNumber;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,42 @@
package org.dromara.materials.domain.dto.materialsuserecord;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author lilemy
* @date 2025-08-22 15:37
*/
@Data
public class MatMaterialsUseRecordQueryReq implements Serializable {
@Serial
private static final long serialVersionUID = 1669916497022457066L;
/**
* 项目ID
*/
private Long projectId;
/**
* 库存ID
*/
private Long inventoryId;
/**
* 使用部位
*/
private String usePart;
/**
* 使用数量
*/
private BigDecimal useNumber;
/**
* 剩余量
*/
private BigDecimal residueNumber;
}

View File

@ -0,0 +1,40 @@
package org.dromara.materials.domain.dto.materialsuserecord;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author lilemy
* @date 2025-08-22 15:36
*/
@Data
public class MatMaterialsUseRecordUpdateReq implements Serializable {
@Serial
private static final long serialVersionUID = 2735762010782547521L;
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空")
private Long id;
/**
* 使用部位
*/
private String usePart;
/**
* 使用数量
*/
private BigDecimal useNumber;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,43 @@
package org.dromara.materials.domain.vo.materials;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author lilemy
* @date 2025-08-22 16:54
*/
@Data
public class MatMaterialsNumberVo implements Serializable {
@Serial
private static final long serialVersionUID = 9174427789976252587L;
/**
* 主键id
*/
private Long id;
/**
* 材料名称
*/
private String materialsName;
/**
* 规格型号名称
*/
private String typeSpecificationName;
/**
* 计量单位
*/
private String weightId;
/**
* 库存数量
*/
private BigDecimal inventoryNumber;
}

View File

@ -102,12 +102,6 @@ public class MatMaterialsInventoryVo implements Serializable {
@ExcelProperty(value = "交接单位")
private String recipient;
/**
* 使用部位
*/
@ExcelProperty(value = "使用部位")
private String usePart;
/**
* 领用人
*/

View File

@ -0,0 +1,70 @@
package org.dromara.materials.domain.vo.materialsuserecord;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.materials.domain.MatMaterialsUseRecord;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 材料使用登记视图对象 mat_materials_use_record
*
* @author lilemy
* @date 2025-08-22
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = MatMaterialsUseRecord.class)
public class MatMaterialsUseRecordVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 项目ID
*/
@ExcelProperty(value = "项目ID")
private Long projectId;
/**
* 库存ID
*/
@ExcelProperty(value = "库存ID")
private Long inventoryId;
/**
* 使用部位
*/
@ExcelProperty(value = "使用部位")
private String usePart;
/**
* 使用数量
*/
@ExcelProperty(value = "使用数量")
private BigDecimal useNumber;
/**
* 剩余量
*/
@ExcelProperty(value = "剩余量")
private BigDecimal residueNumber;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@ -1,13 +1,12 @@
package org.dromara.materials.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.dromara.cailiaoshebei.domain.bo.RepertoryDetailsListReq;
import org.dromara.cailiaoshebei.domain.vo.RepertoryDetailsListRes;
import org.dromara.materials.domain.MatMaterialsInventory;
import org.dromara.materials.domain.dto.materialsinventory.MatMaterialsInventoryQueryReq;
import org.dromara.materials.domain.vo.materialsinventory.MatMaterialsInventoryVo;
import org.apache.ibatis.annotations.Select;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.materials.domain.MatMaterialsInventory;
import org.dromara.materials.domain.vo.materialsinventory.MatMaterialsInventoryVo;
import java.util.List;
/**
* 材料出/入库Mapper接口
@ -22,5 +21,22 @@ public interface MatMaterialsInventoryMapper extends BaseMapperPlus<MatMaterials
// */
// Page<MatMaterialsInventoryVo> getInventoryList(@Param("bo") MatMaterialsInventoryQueryReq req, @Param("page") Page<RepertoryDetailsListReq> page);
/**
* 根据材料id列表查询最新一条数据
*
* @param materialIds 材料id列表
* @return 每个材料id的最新一条数据
*/
@Select("""
SELECT *
FROM (
SELECT m.*,
ROW_NUMBER() OVER (PARTITION BY m.materials_id ORDER BY m.create_time DESC) AS rn
FROM mat_materials_inventory m
WHERE m.materials_id IN (${ids})
) t
WHERE t.rn = 1
""")
List<MatMaterialsInventory> selectLatestByMaterialIds(@Param("ids") List<Long> materialIds);
}

View File

@ -0,0 +1,15 @@
package org.dromara.materials.mapper;
import org.dromara.materials.domain.MatMaterialsUseRecord;
import org.dromara.materials.domain.vo.materialsuserecord.MatMaterialsUseRecordVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 材料使用登记Mapper接口
*
* @author lilemy
* @date 2025-08-22
*/
public interface MatMaterialsUseRecordMapper extends BaseMapperPlus<MatMaterialsUseRecord, MatMaterialsUseRecordVo> {
}

View File

@ -96,4 +96,12 @@ public interface IMatMaterialsInventoryService extends IService<MatMaterialsInve
*/
Page<MatMaterialsInventoryVo> getVoPage(Page<MatMaterialsInventory> materialsInventoryPage);
/**
* 获取最新材料出/入库列表
*
* @param materialIds 材料ID列表
* @return 最新材料出/入库列表
*/
List<MatMaterialsInventory> selectLatestByMaterialIds(List<Long> materialIds);
}

View File

@ -11,8 +11,9 @@ import org.dromara.materials.domain.dto.materials.MatMaterialsCreateReq;
import org.dromara.materials.domain.dto.materials.MatMaterialsGisReq;
import org.dromara.materials.domain.dto.materials.MatMaterialsQueryReq;
import org.dromara.materials.domain.dto.materials.MatMaterialsUpdateReq;
import org.dromara.materials.domain.vo.materials.MatMaterialsVo;
import org.dromara.materials.domain.vo.materials.MatMaterialsGisVo;
import org.dromara.materials.domain.vo.materials.MatMaterialsNumberVo;
import org.dromara.materials.domain.vo.materials.MatMaterialsVo;
import java.util.Collection;
import java.util.List;
@ -112,5 +113,12 @@ public interface IMatMaterialsService extends IService<MatMaterials> {
*/
void create(Long projectId, List<MatMaterialReceiveItemDto> itemList);
/**
* 获取材料库存数据列表
*
* @param projectId 项目id
* @return 材料库存数据列表
*/
List<MatMaterialsNumberVo> queryInventoryList(Long projectId);
}

View File

@ -0,0 +1,97 @@
package org.dromara.materials.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.materials.domain.MatMaterialsUseRecord;
import org.dromara.materials.domain.dto.materialsuserecord.MatMaterialsUseRecordCreateReq;
import org.dromara.materials.domain.dto.materialsuserecord.MatMaterialsUseRecordQueryReq;
import org.dromara.materials.domain.dto.materialsuserecord.MatMaterialsUseRecordUpdateReq;
import org.dromara.materials.domain.vo.materialsuserecord.MatMaterialsUseRecordVo;
import java.util.Collection;
import java.util.List;
/**
* 材料使用登记Service接口
*
* @author lilemy
* @date 2025-08-22
*/
public interface IMatMaterialsUseRecordService extends IService<MatMaterialsUseRecord> {
/**
* 查询材料使用登记
*
* @param id 主键
* @return 材料使用登记
*/
MatMaterialsUseRecordVo queryById(Long id);
/**
* 分页查询材料使用登记列表
*
* @param req 查询条件
* @param pageQuery 分页参数
* @return 材料使用登记分页列表
*/
TableDataInfo<MatMaterialsUseRecordVo> queryPageList(MatMaterialsUseRecordQueryReq req, PageQuery pageQuery);
/**
* 查询符合条件的材料使用登记列表
*
* @param req 查询条件
* @return 材料使用登记列表
*/
List<MatMaterialsUseRecordVo> queryList(MatMaterialsUseRecordQueryReq req);
/**
* 新增材料使用登记
*
* @param req 材料使用登记
* @return 是否新增成功
*/
Boolean insertByBo(MatMaterialsUseRecordCreateReq req);
/**
* 修改材料使用登记
*
* @param req 材料使用登记
* @return 是否修改成功
*/
Boolean updateByBo(MatMaterialsUseRecordUpdateReq req);
/**
* 批量删除材料使用登记信息
*
* @param ids 待删除的主键集合
* @return 是否删除成功
*/
Boolean deleteByIds(Collection<Long> ids);
/**
* 获取材料使用登记视图
*
* @param materialsUseRecord 材料使用登记
* @return 材料使用登记视图
*/
MatMaterialsUseRecordVo getVo(MatMaterialsUseRecord materialsUseRecord);
/**
* 构建查询条件封装
*
* @param req 查询条件
* @return 查询条件封装
*/
LambdaQueryWrapper<MatMaterialsUseRecord> buildQueryWrapper(MatMaterialsUseRecordQueryReq req);
/**
* 获取材料使用登记分页对象视图
*
* @param materialsUseRecordPage 材料使用登记分页对象
* @return 材料使用登记分页对象视图
*/
Page<MatMaterialsUseRecordVo> getVoPage(Page<MatMaterialsUseRecord> materialsUseRecordPage);
}

View File

@ -20,20 +20,24 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.oss.core.OssClient;
import org.dromara.common.oss.exception.OssException;
import org.dromara.common.oss.factory.OssFactory;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.utils.DocumentUtil;
import org.dromara.materials.constants.MatMaterialsConstant;
import org.dromara.materials.domain.MatMaterialIssue;
import org.dromara.materials.domain.MatMaterialIssueItem;
import org.dromara.materials.domain.MatMaterialsInventory;
import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueCreateReq;
import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueQueryReq;
import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueUpdateReq;
import org.dromara.materials.domain.dto.materialissue.MatMaterialIssueWordDto;
import org.dromara.materials.domain.dto.materialissueitem.MatMaterialIssueItemDto;
import org.dromara.materials.domain.dto.materialissueitem.MatMaterialIssueItemWordDto;
import org.dromara.materials.domain.enums.MatMaterialsInventoryOutPutEnum;
import org.dromara.materials.domain.vo.materialissue.MatMaterialIssueVo;
import org.dromara.materials.mapper.MatMaterialIssueMapper;
import org.dromara.materials.service.IMatMaterialIssueItemService;
import org.dromara.materials.service.IMatMaterialIssueService;
import org.dromara.materials.service.IMatMaterialsInventoryService;
import org.dromara.project.service.IBusProjectService;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.service.ISysOssService;
@ -72,6 +76,9 @@ public class MatMaterialIssueServiceImpl extends ServiceImpl<MatMaterialIssueMap
@Resource
private IMatMaterialIssueItemService materialIssueItemService;
@Resource
private IMatMaterialsInventoryService materialsInventoryService;
/**
* 查询物料领料单
*
@ -249,6 +256,25 @@ public class MatMaterialIssueServiceImpl extends ServiceImpl<MatMaterialIssueMap
if (!result) {
throw new ServiceException("物料领料单明细项新增失败", HttpStatus.ERROR);
}
// 创建设备材料出库记录
List<MatMaterialsInventory> inventoryList = itemList.stream().map(item -> {
MatMaterialsInventory inventory = new MatMaterialsInventory();
inventory.setNumber(item.getIssuedQuantity().longValue());
inventory.setOutPutTime(new Date());
inventory.setResidue(item.getRemainingQuantity().longValue());
inventory.setOperator(LoginHelper.getLoginUser().getNickname());
inventory.setRecipient(materialIssue.getIssueUnit());
inventory.setShipper(LoginHelper.getLoginUser().getNickname());
inventory.setMaterialsId(item.getMaterialsId());
inventory.setProjectId(materialIssue.getProjectId());
inventory.setOutPut(MatMaterialsInventoryOutPutEnum.OUT.getValue());
inventory.setRemark(item.getRemark());
return inventory;
}).toList();
boolean saved = materialsInventoryService.saveBatch(inventoryList);
if (!saved) {
throw new ServiceException("物料出库记录新增失败", HttpStatus.ERROR);
}
}
return true;
}

View File

@ -259,7 +259,6 @@ public class MatMaterialsInventoryServiceImpl extends ServiceImpl<MatMaterialsIn
String disposition = req.getDisposition();
String recipient = req.getRecipient();
String shipper = req.getShipper();
String usePart = req.getUsePart();
// 联表查询
if (StringUtils.isNotBlank(materialsName)) {
LambdaQueryWrapper<MatMaterials> materialsQueryWrapper = Wrappers.lambdaQuery(MatMaterials.class)
@ -270,7 +269,6 @@ public class MatMaterialsInventoryServiceImpl extends ServiceImpl<MatMaterialsIn
}
// 模糊查询
lqw.like(StringUtils.isNotBlank(operator), MatMaterialsInventory::getOperator, operator);
lqw.like(StringUtils.isNotBlank(usePart), MatMaterialsInventory::getUsePart, usePart);
lqw.like(StringUtils.isNotBlank(disposition), MatMaterialsInventory::getDisposition, disposition);
lqw.like(StringUtils.isNotBlank(recipient), MatMaterialsInventory::getRecipient, recipient);
lqw.like(StringUtils.isNotBlank(shipper), MatMaterialsInventory::getShipper, shipper);
@ -323,4 +321,15 @@ public class MatMaterialsInventoryServiceImpl extends ServiceImpl<MatMaterialsIn
materialsInventoryVoPage.setRecords(materialsInventoryVoList);
return materialsInventoryVoPage;
}
/**
* 获取最新材料出/入库列表
*
* @param materialIds 材料ID列表
* @return 最新材料出/入库列表
*/
@Override
public List<MatMaterialsInventory> selectLatestByMaterialIds(List<Long> materialIds) {
return baseMapper.selectLatestByMaterialIds(materialIds);
}
}

View File

@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils;
@ -20,14 +21,14 @@ import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.materials.domain.MatMaterials;
import org.dromara.materials.domain.MatMaterialsInventory;
import org.dromara.materials.domain.dto.materialreceiveitem.MatMaterialReceiveItemDto;
import org.dromara.materials.domain.dto.materialsinventory.MatMaterialsInventoryCreateReq;
import org.dromara.materials.domain.dto.materialsinventory.MatMaterialsInventoryUpdateReq;
import org.dromara.materials.domain.enums.MatMaterialsInventoryOutPutEnum;
import org.dromara.materials.domain.dto.materials.MatMaterialsCreateReq;
import org.dromara.materials.domain.dto.materials.MatMaterialsGisReq;
import org.dromara.materials.domain.dto.materials.MatMaterialsQueryReq;
import org.dromara.materials.domain.dto.materials.MatMaterialsUpdateReq;
import org.dromara.materials.domain.dto.materialsinventory.MatMaterialsInventoryCreateReq;
import org.dromara.materials.domain.enums.MatMaterialsInventoryOutPutEnum;
import org.dromara.materials.domain.vo.materials.MatMaterialsGisVo;
import org.dromara.materials.domain.vo.materials.MatMaterialsNumberVo;
import org.dromara.materials.domain.vo.materials.MatMaterialsVo;
import org.dromara.materials.mapper.MatMaterialsMapper;
import org.dromara.materials.service.IMatCompanyService;
@ -42,6 +43,7 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -352,10 +354,10 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
@Override
@Async
public void create(Long projectId,List<MatMaterialReceiveItemDto> itemList) {
public void create(Long projectId, List<MatMaterialReceiveItemDto> itemList) {
for (MatMaterialReceiveItemDto item : itemList) {
Long materialsId ;
Long materialsId;
MatMaterials one = this.getOne(Wrappers.<MatMaterials>lambdaQuery()
.eq(MatMaterials::getMaterialsName, item.getName())
@ -365,7 +367,7 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
BigDecimal bigDecimal = new BigDecimal(one.getQuantityCount());
BigDecimal add = item.getQuantity().add(bigDecimal);
one.setQuantityCount(add.toString());
}else {
} else {
MatMaterials matMaterials = new MatMaterials();
matMaterials.setMaterialsName(item.getName());
matMaterials.setProjectId(projectId);
@ -381,11 +383,43 @@ public class MatMaterialsServiceImpl extends ServiceImpl<MatMaterialsMapper, Mat
req.setMaterialsId(materialsId);
req.setProjectId(projectId);
req.setOutPut("0");
req.setOutPut(MatMaterialsInventoryOutPutEnum.PUT.getValue());
req.setNumber(item.getAcceptedQuantity().longValue());
req.setOutPutTime(new Date());
req.setOperator(LoginHelper.getUsername());
LoginUser loginUser = LoginHelper.getLoginUser();
if (loginUser != null) {
req.setOperator(loginUser.getNickname());
}
materialsInventoryService.insertByBo(req);
}
}
/**
* 获取材料库存数据列表
*
* @param projectId 项目id
* @return 材料库存数据列表
*/
@Override
public List<MatMaterialsNumberVo> queryInventoryList(Long projectId) {
List<MatMaterials> materials = this.lambdaQuery()
.eq(MatMaterials::getProjectId, projectId)
.eq(MatMaterials::getStatus, "0")
.list();
List<Long> materialIds = materials.stream().map(MatMaterials::getId).distinct().toList();
List<MatMaterialsInventory> materialsInventories = materialsInventoryService.selectLatestByMaterialIds(materialIds);
Map<Long, MatMaterialsInventory> map = materialsInventories.stream().collect(Collectors.toMap(
MatMaterialsInventory::getMaterialsId,
Function.identity(),
(a, b) -> a));
return materials.stream().map(material -> {
MatMaterialsNumberVo vo = new MatMaterialsNumberVo();
BeanUtils.copyProperties(material, vo);
Long materialId = material.getId();
if (map.containsKey(materialId)) {
vo.setInventoryNumber(BigDecimal.valueOf(map.get(materialId).getNumber()));
}
return vo;
}).toList();
}
}

View File

@ -0,0 +1,229 @@
package org.dromara.materials.service.impl;
import cn.hutool.core.collection.CollUtil;
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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.materials.domain.MatMaterialsInventory;
import org.dromara.materials.domain.MatMaterialsUseRecord;
import org.dromara.materials.domain.dto.materialsuserecord.MatMaterialsUseRecordCreateReq;
import org.dromara.materials.domain.dto.materialsuserecord.MatMaterialsUseRecordQueryReq;
import org.dromara.materials.domain.dto.materialsuserecord.MatMaterialsUseRecordUpdateReq;
import org.dromara.materials.domain.vo.materialsuserecord.MatMaterialsUseRecordVo;
import org.dromara.materials.mapper.MatMaterialsUseRecordMapper;
import org.dromara.materials.service.IMatMaterialsInventoryService;
import org.dromara.materials.service.IMatMaterialsUseRecordService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
/**
* 材料使用登记Service业务层处理
*
* @author lilemy
* @date 2025-08-22
*/
@Service
public class MatMaterialsUseRecordServiceImpl extends ServiceImpl<MatMaterialsUseRecordMapper, MatMaterialsUseRecord>
implements IMatMaterialsUseRecordService {
@Resource
private IMatMaterialsInventoryService materialsInventoryService;
/**
* 查询材料使用登记
*
* @param id 主键
* @return 材料使用登记
*/
@Override
public MatMaterialsUseRecordVo queryById(Long id) {
MatMaterialsUseRecord materialsUseRecord = this.getById(id);
if (materialsUseRecord == null) {
throw new ServiceException("材料使用登记信息不存在", HttpStatus.NOT_FOUND);
}
return this.getVo(materialsUseRecord);
}
/**
* 分页查询材料使用登记列表
*
* @param req 查询条件
* @param pageQuery 分页参数
* @return 材料使用登记分页列表
*/
@Override
public TableDataInfo<MatMaterialsUseRecordVo> queryPageList(MatMaterialsUseRecordQueryReq req, PageQuery pageQuery) {
Page<MatMaterialsUseRecord> result = this.page(pageQuery.build(), this.buildQueryWrapper(req));
return TableDataInfo.build(this.getVoPage(result));
}
/**
* 查询符合条件的材料使用登记列表
*
* @param req 查询条件
* @return 材料使用登记列表
*/
@Override
public List<MatMaterialsUseRecordVo> queryList(MatMaterialsUseRecordQueryReq req) {
LambdaQueryWrapper<MatMaterialsUseRecord> lqw = this.buildQueryWrapper(req);
return this.list(lqw).stream().map(this::getVo).toList();
}
/**
* 新增材料使用登记
*
* @param req 材料使用登记
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(MatMaterialsUseRecordCreateReq req) {
MatMaterialsUseRecord materialsUseRecord = new MatMaterialsUseRecord();
BeanUtils.copyProperties(req, materialsUseRecord);
Long inventoryId = req.getInventoryId();
MatMaterialsInventory inventory = materialsInventoryService.getById(inventoryId);
if (inventory == null) {
throw new ServiceException("库存信息不存在", HttpStatus.NOT_FOUND);
}
MatMaterialsUseRecord lastRecord = this.getOne(Wrappers.lambdaQuery(MatMaterialsUseRecord.class)
.eq(MatMaterialsUseRecord::getInventoryId, inventoryId)
.orderByDesc(MatMaterialsUseRecord::getCreateTime)
.last("limit 1")
);
BigDecimal residueNumber;
if (lastRecord == null) {
residueNumber = BigDecimal.valueOf(inventory.getNumber());
} else {
residueNumber = lastRecord.getResidueNumber();
}
BigDecimal subtract = residueNumber.subtract(req.getUseNumber());
if (subtract.compareTo(BigDecimal.ZERO) < 0) {
throw new ServiceException("使用数量不能大于库存数量", HttpStatus.BAD_REQUEST);
}
materialsUseRecord.setResidueNumber(subtract);
return this.save(materialsUseRecord);
}
/**
* 修改材料使用登记
*
* @param req 材料使用登记
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(MatMaterialsUseRecordUpdateReq req) {
MatMaterialsUseRecord oldMaterialsUseRecord = this.getById(req.getId());
if (oldMaterialsUseRecord == null) {
throw new ServiceException("材料使用登记信息不存在", HttpStatus.NOT_FOUND);
}
MatMaterialsUseRecord materialsUseRecord = new MatMaterialsUseRecord();
BeanUtils.copyProperties(req, materialsUseRecord);
MatMaterialsUseRecord lastRecord = this.getOne(Wrappers.lambdaQuery(MatMaterialsUseRecord.class)
.select(MatMaterialsUseRecord::getId)
.eq(MatMaterialsUseRecord::getInventoryId, oldMaterialsUseRecord.getInventoryId())
.orderByDesc(MatMaterialsUseRecord::getCreateTime)
.last("limit 1")
);
if (!Objects.equals(lastRecord.getId(), req.getId())) {
throw new ServiceException("只能修改最新数据", HttpStatus.CONFLICT);
}
BigDecimal useNumber = req.getUseNumber();
if (useNumber != null && useNumber.compareTo(oldMaterialsUseRecord.getUseNumber()) != 0) {
BigDecimal subtract = oldMaterialsUseRecord.getResidueNumber().add(oldMaterialsUseRecord.getUseNumber()).subtract(useNumber);
if (subtract.compareTo(BigDecimal.ZERO) < 0) {
throw new ServiceException("使用数量不能大于库存数量", HttpStatus.BAD_REQUEST);
}
materialsUseRecord.setResidueNumber(subtract);
}
return this.updateById(materialsUseRecord);
}
/**
* 批量删除材料使用登记信息
*
* @param ids 待删除的主键集合
* @return 是否删除成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteByIds(Collection<Long> ids) {
return removeBatchByIds(ids);
}
/**
* 获取材料使用登记视图
*
* @param materialsUseRecord 材料使用登记
* @return 材料使用登记视图
*/
@Override
public MatMaterialsUseRecordVo getVo(MatMaterialsUseRecord materialsUseRecord) {
MatMaterialsUseRecordVo vo = new MatMaterialsUseRecordVo();
if (materialsUseRecord == null) {
return vo;
}
BeanUtils.copyProperties(materialsUseRecord, vo);
return vo;
}
/**
* 构建查询条件封装
*
* @param req 查询条件
* @return 查询条件封装
*/
@Override
public LambdaQueryWrapper<MatMaterialsUseRecord> buildQueryWrapper(MatMaterialsUseRecordQueryReq req) {
LambdaQueryWrapper<MatMaterialsUseRecord> lqw = new LambdaQueryWrapper<>();
if (req == null) {
return lqw;
}
Long projectId = req.getProjectId();
Long inventoryId = req.getInventoryId();
String usePart = req.getUsePart();
BigDecimal useNumber = req.getUseNumber();
BigDecimal residueNumber = req.getResidueNumber();
lqw.eq(ObjectUtils.isNotEmpty(projectId), MatMaterialsUseRecord::getProjectId, projectId);
lqw.eq(ObjectUtils.isNotEmpty(inventoryId), MatMaterialsUseRecord::getInventoryId, inventoryId);
lqw.eq(ObjectUtils.isNotEmpty(usePart), MatMaterialsUseRecord::getUsePart, usePart);
lqw.eq(ObjectUtils.isNotEmpty(useNumber), MatMaterialsUseRecord::getUseNumber, useNumber);
lqw.eq(ObjectUtils.isNotEmpty(residueNumber), MatMaterialsUseRecord::getResidueNumber, residueNumber);
lqw.orderByDesc(MatMaterialsUseRecord::getCreateTime);
return lqw;
}
/**
* 获取材料使用登记分页对象视图
*
* @param materialsUseRecordPage 材料使用登记分页对象
* @return 材料使用登记分页对象视图
*/
@Override
public Page<MatMaterialsUseRecordVo> getVoPage(Page<MatMaterialsUseRecord> materialsUseRecordPage) {
List<MatMaterialsUseRecord> materialsUseRecords = materialsUseRecordPage.getRecords();
Page<MatMaterialsUseRecordVo> materialsUseRecordVoPage = new Page<>(
materialsUseRecordPage.getCurrent(),
materialsUseRecordPage.getSize(),
materialsUseRecordPage.getTotal()
);
if (CollUtil.isEmpty(materialsUseRecords)) {
return materialsUseRecordVoPage;
}
List<MatMaterialsUseRecordVo> materialsUseRecordVos = materialsUseRecords.stream().map(this::getVo).toList();
materialsUseRecordVoPage.setRecords(materialsUseRecordVos);
return materialsUseRecordVoPage;
}
}

View File

@ -99,6 +99,11 @@ public class PgsProgressCategory extends BaseEntity {
*/
private String status;
/**
* 祖级列表
*/
private String ancestors;
/**
* 工作类型
*/

View File

@ -57,6 +57,11 @@ public class PgsProgressCategoryTemplate implements Serializable {
*/
private String constructionType;
/**
* 祖级列表
*/
private String ancestors;
/**
* 备注
*/

View File

@ -187,6 +187,17 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
PgsProgressCategory progressCategory = new PgsProgressCategory();
BeanUtils.copyProperties(req, progressCategory);
validEntityBeforeSave(progressCategory);
// 获取祖级列表
Long parentId = req.getParentId();
if (PgsProgressCategoryConstant.TOP_PARENT_ID.equals(parentId)) {
progressCategory.setAncestors(PgsProgressCategoryConstant.TOP_PARENT_ID.toString());
} else {
PgsProgressCategory parent = this.getById(parentId);
if (parent == null) {
throw new ServiceException("父进度类别模版不存在", HttpStatus.NOT_FOUND);
}
progressCategory.setAncestors(parent.getAncestors() + StringUtils.SEPARATOR + progressCategory.getParentId());
}
// 计算产值
if (unitPrice != null && total != null && unitPrice.compareTo(BigDecimal.ZERO) >= 0 && total.compareTo(BigDecimal.ZERO) >= 0) {
progressCategory.setOutputValue(unitPrice.multiply(total));
@ -294,6 +305,17 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
}
// 数据校验
validEntityBeforeSave(progressCategory);
// 获取祖级列表
Long parentId = req.getParentId();
if (PgsProgressCategoryConstant.TOP_PARENT_ID.equals(parentId)) {
progressCategory.setAncestors(PgsProgressCategoryConstant.TOP_PARENT_ID.toString());
} else {
PgsProgressCategory parent = this.getById(parentId);
if (parent == null) {
throw new ServiceException("父进度类别模版不存在", HttpStatus.NOT_FOUND);
}
progressCategory.setAncestors(parent.getAncestors() + StringUtils.SEPARATOR + progressCategory.getParentId());
}
// 写入数据库
boolean result = this.updateById(progressCategory);
if (!result) {

View File

@ -103,6 +103,17 @@ public class PgsProgressCategoryTemplateServiceImpl extends ServiceImpl<PgsProgr
// 数据校验
validEntityBeforeSave(progressCategoryTemplate);
progressCategoryTemplate.setWorkType(this.getTempWorkType(progressCategoryTemplate));
// 获取祖级列表
if (PgsProgressCategoryConstant.TOP_PARENT_ID.equals(progressCategoryTemplate.getParentId())) {
progressCategoryTemplate.setAncestors(PgsProgressCategoryConstant.TOP_PARENT_ID.toString());
} else {
Long parentId = req.getParentId();
PgsProgressCategoryTemplate parent = this.getById(parentId);
if (parent == null) {
throw new ServiceException("父进度类别模版不存在", HttpStatus.NOT_FOUND);
}
progressCategoryTemplate.setAncestors(parent.getAncestors() + StringUtils.SEPARATOR + progressCategoryTemplate.getParentId());
}
// 写入数据库
boolean result = this.save(progressCategoryTemplate);
if (!result) {
@ -129,6 +140,17 @@ public class PgsProgressCategoryTemplateServiceImpl extends ServiceImpl<PgsProgr
// 数据校验
validEntityBeforeSave(progressCategoryTemplate);
progressCategoryTemplate.setWorkType(this.getTempWorkType(progressCategoryTemplate));
// 获取祖级列表
Long parentId = req.getParentId();
if (PgsProgressCategoryConstant.TOP_PARENT_ID.equals(parentId)) {
progressCategoryTemplate.setAncestors(PgsProgressCategoryConstant.TOP_PARENT_ID.toString());
} else {
PgsProgressCategoryTemplate parent = this.getById(parentId);
if (parent == null) {
throw new ServiceException("父进度类别模版不存在", HttpStatus.NOT_FOUND);
}
progressCategoryTemplate.setAncestors(parent.getAncestors() + StringUtils.SEPARATOR + progressCategoryTemplate.getParentId());
}
// 写入数据库
boolean result = this.updateById(progressCategoryTemplate);
if (!result) {

View File

@ -0,0 +1,7 @@
<?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.materials.mapper.MatMaterialsUseRecordMapper">
</mapper>

View File

@ -1994,3 +1994,23 @@ values(1952650149079576582, '通知人员配置详情删除', 195265014907957657
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1952650149079576583, '通知人员配置详情导出', 1952650149079576578, '5', '#', '', 1, 0, 'F', '0', '0', 'message:notifyTargetDetail:export', '#', 103, 1, sysdate(), null, null, '');
-- 菜单 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1958793620743024641, '材料使用登记', '1953994827229114369', '1', 'materialsUseRecord', 'materials/materialsUseRecord/index', 1, 0, 'C', '0', '0', 'materials:materialsUseRecord:list', '#', 103, 1, sysdate(), null, null, '材料使用登记菜单');
-- 按钮 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1958793620743024642, '材料使用登记查询', 1958793620743024641, '1', '#', '', 1, 0, 'F', '0', '0', 'materials:materialsUseRecord:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1958793620743024643, '材料使用登记新增', 1958793620743024641, '2', '#', '', 1, 0, 'F', '0', '0', 'materials:materialsUseRecord:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1958793620743024644, '材料使用登记修改', 1958793620743024641, '3', '#', '', 1, 0, 'F', '0', '0', 'materials:materialsUseRecord:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1958793620743024645, '材料使用登记删除', 1958793620743024641, '4', '#', '', 1, 0, 'F', '0', '0', 'materials:materialsUseRecord:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1958793620743024646, '材料使用登记导出', 1958793620743024641, '5', '#', '', 1, 0, 'F', '0', '0', 'materials:materialsUseRecord:export', '#', 103, 1, sysdate(), null, null, '');

View File

@ -1791,3 +1791,23 @@ create table msg_notify_target_detail
primary key (`id`) using btree,
unique index `un_idx_config_target` (`config_id`, `target_type`, `target_id`)
) comment '通知人员配置详情' collate = utf8mb4_unicode_ci;
drop table if exists mat_materials_use_record;
create table mat_materials_use_record
(
`id` bigint not null auto_increment comment '主键ID',
`project_id` bigint default 0 not null comment '项目ID',
`inventory_id` bigint default 0 not null comment '库存ID',
`use_part` varchar(512) not null comment '使用部位',
`use_number` decimal(10) default 0 not null comment '使用数量',
`residue_number` decimal(10) default 0 not null comment '剩余量',
`remark` varchar(255) null comment '备注',
`create_by` bigint null comment '创建者',
`update_by` bigint null comment '更新者',
`create_dept` bigint null comment '创建部门',
`create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间',
`update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间',
primary key (`id`) using btree,
index `idx_project_id` (`project_id` asc) using btree comment '项目ID',
index `idx_inventory_id` (`inventory_id` asc) using btree comment '库存ID'
) comment '材料使用登记' collate = utf8mb4_unicode_ci;