diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java index 14f3333..bff0ab2 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java @@ -59,7 +59,6 @@ public class SysUserController extends BaseController { /** * 获取用户列表 */ - @SaCheckPermission("system:user:list") @GetMapping("/list") public TableDataInfo list(SysUser user, PageQuery pageQuery) { return userService.selectPageUserList(user, pageQuery); @@ -86,7 +85,6 @@ public class SysUserController extends BaseController { * 导出用户列表 */ @Log(title = "用户管理", businessType = BusinessType.EXPORT) - @SaCheckPermission("system:user:export") @PostMapping("/export") public void export(SysUser user, HttpServletResponse response) { List list = userService.selectUserList(user); @@ -109,7 +107,6 @@ public class SysUserController extends BaseController { * @param updateSupport 是否更新已存在数据 */ @Log(title = "用户管理", businessType = BusinessType.IMPORT) - @SaCheckPermission("system:user:import") @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public R importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception { ExcelResult result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport)); @@ -149,8 +146,6 @@ public class SysUserController extends BaseController { /** * 新增用户 */ - @SaCheckPermission("system:user:add") - @Log(title = "用户管理", businessType = BusinessType.INSERT) @PostMapping public R add(@Validated @RequestBody SysUser user) { if (!userService.checkUserNameUnique(user)) { @@ -167,7 +162,6 @@ public class SysUserController extends BaseController { /** * 修改用户 */ - @SaCheckPermission("system:user:edit") @Log(title = "用户管理", businessType = BusinessType.UPDATE) @PutMapping public R edit(@Validated @RequestBody SysUser user) { @@ -188,7 +182,6 @@ public class SysUserController extends BaseController { * * @param userIds 角色ID串 */ - @SaCheckPermission("system:user:remove") @Log(title = "用户管理", businessType = BusinessType.DELETE) @DeleteMapping("/{userIds}") public R remove(@PathVariable Long[] userIds) { @@ -201,7 +194,6 @@ public class SysUserController extends BaseController { /** * 重置密码 */ - @SaCheckPermission("system:user:resetPwd") @Log(title = "用户管理", businessType = BusinessType.UPDATE) @PutMapping("/resetPwd") public R resetPwd(@RequestBody SysUser user) { @@ -214,7 +206,6 @@ public class SysUserController extends BaseController { /** * 状态修改 */ - @SaCheckPermission("system:user:edit") @Log(title = "用户管理", businessType = BusinessType.UPDATE) @PutMapping("/changeStatus") public R changeStatus(@RequestBody SysUser user) { @@ -228,7 +219,6 @@ public class SysUserController extends BaseController { * * @param userId 用户ID */ - @SaCheckPermission("system:user:query") @GetMapping("/authRole/{userId}") public R> authRole(@PathVariable Long userId) { SysUser user = userService.selectUserById(userId); @@ -245,7 +235,6 @@ public class SysUserController extends BaseController { * @param userId 用户Id * @param roleIds 角色ID串 */ - @SaCheckPermission("system:user:edit") @Log(title = "用户管理", businessType = BusinessType.GRANT) @PutMapping("/authRole") public R insertAuthRole(Long userId, Long[] roleIds) { @@ -257,7 +246,6 @@ public class SysUserController extends BaseController { /** * 获取部门树列表 */ - @SaCheckPermission("system:user:list") @GetMapping("/deptTree") public R>> deptTree(SysDept dept) { return R.ok(deptService.selectDeptTreeList(dept)); @@ -269,7 +257,6 @@ public class SysUserController extends BaseController { * * @param userId 用户Id */ - @SaCheckPermission("system:user:edit") @Log(title = "用户管理", businessType = BusinessType.GRANT) @GetMapping("/tempRole/{userId}") public R insertTempRole(@PathVariable("userId") Long userId) { diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseController.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseController.java index 0db9238..adbe18e 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseController.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseController.java @@ -1,5 +1,7 @@ package com.ruoyi.oa.controller; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Arrays; @@ -10,12 +12,16 @@ import com.ruoyi.common.excel.ExcelResult; import com.ruoyi.oa.domain.SysOaWarehouseMaster; import com.ruoyi.oa.domain.bo.SysOaWarehouseDetailBo; import com.ruoyi.oa.domain.bo.SysOaWarehouseMasterBo; +import com.ruoyi.oa.domain.dto.MonthlyStatsDTO; +import com.ruoyi.oa.domain.dto.SummaryFilterDTO; +import com.ruoyi.oa.domain.vo.SummaryCardVo; import com.ruoyi.oa.listener.SysOaWarehouseListener; import com.ruoyi.oa.service.ISysOaWarehouseMasterService; import lombok.RequiredArgsConstructor; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; @@ -188,4 +194,38 @@ public class SysOaWarehouseController extends BaseController { public void importTemplate(HttpServletResponse response) { ExcelUtil.exportExcel(new ArrayList<>(), "投诉工单", SysOaWarehouseVo.class, response); } + + @GetMapping("/recent") + public R> selectRecentOutbound(@RequestParam(name = "limit", defaultValue = "10") int limit){ + return R.ok(iSysOaWarehouseService.selectRecentOutbound(limit)); + } + + @GetMapping("/cards") + public R> summaryCards( + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + LocalDateTime beginTime, + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + LocalDateTime endTime, + @RequestParam(required = false) String name, + @RequestParam(required = false) String brand, + @RequestParam(required = false) String supplier + ) { + SummaryFilterDTO filter = new SummaryFilterDTO(); + filter.setBeginTime(beginTime); + filter.setEndTime(endTime); + filter.setName(name); + filter.setBrand(brand); + filter.setSupplier(supplier); + return R.ok(iSysOaWarehouseService.getSummaryCards(filter)); + } + + + /** + * 获取某年 1–12 月的入库/出库/库存快照数据 + * @param month 可选参数,格式 yyyy-MM-dd;只读取其年份 + */ + @GetMapping("/monthly") + public R monthly( @RequestParam(required = false) String month ) { + return R.ok(iSysOaWarehouseService.getMonthlyStats(month)); + } } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseMasterController.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseMasterController.java index 150f154..56e03d4 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseMasterController.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseMasterController.java @@ -108,6 +108,15 @@ public class SysOaWarehouseMasterController extends BaseController { return toAjax(iSysOaWarehouseMasterService.updateByBo(bo)); } + /** + * 修改出库单管理 + */ + @RepeatSubmit() + @PutMapping("/updateMasterAndInsertBatchWare") + public R updateMasterAndInsertBatchWare(@Validated(EditGroup.class) @RequestBody SysOaWarehouseMasterBo bo) { + return toAjax(iSysOaWarehouseMasterService.updateMasterAndInsertBatchWare(bo)); + } + /** * 删除出库单管理 * diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseTaskController.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseTaskController.java index b99a31b..8bf6568 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseTaskController.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SysOaWarehouseTaskController.java @@ -111,6 +111,40 @@ public class SysOaWarehouseTaskController extends BaseController { return toAjax(iSysOaWarehouseTaskService.updateByBo(bo)); } + /** + * 修改采购计划 + */ + @Log(title = "采购计划", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping("/editBatch") + public R editBatch(@Validated(EditGroup.class) @RequestBody List bo) { + return toAjax(iSysOaWarehouseTaskService.updateByBoBatch(bo)); + } + + + /** + * 处理单个物料入库 + */ + @RepeatSubmit() + @PutMapping("/status") + public R status(@Validated(EditGroup.class) @RequestBody SysOaWarehouseTaskBo bo) { + return toAjax(iSysOaWarehouseTaskService.updateToWare(bo)); + } + + + /** + * 处理单个物料入库 + */ + @RepeatSubmit() + @PutMapping("/status-list") + public R status(@Validated(EditGroup.class) @RequestBody List boList) { + boList.forEach(bo -> { + int i = iSysOaWarehouseTaskService.updateToWare(bo); + }); + return toAjax(1); + } + + /** * 删除采购计划 * diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaWarehouseDetail.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaWarehouseDetail.java index 24be0e1..1139f34 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaWarehouseDetail.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaWarehouseDetail.java @@ -50,5 +50,7 @@ public class SysOaWarehouseDetail extends BaseEntity { private Double signPrice; + private Long fatherId; + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaWarehouseTask.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaWarehouseTask.java index 028e9e5..48bf2bb 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaWarehouseTask.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/SysOaWarehouseTask.java @@ -1,6 +1,7 @@ package com.ruoyi.oa.domain; import com.baomidou.mybatisplus.annotation.*; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; @@ -8,6 +9,7 @@ import java.util.Date; import java.math.BigDecimal; import com.ruoyi.common.core.domain.BaseEntity; +import org.springframework.format.annotation.DateTimeFormat; /** * 采购计划对象 sys_oa_warehouse_task @@ -66,4 +68,15 @@ public class SysOaWarehouseTask extends BaseEntity { */ private String remark; + /** + * 采购细节状态 + */ + private Long taskStatus; + + + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date endTime; + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseBo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseBo.java index ed93846..e4c6f96 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseBo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseBo.java @@ -80,5 +80,10 @@ public class SysOaWarehouseBo extends BaseEntity { private Long warehouseId; + /** + * 批量新增时状态 + */ + private Long taskStatus; + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseDetailBo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseDetailBo.java index 5c48717..592ec34 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseDetailBo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseDetailBo.java @@ -66,4 +66,7 @@ public class SysOaWarehouseDetailBo extends BaseEntity { // 当为1的时候为入库单 private Long type; + + + private Long fatherId; } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseMasterBo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseMasterBo.java index 7b7e5e3..95788d8 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseMasterBo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseMasterBo.java @@ -65,6 +65,11 @@ public class SysOaWarehouseMasterBo extends BaseEntity { */ private List warehouseList; + /** + * 采购物料详情列表 + */ + private List warehouseTaskList; + private Long status; } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseTaskBo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseTaskBo.java index 093e828..9940f02 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseTaskBo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/SysOaWarehouseTaskBo.java @@ -1,5 +1,6 @@ package com.ruoyi.oa.domain.bo; +import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; import lombok.Data; @@ -9,6 +10,7 @@ import javax.validation.constraints.*; import java.util.Date; import com.ruoyi.common.core.domain.BaseEntity; +import org.springframework.format.annotation.DateTimeFormat; /** * 采购计划业务对象 sys_oa_warehouse_task @@ -71,5 +73,15 @@ public class SysOaWarehouseTaskBo extends BaseEntity { */ private Long id; + /** + * 采购细节状态 + */ + private Long taskStatus; + private Double price; + + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date endTime; } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/dto/MonthlyStatsDTO.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/dto/MonthlyStatsDTO.java new file mode 100644 index 0000000..d2b0a04 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/dto/MonthlyStatsDTO.java @@ -0,0 +1,40 @@ +package com.ruoyi.oa.domain.dto; + +import java.util.List; +import java.util.Map; + +public class MonthlyStatsDTO { + + /** + * key 为 "月",value 为 12 个点(1 月–12 月) + */ + private Map> inData; + private Map> outData; + private Map> dataMap; + + // —— getters & setters —— + + public Map> getInData() { + return inData; + } + + public void setInData(Map> inData) { + this.inData = inData; + } + + public Map> getOutData() { + return outData; + } + + public void setOutData(Map> outData) { + this.outData = outData; + } + + public Map> getDataMap() { + return dataMap; + } + + public void setDataMap(Map> dataMap) { + this.dataMap = dataMap; + } +} diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/dto/SummaryFilterDTO.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/dto/SummaryFilterDTO.java new file mode 100644 index 0000000..714376f --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/dto/SummaryFilterDTO.java @@ -0,0 +1,17 @@ +package com.ruoyi.oa.domain.dto; + + +import lombok.Data; + +import java.time.LocalDateTime; + + +@Data +public class SummaryFilterDTO { + private LocalDateTime beginTime; + private LocalDateTime endTime; + private String name; + private String brand; + private String supplier; + +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SummaryCardVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SummaryCardVo.java new file mode 100644 index 0000000..cae1fe4 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SummaryCardVo.java @@ -0,0 +1,18 @@ +package com.ruoyi.oa.domain.vo; + + +import lombok.Data; + +@Data +public class SummaryCardVo { + private String title; + private Long value; + private Double trend; + + + public SummaryCardVo(String title, Long value, Double trend) { + this.title = title; + this.value = value; + this.trend = trend; + } +} diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseDetailVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseDetailVo.java index 81628a2..2182e6d 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseDetailVo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseDetailVo.java @@ -69,4 +69,6 @@ public class SysOaWarehouseDetailVo extends BaseEntity { private String specifications; private String brand; + + private Long fatherId; } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseMasterVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseMasterVo.java index de17887..279ec13 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseMasterVo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseMasterVo.java @@ -79,5 +79,6 @@ public class SysOaWarehouseMasterVo { private Long status; + private Date nearestEndTime; } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseTaskVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseTaskVo.java index b793246..34cb8a4 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseTaskVo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseTaskVo.java @@ -2,9 +2,12 @@ package com.ruoyi.oa.domain.vo; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.annotation.ExcelDictFormat; import com.ruoyi.common.convert.ExcelDictConvert; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + import java.util.Date; @@ -73,5 +76,14 @@ public class SysOaWarehouseTaskVo { */ private Long warehouseId; + /** + * 采购细节状态 + */ + private Long taskStatus; + + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date endTime; } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseVo.java index 9ae5ae2..80a044d 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseVo.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/SysOaWarehouseVo.java @@ -88,4 +88,10 @@ public class SysOaWarehouseVo extends SysOaWarehouse { private Long threshold; private Long taskInventory; + + private Long lastInbound; + + private Long lastOutbound; + + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaWarehouseDetailMapper.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaWarehouseDetailMapper.java index b119f61..a044b23 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaWarehouseDetailMapper.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaWarehouseDetailMapper.java @@ -6,6 +6,7 @@ import com.ruoyi.oa.domain.bo.SysOaWarehouseDetailBo; import com.ruoyi.oa.domain.vo.SysOaOutWarehouseListVo; import com.ruoyi.oa.domain.vo.SysOaWarehouseDetailVo; import com.ruoyi.common.core.mapper.BaseMapperPlus; +import com.ruoyi.oa.domain.vo.SysOaWarehouseVo; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; @@ -32,4 +33,6 @@ public interface SysOaWarehouseDetailMapper extends BaseMapperPlus List(@Param("projectId") Long projectId); + + List selectRecentOutbound(int limit); } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaWarehouseMapper.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaWarehouseMapper.java index 13a30e6..b76726a 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaWarehouseMapper.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SysOaWarehouseMapper.java @@ -5,10 +5,15 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.oa.domain.SysOaWarehouse; +import com.ruoyi.oa.domain.dto.SummaryFilterDTO; import com.ruoyi.oa.domain.vo.SysOaWarehouseVo; import com.ruoyi.common.core.mapper.BaseMapperPlus; import org.apache.ibatis.annotations.Param; +import java.time.LocalDate; +import java.util.List; +import java.util.Map; + /** * 仓库管理Mapper接口 * @@ -28,4 +33,33 @@ public interface SysOaWarehouseMapper extends BaseMapperPlus selectVoPageThreshold(@Param("page")Page build,@Param(Constants.WRAPPER) LambdaQueryWrapper lqw); Page selectListVoPage(@Param("page")Page build,@Param(Constants.WRAPPER) QueryWrapper lqw); + + /** + * 数据报表使用接口 + */ + // 快照时点的库存总量 + Long selectInventoryAt(@Param("f") SummaryFilterDTO filter); + + // 区间内的在途物料 + Long selectInTransitBetween(@Param("f") SummaryFilterDTO filter); + + // 某日的入库量 + Long selectInboundOn(@Param("f") SummaryFilterDTO filter); + + // 某日的出库量 + Long selectOutboundOn(@Param("f") SummaryFilterDTO filter); + + // 某日的预警信息 + Integer selectWarningOn(@Param("f") SummaryFilterDTO filter); + + + /** 年度入库量按月分组 */ + List> selectInboundByMonth(@Param("year") int year); + + /** 年度出库量按月分组 */ + List> selectOutboundByMonth(@Param("year") int year); + + /** 任意日期的库存快照 */ + Long selectInventorySnapshot(@Param("date") LocalDate date); + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseMasterService.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseMasterService.java index f9134a0..54d75b6 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseMasterService.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseMasterService.java @@ -55,4 +55,12 @@ public interface ISysOaWarehouseMasterService { * @return */ int insertInWarehouse(SysOaWarehouseBo bo, Long id); + + /** + * 更新采购单状态 并且将未作废的以及未完成的 taskStatus=0,1的完成入库操作 + * @param bo + * @return + */ + int updateMasterAndInsertBatchWare(SysOaWarehouseMasterBo bo); + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseService.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseService.java index 8051718..4bce475 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseService.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseService.java @@ -1,5 +1,8 @@ package com.ruoyi.oa.service; +import com.ruoyi.oa.domain.dto.MonthlyStatsDTO; +import com.ruoyi.oa.domain.dto.SummaryFilterDTO; +import com.ruoyi.oa.domain.vo.SummaryCardVo; import com.ruoyi.oa.domain.vo.SysOaWarehouseVo; import com.ruoyi.oa.domain.bo.SysOaWarehouseBo; import com.ruoyi.common.core.page.TableDataInfo; @@ -67,4 +70,19 @@ public interface ISysOaWarehouseService { * @return */ Boolean insertBatch(List boList); + + + /** + * 以下为数据分析专用 + * @param filter + * @return + */ + List getSummaryCards(SummaryFilterDTO filter); + + /** + * @param ymStr 格式 "yyyy-MM",可选;不传则默认当前年月 + */ + MonthlyStatsDTO getMonthlyStats(String ymStr); + + List selectRecentOutbound(int limit); } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseTaskService.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseTaskService.java index 3607527..25eeabd 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseTaskService.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISysOaWarehouseTaskService.java @@ -57,4 +57,8 @@ public interface ISysOaWarehouseTaskService { */ Boolean addBatch(List boList); + int updateByBoBatch(List bo); + + int updateToWare(SysOaWarehouseTaskBo bo); + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaAttendanceServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaAttendanceServiceImpl.java index f08dd88..5a2c53a 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaAttendanceServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaAttendanceServiceImpl.java @@ -243,28 +243,20 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService { Double overTime = 0.0; Double tripDays = 0.0; Double leaveCount = 0.0; - Double workDays = 0.0; Set projSet = new HashSet<>(); for (SysOaAttendanceVo oaAttendanceVo : sysOaAttendanceVos) { - // 出差问题解决 - // 出差 - if (oaAttendanceVo.getProjectId() == 0) { - tripDays++; - - } else if (oaAttendanceVo.getProjectId() == 1) { - leaveCount++; - } - if (oaAttendanceVo.getProjectId() != 0 && oaAttendanceVo.getProjectId() != 1) { + tripDays += oaAttendanceVo.getTripDays(); + leaveCount+=oaAttendanceVo.getAbsenceDays(); + workTimes += oaAttendanceVo.getWorkTimes(); + hourWorkTimes += oaAttendanceVo.getHourWorkTimes(); + overTime += oaAttendanceVo.getOverTime(); + if (oaAttendanceVo.getProjectId() != 0L && oaAttendanceVo.getProjectId() != 1L) { SysOaProjectVo sysOaProjectVo = projectService.queryById(oaAttendanceVo.getProjectId()); oaAttendanceVo.setColor(sysOaProjectVo.getColor()); oaAttendanceVo.setSysOaProjectVo(sysOaProjectVo); oaAttendanceVo.setProjectName(sysOaProjectVo.getProjectName()); projectVos.add(sysOaProjectVo); - workTimes += oaAttendanceVo.getWorkTimes(); - hourWorkTimes += oaAttendanceVo.getHourWorkTimes(); - overTime += oaAttendanceVo.getOverTime(); projSet.add(oaAttendanceVo.getProjectId()); - workDays++; } } // 此为所有小时计的综合 @@ -281,7 +273,7 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService { laborCostData.setOvertime(overTime); costDataList.add(laborCostData); // 构造并保存记录 - addGenData(firstDay, sysUser, tripDays, leaveCount, workDays, projSet, overTime); + addGenData(firstDay, sysUser, tripDays, leaveCount, workTimes, projSet, overTime); } @@ -297,9 +289,9 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService { // 当前操作人昵称 rec.setNickName(sysUser.getNickName()); rec.setUserId(sysUser.getUserId()); - rec.setTrips(BigDecimal.valueOf(tripDays)); - rec.setNotNum(BigDecimal.valueOf(leaveCount)); - rec.setWorks(BigDecimal.valueOf(workDays)); + rec.setTrips(new BigDecimal(tripDays.toString())); + rec.setNotNum(new BigDecimal(leaveCount.toString())); + rec.setWorks(new BigDecimal(workDays.toString())); rec.setProjectIds( String.join(",", projSet.stream().map(String::valueOf).toArray(String[]::new) @@ -362,7 +354,6 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService { // 将字符串拼接 format += dateLength; format += " 23:59:59"; - return DateUtils.parseDate(DateUtils.parseDateToStr(format, time)); } } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseDetailServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseDetailServiceImpl.java index e0d6ecf..324410a 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseDetailServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseDetailServiceImpl.java @@ -126,6 +126,7 @@ public class SysOaWarehouseDetailServiceImpl implements ISysOaWarehouseDetailSer lqw.eq(bo.getProjectId() != null, SysOaWarehouseDetail::getProjectId, bo.getProjectId()); lqw.eq(bo.getAmount() != null, SysOaWarehouseDetail::getAmount, bo.getAmount()); lqw.eq(bo.getWarehouseId() != null, SysOaWarehouseDetail::getWarehouseId, bo.getWarehouseId()); + lqw.eq(bo.getFatherId() != null, SysOaWarehouseDetail::getFatherId, bo.getFatherId()); return lqw; } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseMasterServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseMasterServiceImpl.java index a169576..5209617 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseMasterServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseMasterServiceImpl.java @@ -70,19 +70,31 @@ public class SysOaWarehouseMasterServiceImpl implements ISysOaWarehouseMasterSer private QueryWrapper buildQueryWrapper(SysOaWarehouseMasterBo bo) { Map params = bo.getParams(); QueryWrapper lqw = Wrappers.query(); - lqw.eq(bo.getType() != null, "sowm.type", bo.getType()); - lqw.eq(bo.getProjectId() != null, "sowm.project_id", bo.getProjectId()); + lqw.eq(bo.getType() != null, "sowm.type", bo.getType()) + .eq(bo.getProjectId()!= null, "sowm.project_id", bo.getProjectId()) + // 其他过滤…… + .eq("sowm.del_flag", 0) + .orderByDesc("sowm.create_time"); - if (bo.getSignTime() != null) { - long time = bo.getSignTime().getTime(); - lqw.apply( - "DATE(sowm.sign_time) = {0}", // MySQL DATE() 抽取日期部分 - new Date(time)); // 2025‑05‑13 + // 只有在 type = 2 时,才附带这个子查询字段 + if (bo.getType() != null && bo.getType() == 2L) { + lqw.select( + "sowm.*", // 先选出主表所有列 + // 然后选出子查询,重命名为 nearest_end_time(实体上需要有对应的 @TableField(exist = false) 字段) + "(SELECT COALESCE(\n" + + " MIN(CASE WHEN sowt.end_time > NOW() THEN sowt.end_time END),\n" + + " MAX(CASE WHEN sowt.end_time <= NOW() THEN sowt.end_time END)\n" + + ")\n" + + "FROM sys_oa_warehouse_task sowt\n" + + "WHERE sowt.master_id = sowm.master_id\n" + + " AND sowt.task_status IN (0,1)\n" + + ") AS nearest_end_time" + ); + } else { + // 否则只选主表列 + lqw.select("sowm.*"); } - lqw.like(StringUtils.isNotBlank(bo.getSignUser()), "sowm.sign_user", bo.getSignUser()); - lqw.eq("sowm.del_flag", 0L); - lqw.orderByDesc("sowm.create_time"); return lqw; } @@ -112,7 +124,7 @@ public class SysOaWarehouseMasterServiceImpl implements ISysOaWarehouseMasterSer */ @Override public Boolean updateByBo(SysOaWarehouseMasterBo bo) { - System.out.println(bo); + // 判断是否为采购单,采购单,用户是直接点击完成按钮,所以直接更新单子状态就可以 if (bo.getType() != 2L) { SysOaWarehouseMaster update = BeanUtil.toBean(bo, SysOaWarehouseMaster.class); @@ -124,12 +136,12 @@ public class SysOaWarehouseMasterServiceImpl implements ISysOaWarehouseMasterSer sysOaWarehouseDetailBo.setMasterId(bo.getMasterId()); sysOaWarehouseDetailBo.setType(bo.getType()); warehouseDetailService.insertByBo(sysOaWarehouseDetailBo); - } } return flag; } else { + SysOaWarehouseMaster update = BeanUtil.toBean(bo, SysOaWarehouseMaster.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; @@ -180,4 +192,59 @@ public class SysOaWarehouseMasterServiceImpl implements ISysOaWarehouseMasterSer return flag; } + + @Override + public int updateMasterAndInsertBatchWare(SysOaWarehouseMasterBo bo) { + // 判断是否为采购单,采购单,用户是直接点击完成按钮,所以直接更新单子状态就可以 + + + if (bo.getType() == 2L) { + SysOaWarehouseMaster update = BeanUtil.toBean(bo, SysOaWarehouseMaster.class); + validEntityBeforeSave(update); + int flag = baseMapper.updateById(update); + bo.getWarehouseList().forEach(warehouse -> { + + }); + // 判断是否为采购单,采购单,用户是直接点击完成按钮,所以直接更新单子状态就可以 + // 我认为首先要先判断是否已经有此单子的入库单 如果有的话应该直接根据入库单id从而将其他的新增进去就可以了 + + return flag; + + +// // 获取是否存在此采购单的入库单 +// if (bo.getType() == 2L) { +// for (SysOaWarehouseDetailBo sysOaWarehouseDetailBo : bo.getWarehouseList()) { +// Long taskStatus = item.getTaskStatus(); +// if (taskStatus == 1|| taskStatus == 0) { +// item.setInventory(item.getTaskInventory()); +// SysOaWarehouseDetailBo bo = new SysOaWarehouseDetailBo(); +// bo.setAmount(item.getInventory()); +// bo.setSignPrice(item.getPrice()); +// Long warehouseId = insertByBo2(item); +// bo.setWarehouseId(warehouseId); +// list.add(bo); +// } +// } +// SysOaWarehouseMasterBo sysOaWarehouseMaster = new SysOaWarehouseMasterBo(); +// sysOaWarehouseMaster.setType(1L); +// List list = new ArrayList<>(); +// boList.forEach(item -> { +// +// }); +// sysOaWarehouseMaster.setWarehouseList(list); +// sysOaWarehouseMaster.setMasterNum(UUID.randomUUID().toString()); +// return masterService.insertByBo(sysOaWarehouseMaster); +// } +// +// +// // 如果不是2应该进不来 后面看一下是否删除掉 + + + } + + + // 如果不是2应该进不来 + return 0; + + } } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseServiceImpl.java index fae9616..374a5bb 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseServiceImpl.java @@ -10,6 +10,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.oa.domain.bo.SysOaWarehouseDetailBo; import com.ruoyi.oa.domain.bo.SysOaWarehouseMasterBo; +import com.ruoyi.oa.domain.dto.MonthlyStatsDTO; +import com.ruoyi.oa.domain.dto.SummaryFilterDTO; +import com.ruoyi.oa.domain.vo.SummaryCardVo; import com.ruoyi.oa.mapper.SysOaWarehouseDetailMapper; import com.ruoyi.oa.service.ISysOaWarehouseMasterService; import lombok.RequiredArgsConstructor; @@ -21,6 +24,10 @@ import com.ruoyi.oa.domain.SysOaWarehouse; import com.ruoyi.oa.mapper.SysOaWarehouseMapper; import com.ruoyi.oa.service.ISysOaWarehouseService; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.*; +import java.time.format.DateTimeFormatter; import java.util.*; /** @@ -39,6 +46,7 @@ public class SysOaWarehouseServiceImpl implements ISysOaWarehouseService { private final SysOaWarehouseDetailMapper outWareMapper; private final ISysOaWarehouseMasterService masterService; + /** * 查询仓库管理 */ @@ -54,14 +62,14 @@ public class SysOaWarehouseServiceImpl implements ISysOaWarehouseService { public TableDataInfo queryPageList(SysOaWarehouseBo bo, PageQuery pageQuery) { QueryWrapper lqw = new QueryWrapper<>(); lqw.eq("sow.del_flag", 0); - lqw.and(StringUtils.isNotBlank(bo.getName()),qw -> qw - .like( "sow.name", bo.getName()) + lqw.and(StringUtils.isNotBlank(bo.getName()), qw -> qw + .like("sow.name", bo.getName()) .or() .like("sow.brand", bo.getName()) .or() .like("sow.model", bo.getName()) ) - .eq(StringUtils.isNotBlank(bo.getModel()), "sow.model", bo.getModel()) + .eq(StringUtils.isNotBlank(bo.getModel()), "sow.model", bo.getModel()) .eq(StringUtils.isNotBlank(bo.getBrand()), "sow.brand", bo.getBrand()); Page result = baseMapper.selectListVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); @@ -71,22 +79,22 @@ public class SysOaWarehouseServiceImpl implements ISysOaWarehouseService { public TableDataInfo queryPageListThreshold(SysOaWarehouseBo bo, PageQuery pageQuery, boolean b) { QueryWrapper lqw = new QueryWrapper<>(); lqw.eq("sow.del_flag", 0); - if (b){ + if (b) { lqw.apply("sow.inventory < sow.threshold"); - }else{ + } else { lqw.apply("sow.inventory >= sow.threshold"); } lqw.eq(StringUtils.isNotBlank(bo.getModel()), "sow.model", bo.getModel()); lqw.eq(StringUtils.isNotBlank(bo.getBrand()), "sow.brand", bo.getBrand()); - lqw.and(StringUtils.isNotBlank(bo.getName()),qw -> qw - .like( "sow.name", bo.getName()) + lqw.and(StringUtils.isNotBlank(bo.getName()), qw -> qw + .like("sow.name", bo.getName()) .or() .like("sow.brand", bo.getName()) .or() .like("sow.model", bo.getName()) ) - .eq(StringUtils.isNotBlank(bo.getModel()), "sow.model", bo.getModel()) + .eq(StringUtils.isNotBlank(bo.getModel()), "sow.model", bo.getModel()) .eq(StringUtils.isNotBlank(bo.getBrand()), "sow.brand", bo.getBrand()); Page result = baseMapper.selectListVoPage(pageQuery.build(), lqw); @@ -106,12 +114,14 @@ public class SysOaWarehouseServiceImpl implements ISysOaWarehouseService { Long warehouseId = insertByBo2(item); bo.setWarehouseId(warehouseId); list.add(bo); + }); sysOaWarehouseMaster.setWarehouseList(list); sysOaWarehouseMaster.setMasterNum(UUID.randomUUID().toString()); return masterService.insertByBo(sysOaWarehouseMaster); } + /** * 查询仓库管理列表 */ @@ -132,7 +142,6 @@ public class SysOaWarehouseServiceImpl implements ISysOaWarehouseService { } - private LambdaQueryWrapper buildQueryWrapper(SysOaWarehouseBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); @@ -162,11 +171,11 @@ public class SysOaWarehouseServiceImpl implements ISysOaWarehouseService { Long flag; if (select == null) { baseMapper.insert(add); - flag = add.getId(); + flag = add.getId(); } else { select.setInventory(select.getInventory() + bo.getInventory()); - select.setPrice((select.getPrice()*select.getInventory() + bo.getPrice()*bo.getInventory())/(select.getInventory()+bo.getInventory())); - flag = select.getId(); + select.setPrice((select.getPrice() * select.getInventory() + bo.getPrice() * bo.getInventory()) / (select.getInventory() + bo.getInventory())); + flag = select.getId(); } return flag; @@ -189,9 +198,8 @@ public class SysOaWarehouseServiceImpl implements ISysOaWarehouseService { baseMapper.insert(add); return add.getId(); } else { - System.out.println(select); select.setInventory(select.getInventory() + bo.getTaskInventory()); - select.setPrice((select.getPrice()*select.getInventory() + bo.getPrice()*bo.getInventory())/(select.getInventory()+bo.getInventory())); + select.setPrice((select.getPrice() * select.getInventory() + bo.getPrice() * bo.getInventory()) / (select.getInventory() + bo.getInventory())); baseMapper.updateById(select); return select.getId(); } @@ -227,5 +235,161 @@ public class SysOaWarehouseServiceImpl implements ISysOaWarehouseService { return baseMapper.deleteBatchIds(ids) > 0; } + @Override + public List selectRecentOutbound(int limit) { + return outWareMapper.selectRecentOutbound(limit); + } + + @Override + public List getSummaryCards(SummaryFilterDTO f) { + // —— 1. 处理默认 endTime —— + // 如果调用方没有传 endTime,则当日查询用当前时点 + LocalDateTime now = LocalDateTime.now(); + LocalDateTime end = f.getEndTime() != null ? f.getEndTime() : now; + f.setEndTime(end); + + // ① 快照时点库存 + Long endInv = baseMapper.selectInventoryAt(f); + // ② 月份对比:如果同时传了 beginTime,则按 begin/end 计算环比 + double invTrend; + if (f.getBeginTime() != null) { + SummaryFilterDTO fb = new SummaryFilterDTO(); + fb.setEndTime(f.getBeginTime()); + fb.setName(f.getName()); + fb.setBrand(f.getBrand()); + fb.setSupplier(f.getSupplier()); + long beginInv = baseMapper.selectInventoryAt(fb); + invTrend = ratio(endInv, beginInv); + } else { + // 回退:上月快照计算(例:CURDATE()-1月) + SummaryFilterDTO fb = new SummaryFilterDTO(); + fb.setEndTime(f.getEndTime() != null + ? f.getEndTime().minusMonths(1) + : LocalDateTime.now().minusMonths(1)); + fb.setName(f.getName()); + fb.setBrand(f.getBrand()); + fb.setSupplier(f.getSupplier()); + long prevInv = baseMapper.selectInventoryAt(fb); + invTrend = ratio(endInv, prevInv); + } + + // ③ 在途 + long currTransit = baseMapper.selectInTransitBetween(f); + // —— 上一周期在途(若有 beginTime/endTime,则平移同长度;否则前一天) + long prevTransit; + if (f.getBeginTime() != null && f.getEndTime() != null) { + Duration dur = Duration.between(f.getBeginTime(), f.getEndTime()); + SummaryFilterDTO fp = new SummaryFilterDTO(); + fp.setBeginTime(f.getBeginTime().minus(dur)); + fp.setEndTime(f.getEndTime().minus(dur)); + fp.setName(f.getName()); + fp.setBrand(f.getBrand()); + fp.setSupplier(f.getSupplier()); + prevTransit = baseMapper.selectInTransitBetween(fp); + } else { + SummaryFilterDTO fp = new SummaryFilterDTO(); + fp.setEndTime(f.getEndTime() != null + ? f.getEndTime().minusDays(1) + : LocalDateTime.now().minusDays(1)); + fp.setName(f.getName()); + fp.setBrand(f.getBrand()); + fp.setSupplier(f.getSupplier()); + prevTransit = baseMapper.selectInTransitBetween(fp); + } + double transitTrend = ratio(currTransit, prevTransit); + + // ④ 当日入/出库 & 增长 + // 注意:此时 f.endTime 已经一定不为 null,selectInboundOn/selectOutboundOn 都是“当日” + long todayIn = baseMapper.selectInboundOn(f); + long todayOut = baseMapper.selectOutboundOn(f); + + // 前一天快照 + SummaryFilterDTO fPrev = new SummaryFilterDTO(); + fPrev.setEndTime(end.minusDays(1)); + fPrev.setBeginTime(null); // 不影响“当日”接口 + fPrev.setName(f.getName()); + fPrev.setBrand(f.getBrand()); + fPrev.setSupplier(f.getSupplier()); + + long prevIn = baseMapper.selectInboundOn(fPrev); + long prevOut = baseMapper.selectOutboundOn(fPrev); + + double inTrend = ratio(todayIn, prevIn); + double outTrend = ratio(todayOut, prevOut); + + // ⑤ 预警(默认是“当日”,因为我们一开始就把 f.endTime 设成了 today) + int warnCount = baseMapper.selectWarningOn(f); + + // —— 拼装返回 —— + List cards = new ArrayList<>(); + cards.add(new SummaryCardVo("当前总库存量", endInv, round(invTrend))); + cards.add(new SummaryCardVo("在途物料数量", currTransit, round(transitTrend))); + cards.add(new SummaryCardVo("当日入库量", todayIn, round(inTrend))); + cards.add(new SummaryCardVo("当日出库量", todayOut, round(outTrend))); + cards.add(new SummaryCardVo("预警信息", (long) warnCount, 0.0)); + return cards; + } + + + @Override + public MonthlyStatsDTO getMonthlyStats(String ymStr) { + // 1. 解析年月 + YearMonth ym = (ymStr != null && !ymStr.isEmpty()) + ? YearMonth.parse(ymStr, DateTimeFormatter.ofPattern("yyyy-MM")) + : YearMonth.now(); + int year = ym.getYear(); + int month = ym.getMonthValue(); + + // 2. 年度入/出库原始数据 + List> inRaw = baseMapper.selectInboundByMonth(year); + List> outRaw = baseMapper.selectOutboundByMonth(year); + + // 3. 填充 12 个月的占位列表 + List inMonthList = new ArrayList<>(Collections.nCopies(12, 0L)); + List outMonthList = new ArrayList<>(Collections.nCopies(12, 0L)); + inRaw.forEach(r -> { + int m = (Integer) r.get("month"); + long t = ((Number) r.get("total")).longValue(); + inMonthList.set(m - 1, t); + }); + outRaw.forEach(r -> { + int m = (Integer) r.get("month"); + long t = ((Number) r.get("total")).longValue(); + outMonthList.set(m - 1, t); + }); + + // 4. 当月按天库存快照 + int days = ym.lengthOfMonth(); + List snapList = new ArrayList<>(days); + for (int d = 1; d <= days; d++) { + LocalDate date = LocalDate.of(year, month, d); + snapList.add(baseMapper.selectInventorySnapshot(date)); + } + + // 5. 封装返回 + MonthlyStatsDTO dto = new MonthlyStatsDTO(); + dto.setInData(Collections.singletonMap("月", inMonthList)); + dto.setOutData(Collections.singletonMap("月", outMonthList)); + dto.setDataMap(Collections.singletonMap("日", snapList)); + return dto; + } + + /** + * 计算环比,prev = 0 则返回 0 + */ + private double ratio(double curr, double prev) { + if (prev == 0) return 0.0; + return (curr - prev) / prev * 100; + } + + /** + * 四舍五入到 1 位小数 + */ + private double round(double v) { + return BigDecimal.valueOf(v) + .setScale(1, RoundingMode.HALF_UP) + .doubleValue(); + } + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseTaskServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseTaskServiceImpl.java index e65c877..ac84cbb 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseTaskServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaWarehouseTaskServiceImpl.java @@ -8,11 +8,20 @@ import com.ruoyi.common.core.domain.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.oa.domain.SysOaWarehouse; +import com.ruoyi.oa.domain.SysOaWarehouseDetail; import com.ruoyi.oa.domain.SysOaWarehouseMaster; +import com.ruoyi.oa.domain.bo.SysOaWarehouseDetailBo; import com.ruoyi.oa.domain.bo.SysOaWarehouseMasterBo; +import com.ruoyi.oa.domain.vo.SysOaWarehouseDetailVo; +import com.ruoyi.oa.domain.vo.SysOaWarehouseMasterVo; +import com.ruoyi.oa.domain.vo.SysOaWarehouseVo; +import com.ruoyi.oa.mapper.SysOaWarehouseMapper; import com.ruoyi.oa.mapper.SysOaWarehouseMasterMapper; +import com.ruoyi.oa.service.ISysOaWarehouseDetailService; import com.ruoyi.oa.service.ISysOaWarehouseMasterService; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.ruoyi.oa.domain.bo.SysOaWarehouseTaskBo; import com.ruoyi.oa.domain.vo.SysOaWarehouseTaskVo; @@ -36,11 +45,17 @@ public class SysOaWarehouseTaskServiceImpl implements ISysOaWarehouseTaskService private final SysOaWarehouseMasterMapper masterMapper; + @Autowired + private ISysOaWarehouseDetailService detailService; + + @Autowired + private SysOaWarehouseMapper wareMapper; + /** * 查询采购计划 */ @Override - public SysOaWarehouseTaskVo queryById(Long taskId){ + public SysOaWarehouseTaskVo queryById(Long taskId) { return baseMapper.selectVoById(taskId); } @@ -102,7 +117,7 @@ public class SysOaWarehouseTaskServiceImpl implements ISysOaWarehouseTaskService /** * 保存前的数据校验 */ - private void validEntityBeforeSave(SysOaWarehouseTask entity){ + private void validEntityBeforeSave(SysOaWarehouseTask entity) { //TODO 做一些数据校验,如唯一约束 } @@ -111,7 +126,7 @@ public class SysOaWarehouseTaskServiceImpl implements ISysOaWarehouseTaskService */ @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if(isValid){ + if (isValid) { //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteBatchIds(ids) > 0; @@ -132,7 +147,7 @@ public class SysOaWarehouseTaskServiceImpl implements ISysOaWarehouseTaskService sysOaWarehouseMaster.setStatus(0L); sysOaWarehouseMaster.setMasterNum(UUID.randomUUID().toString()); sysOaWarehouseMaster.setSignUser(LoginHelper.getNickName()); - Boolean flag = masterMapper.insert(sysOaWarehouseMaster)>0; + Boolean flag = masterMapper.insert(sysOaWarehouseMaster) > 0; Long masterId = sysOaWarehouseMaster.getMasterId(); for (SysOaWarehouseTaskBo sysOaWarehouseTaskBo : boList) { sysOaWarehouseTaskBo.setMasterId(masterId); @@ -142,4 +157,98 @@ public class SysOaWarehouseTaskServiceImpl implements ISysOaWarehouseTaskService return flag; } + + @Override + public int updateByBoBatch(List boList) { + List sysOaWarehouseTasks = BeanUtil.copyToList(boList, SysOaWarehouseTask.class); + return baseMapper.updateBatchById(sysOaWarehouseTasks) ? 1 : 0; + } + + @Override + public int updateToWare(SysOaWarehouseTaskBo bo) { + + System.out.println(bo); + // 判断是否为此物料完成状态 + if (bo.getTaskStatus() == 2) { + Long masterId; + // 首先判断是否有此采购单对应的入库单 + SysOaWarehouseDetailBo sysOaWarehouseDetailBo = new SysOaWarehouseDetailBo(); + sysOaWarehouseDetailBo.setFatherId(bo.getMasterId()); + List sysOaWarehouseDetailVos = detailService.queryList(sysOaWarehouseDetailBo); + if (sysOaWarehouseDetailVos.isEmpty()) { + // 如果为空代表此task 为首次入库则创建入库单 + SysOaWarehouseMaster sysOaWarehouseMaster = new SysOaWarehouseMaster(); + sysOaWarehouseMaster.setType(1L); + sysOaWarehouseMaster.setMasterNum(UUID.randomUUID().toString()); + sysOaWarehouseMaster.setSignUser(LoginHelper.getNickName()); + masterMapper.insert(sysOaWarehouseMaster); + // 此masterId就是新的入库单id + masterId = sysOaWarehouseMaster.getMasterId(); + } else { + // 另外一种情况是已经存在了此采购单的入库单 这个时候就要在此入库单中进行新增 + SysOaWarehouseDetailVo sysOaWarehouseDetailVo = sysOaWarehouseDetailVos.get(0); + masterId = sysOaWarehouseDetailVo.getMasterId(); + } + toWareOne(masterId, bo, sysOaWarehouseDetailBo); + // 最终将判断此master是否还存在0||1的 + // 如果不存在则将此采购单的完成情况置1 + LambdaQueryWrapper taskLambdaQueryWrapper = new LambdaQueryWrapper<>(); + taskLambdaQueryWrapper.eq(SysOaWarehouseTask::getDelFlag, 0) + .eq(SysOaWarehouseTask::getMasterId, bo.getMasterId()) + .in(SysOaWarehouseTask::getTaskStatus, Arrays.asList(0, 1)); + List sysOaWarehouseTasks = baseMapper.selectList(taskLambdaQueryWrapper); + System.out.println(sysOaWarehouseTasks); + if (sysOaWarehouseTasks.isEmpty()) { + SysOaWarehouseMasterVo sysOaWarehouseMasterVo = masterMapper.selectVoById(bo.getMasterId()); + System.out.println("184513807548012740712308470812"); + // 如果为空代表了所有都结束了 将采购单状态置1 + sysOaWarehouseMasterVo.setStatus(1L); + masterMapper.updateById(BeanUtil.toBean(sysOaWarehouseMasterVo, SysOaWarehouseMaster.class)); + } + return 1; + } + + SysOaWarehouseTask task = BeanUtil.copyProperties(bo, SysOaWarehouseTask.class); + + return baseMapper.updateById(task); + } + + private int toWareOne(Long masterId, SysOaWarehouseTaskBo bo, SysOaWarehouseDetailBo sysOaWarehouseDetailBo) { + // 进行入库操作 (因为存在一种情况是此为全新物料是没有物料id的) + SysOaWarehouse sysOaWarehouse = new SysOaWarehouse(); + Long warehouseId = 0L; + SysOaWarehouseVo sysOaWarehouseVo = wareMapper.selectVoById(bo.getWarehouseId()); + if (Objects.isNull(sysOaWarehouseVo)) { + sysOaWarehouse.setPrice(bo.getPrice()); + sysOaWarehouse.setInventory(bo.getTaskInventory()); + sysOaWarehouse.setBrand(bo.getBrand()); + sysOaWarehouse.setModel(bo.getModel()); + sysOaWarehouse.setSpecifications(bo.getSpecifications()); + sysOaWarehouse.setName(bo.getName()); + sysOaWarehouse.setRemark(bo.getRemark()); + sysOaWarehouse.setUnit("件"); + wareMapper.insert(sysOaWarehouse); + warehouseId = sysOaWarehouse.getId(); + } else { + warehouseId = bo.getWarehouseId(); + sysOaWarehouse = wareMapper.selectById(warehouseId); + + sysOaWarehouse.setPrice((sysOaWarehouse.getPrice() * sysOaWarehouse.getInventory() + bo.getPrice() * bo.getTaskInventory()) / (sysOaWarehouse.getInventory() + bo.getTaskInventory())); + sysOaWarehouse.setInventory(sysOaWarehouse.getInventory() + bo.getTaskInventory()); + System.out.println(sysOaWarehouse); + wareMapper.updateById(sysOaWarehouse); + } + + // 接下来拿到masterId后开始将采购单数据写入入库单 + sysOaWarehouseDetailBo.setMasterId(masterId); + sysOaWarehouseDetailBo.setWarehouseId(bo.getWarehouseId()); + sysOaWarehouseDetailBo.setAmount(bo.getTaskInventory()); + sysOaWarehouseDetailBo.setSignPrice(bo.getPrice()); + sysOaWarehouseDetailBo.setWarehouseId(warehouseId); + sysOaWarehouseDetailBo.setType(1L); + detailService.insertByBo(sysOaWarehouseDetailBo); + SysOaWarehouseTask bean = BeanUtil.toBean(bo, SysOaWarehouseTask.class); + // 最后将此物料更新为完成入库 + return baseMapper.updateById(bean); + } } diff --git a/ruoyi-oa/src/main/resources/mapper/oa/SysOaAttendanceMapper.xml b/ruoyi-oa/src/main/resources/mapper/oa/SysOaAttendanceMapper.xml index a23168f..b77e703 100644 --- a/ruoyi-oa/src/main/resources/mapper/oa/SysOaAttendanceMapper.xml +++ b/ruoyi-oa/src/main/resources/mapper/oa/SysOaAttendanceMapper.xml @@ -112,11 +112,10 @@ COUNT(id) AS count, SUM( CASE - WHEN day_length > 0 THEN 1 - WHEN hour > 0 THEN 1 + WHEN day_length != 0 OR hour != 0 THEN 1 ELSE 0 END - ) AS work_times, + ) AS work_times, SUM( CASE WHEN day_length > 0 THEN day_length * 8 @@ -137,8 +136,8 @@ FROM sys_oa_attendance soa WHERE user_id = #{userId} - AND #{lastDay} > create_time - AND create_time > #{firstDay} + AND #{lastDay} >= create_time + AND create_time >= #{firstDay} AND del_flag = '0' GROUP BY soa.project_id; diff --git a/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseDetailMapper.xml b/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseDetailMapper.xml index b9fec47..1da4529 100644 --- a/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseDetailMapper.xml +++ b/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseDetailMapper.xml @@ -107,5 +107,49 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + diff --git a/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseMapper.xml b/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseMapper.xml index 33801a6..0362d50 100644 --- a/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseMapper.xml +++ b/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseMapper.xml @@ -69,6 +69,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join sys_oa_warehouse_master sowm on sowm.master_id = sowt.master_id where sowt.warehouse_id = sow.id and sowm.type = 2 + and (sowt.task_status = 0 or sowt.task_status = 1) and sowt.del_flag = '0' and sowm.del_flag = '0' and sowm.status = 0 @@ -79,4 +80,208 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseMasterMapper.xml b/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseMasterMapper.xml index ee66aa5..bdd5eff 100644 --- a/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseMasterMapper.xml +++ b/ruoyi-oa/src/main/resources/mapper/oa/SysOaWarehouseMasterMapper.xml @@ -20,6 +20,7 @@ +