From bdea5287cb6e08ceff9914a2eeb22edf65a58fa3 Mon Sep 17 00:00:00 2001 From: c Date: Sat, 28 Feb 2026 18:14:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BA=86=20BOM=20=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=92=8C=E7=94=9F=E4=BA=A7=E7=AE=A1=E7=90=86=EF=BC=8C?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=83=A8=E5=88=86=E5=8F=91=E6=96=99=E5=8D=95?= =?UTF-8?q?=E3=80=81=E9=87=87=E8=B4=AD=E8=AE=A1=E5=88=92=E5=92=8C=E8=B0=83?= =?UTF-8?q?=E6=8B=A8=E5=8D=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../niuan/erp/common/base/BaseSelectDto.java | 4 + .../erp/common/config/MybatisConfig.java | 5 + .../common/handler/CustomerTenantHandler.java | 42 ++++ .../niuan/erp/common/utils/SecurityUtils.java | 4 + .../erp/common/utils/SystemAuthFactory.java | 105 +++++++++- .../auth/controller/SystemAuthController.java | 8 + .../controller/dto/RouterConfigRawMeta.java | 5 + .../service/CustomUserDetailsService.java | 20 +- .../service/impl/SystemAuthServiceImpl.java | 9 +- .../erp/module/common/entity/Document.java | 3 +- .../erp/module/common/enums/DocumentType.java | 7 +- .../production/controller/BomController.java | 101 +++++---- .../controller/ProductionIssueController.java | 3 +- .../controller/ProductionPlanController.java | 101 ++++++--- .../production/controller/dto/BomAddDto.java | 30 +++ .../production/controller/dto/BomDto.java | 44 ++-- .../controller/dto/BomItemAddDto.java | 30 +++ .../production/controller/dto/BomItemDto.java | 30 +-- .../controller/dto/BomSearchParams.java | 5 + .../dto/PlanProductionIssueAddDto.java | 17 ++ .../controller/dto/ProductionIssueAddDto.java | 27 +++ .../dto/ProductionIssueItemAddDto.java | 24 +++ .../controller/dto/ProductionPlanDto.java | 23 ++- .../dto/ProductionPlanShortageDto.java | 12 ++ .../production/converter/BomConverter.java | 3 + .../converter/BomItemConverter.java | 3 + .../converter/ProductionIssueConverter.java | 6 + .../erp/module/production/entity/Bom.java | 5 + .../production/entity/ProduceOrderList.java | 42 ++++ .../production/entity/ProductionPlan.java | 3 +- .../enums/ProductionPlanStatus.java | 32 +++ .../production/mapper/BomItemMapper.java | 7 + .../module/production/mapper/BomMapper.java | 9 + .../mapper/ProductionPlanMapper.java | 12 ++ .../module/production/service/BomService.java | 11 +- .../service/ProductionIssueService.java | 3 +- .../service/ProductionPlanService.java | 7 + .../service/impl/BomServiceImpl.java | 67 +++++- .../impl/ProductionIssueServiceImpl.java | 34 +++- .../impl/ProductionPlanServiceImpl.java | 192 +++++++++++++++++- .../controller/PurchasePlanController.java | 3 +- .../controller/dto/PurchasePlanAddDto.java | 22 ++ .../dto/PurchasePlanItemAddDto.java | 16 ++ .../converter/PurchasePlanConverter.java | 2 + .../converter/PurchasePlanItemConverter.java | 3 + .../module/purchase/entity/PurchasePlan.java | 3 +- .../purchase/enums/PurchasePlanStatus.java | 31 +++ .../purchase/service/PurchasePlanService.java | 3 +- .../service/impl/PurchasePlanServiceImpl.java | 19 +- .../erp/module/sys/enums/PermissionType.java | 32 +++ .../controller/StockByBrandController.java | 82 -------- .../controller/StockByTypeController.java | 82 -------- .../StockByWarehouseController.java | 82 -------- .../warehouse/controller/StockController.java | 32 +++ .../StockTransferOrderController.java | 3 +- .../controller/WarehouseController.java | 22 +- .../controller/WarehouseItemController.java | 33 ++- .../warehouse/controller/dto/StockDto.java | 30 ++- .../dto/StockTransferOrderAddDto.java | 39 ++++ .../dto/StockTransferOrderItemAddDto.java | 23 +++ .../controller/dto/WarehouseDto.java | 3 +- .../controller/dto/WarehouseItemDto.java | 3 +- .../StockTransferOrderConverter.java | 8 + .../module/warehouse/mapper/StockMapper.java | 9 + .../warehouse/mapper/WarehouseItemMapper.java | 11 + .../warehouse/mapper/WarehouseMapper.java | 5 + .../warehouse/service/StockService.java | 10 +- .../service/StockTransferOrderService.java | 3 +- .../service/WarehouseItemService.java | 8 + .../warehouse/service/WarehouseService.java | 4 + .../service/impl/StockServiceImpl.java | 35 +--- .../impl/StockTransferOrderServiceImpl.java | 35 +++- .../impl/WarehouseItemServiceImpl.java | 22 ++ .../service/impl/WarehouseServiceImpl.java | 6 + src/main/resources/application-dev.yml | 10 +- src/main/resources/application.yml | 2 +- src/main/resources/i18n/messages.properties | 60 ++++++ .../mapper/production/BomItemMapper.xml | 18 ++ .../resources/mapper/production/BomMapper.xml | 40 ++-- .../production/ProductionPlanMapper.xml | 79 +++++++ .../mapper/sys/RolePermissionMapper.xml | 11 + .../mapper/sys/SysPermissionMapper.xml | 37 ++++ .../mapper/warehouse/StockMapper.xml | 26 +++ .../warehouse/StockTransferOrderMapper.xml | 33 --- .../mapper/warehouse/WarehouseItemMapper.xml | 20 ++ .../mapper/warehouse/WarehouseMapper.xml | 4 + .../resources/sql/dev/permission-data.sql | 15 ++ .../resources/sql/dev/permission-schema.sql | 37 ++++ 88 files changed, 1693 insertions(+), 518 deletions(-) create mode 100644 src/main/java/com/niuan/erp/common/base/BaseSelectDto.java create mode 100644 src/main/java/com/niuan/erp/common/handler/CustomerTenantHandler.java create mode 100644 src/main/java/com/niuan/erp/module/production/controller/dto/BomAddDto.java create mode 100644 src/main/java/com/niuan/erp/module/production/controller/dto/BomItemAddDto.java create mode 100644 src/main/java/com/niuan/erp/module/production/controller/dto/BomSearchParams.java create mode 100644 src/main/java/com/niuan/erp/module/production/controller/dto/PlanProductionIssueAddDto.java create mode 100644 src/main/java/com/niuan/erp/module/production/controller/dto/ProductionIssueAddDto.java create mode 100644 src/main/java/com/niuan/erp/module/production/controller/dto/ProductionIssueItemAddDto.java create mode 100644 src/main/java/com/niuan/erp/module/production/controller/dto/ProductionPlanShortageDto.java create mode 100644 src/main/java/com/niuan/erp/module/production/entity/ProduceOrderList.java create mode 100644 src/main/java/com/niuan/erp/module/production/enums/ProductionPlanStatus.java create mode 100644 src/main/java/com/niuan/erp/module/purchase/controller/dto/PurchasePlanAddDto.java create mode 100644 src/main/java/com/niuan/erp/module/purchase/controller/dto/PurchasePlanItemAddDto.java create mode 100644 src/main/java/com/niuan/erp/module/purchase/enums/PurchasePlanStatus.java create mode 100644 src/main/java/com/niuan/erp/module/sys/enums/PermissionType.java delete mode 100644 src/main/java/com/niuan/erp/module/warehouse/controller/StockByBrandController.java delete mode 100644 src/main/java/com/niuan/erp/module/warehouse/controller/StockByTypeController.java delete mode 100644 src/main/java/com/niuan/erp/module/warehouse/controller/StockByWarehouseController.java create mode 100644 src/main/java/com/niuan/erp/module/warehouse/controller/StockController.java create mode 100644 src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockTransferOrderAddDto.java create mode 100644 src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockTransferOrderItemAddDto.java create mode 100644 src/main/resources/mapper/sys/RolePermissionMapper.xml create mode 100644 src/main/resources/mapper/sys/SysPermissionMapper.xml delete mode 100644 src/main/resources/mapper/warehouse/StockTransferOrderMapper.xml create mode 100644 src/main/resources/sql/dev/permission-data.sql create mode 100644 src/main/resources/sql/dev/permission-schema.sql diff --git a/src/main/java/com/niuan/erp/common/base/BaseSelectDto.java b/src/main/java/com/niuan/erp/common/base/BaseSelectDto.java new file mode 100644 index 0000000..70511fc --- /dev/null +++ b/src/main/java/com/niuan/erp/common/base/BaseSelectDto.java @@ -0,0 +1,4 @@ +package com.niuan.erp.common.base; + +public record BaseSelectDto(Object value, String label) { +} diff --git a/src/main/java/com/niuan/erp/common/config/MybatisConfig.java b/src/main/java/com/niuan/erp/common/config/MybatisConfig.java index 8eba77f..cfce76a 100644 --- a/src/main/java/com/niuan/erp/common/config/MybatisConfig.java +++ b/src/main/java/com/niuan/erp/common/config/MybatisConfig.java @@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.autoconfigure.MybatisPlusPropertiesCustomizer; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; +import com.niuan.erp.common.handler.CustomerTenantHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -14,6 +16,9 @@ public class MybatisConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + var tenantLineInnerInterceptor = new TenantLineInnerInterceptor(); + tenantLineInnerInterceptor.setTenantLineHandler(new CustomerTenantHandler()); + interceptor.addInnerInterceptor(tenantLineInnerInterceptor); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } diff --git a/src/main/java/com/niuan/erp/common/handler/CustomerTenantHandler.java b/src/main/java/com/niuan/erp/common/handler/CustomerTenantHandler.java new file mode 100644 index 0000000..7c1a99f --- /dev/null +++ b/src/main/java/com/niuan/erp/common/handler/CustomerTenantHandler.java @@ -0,0 +1,42 @@ +package com.niuan.erp.common.handler; + +import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; +import com.niuan.erp.common.utils.SecurityUtils; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.LongValue; + +import java.util.HashSet; +import java.util.Set; + +/** + * 数据区分的 Handler + */ +public class CustomerTenantHandler implements TenantLineHandler { + + private final static Set activeTables = new HashSet(); + + /* + 这里添加需要进行账户验证的数据表 + */ + static { + activeTables.add("product"); + activeTables.add("storage_list"); + activeTables.add("bom_list"); + } + + @Override + public Expression getTenantId() { + Integer customerId = SecurityUtils.getLoginUser().getUser().getCustomerId(); + return new LongValue(customerId); + } + + @Override + public String getTenantIdColumn() { + return "CustomerId"; + } + + @Override + public boolean ignoreTable(String tableName) { + return !activeTables.contains(tableName); + } +} diff --git a/src/main/java/com/niuan/erp/common/utils/SecurityUtils.java b/src/main/java/com/niuan/erp/common/utils/SecurityUtils.java index b7496df..f78dbd8 100644 --- a/src/main/java/com/niuan/erp/common/utils/SecurityUtils.java +++ b/src/main/java/com/niuan/erp/common/utils/SecurityUtils.java @@ -21,6 +21,10 @@ public class SecurityUtils { throw new SystemException("auth.userDetailsError"); } + public static Integer getCustomerId() { + return getLoginUser().getUser().getCustomerId(); + } + public static Long getUserId(){ return getLoginUser().getUser().getId(); } diff --git a/src/main/java/com/niuan/erp/common/utils/SystemAuthFactory.java b/src/main/java/com/niuan/erp/common/utils/SystemAuthFactory.java index 71df947..fddde2b 100644 --- a/src/main/java/com/niuan/erp/common/utils/SystemAuthFactory.java +++ b/src/main/java/com/niuan/erp/common/utils/SystemAuthFactory.java @@ -4,6 +4,9 @@ import com.niuan.erp.module.auth.controller.dto.ButtonProp; import com.niuan.erp.module.auth.controller.dto.RouterConfigRaw; import com.niuan.erp.module.auth.controller.dto.RouterConfigRawMeta; import com.niuan.erp.module.sys.entity.SysChannel; +import com.niuan.erp.module.sys.entity.SysPermission; +import com.niuan.erp.module.sys.enums.PermissionType; +import org.springframework.util.StringUtils; import java.util.*; @@ -19,12 +22,63 @@ public class SystemAuthFactory { private static final Integer BUTTON_TYPE = 1; + public static List generateTeekFrameMenuBySysPermissions(List sysPermissions) { + List configList = new ArrayList<>(); + + HashMap configMap = new HashMap<>(); + + sysPermissions.stream().filter(p -> p.getPermissionType().equals(PermissionType.MENU)).forEach(p -> { + var config = convertToRouterConfigRaw(p); + if (Objects.equals(p.getParentId(), ROOT_ID)) { + // 如果是顶级节点则加入最后结果 + configList.add(config); + // 将自身添加进 Map 中 + saveInConfigMap(config, p.getId(), configMap); + } else { + // 如果不是是顶级节点则说明有上级节点 + // 先添加到父组件 + if (configMap.containsKey(p.getParentId())) { + // 如果 Map 里有保存这个内容,说明已经被作为父组件 + var parentConfig = configMap.get(p.getParentId()); + if (parentConfig.getChildren() != null) parentConfig.getChildren().add(config); + else parentConfig.setChildren(new ArrayList<>(List.of(config))); + } else { + // 如果 Map 没有父节点则缓存一个父节点 + var parentConfig = new RouterConfigRaw(null, null); + parentConfig.setChildren(new ArrayList<>(List.of(config))); + configMap.put(p.getParentId(), parentConfig); + } + // 接着将自身添加进 Map 中 + saveInConfigMap(config, p.getId(), configMap); + } + }); + + sysPermissions.stream().filter(p -> p.getPermissionType().equals(PermissionType.TOP_PAGE_BUTTON) || + p.getPermissionType().equals(PermissionType.TABLE_OPERATOR_BUTTON) || + p.getPermissionType().equals(PermissionType.TABLE_STATUS_BUTTON) || + p.getPermissionType().equals(PermissionType.DIALOG_BUTTON)) + .forEach(p -> { + var buttonProp = convertToButtonProp(p); + var menuConfig = configMap.get(p.getParentId()); + if (menuConfig != null) { + switch (p.getPermissionType()) { + case TOP_PAGE_BUTTON -> saveInButtonAuthList(menuConfig.getMeta().getButtonAuth(), buttonProp); + case TABLE_OPERATOR_BUTTON -> saveInButtonAuthList(menuConfig.getMeta().getToolButtonAuth(), buttonProp); + case DIALOG_BUTTON -> saveInButtonAuthList(menuConfig.getMeta().getDialogButtonAuth(), buttonProp); + } + } + }); + + return configList; + } + + /** * 生成 Teek 框架的前端动态菜单数据 * @param sysChannels * @return */ - public static List generateTeekFrameMenu(List sysChannels) { + public static List generateTeekFrameMenuBySysChannels(List sysChannels) { List configList = new ArrayList<>(); HashMap configMap = new HashMap<>(); @@ -133,6 +187,23 @@ public class SystemAuthFactory { configMap.put(id, config); } + + /** + * 转化成权限按钮属性,里面包含按钮的各项属性 + * @param sysPermission + * @return + */ + private static ButtonProp convertToButtonProp(SysPermission sysPermission) { + ButtonProp buttonProp = new ButtonProp(); + buttonProp.setButtonName(sysPermission.getPermissionName()); + buttonProp.setText(sysPermission.getPermissionName()); + buttonProp.setEventName(sysPermission.getEventName()); + buttonProp.setColorType(TeekFrameMappingUtils.getTeekButtonType(sysPermission.getClassName())); + buttonProp.setIcon(sysPermission.getIconName()); + buttonProp.setRank(sysPermission.getSort()); + return buttonProp; + } + /** * 转化成权限按钮属性,里面包含按钮的各项属性 * @param sysChannel @@ -172,5 +243,37 @@ public class SystemAuthFactory { return config; } + /** + * 转化成 初始化的 RouterConfigRaw,需要进一步完善才能匹配前端框架 + * @param sysPermission + * @return + */ + private static RouterConfigRaw convertToRouterConfigRaw(SysPermission sysPermission) { + // 使用 channelLink 和 eventName 来作为菜单路径和名字 + RouterConfigRaw config = new RouterConfigRaw(sysPermission.getPageLink(), sysPermission.getPageLink()); + + if (StringUtils.hasText(sysPermission.getViewLink())) { + config.setComponent(sysPermission.getViewLink()); + } + + RouterConfigRawMeta meta = new RouterConfigRawMeta(); + + // 设置 i18n 的位置 + if (StringUtils.hasText(sysPermission.getPermissionI18n())) { + meta.setTitle("{{ _route.%s }}".formatted(sysPermission.getPermissionI18n())); + } else { + meta.setTitle(sysPermission.getPermissionName()); + } + // 设置排序 + meta.setRank(sysPermission.getSort()); + // 设置图标 + meta.setIcon(sysPermission.getIconName()); + // 设置是否隐藏图标 + meta.setHideInMenu(sysPermission.getHidden()); + + config.setMeta(meta); + return config; + } + } diff --git a/src/main/java/com/niuan/erp/module/auth/controller/SystemAuthController.java b/src/main/java/com/niuan/erp/module/auth/controller/SystemAuthController.java index 1436047..1b8351b 100644 --- a/src/main/java/com/niuan/erp/module/auth/controller/SystemAuthController.java +++ b/src/main/java/com/niuan/erp/module/auth/controller/SystemAuthController.java @@ -2,11 +2,14 @@ package com.niuan.erp.module.auth.controller; import com.niuan.erp.common.base.BaseResult; import com.niuan.erp.module.auth.service.SystemAuthService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +@Tag(name = "系统权限") @RestController @RequestMapping("/auth") @RequiredArgsConstructor @@ -14,7 +17,12 @@ public class SystemAuthController { private final SystemAuthService systemAuthService; + /** + * 后台权限接口 + * @return + */ @GetMapping("/getRouterConfigRawList") + @Operation(summary = "查询后台权限", operationId = "getRouterConfigRawList") public BaseResult getRouterConfigRawList() { return BaseResult.successWithData(systemAuthService.getRouterConfigRawList()); } diff --git a/src/main/java/com/niuan/erp/module/auth/controller/dto/RouterConfigRawMeta.java b/src/main/java/com/niuan/erp/module/auth/controller/dto/RouterConfigRawMeta.java index 4d68979..665c592 100644 --- a/src/main/java/com/niuan/erp/module/auth/controller/dto/RouterConfigRawMeta.java +++ b/src/main/java/com/niuan/erp/module/auth/controller/dto/RouterConfigRawMeta.java @@ -136,4 +136,9 @@ public class RouterConfigRawMeta { * 操作栏 Button 权限 */ private List toolButtonAuth = new ArrayList<>(); + + /** + * Dialog Button 权限 + */ + private List dialogButtonAuth = new ArrayList<>(); } diff --git a/src/main/java/com/niuan/erp/module/auth/service/CustomUserDetailsService.java b/src/main/java/com/niuan/erp/module/auth/service/CustomUserDetailsService.java index f500249..e7fffa2 100644 --- a/src/main/java/com/niuan/erp/module/auth/service/CustomUserDetailsService.java +++ b/src/main/java/com/niuan/erp/module/auth/service/CustomUserDetailsService.java @@ -6,12 +6,15 @@ import com.github.benmanes.caffeine.cache.LoadingCache; import com.niuan.erp.common.base.LoginUser; import com.niuan.erp.common.exception.BusinessException; import com.niuan.erp.module.sys.entity.SysChannel; +import com.niuan.erp.module.sys.entity.SysPermission; import com.niuan.erp.module.sys.entity.SysRole; import com.niuan.erp.module.sys.entity.SysUser; import com.niuan.erp.module.sys.mapper.SysChannelMapper; +import com.niuan.erp.module.sys.mapper.SysPermissionMapper; import com.niuan.erp.module.sys.mapper.SysRoleMapper; import com.niuan.erp.module.sys.mapper.SysUserMapper; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -22,6 +25,7 @@ import org.springframework.util.StringUtils; import java.time.Duration; import java.util.List; +import java.util.stream.Collectors; @Service @Transactional @@ -30,10 +34,10 @@ public class CustomUserDetailsService implements UserDetailsService { private final SysUserMapper sysUserMapper; - private final SysChannelMapper sysChannelMapper; - private final SysRoleMapper sysRoleMapper; + private final SysPermissionMapper sysPermissionMapper; + private final LoadingCache userCache = Caffeine.newBuilder() .maximumSize(100) .expireAfterWrite(Duration.ofMinutes(10)) @@ -52,15 +56,15 @@ public class CustomUserDetailsService implements UserDetailsService { throw new BusinessException(""); } List roleList = sysRoleMapper.selectByUserId(user.getId()); - List channelList = sysChannelMapper.selectByUserId(user.getId()); - List authorityList = channelList.stream() - .map(SysChannel::getChannelLink) - .filter(StringUtils::hasText) - .toList(); + var permissionList = sysPermissionMapper.selectByUserId(user.getId()); + List authorities = permissionList.stream() + .filter(p -> StringUtils.hasText(p.getPermissionCode())) + .map(p -> new SimpleGrantedAuthority(p.getPermissionCode())) + .collect(Collectors.toUnmodifiableList()); return LoginUser.builder() .user(user) .roleList(roleList) - .authorities(List.of(new SimpleGrantedAuthority("vendor:index"))) + .authorities(authorities) .build(); } diff --git a/src/main/java/com/niuan/erp/module/auth/service/impl/SystemAuthServiceImpl.java b/src/main/java/com/niuan/erp/module/auth/service/impl/SystemAuthServiceImpl.java index d1bdca6..a4e3803 100644 --- a/src/main/java/com/niuan/erp/module/auth/service/impl/SystemAuthServiceImpl.java +++ b/src/main/java/com/niuan/erp/module/auth/service/impl/SystemAuthServiceImpl.java @@ -6,7 +6,9 @@ import com.niuan.erp.common.utils.SystemAuthFactory; import com.niuan.erp.module.auth.controller.dto.RouterConfigRaw; import com.niuan.erp.module.auth.service.SystemAuthService; import com.niuan.erp.module.sys.entity.SysChannel; +import com.niuan.erp.module.sys.entity.SysPermission; import com.niuan.erp.module.sys.mapper.SysChannelMapper; +import com.niuan.erp.module.sys.mapper.SysPermissionMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,10 +20,11 @@ public class SystemAuthServiceImpl implements SystemAuthService { private final SysChannelMapper sysChannelMapper; + private final SysPermissionMapper sysPermissionMapper; + @Override public List getRouterConfigRawList() { - LoginUser loginUser = SecurityUtils.getLoginUser(); - List sysChannels = sysChannelMapper.selectByUserId(loginUser.getUser().getId()); - return SystemAuthFactory.generateTeekFrameMenu(sysChannels); + List sysPermissions = sysPermissionMapper.selectByUserId(SecurityUtils.getUserId()); + return SystemAuthFactory.generateTeekFrameMenuBySysPermissions(sysPermissions); } } diff --git a/src/main/java/com/niuan/erp/module/common/entity/Document.java b/src/main/java/com/niuan/erp/module/common/entity/Document.java index ee5f30a..8c52b72 100644 --- a/src/main/java/com/niuan/erp/module/common/entity/Document.java +++ b/src/main/java/com/niuan/erp/module/common/entity/Document.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.niuan.erp.module.common.enums.DocumentType; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -58,7 +59,7 @@ public class Document implements Serializable { private String storeName; @TableField("FormType") - private Integer formType; + private DocumentType formType; @TableField("FormCode") private String formCode; diff --git a/src/main/java/com/niuan/erp/module/common/enums/DocumentType.java b/src/main/java/com/niuan/erp/module/common/enums/DocumentType.java index 8335714..3e525cb 100644 --- a/src/main/java/com/niuan/erp/module/common/enums/DocumentType.java +++ b/src/main/java/com/niuan/erp/module/common/enums/DocumentType.java @@ -1,5 +1,6 @@ package com.niuan.erp.module.common.enums; +import com.baomidou.mybatisplus.annotation.IEnum; import lombok.Getter; /** @@ -9,7 +10,7 @@ import lombok.Getter; * 5.生产发料单 6.生产退料单 7.成品出货单 8.仓库调拨单 9.库存盘点单 */ @Getter -public enum DocumentType { +public enum DocumentType implements IEnum { PURCHASE_ORDER(1, "采购订单"), SALES_ORDER(2, "销售订单"), WAREHOUSE_RECEIPT(3, "仓库入库单"), @@ -27,4 +28,8 @@ public enum DocumentType { } + @Override + public Integer getValue() { + return code; + } } diff --git a/src/main/java/com/niuan/erp/module/production/controller/BomController.java b/src/main/java/com/niuan/erp/module/production/controller/BomController.java index 8fbded1..35c6eb3 100644 --- a/src/main/java/com/niuan/erp/module/production/controller/BomController.java +++ b/src/main/java/com/niuan/erp/module/production/controller/BomController.java @@ -4,23 +4,23 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.niuan.erp.common.annotation.ApiLog; import com.niuan.erp.common.annotation.ModuleLog; -import com.niuan.erp.common.base.BaseDeleteBody; -import com.niuan.erp.common.base.BasePageReqParams; -import com.niuan.erp.common.base.BaseResult; +import com.niuan.erp.common.base.*; import com.niuan.erp.common.base.CommonValidateGroup.*; -import com.niuan.erp.common.base.OperationType; -import com.niuan.erp.module.production.controller.dto.BomDto; +import com.niuan.erp.module.production.controller.dto.*; import com.niuan.erp.module.production.entity.Bom; import com.niuan.erp.module.production.service.BomService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -@Tag(name = "Bom") +import java.util.List; + +@Tag(name = "Bom管理") @ModuleLog("Bom管理") @RestController @RequestMapping("/production/bom") @@ -32,54 +32,71 @@ public class BomController { @Operation(summary = "分页查询Bom数据", operationId = "getBomPage") @GetMapping("/getBomPage") @PreAuthorize("hasAuthority('bom:index')") - public BaseResult> getBomPage(@Validated BasePageReqParams pageParams, - @Validated(Get.class) BomDto searchParams) { + public BaseResult> getBomPage(@Validated BasePageReqParams pageParams, BomSearchParams searchParams) { var wrapper = new LambdaQueryWrapper(); - if (searchParams != null) { - if (StringUtils.hasText(searchParams.customerName())) { - wrapper.like(Bom::getCustomerName, searchParams.customerName()); - } - if (StringUtils.hasText(searchParams.searchCode())) { - wrapper.like(Bom::getBomNo, searchParams.searchCode()); - } + if (searchParams != null) { + if (StringUtils.hasText(searchParams.partNumber())) { + return BaseResult.successWithData(bomService.getBomPageWithItem(pageParams, searchParams.searchCode(), + searchParams.partNumber())); } + if (StringUtils.hasText(searchParams.searchCode())) { + wrapper.like(Bom::getBomNo, searchParams.searchCode()).or().like(Bom::getBomName, searchParams.searchCode()); + } + } + wrapper.orderByDesc(Bom::getCreateDate); return BaseResult.successWithData(bomService.getBomPage(pageParams, wrapper)); } + @Operation(summary = "查询Bom明细数据", operationId = "getBomItemList") + @GetMapping("/getBomItemList") + @PreAuthorize("hasAuthority('bom:showItem')") + public BaseResult> getBomItemList(@RequestParam("bomId") + @NotNull(message = "production.bom.validate.bom_id.not_null") + Long bomId) { + return BaseResult.successWithData(bomService.getBomItemList(bomId)); + } + + @Operation(summary = "查询 BOM 列表", operationId = "getBomSelectList") + @GetMapping("/getBomSelectList") + @PreAuthorize("hasAnyAuthority('production_plan:add')") + public BaseResult> getBomSelectList() { + return BaseResult.successWithData(bomService.getBomSelectList()); + } + @ApiLog(type = OperationType.ADD, remark = "新增一条Bom记录") @Operation(summary = "新增Bom", operationId = "addBom") @PostMapping("/addBom") @PreAuthorize("hasAuthority('bom:add')") - public BaseResult addBom(@Validated(Add.class) @RequestBody BomDto dto) { + public BaseResult addBom(@RequestBody BomAddDto dto) { bomService.addBom(dto); return BaseResult.success(); } - @ApiLog(type = OperationType.UPDATE, remark = "更新一条Bom记录") - @Operation(summary = "更新Bom", operationId = "updateBom") - @PostMapping("/updateBom") - @PreAuthorize("hasAuthority('bom:update')") - public BaseResult updateBom(@Validated(Update.class) @RequestBody BomDto dto) { - bomService.updateBom(dto); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.DELETE, remark = "删除一条Bom记录") - @Operation(summary = "删除Bom", operationId = "deleteBom") - @PostMapping("/deleteBom") - @PreAuthorize("hasAuthority('bom:delete')") - public BaseResult deleteBom(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) { - bomService.deleteBom(req.id()); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.DELETE, remark = "批量删除Bom记录") - @Operation(summary = "批量删除Bom", operationId = "deleteBomBatch") - @PostMapping("/deleteBomBatch") - @PreAuthorize("hasAuthority('bom:deleteBatch')") - public BaseResult deleteBomBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) { - bomService.deleteBatch(req.ids()); - return BaseResult.success(); - } +// @ApiLog(type = OperationType.UPDATE, remark = "更新一条Bom记录") +// @Operation(summary = "更新Bom", operationId = "updateBom") +// @PostMapping("/updateBom") +// @PreAuthorize("hasAuthority('bom:update')") +// public BaseResult updateBom(@Validated(Update.class) @RequestBody BomDto dto) { +// bomService.updateBom(dto); +// return BaseResult.success(); +// } +// +// @ApiLog(type = OperationType.DELETE, remark = "删除一条Bom记录") +// @Operation(summary = "删除Bom", operationId = "deleteBom") +// @PostMapping("/deleteBom") +// @PreAuthorize("hasAuthority('bom:delete')") +// public BaseResult deleteBom(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) { +// bomService.deleteBom(req.id()); +// return BaseResult.success(); +// } +// +// @ApiLog(type = OperationType.DELETE, remark = "批量删除Bom记录") +// @Operation(summary = "批量删除Bom", operationId = "deleteBomBatch") +// @PostMapping("/deleteBomBatch") +// @PreAuthorize("hasAuthority('bom:deleteBatch')") +// public BaseResult deleteBomBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) { +// bomService.deleteBatch(req.ids()); +// return BaseResult.success(); +// } } diff --git a/src/main/java/com/niuan/erp/module/production/controller/ProductionIssueController.java b/src/main/java/com/niuan/erp/module/production/controller/ProductionIssueController.java index ddf169c..b6f558d 100644 --- a/src/main/java/com/niuan/erp/module/production/controller/ProductionIssueController.java +++ b/src/main/java/com/niuan/erp/module/production/controller/ProductionIssueController.java @@ -10,6 +10,7 @@ import com.niuan.erp.common.base.BaseResult; import com.niuan.erp.common.base.CommonValidateGroup.*; import com.niuan.erp.common.base.OperationType; import com.niuan.erp.module.common.entity.Document; +import com.niuan.erp.module.production.controller.dto.ProductionIssueAddDto; import com.niuan.erp.module.production.controller.dto.ProductionIssueDto; import com.niuan.erp.module.production.service.ProductionIssueService; import io.swagger.v3.oas.annotations.Operation; @@ -42,7 +43,7 @@ public class ProductionIssueController { @Operation(summary = "新增ProductionIssue", operationId = "addProductionIssue") @PostMapping("/addProductionIssue") @PreAuthorize("hasAuthority('productionissue:add')") - public BaseResult addProductionIssue(@Validated(Add.class) @RequestBody ProductionIssueDto dto) { + public BaseResult addProductionIssue(@Validated(Add.class) @RequestBody ProductionIssueAddDto dto) { productionIssueService.addProductionIssue(dto); return BaseResult.success(); } diff --git a/src/main/java/com/niuan/erp/module/production/controller/ProductionPlanController.java b/src/main/java/com/niuan/erp/module/production/controller/ProductionPlanController.java index f92f0a4..37fa0c5 100644 --- a/src/main/java/com/niuan/erp/module/production/controller/ProductionPlanController.java +++ b/src/main/java/com/niuan/erp/module/production/controller/ProductionPlanController.java @@ -9,9 +9,15 @@ import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BaseResult; import com.niuan.erp.common.base.CommonValidateGroup.*; import com.niuan.erp.common.base.OperationType; +import com.niuan.erp.module.production.controller.dto.PlanProductionIssueAddDto; import com.niuan.erp.module.production.controller.dto.ProductionPlanDto; +import com.niuan.erp.module.production.controller.dto.ProductionPlanShortageDto; import com.niuan.erp.module.production.entity.ProductionPlan; import com.niuan.erp.module.production.service.ProductionPlanService; +import com.niuan.erp.module.purchase.controller.dto.PurchasePlanAddDto; +import com.niuan.erp.module.purchase.service.PurchasePlanService; +import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderAddDto; +import com.niuan.erp.module.warehouse.service.StockTransferOrderService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -20,66 +26,109 @@ import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.List; + @Tag(name = "ProductionPlan") -@ModuleLog("ProductionPlan管理") +@ModuleLog("生产计划管理") @RestController -@RequestMapping("/production/productionplan") +@RequestMapping("/production/productionPlan") @RequiredArgsConstructor public class ProductionPlanController { private final ProductionPlanService productionPlanService; - @Operation(summary = "分页查询ProductionPlan数据", operationId = "getProductionPlanPage") + private final PurchasePlanService purchasePlanService; + + private final StockTransferOrderService stockTransferOrderService; + + @Operation(summary = "分页查询生产计划数据", operationId = "getProductionPlanPage") @GetMapping("/getProductionPlanPage") - @PreAuthorize("hasAuthority('productionplan:index')") + @PreAuthorize("hasAuthority('production_plan:index')") public BaseResult> getProductionPlanPage(@Validated BasePageReqParams pageParams, @Validated(Get.class) ProductionPlanDto searchParams) { var wrapper = new LambdaQueryWrapper(); - if (searchParams != null) { - if (StringUtils.hasText(searchParams.customerName())) { - wrapper.like(ProductionPlan::getCreateUserName, searchParams.customerName()); - } - if (StringUtils.hasText(searchParams.projectName())) { - wrapper.like(ProductionPlan::getProjectName, searchParams.projectName()); - } + if (searchParams != null) { + if (StringUtils.hasText(searchParams.customerName())) { + wrapper.like(ProductionPlan::getCreateUserName, searchParams.customerName()); } + if (StringUtils.hasText(searchParams.projectName())) { + wrapper.like(ProductionPlan::getProjectName, searchParams.projectName()); + } + } + wrapper.orderByDesc(ProductionPlan::getCreateDate); return BaseResult.successWithData(productionPlanService.getProductionPlanPage(pageParams, wrapper)); } - @ApiLog(type = OperationType.ADD, remark = "新增一条ProductionPlan记录") - @Operation(summary = "新增ProductionPlan", operationId = "addProductionPlan") + @ApiLog(type = OperationType.ADD, remark = "新增一条生产计划记录") + @Operation(summary = "新增生产计划", operationId = "addProductionPlan") @PostMapping("/addProductionPlan") - @PreAuthorize("hasAuthority('productionplan:add')") + @PreAuthorize("hasAuthority('production_plan:add')") public BaseResult addProductionPlan(@Validated(Add.class) @RequestBody ProductionPlanDto dto) { productionPlanService.addProductionPlan(dto); return BaseResult.success(); } - @ApiLog(type = OperationType.UPDATE, remark = "更新一条ProductionPlan记录") - @Operation(summary = "更新ProductionPlan", operationId = "updateProductionPlan") + @ApiLog(type = OperationType.UPDATE, remark = "更新一条生产计划记录") + @Operation(summary = "更新生产计划", operationId = "updateProductionPlan") @PostMapping("/updateProductionPlan") - @PreAuthorize("hasAuthority('productionplan:update')") + @PreAuthorize("hasAuthority('production_plan:update')") public BaseResult updateProductionPlan(@Validated(Update.class) @RequestBody ProductionPlanDto dto) { productionPlanService.updateProductionPlan(dto); return BaseResult.success(); } - @ApiLog(type = OperationType.DELETE, remark = "删除一条ProductionPlan记录") - @Operation(summary = "删除ProductionPlan", operationId = "deleteProductionPlan") + @ApiLog(type = OperationType.DELETE, remark = "删除一条生产计划记录") + @Operation(summary = "删除生产计划", operationId = "deleteProductionPlan") @PostMapping("/deleteProductionPlan") - @PreAuthorize("hasAuthority('productionplan:delete')") + @PreAuthorize("hasAuthority('production_plan:delete')") public BaseResult deleteProductionPlan(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) { productionPlanService.deleteProductionPlan(req.id()); return BaseResult.success(); } - @ApiLog(type = OperationType.DELETE, remark = "批量删除ProductionPlan记录") - @Operation(summary = "批量删除ProductionPlan", operationId = "deleteProductionPlanBatch") - @PostMapping("/deleteProductionPlanBatch") - @PreAuthorize("hasAuthority('productionplan:deleteBatch')") - public BaseResult deleteProductionPlanBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) { - productionPlanService.deleteBatch(req.ids()); + @Operation(summary = "得到生产计划缺料值", operationId = "getMaterialShortageList") + @GetMapping("/getMaterialShortageList") + @PreAuthorize("hasAuthority('production_plan:viewMaterialShortage')") + public BaseResult> getMaterialShortageList(@RequestParam("ids") List ids) { + return BaseResult.successWithData(productionPlanService.getProductionPlanShortageList(ids)); + } + + @ApiLog(type = OperationType.ADD, remark = "生成一个采购计划") + @Operation(summary = "生成采购计划", operationId = "generatePurchasePlan") + @PostMapping("/generatePurchasePlan") + @PreAuthorize("hasAuthority('production_plan:generatePurchasePlan')") + public BaseResult generatePurchasePlan(@Validated @RequestBody PurchasePlanAddDto dto) { + purchasePlanService.addPurchasePlan(dto); return BaseResult.success(); } + + @ApiLog(type = OperationType.ADD, remark = "生成一个调拨单") + @Operation(summary = "生成调拨单", operationId = "generateTransferOrder") + @PostMapping("/generateTransferOrder") + @PreAuthorize("hasAuthority('production_plan:generateTransferOrder')") + public BaseResult generateTransferOrder(@Validated @RequestBody StockTransferOrderAddDto dto) { + stockTransferOrderService.addStockTransferOrder(dto); + return BaseResult.success(); + } + + @ApiLog(type = OperationType.ADD, remark = "生成一个出料单") + @Operation(summary = "生成出料单", operationId = "generateProductionIssue") + @PostMapping("/generateProductionIssue") + @PreAuthorize("hasAuthority('production_plan:generateProductionIssue')") + public BaseResult generateProductionIssue(@Validated @RequestBody PlanProductionIssueAddDto dto) { + productionPlanService.generateProductionIssue(dto); + return BaseResult.success(); + } + + + +// @ApiLog(type = OperationType.DELETE, remark = "批量删除ProductionPlan记录") +// @Operation(summary = "批量删除生产计划", operationId = "deleteProductionPlanBatch") +// @PostMapping("/deleteProductionPlanBatch") +// @PreAuthorize("hasAuthority('production_plan:deleteBatch')") +// public BaseResult deleteProductionPlanBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) { +// productionPlanService.deleteBatch(req.ids()); +// return BaseResult.success(); +// } } diff --git a/src/main/java/com/niuan/erp/module/production/controller/dto/BomAddDto.java b/src/main/java/com/niuan/erp/module/production/controller/dto/BomAddDto.java new file mode 100644 index 0000000..9860353 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/production/controller/dto/BomAddDto.java @@ -0,0 +1,30 @@ +package com.niuan.erp.module.production.controller.dto; + +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * 添加 BOM Dto + * @param bomNo + * @param bomName + * @param manufacturer + * @param spec + * @param brandName + * @param formMark + * @param bomItems + */ +public record BomAddDto( + @NotNull(message = "production.bom.validate.bom_no.not_null") + String bomNo, + @NotNull(message = "production.bom.validate.bom_name.not_null") + String bomName, + @NotNull(message = "production.bom.validate.manufacturer.not_null") + String manufacturer, + @NotNull(message = "production.bom.validate.spec.not_null") + String spec, + @NotNull(message = "production.bom.validate.brand_name.not_null") + String brandName, + String formMark, + List bomItems +) {} diff --git a/src/main/java/com/niuan/erp/module/production/controller/dto/BomDto.java b/src/main/java/com/niuan/erp/module/production/controller/dto/BomDto.java index f791e43..c0b467c 100644 --- a/src/main/java/com/niuan/erp/module/production/controller/dto/BomDto.java +++ b/src/main/java/com/niuan/erp/module/production/controller/dto/BomDto.java @@ -1,23 +1,29 @@ package com.niuan.erp.module.production.controller.dto; -import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; + +/** + * 前端展示 Dto + * @param id + * @param bomNo + * @param manufacturer + * @param bomName + * @param spec + * @param brandName + * @param formMark + * @param customerName + * @param bomItems + */ +@JsonInclude(JsonInclude.Include.NON_NULL) public record BomDto( - Long id, - Integer status, - LocalDateTime createDate, - Long createUserId, - String createUserName, - LocalDateTime updateDate, - Long updateUserId, - String updateUserName, - Long parentId, - String bomNo, - String manufacturer, - String bomName, - String spec, - String brandName, - String formMark, - String customerName, - Integer customerId, - String searchCode) {} \ No newline at end of file + Long id, + String bomNo, + String manufacturer, + String bomName, + String spec, + String brandName, + String formMark, + String customerName, + List bomItems) {} \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/production/controller/dto/BomItemAddDto.java b/src/main/java/com/niuan/erp/module/production/controller/dto/BomItemAddDto.java new file mode 100644 index 0000000..8d7de9a --- /dev/null +++ b/src/main/java/com/niuan/erp/module/production/controller/dto/BomItemAddDto.java @@ -0,0 +1,30 @@ +package com.niuan.erp.module.production.controller.dto; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +/** + * 添加 BOM 明细 Dto + * @param partNumber + * @param manufactureCount + * @param itemPosition + * @param productMark + * @param sameUseNum1 + * @param sameUseNum2 + * @param sameUseNum3 + * @param sameUseNum + */ +public record BomItemAddDto( + @NotNull(message = "production.bom.validate.part_number.not_null") + String partNumber, + @NotNull(message = "production.bom.validate.manufacture_count.not_null") + @Min(value = 1, message = "production.bom.validate.manufacture_count.min") + Integer manufactureCount, + @NotNull(message = "production.bom.validate.item_position.not_null") + String itemPosition, + String productMark, + String sameUseNum1, + String sameUseNum2, + String sameUseNum3, + String sameUseNum +) {} diff --git a/src/main/java/com/niuan/erp/module/production/controller/dto/BomItemDto.java b/src/main/java/com/niuan/erp/module/production/controller/dto/BomItemDto.java index efb2574..ac65289 100644 --- a/src/main/java/com/niuan/erp/module/production/controller/dto/BomItemDto.java +++ b/src/main/java/com/niuan/erp/module/production/controller/dto/BomItemDto.java @@ -1,18 +1,24 @@ package com.niuan.erp.module.production.controller.dto; +/** + * 前端展示 BOM 明细 Dto + * @param partNumber + * @param productType + * @param productSpecs + * @param productPackSize + * @param productBrand + * @param manufactureCount + * @param itemPosition + * @param sameUseCount + * @param productMark + */ public record BomItemDto( - Long id, - Integer bomId, - String projectName, String partNumber, - String itemPosition, + String productType, + String productSpecs, + String productPackSize, + String productBrand, Integer manufactureCount, + String itemPosition, Integer sameUseCount, - String sameUseNum1, - String sameUseNum2, - String sameUseNum3, - Integer loseRate, - Integer manufactureSpec, - String productMark, - Integer reserve1, - String reserve2) {} \ No newline at end of file + String productMark) {} \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/production/controller/dto/BomSearchParams.java b/src/main/java/com/niuan/erp/module/production/controller/dto/BomSearchParams.java new file mode 100644 index 0000000..9fd439d --- /dev/null +++ b/src/main/java/com/niuan/erp/module/production/controller/dto/BomSearchParams.java @@ -0,0 +1,5 @@ +package com.niuan.erp.module.production.controller.dto; + +public record BomSearchParams( + String searchCode, + String partNumber) {} diff --git a/src/main/java/com/niuan/erp/module/production/controller/dto/PlanProductionIssueAddDto.java b/src/main/java/com/niuan/erp/module/production/controller/dto/PlanProductionIssueAddDto.java new file mode 100644 index 0000000..ad7c736 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/production/controller/dto/PlanProductionIssueAddDto.java @@ -0,0 +1,17 @@ +package com.niuan.erp.module.production.controller.dto; + +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * 用于生产计划生成发料单 + * @param ids 生产计划 ID List + * @param issue + */ +public record PlanProductionIssueAddDto( + @NotNull(message = "production.production_plan.validate.ids.not_null") + List ids, + @NotNull(message = "production.production_plan.validate.issue.not_null") + ProductionIssueAddDto issue +) {} diff --git a/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionIssueAddDto.java b/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionIssueAddDto.java new file mode 100644 index 0000000..e236403 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionIssueAddDto.java @@ -0,0 +1,27 @@ +package com.niuan.erp.module.production.controller.dto; + +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * 添加发料单 Dto + * @param formCode + * @param formName + * @param formMark + * @param storeNo + * @param storeName + * @param items + */ +public record ProductionIssueAddDto( + @NotNull(message = "production.production_plan.validate.form_code.not_null") + String formCode, + String formName, + String formMark, + @NotNull(message = "production.production_plan.validate.store_no.not_null") + Long storeNo, + @NotNull(message = "production.production_plan.validate.store_name.not_null") + String storeName, + @NotNull(message = "production.production_plan.validate.items.not_null") + List items +) {} diff --git a/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionIssueItemAddDto.java b/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionIssueItemAddDto.java new file mode 100644 index 0000000..ee018e3 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionIssueItemAddDto.java @@ -0,0 +1,24 @@ +package com.niuan.erp.module.production.controller.dto; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +/** + * 发料单明细 Dto + * @param partNumber 物料便哈 + * @param storeNo 发料仓库 + * @param productCount 实发数量 + * @param demandCount 需求数量 + */ +public record ProductionIssueItemAddDto( + @NotNull(message = "production.production_plan.validate.part_number.not_null") + String partNumber, + @NotNull(message = "production.production_plan.validate.store_no.not_null") + Long storeNo, + @NotNull(message = "production.production_plan.validate.product_count.not_null") + @Min(value = 1, message = "production.production_plan.validate.product_count.min") + Integer productCount, + @NotNull(message = "production.production_plan.validate.demand_count.not_null") + @Min(value = 1, message = "production.production_plan.validate.demand_count.min") + Integer demandCount +) {} diff --git a/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionPlanDto.java b/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionPlanDto.java index 7ac8a8c..c6f7989 100644 --- a/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionPlanDto.java +++ b/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionPlanDto.java @@ -1,29 +1,30 @@ package com.niuan.erp.module.production.controller.dto; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.niuan.erp.common.base.CommonValidateGroup.*; +import jakarta.validation.constraints.NotNull; + import java.time.LocalDateTime; +@JsonInclude(JsonInclude.Include.NON_NULL) public record ProductionPlanDto( + @NotNull(groups = Update.class, message = "") Long id, - Integer status, LocalDateTime createDate, - Long createUserId, - String createUserName, - LocalDateTime updateDate, - Long updateUserId, - String updateUserName, + @NotNull(groups = { Add.class, Update.class }, message = "") String productionNum, + @NotNull(groups = { Add.class, Update.class }, message = "") String projectName, + @NotNull(groups = { Add.class, Update.class }, message = "") Integer projectId, + @NotNull(groups = { Add.class, Update.class }, message = "") Integer productionCount, Integer productionStatus, String productionNote, String productionReport, String productionMark, - String reserve1, - String reserve2, + @NotNull(groups = { Add.class, Update.class }, message = "") Integer storeNo, + @NotNull(groups = { Add.class, Update.class }, message = "") String storeName, - Integer groupId, - String groupName, - Integer customerId, String customerName) {} \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionPlanShortageDto.java b/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionPlanShortageDto.java new file mode 100644 index 0000000..cd28736 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/production/controller/dto/ProductionPlanShortageDto.java @@ -0,0 +1,12 @@ +package com.niuan.erp.module.production.controller.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public record ProductionPlanShortageDto( + Long id, + String partNumber, + String productSpecs, + Integer requiredQty, + Integer stockQty, + Integer diffQty) {} diff --git a/src/main/java/com/niuan/erp/module/production/converter/BomConverter.java b/src/main/java/com/niuan/erp/module/production/converter/BomConverter.java index e6194bd..63ce5aa 100644 --- a/src/main/java/com/niuan/erp/module/production/converter/BomConverter.java +++ b/src/main/java/com/niuan/erp/module/production/converter/BomConverter.java @@ -1,5 +1,6 @@ package com.niuan.erp.module.production.converter; +import com.niuan.erp.module.production.controller.dto.BomAddDto; import com.niuan.erp.module.production.controller.dto.BomDto; import com.niuan.erp.module.production.entity.Bom; import org.mapstruct.Mapper; @@ -12,4 +13,6 @@ public interface BomConverter { Bom toEntity(BomDto dto); BomDto toDto(Bom entity); List toDtoList(List entities); + + Bom toEntity(BomAddDto dto); } \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/production/converter/BomItemConverter.java b/src/main/java/com/niuan/erp/module/production/converter/BomItemConverter.java index 1a15dbc..ca6d501 100644 --- a/src/main/java/com/niuan/erp/module/production/converter/BomItemConverter.java +++ b/src/main/java/com/niuan/erp/module/production/converter/BomItemConverter.java @@ -1,5 +1,6 @@ package com.niuan.erp.module.production.converter; +import com.niuan.erp.module.production.controller.dto.BomItemAddDto; import com.niuan.erp.module.production.controller.dto.BomItemDto; import com.niuan.erp.module.production.entity.BomItem; import org.mapstruct.Mapper; @@ -10,6 +11,8 @@ import java.util.List; @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) public interface BomItemConverter { BomItem toEntity(BomItemDto dto); + BomItem toEntity(BomItemAddDto dto); BomItemDto toDto(BomItem entity); List toDtoList(List entities); + List toEntityList(List dtos); } \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/production/converter/ProductionIssueConverter.java b/src/main/java/com/niuan/erp/module/production/converter/ProductionIssueConverter.java index 166fd5e..ba50134 100644 --- a/src/main/java/com/niuan/erp/module/production/converter/ProductionIssueConverter.java +++ b/src/main/java/com/niuan/erp/module/production/converter/ProductionIssueConverter.java @@ -1,7 +1,10 @@ package com.niuan.erp.module.production.converter; import com.niuan.erp.module.common.entity.Document; +import com.niuan.erp.module.common.entity.DocumentMaterial; +import com.niuan.erp.module.production.controller.dto.ProductionIssueAddDto; import com.niuan.erp.module.production.controller.dto.ProductionIssueDto; +import com.niuan.erp.module.production.controller.dto.ProductionIssueItemAddDto; import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; @@ -10,6 +13,9 @@ import java.util.List; @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) public interface ProductionIssueConverter { Document toEntity(ProductionIssueDto dto); + Document toEntity(ProductionIssueAddDto dto); + DocumentMaterial toEntity(ProductionIssueItemAddDto dto); + List toEntityList(List dtoList); ProductionIssueDto toDto(Document entity); List toDtoList(List entities); } \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/production/entity/Bom.java b/src/main/java/com/niuan/erp/module/production/entity/Bom.java index e693cc1..f51fcdb 100644 --- a/src/main/java/com/niuan/erp/module/production/entity/Bom.java +++ b/src/main/java/com/niuan/erp/module/production/entity/Bom.java @@ -4,12 +4,14 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.niuan.erp.module.production.controller.dto.BomItemDto; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.List; /** *

@@ -77,4 +79,7 @@ public class Bom implements Serializable { @TableField("CustomerId") private Integer customerId; + + @TableField(exist = false) + private List bomItems; } diff --git a/src/main/java/com/niuan/erp/module/production/entity/ProduceOrderList.java b/src/main/java/com/niuan/erp/module/production/entity/ProduceOrderList.java new file mode 100644 index 0000000..c1efd26 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/production/entity/ProduceOrderList.java @@ -0,0 +1,42 @@ +package com.niuan.erp.module.production.entity; + +import lombok.Data; +import java.io.Serializable; + +@Data +public class ProduceOrderList implements Serializable { + // 基础信息 + private Integer id; + private String partnumber; + private String productspecs; + private String storeNo; + + // BOM 信息 + private Integer sameUseCount; // 1, 2, 3 + private String sameNum1; + private String sameNum2; + private String sameNum3; + private Integer bomTotal; // 单个BOM用量 + private Integer orderTotal; // 订单数量 + + // 【新增】从 SQL 直接查出的库存字段 + // 主料库存 + private Integer mainStock; + // 替换料1库存 + private Integer sub1Stock; + // 替换料2库存 + private Integer sub2Stock; + // 替换料3库存 + private Integer sub3Stock; + // 占用数量 (假设默认0或从其他字段映射,此处保持逻辑一致) + private Integer productOccupyTotal = 0; + + // 【计算字段】(对应 C# 中的 m.Productstocktotal 等) + // 注意:C# 代码中 m.Productstocktotal 初始值是主料库存,后续会累加替换料 + private Integer productstocktotal; + private Integer demandTotal; + private Integer surplus; + private Integer differenceTotal; + private String mark; + private String shortageForm; +} diff --git a/src/main/java/com/niuan/erp/module/production/entity/ProductionPlan.java b/src/main/java/com/niuan/erp/module/production/entity/ProductionPlan.java index 0242056..ad922b1 100644 --- a/src/main/java/com/niuan/erp/module/production/entity/ProductionPlan.java +++ b/src/main/java/com/niuan/erp/module/production/entity/ProductionPlan.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.niuan.erp.module.production.enums.ProductionPlanStatus; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -64,7 +65,7 @@ public class ProductionPlan implements Serializable { private Integer productionCount; @TableField("ProductionStatus") - private Integer productionStatus; + private ProductionPlanStatus productionStatus; @TableField("ProductionNote") private String productionNote; diff --git a/src/main/java/com/niuan/erp/module/production/enums/ProductionPlanStatus.java b/src/main/java/com/niuan/erp/module/production/enums/ProductionPlanStatus.java new file mode 100644 index 0000000..0a42a36 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/production/enums/ProductionPlanStatus.java @@ -0,0 +1,32 @@ +package com.niuan.erp.module.production.enums; + +import com.baomidou.mybatisplus.annotation.IEnum; +import com.niuan.erp.common.base.BaseStatus; + +public enum ProductionPlanStatus implements IEnum { + NoComplete(0, "未完成"), + Completed(1, "已完成"), + Approving(2, "审核中"), + Reviewed(3, "已审核"); + final int code; + final String description; + ProductionPlanStatus(int code, String description) { + this.code = code; + this.description = description; + } + + /** + * + * @param code + * @return + */ + public static ProductionPlanStatus fromCode(int code) { + return ProductionPlanStatus.values()[code]; + } + + + @Override + public Integer getValue() { + return code; + } +} diff --git a/src/main/java/com/niuan/erp/module/production/mapper/BomItemMapper.java b/src/main/java/com/niuan/erp/module/production/mapper/BomItemMapper.java index f8186d5..01cecf5 100644 --- a/src/main/java/com/niuan/erp/module/production/mapper/BomItemMapper.java +++ b/src/main/java/com/niuan/erp/module/production/mapper/BomItemMapper.java @@ -1,8 +1,11 @@ package com.niuan.erp.module.production.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.niuan.erp.module.production.controller.dto.BomItemDto; import com.niuan.erp.module.production.entity.BomItem; +import java.util.List; + /** *

* Mapper 接口 @@ -13,4 +16,8 @@ import com.niuan.erp.module.production.entity.BomItem; */ public interface BomItemMapper extends BaseMapper { + List getBomItemListByBomId(Long bomId); + + List getBomItemListByBomIdAndPartNumber(Long bomId, String partNumber); + } diff --git a/src/main/java/com/niuan/erp/module/production/mapper/BomMapper.java b/src/main/java/com/niuan/erp/module/production/mapper/BomMapper.java index b04074d..05a9449 100644 --- a/src/main/java/com/niuan/erp/module/production/mapper/BomMapper.java +++ b/src/main/java/com/niuan/erp/module/production/mapper/BomMapper.java @@ -1,8 +1,13 @@ package com.niuan.erp.module.production.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.niuan.erp.common.base.BaseSelectDto; import com.niuan.erp.module.production.entity.Bom; +import java.util.List; + /** *

* Mapper 接口 @@ -13,4 +18,8 @@ import com.niuan.erp.module.production.entity.Bom; */ public interface BomMapper extends BaseMapper { + IPage selectPageByPartNumber(Page page, String searchCode, String partNumber); + + List getBomSelectList(); + } diff --git a/src/main/java/com/niuan/erp/module/production/mapper/ProductionPlanMapper.java b/src/main/java/com/niuan/erp/module/production/mapper/ProductionPlanMapper.java index c35b12c..0e2421a 100644 --- a/src/main/java/com/niuan/erp/module/production/mapper/ProductionPlanMapper.java +++ b/src/main/java/com/niuan/erp/module/production/mapper/ProductionPlanMapper.java @@ -1,7 +1,14 @@ package com.niuan.erp.module.production.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.niuan.erp.module.production.controller.dto.ProductionPlanShortageDto; +import com.niuan.erp.module.production.entity.ProduceOrderList; import com.niuan.erp.module.production.entity.ProductionPlan; +import org.apache.ibatis.annotations.MapKey; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; /** *

@@ -13,4 +20,9 @@ import com.niuan.erp.module.production.entity.ProductionPlan; */ public interface ProductionPlanMapper extends BaseMapper { + List getProductionPlanRequiredQtyList(@Param("ids") List ids, + @Param("warehouseId") Long warehouseId); + + List selectProduceOrderData(@Param("ids") List ids); + } diff --git a/src/main/java/com/niuan/erp/module/production/service/BomService.java b/src/main/java/com/niuan/erp/module/production/service/BomService.java index b684398..77abbd2 100644 --- a/src/main/java/com/niuan/erp/module/production/service/BomService.java +++ b/src/main/java/com/niuan/erp/module/production/service/BomService.java @@ -3,7 +3,10 @@ package com.niuan.erp.module.production.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.common.base.BaseSelectDto; +import com.niuan.erp.module.production.controller.dto.BomAddDto; import com.niuan.erp.module.production.controller.dto.BomDto; +import com.niuan.erp.module.production.controller.dto.BomItemDto; import com.niuan.erp.module.production.entity.Bom; import java.util.List; @@ -12,7 +15,13 @@ public interface BomService { IPage getBomPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper); - void addBom(BomDto dto); + IPage getBomPageWithItem(BasePageReqParams pageParams, String searchCode, String partNumber); + + List getBomSelectList(); + + List getBomItemList(Long bomId); + + void addBom(BomAddDto dto); void updateBom(BomDto dto); diff --git a/src/main/java/com/niuan/erp/module/production/service/ProductionIssueService.java b/src/main/java/com/niuan/erp/module/production/service/ProductionIssueService.java index 3a6531c..4e23b95 100644 --- a/src/main/java/com/niuan/erp/module/production/service/ProductionIssueService.java +++ b/src/main/java/com/niuan/erp/module/production/service/ProductionIssueService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.module.common.entity.Document; +import com.niuan.erp.module.production.controller.dto.ProductionIssueAddDto; import com.niuan.erp.module.production.controller.dto.ProductionIssueDto; import java.util.List; @@ -12,7 +13,7 @@ public interface ProductionIssueService { IPage getProductionIssuePage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper); - void addProductionIssue(ProductionIssueDto dto); + void addProductionIssue(ProductionIssueAddDto dto); void updateProductionIssue(ProductionIssueDto dto); diff --git a/src/main/java/com/niuan/erp/module/production/service/ProductionPlanService.java b/src/main/java/com/niuan/erp/module/production/service/ProductionPlanService.java index faff2f3..085b8cd 100644 --- a/src/main/java/com/niuan/erp/module/production/service/ProductionPlanService.java +++ b/src/main/java/com/niuan/erp/module/production/service/ProductionPlanService.java @@ -3,7 +3,10 @@ package com.niuan.erp.module.production.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.module.production.controller.dto.PlanProductionIssueAddDto; +import com.niuan.erp.module.production.controller.dto.ProductionIssueAddDto; import com.niuan.erp.module.production.controller.dto.ProductionPlanDto; +import com.niuan.erp.module.production.controller.dto.ProductionPlanShortageDto; import com.niuan.erp.module.production.entity.ProductionPlan; import java.util.List; @@ -20,4 +23,8 @@ public interface ProductionPlanService { void deleteBatch(List ids); + List getProductionPlanShortageList(List ids); + + void generateProductionIssue(PlanProductionIssueAddDto dto); + } diff --git a/src/main/java/com/niuan/erp/module/production/service/impl/BomServiceImpl.java b/src/main/java/com/niuan/erp/module/production/service/impl/BomServiceImpl.java index b9d4a48..ff01f9d 100644 --- a/src/main/java/com/niuan/erp/module/production/service/impl/BomServiceImpl.java +++ b/src/main/java/com/niuan/erp/module/production/service/impl/BomServiceImpl.java @@ -5,12 +5,19 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.common.base.BaseSelectDto; +import com.niuan.erp.common.exception.BusinessException; import com.niuan.erp.common.utils.SecurityUtils; -import com.niuan.erp.module.production.controller.dto.BomDto; +import com.niuan.erp.module.production.controller.dto.*; import com.niuan.erp.module.production.converter.BomConverter; +import com.niuan.erp.module.production.converter.BomItemConverter; import com.niuan.erp.module.production.entity.Bom; +import com.niuan.erp.module.production.entity.BomItem; +import com.niuan.erp.module.production.mapper.BomItemMapper; import com.niuan.erp.module.production.mapper.BomMapper; import com.niuan.erp.module.production.service.BomService; +import com.niuan.erp.module.warehouse.entity.WarehouseItem; +import com.niuan.erp.module.warehouse.mapper.WarehouseItemMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -27,6 +34,12 @@ public class BomServiceImpl extends ServiceImpl implements BomSe private final BomConverter bomConverter; + private final BomItemMapper bomItemMapper; + + private final WarehouseItemMapper warehouseItemMapper; + + private final BomItemConverter bomItemConverter; + @Override public IPage getBomPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper) { IPage result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); @@ -34,13 +47,63 @@ public class BomServiceImpl extends ServiceImpl implements BomSe } @Override - public void addBom(BomDto dto) { + public IPage getBomPageWithItem(BasePageReqParams pageParams, String searchCode, String partNumber) { + IPage bomPage = this.baseMapper.selectPageByPartNumber(new Page<>(pageParams.page(), pageParams.pageSize()), + searchCode, partNumber); + List bomList = bomPage.getRecords(); + bomList.forEach(b -> { + b.setBomItems(bomItemMapper.getBomItemListByBomIdAndPartNumber(b.getId(), partNumber)); + }); + return bomPage.convert(bomConverter::toDto); + } + + @Override + public List getBomSelectList() { + return this.baseMapper.getBomSelectList(); + } + + @Override + public List getBomItemList(Long bomId) { + return bomItemMapper.getBomItemListByBomId(bomId); + } + + @Override + public void addBom(BomAddDto dto) { + // 检验数据 + var searchBomNameWrapper = new LambdaQueryWrapper().eq(Bom::getBomName, dto.bomName()); + if (this.baseMapper.selectCount(searchBomNameWrapper) > 0) { + throw new BusinessException("production.bom.exception.duplicate_bom_name"); + } + List items = dto.bomItems(); + List itemPartNumbers = items.stream().map(BomItemAddDto::partNumber).distinct().toList(); + if (items.size() != itemPartNumbers.size()) { + throw new BusinessException("production.bom.exception.duplicate_bom_item"); + } + items.forEach(item -> { + if (item.itemPosition().split(",").length != item.manufactureCount()) { + throw new BusinessException("production.bom.exception.unpair_position_count"); + } + }); + var searchBomItemWrapper = new LambdaQueryWrapper().in(WarehouseItem::getPartNumber, itemPartNumbers); + if (warehouseItemMapper.selectCount(searchBomItemWrapper) != items.size()) { + throw new BusinessException("production.bom.exception.unexists_bom_item"); + } + + // save Bom entity = bomConverter.toEntity(dto); entity.setCreateUserId(SecurityUtils.getUserId()); entity.setCreateUserName(SecurityUtils.getUserName()); entity.setCreateDate(LocalDateTime.now()); entity.setStatus(0); + entity.setCustomerId(SecurityUtils.getLoginUser().getUser().getCustomerId()); + entity.setCustomerName(SecurityUtils.getUserName()); this.baseMapper.insert(entity); + + List bomItemEntities = bomItemConverter.toEntityList(items); + bomItemEntities.forEach(item -> { + item.setBomId(Math.toIntExact(entity.getId())); + }); + bomItemMapper.insert(bomItemEntities); } @Override diff --git a/src/main/java/com/niuan/erp/module/production/service/impl/ProductionIssueServiceImpl.java b/src/main/java/com/niuan/erp/module/production/service/impl/ProductionIssueServiceImpl.java index d671821..d4109a6 100644 --- a/src/main/java/com/niuan/erp/module/production/service/impl/ProductionIssueServiceImpl.java +++ b/src/main/java/com/niuan/erp/module/production/service/impl/ProductionIssueServiceImpl.java @@ -7,16 +7,22 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.utils.SecurityUtils; import com.niuan.erp.module.common.entity.Document; +import com.niuan.erp.module.common.entity.DocumentMaterial; +import com.niuan.erp.module.common.enums.DocumentType; import com.niuan.erp.module.common.mapper.DocumentMapper; +import com.niuan.erp.module.common.mapper.DocumentMaterialMapper; +import com.niuan.erp.module.production.controller.dto.ProductionIssueAddDto; import com.niuan.erp.module.production.controller.dto.ProductionIssueDto; import com.niuan.erp.module.production.converter.ProductionIssueConverter; import com.niuan.erp.module.production.service.ProductionIssueService; +import com.niuan.erp.module.warehouse.mapper.WarehouseItemMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.List; +import java.util.Map; @Service @@ -24,9 +30,12 @@ import java.util.List; @RequiredArgsConstructor public class ProductionIssueServiceImpl extends ServiceImpl implements ProductionIssueService { - private final ProductionIssueConverter productionIssueConverter; + private final WarehouseItemMapper warehouseItemMapper; + + private final DocumentMaterialMapper documentMaterialMapper; + @Override public IPage getProductionIssuePage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper) { IPage result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); @@ -34,13 +43,34 @@ public class ProductionIssueServiceImpl extends ServiceImpl materials = productionIssueConverter.toEntityList(dto.items()); + // 查库存 + Map> warehouseItems = + warehouseItemMapper.getWarehouseItemStockListByPartNumbers(materials.stream() + .map(DocumentMaterial::getPartNumber) + .toList()); + + materials.forEach(m -> { + m.setCreateUserId(SecurityUtils.getUserId()); + m.setCreateUserName(SecurityUtils.getUserName()); + m.setCreateDate(LocalDateTime.now()); + m.setStatus(0); + m.setDocumentNo(entity.getId().intValue()); + }); + + documentMaterialMapper.insert(materials); } @Override diff --git a/src/main/java/com/niuan/erp/module/production/service/impl/ProductionPlanServiceImpl.java b/src/main/java/com/niuan/erp/module/production/service/impl/ProductionPlanServiceImpl.java index 5b94833..a4e722f 100644 --- a/src/main/java/com/niuan/erp/module/production/service/impl/ProductionPlanServiceImpl.java +++ b/src/main/java/com/niuan/erp/module/production/service/impl/ProductionPlanServiceImpl.java @@ -5,18 +5,25 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.common.exception.BusinessException; import com.niuan.erp.common.utils.SecurityUtils; -import com.niuan.erp.module.production.controller.dto.ProductionPlanDto; +import com.niuan.erp.module.common.mapper.DocumentMapper; +import com.niuan.erp.module.production.controller.dto.*; import com.niuan.erp.module.production.converter.ProductionPlanConverter; +import com.niuan.erp.module.production.entity.ProduceOrderList; import com.niuan.erp.module.production.entity.ProductionPlan; +import com.niuan.erp.module.production.enums.ProductionPlanStatus; import com.niuan.erp.module.production.mapper.ProductionPlanMapper; +import com.niuan.erp.module.production.service.ProductionIssueService; import com.niuan.erp.module.production.service.ProductionPlanService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.Validator; import java.time.LocalDateTime; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; @Service @@ -24,9 +31,14 @@ import java.util.List; @RequiredArgsConstructor public class ProductionPlanServiceImpl extends ServiceImpl implements ProductionPlanService { - private final ProductionPlanConverter productionPlanConverter; + private final ProductionIssueService productionIssueService; + + private final DocumentMapper documentMapper; + + private final Validator validator; + @Override public IPage getProductionPlanPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper) { IPage result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); @@ -40,6 +52,9 @@ public class ProductionPlanServiceImpl extends ServiceImpl getProductionPlanShortageList(List ids) { + + // 2. 【性能优化点】一次性查出所有数据 (包含主料和所有替换料库存) + // 对应 C#: base.Context.Queryable(...).ToPageListAsync(...) + // 注意:这里先不分页,因为后面有 GroupBy,分页应在聚合后处理,或者如果数据量极大,需在 SQL 层面先过滤明细再聚合 + List list = this.baseMapper.selectProduceOrderData(ids); + + // 3. 【核心逻辑】内存计算 (对应 C# 的 forList 方法) + // 此时不再访问数据库,直接使用 list 中已查出的 mainStock, sub1Stock 等字段 + for (ProduceOrderList m : list) { + int count1 = 0; + int count2 = 0; + int count3 = 0; + + // 初始化主料库存 (对应 C# m.Productstocktotal 初始值) + // C# 代码中 m.Productstocktotal 来自 f.ProductCount (即主料) + int currentStockTotal = (m.getMainStock() == null) ? 0 : m.getMainStock(); + int occupyTotal = (m.getProductOccupyTotal() == null) ? 0 : m.getProductOccupyTotal(); + + // --- 开始模拟 C# 的 if 判断 --- + + // if (m.SameUseCount == 1) + if (m.getSameUseCount() != null && m.getSameUseCount() == 1) { + // C#: productcount1 = ... Where(PartNumber == m.SameNum1) + // Java: 直接从 sub1Stock 取 (SQL 已经帮我们要到了) + count1 = (m.getSub1Stock() == null) ? 0 : m.getSub1Stock(); + } + + // if (m.SameUseCount == 2) + if (m.getSameUseCount() != null && m.getSameUseCount() == 2) { + count1 = (m.getSub1Stock() == null) ? 0 : m.getSub1Stock(); + count2 = (m.getSub2Stock() == null) ? 0 : m.getSub2Stock(); + } + + // if (m.SameUseCount == 3) + if (m.getSameUseCount() != null && m.getSameUseCount() == 3) { + count1 = (m.getSub1Stock() == null) ? 0 : m.getSub1Stock(); + count2 = (m.getSub2Stock() == null) ? 0 : m.getSub2Stock(); + count3 = (m.getSub3Stock() == null) ? 0 : m.getSub3Stock(); + } + + // --- 开始计算逻辑 (与 C# 完全一致) --- + + // m.DemandTotal = m.OrderTotal * m.BomTotal; + int orderTotal = (m.getOrderTotal() == null) ? 0 : m.getOrderTotal(); + int bomTotal = (m.getBomTotal() == null) ? 0 : m.getBomTotal(); + m.setDemandTotal(orderTotal * bomTotal); + + // m.Surplus = m.Productstocktotal - m.ProductOccupyTotal; + m.setProductstocktotal(currentStockTotal); // 设置初始库存 + m.setSurplus(currentStockTotal - occupyTotal); + + // m.DifferenceTotal = m.Surplus - m.DemandTotal; + m.setDifferenceTotal(m.getSurplus() - m.getDemandTotal()); + + // 当Bom里主干物料够用的时候,替换料不计入统计 + // if ((m.DifferenceTotal < 0) && (count1 > 0 || count2 > 0 || count3 > 0)) + if ((m.getDifferenceTotal() < 0) && (count1 > 0 || count2 > 0 || count3 > 0)) { + StringBuilder markBuilder = new StringBuilder("用到替换料:"); + boolean hasSub = false; + + if (count1 > 0) { + markBuilder.append(m.getSameNum1()).append("."); + hasSub = true; + } + if (count2 > 0) { + markBuilder.append(m.getSameNum2()).append("."); + hasSub = true; + } + if (count3 > 0) { + markBuilder.append(m.getSameNum3()).append("."); + hasSub = true; + } + + if (hasSub) { + m.setMark(markBuilder.toString()); + + // m.DifferenceTotal += count1 + count2 + count3; + m.setDifferenceTotal(m.getDifferenceTotal() + count1 + count2 + count3); + + // m.Productstocktotal += count1 + count2 + count3; + int newStockTotal = currentStockTotal + count1 + count2 + count3; + m.setProductstocktotal(newStockTotal); + + // m.Surplus = m.Productstocktotal - m.ProductOccupyTotal; + m.setSurplus(newStockTotal - occupyTotal); + } + } + + // m.DifferenceTotal = m.DifferenceTotal > 0 ? 0 : m.DifferenceTotal; + if (m.getDifferenceTotal() > 0) { + m.setDifferenceTotal(0); + } + } + + // 4. 【聚合逻辑】对应 C# 的 GroupBy + // Key: Id, Partnumber, Productspecs, Mark + List resultList = list.stream() + .collect(Collectors.groupingBy(m -> { + // 构建复合键 + return Arrays.asList( + m.getId(), + m.getPartnumber(), + m.getProductspecs(), + m.getMark() == null ? "" : m.getMark() + ); + })) + .values().stream() + .map(group -> { + ProduceOrderList first = group.get(0); + ProduceOrderList aggregated = new ProduceOrderList(); + + aggregated.setId(first.getId()); + aggregated.setPartnumber(first.getPartnumber()); + aggregated.setProductspecs(first.getProductspecs()); + aggregated.setMark(first.getMark()); + + // Sum DemandTotal + int sumDemand = group.stream() + .mapToInt(item -> (item.getDemandTotal() == null ? 0 : item.getDemandTotal())) + .sum(); + aggregated.setDemandTotal(sumDemand); + + // Max Surplus (C# 逻辑: a.Max(c => c.Surplus)) + int maxSurplus = group.stream() + .mapToInt(item -> (item.getSurplus() == null ? 0 : item.getSurplus())) + .max() + .orElse(0); + aggregated.setSurplus(maxSurplus); + + // DifferenceTotal = Max(Surplus) - Sum(DemandTotal) + aggregated.setDifferenceTotal(maxSurplus - sumDemand); + + return aggregated; + }) + .toList(); + + + return resultList.stream().map(result -> new ProductionPlanShortageDto( + Long.valueOf(result.getId()), result.getPartnumber(), result.getProductspecs(), + result.getDemandTotal(), result.getSurplus(), result.getDifferenceTotal())).toList(); + } + + @Override + public void generateProductionIssue(PlanProductionIssueAddDto dto) { + List plans = this.baseMapper + .selectList(new LambdaQueryWrapper().in(ProductionPlan::getId, dto.ids())); + plans.forEach(plan -> { + if (!plan.getProductionStatus().equals(ProductionPlanStatus.NoComplete)) { + throw new BusinessException("production.production_plan.exception.must_no_complete"); + } + }); + if (plans.stream().collect(Collectors.groupingBy(ProductionPlan::getStoreNo)).size() > 1) { + throw new BusinessException("production.production_plan.exception.more_than_one_warehouse"); + } + plans.forEach(plan -> { + plan.setUpdateUserId(SecurityUtils.getUserId()); + plan.setUpdateUserName(SecurityUtils.getUserName()); + plan.setUpdateDate(LocalDateTime.now()); + plan.setProductionStatus(ProductionPlanStatus.Completed); + }); + this.baseMapper.updateById(plans); + + productionIssueService.addProductionIssue(dto.issue()); + } + } \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/purchase/controller/PurchasePlanController.java b/src/main/java/com/niuan/erp/module/purchase/controller/PurchasePlanController.java index db0d2fa..02e8d3f 100644 --- a/src/main/java/com/niuan/erp/module/purchase/controller/PurchasePlanController.java +++ b/src/main/java/com/niuan/erp/module/purchase/controller/PurchasePlanController.java @@ -9,6 +9,7 @@ import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.base.BaseResult; import com.niuan.erp.common.base.CommonValidateGroup.*; import com.niuan.erp.common.base.OperationType; +import com.niuan.erp.module.purchase.controller.dto.PurchasePlanAddDto; import com.niuan.erp.module.purchase.controller.dto.PurchasePlanDto; import com.niuan.erp.module.purchase.entity.PurchasePlan; import com.niuan.erp.module.purchase.service.PurchasePlanService; @@ -48,7 +49,7 @@ public class PurchasePlanController { @Operation(summary = "新增PurchasePlan", operationId = "addPurchasePlan") @PostMapping("/addPurchasePlan") @PreAuthorize("hasAuthority('purchaseplan:add')") - public BaseResult addPurchasePlan(@Validated(Add.class) @RequestBody PurchasePlanDto dto) { + public BaseResult addPurchasePlan(@Validated(Add.class) @RequestBody PurchasePlanAddDto dto) { purchasePlanService.addPurchasePlan(dto); return BaseResult.success(); } diff --git a/src/main/java/com/niuan/erp/module/purchase/controller/dto/PurchasePlanAddDto.java b/src/main/java/com/niuan/erp/module/purchase/controller/dto/PurchasePlanAddDto.java new file mode 100644 index 0000000..b6571cd --- /dev/null +++ b/src/main/java/com/niuan/erp/module/purchase/controller/dto/PurchasePlanAddDto.java @@ -0,0 +1,22 @@ +package com.niuan.erp.module.purchase.controller.dto; + +import jakarta.validation.constraints.NotNull; + +import java.util.List; + + +public record PurchasePlanAddDto( + @NotNull(message = "purchase.purchase_plan.validate.plan_no.not_null") + String planNo, + // 收货仓库 + @NotNull(message = "purchase.purchase_plan.validate.store_no.not_null") + Long storeNo, + @NotNull(message = "purchase.purchase_plan.validate.store_name.not_null") + String storeName, + // 备注 + String remask, + // 计划单名称内容 + @NotNull(message = "purchase.purchase_plan.validate.plan_name.not_null") + String planName, + List planItems +) {} \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/purchase/controller/dto/PurchasePlanItemAddDto.java b/src/main/java/com/niuan/erp/module/purchase/controller/dto/PurchasePlanItemAddDto.java new file mode 100644 index 0000000..524aac5 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/purchase/controller/dto/PurchasePlanItemAddDto.java @@ -0,0 +1,16 @@ +package com.niuan.erp.module.purchase.controller.dto; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +import java.math.BigDecimal; + +public record PurchasePlanItemAddDto( + @NotNull(message = "purchase.purchase_plan.validate.part_number.not_null") + String partNumber, + @NotNull(message = "purchase.purchase_plan.validate.purchase_count.not_null") + @Min(value = 0, message = "purchase.purchase_plan.validate.purchase_count.min") + Integer purchaseCount, + @NotNull(message = "purchase.purchase_plan.validate.part_id.not_null") + Long partId +) {} diff --git a/src/main/java/com/niuan/erp/module/purchase/converter/PurchasePlanConverter.java b/src/main/java/com/niuan/erp/module/purchase/converter/PurchasePlanConverter.java index 8609b24..8b91d61 100644 --- a/src/main/java/com/niuan/erp/module/purchase/converter/PurchasePlanConverter.java +++ b/src/main/java/com/niuan/erp/module/purchase/converter/PurchasePlanConverter.java @@ -1,5 +1,6 @@ package com.niuan.erp.module.purchase.converter; +import com.niuan.erp.module.purchase.controller.dto.PurchasePlanAddDto; import com.niuan.erp.module.purchase.controller.dto.PurchasePlanDto; import com.niuan.erp.module.purchase.entity.PurchasePlan; import org.mapstruct.Mapper; @@ -10,6 +11,7 @@ import java.util.List; @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) public interface PurchasePlanConverter { PurchasePlan toEntity(PurchasePlanDto dto); + PurchasePlan toEntity(PurchasePlanAddDto dto); PurchasePlanDto toDto(PurchasePlan entity); List toDtoList(List entities); } \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/purchase/converter/PurchasePlanItemConverter.java b/src/main/java/com/niuan/erp/module/purchase/converter/PurchasePlanItemConverter.java index 7412a32..07f61e8 100644 --- a/src/main/java/com/niuan/erp/module/purchase/converter/PurchasePlanItemConverter.java +++ b/src/main/java/com/niuan/erp/module/purchase/converter/PurchasePlanItemConverter.java @@ -1,5 +1,6 @@ package com.niuan.erp.module.purchase.converter; +import com.niuan.erp.module.purchase.controller.dto.PurchasePlanItemAddDto; import com.niuan.erp.module.purchase.controller.dto.PurchasePlanItemDto; import com.niuan.erp.module.purchase.entity.PurchasePlanItem; import org.mapstruct.Mapper; @@ -10,6 +11,8 @@ import java.util.List; @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) public interface PurchasePlanItemConverter { PurchasePlanItem toEntity(PurchasePlanItemDto dto); + PurchasePlanItem toEntity(PurchasePlanItemAddDto dto); + List toEntityList(List dtoList); PurchasePlanItemDto toDto(PurchasePlanItem entity); List toDtoList(List entities); } \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/purchase/entity/PurchasePlan.java b/src/main/java/com/niuan/erp/module/purchase/entity/PurchasePlan.java index 2fb2518..e3a0b73 100644 --- a/src/main/java/com/niuan/erp/module/purchase/entity/PurchasePlan.java +++ b/src/main/java/com/niuan/erp/module/purchase/entity/PurchasePlan.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.niuan.erp.module.purchase.enums.PurchasePlanStatus; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -64,7 +65,7 @@ public class PurchasePlan implements Serializable { private Long storeNo; @TableField("PlanStatus") - private Integer planStatus; + private PurchasePlanStatus planStatus; @TableField("StoreName") private String storeName; diff --git a/src/main/java/com/niuan/erp/module/purchase/enums/PurchasePlanStatus.java b/src/main/java/com/niuan/erp/module/purchase/enums/PurchasePlanStatus.java new file mode 100644 index 0000000..739de35 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/purchase/enums/PurchasePlanStatus.java @@ -0,0 +1,31 @@ +package com.niuan.erp.module.purchase.enums; + +import com.baomidou.mybatisplus.annotation.IEnum; +import com.niuan.erp.common.base.BaseStatus; + +public enum PurchasePlanStatus implements IEnum { + UNSTART(0, "未开始"), + IN_PROGRESS(1, "执行中"), + Completed(2, "已完成"); + final int code; + final String description; + PurchasePlanStatus(int code, String description) { + this.code = code; + this.description = description; + } + + /** + * + * @param code + * @return + */ + public static PurchasePlanStatus fromCode(int code) { + return PurchasePlanStatus.values()[code]; + } + + + @Override + public Integer getValue() { + return code; + } +} diff --git a/src/main/java/com/niuan/erp/module/purchase/service/PurchasePlanService.java b/src/main/java/com/niuan/erp/module/purchase/service/PurchasePlanService.java index afb89e9..c76a1cd 100644 --- a/src/main/java/com/niuan/erp/module/purchase/service/PurchasePlanService.java +++ b/src/main/java/com/niuan/erp/module/purchase/service/PurchasePlanService.java @@ -3,6 +3,7 @@ package com.niuan.erp.module.purchase.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.module.purchase.controller.dto.PurchasePlanAddDto; import com.niuan.erp.module.purchase.controller.dto.PurchasePlanDto; import com.niuan.erp.module.purchase.entity.PurchasePlan; @@ -12,7 +13,7 @@ public interface PurchasePlanService { IPage getPurchasePlanPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper); - void addPurchasePlan(PurchasePlanDto dto); + void addPurchasePlan(PurchasePlanAddDto dto); void updatePurchasePlan(PurchasePlanDto dto); diff --git a/src/main/java/com/niuan/erp/module/purchase/service/impl/PurchasePlanServiceImpl.java b/src/main/java/com/niuan/erp/module/purchase/service/impl/PurchasePlanServiceImpl.java index cab243f..d2acc82 100644 --- a/src/main/java/com/niuan/erp/module/purchase/service/impl/PurchasePlanServiceImpl.java +++ b/src/main/java/com/niuan/erp/module/purchase/service/impl/PurchasePlanServiceImpl.java @@ -6,9 +6,14 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.utils.SecurityUtils; +import com.niuan.erp.module.purchase.controller.dto.PurchasePlanAddDto; import com.niuan.erp.module.purchase.controller.dto.PurchasePlanDto; import com.niuan.erp.module.purchase.converter.PurchasePlanConverter; +import com.niuan.erp.module.purchase.converter.PurchasePlanItemConverter; import com.niuan.erp.module.purchase.entity.PurchasePlan; +import com.niuan.erp.module.purchase.entity.PurchasePlanItem; +import com.niuan.erp.module.purchase.enums.PurchasePlanStatus; +import com.niuan.erp.module.purchase.mapper.PurchasePlanItemMapper; import com.niuan.erp.module.purchase.mapper.PurchasePlanMapper; import com.niuan.erp.module.purchase.service.PurchasePlanService; import lombok.RequiredArgsConstructor; @@ -24,9 +29,12 @@ import java.util.List; @RequiredArgsConstructor public class PurchasePlanServiceImpl extends ServiceImpl implements PurchasePlanService { - private final PurchasePlanConverter purchasePlanConverter; + private final PurchasePlanItemConverter purchasePlanItemConverter; + + private final PurchasePlanItemMapper purchasePlanItemMapper; + @Override public IPage getPurchasePlanPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper) { IPage result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); @@ -34,13 +42,20 @@ public class PurchasePlanServiceImpl extends ServiceImpl planItems = purchasePlanItemConverter.toEntityList(dto.planItems()); + planItems.forEach(item -> { + item.setPlanId(entity.getId()); + }); + purchasePlanItemMapper.insert(planItems); } @Override diff --git a/src/main/java/com/niuan/erp/module/sys/enums/PermissionType.java b/src/main/java/com/niuan/erp/module/sys/enums/PermissionType.java new file mode 100644 index 0000000..8d5b919 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/sys/enums/PermissionType.java @@ -0,0 +1,32 @@ +package com.niuan.erp.module.sys.enums; + +import com.baomidou.mybatisplus.annotation.IEnum; +import lombok.Getter; + +@Getter +public enum PermissionType implements IEnum { + MENU(0, "菜单"), + TOP_PAGE_BUTTON(1, "页面按钮"), + TABLE_OPERATOR_BUTTON(2, "表格操作按钮"), + TABLE_STATUS_BUTTON(3, "表格状态按钮"), + DIALOG_BUTTON(4, "对话框按钮"); + final int code; + final String description; + PermissionType(int code, String description) { + this.code = code; + this.description = description; + } + + public static PermissionType fromCode(int code) { + for (PermissionType permissionType : PermissionType.values()) { + if (permissionType.code == code) return permissionType; + } + // TODO 异常 + return null; + } + + @Override + public Integer getValue() { + return code; + } +} diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/StockByBrandController.java b/src/main/java/com/niuan/erp/module/warehouse/controller/StockByBrandController.java deleted file mode 100644 index 9588628..0000000 --- a/src/main/java/com/niuan/erp/module/warehouse/controller/StockByBrandController.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.niuan.erp.module.warehouse.controller; - -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.niuan.erp.common.annotation.ApiLog; -import com.niuan.erp.common.annotation.ModuleLog; -import com.niuan.erp.common.base.BaseDeleteBody; -import com.niuan.erp.common.base.BasePageReqParams; -import com.niuan.erp.common.base.BaseResult; -import com.niuan.erp.common.base.CommonValidateGroup.*; -import com.niuan.erp.common.base.OperationType; -import com.niuan.erp.module.warehouse.controller.dto.StockByBrandDto; -import com.niuan.erp.module.warehouse.entity.Stock; -import com.niuan.erp.module.warehouse.service.StockByBrandService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.util.StringUtils; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -@Tag(name = "StockByBrand") -@ModuleLog("StockByBrand管理") -@RestController -@RequestMapping("/warehouse/stockbybrand") -@RequiredArgsConstructor -public class StockByBrandController { - - private final StockByBrandService stockByBrandService; - - @Operation(summary = "分页查询StockByBrand数据", operationId = "getStockByBrandPage") - @GetMapping("/getStockByBrandPage") - @PreAuthorize("hasAuthority('stockbybrand:index')") - public BaseResult> getStockByBrandPage(@Validated BasePageReqParams pageParams, - @Validated(Get.class) StockByBrandDto searchParams) { - var wrapper = new LambdaQueryWrapper(); - if (searchParams != null) { - if (StringUtils.hasText(searchParams.partNumber())) { - wrapper.like(Stock::getPartNumber, searchParams.partNumber()); - } - } - return BaseResult.successWithData(stockByBrandService.getStockByBrandPage(pageParams, wrapper)); - } - - - @ApiLog(type = OperationType.ADD, remark = "新增一条StockByBrand记录") - @Operation(summary = "新增StockByBrand", operationId = "addStockByBrand") - @PostMapping("/addStockByBrand") - @PreAuthorize("hasAuthority('stockbybrand:add')") - public BaseResult addStockByBrand(@Validated(Add.class) @RequestBody StockByBrandDto dto) { - stockByBrandService.addStockByBrand(dto); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.UPDATE, remark = "更新一条StockByBrand记录") - @Operation(summary = "更新StockByBrand", operationId = "updateStockByBrand") - @PostMapping("/updateStockByBrand") - @PreAuthorize("hasAuthority('stockbybrand:update')") - public BaseResult updateStockByBrand(@Validated(Update.class) @RequestBody StockByBrandDto dto) { - stockByBrandService.updateStockByBrand(dto); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.DELETE, remark = "删除一条StockByBrand记录") - @Operation(summary = "删除StockByBrand", operationId = "deleteStockByBrand") - @PostMapping("/deleteStockByBrand") - @PreAuthorize("hasAuthority('stockbybrand:delete')") - public BaseResult deleteStockByBrand(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) { - stockByBrandService.deleteStockByBrand(req.id()); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.DELETE, remark = "批量删除StockByBrand记录") - @Operation(summary = "批量删除StockByBrand", operationId = "deleteStockByBrandBatch") - @PostMapping("/deleteStockByBrandBatch") - @PreAuthorize("hasAuthority('stockbybrand:deleteBatch')") - public BaseResult deleteStockByBrandBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) { - stockByBrandService.deleteBatch(req.ids()); - return BaseResult.success(); - } -} diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/StockByTypeController.java b/src/main/java/com/niuan/erp/module/warehouse/controller/StockByTypeController.java deleted file mode 100644 index fba386e..0000000 --- a/src/main/java/com/niuan/erp/module/warehouse/controller/StockByTypeController.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.niuan.erp.module.warehouse.controller; - -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.niuan.erp.common.annotation.ApiLog; -import com.niuan.erp.common.annotation.ModuleLog; -import com.niuan.erp.common.base.BaseDeleteBody; -import com.niuan.erp.common.base.BasePageReqParams; -import com.niuan.erp.common.base.BaseResult; -import com.niuan.erp.common.base.CommonValidateGroup.*; -import com.niuan.erp.common.base.OperationType; -import com.niuan.erp.module.warehouse.controller.dto.StockByTypeDto; -import com.niuan.erp.module.warehouse.entity.Stock; -import com.niuan.erp.module.warehouse.service.StockByTypeService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.util.StringUtils; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -@Tag(name = "StockByType") -@ModuleLog("StockByType管理") -@RestController -@RequestMapping("/warehouse/stockbytype") -@RequiredArgsConstructor -public class StockByTypeController { - - private final StockByTypeService stockByTypeService; - - @Operation(summary = "分页查询StockByType数据", operationId = "getStockByTypePage") - @GetMapping("/getStockByTypePage") - @PreAuthorize("hasAuthority('stockbytype:index')") - public BaseResult> getStockByTypePage(@Validated BasePageReqParams pageParams, - @Validated(Get.class) StockByTypeDto searchParams) { - var wrapper = new LambdaQueryWrapper(); - if (searchParams != null) { - if (StringUtils.hasText(searchParams.partNumber())) { - wrapper.like(Stock::getPartNumber, searchParams.partNumber()); - } - } - return BaseResult.successWithData(stockByTypeService.getStockByTypePage(pageParams, wrapper)); - } - - - @ApiLog(type = OperationType.ADD, remark = "新增一条StockByType记录") - @Operation(summary = "新增StockByType", operationId = "addStockByType") - @PostMapping("/addStockByType") - @PreAuthorize("hasAuthority('stockbytype:add')") - public BaseResult addStockByType(@Validated(Add.class) @RequestBody StockByTypeDto dto) { - stockByTypeService.addStockByType(dto); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.UPDATE, remark = "更新一条StockByType记录") - @Operation(summary = "更新StockByType", operationId = "updateStockByType") - @PostMapping("/updateStockByType") - @PreAuthorize("hasAuthority('stockbytype:update')") - public BaseResult updateStockByType(@Validated(Update.class) @RequestBody StockByTypeDto dto) { - stockByTypeService.updateStockByType(dto); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.DELETE, remark = "删除一条StockByType记录") - @Operation(summary = "删除StockByType", operationId = "deleteStockByType") - @PostMapping("/deleteStockByType") - @PreAuthorize("hasAuthority('stockbytype:delete')") - public BaseResult deleteStockByType(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) { - stockByTypeService.deleteStockByType(req.id()); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.DELETE, remark = "批量删除StockByType记录") - @Operation(summary = "批量删除StockByType", operationId = "deleteStockByTypeBatch") - @PostMapping("/deleteStockByTypeBatch") - @PreAuthorize("hasAuthority('stockbytype:deleteBatch')") - public BaseResult deleteStockByTypeBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) { - stockByTypeService.deleteBatch(req.ids()); - return BaseResult.success(); - } -} diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/StockByWarehouseController.java b/src/main/java/com/niuan/erp/module/warehouse/controller/StockByWarehouseController.java deleted file mode 100644 index 268acef..0000000 --- a/src/main/java/com/niuan/erp/module/warehouse/controller/StockByWarehouseController.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.niuan.erp.module.warehouse.controller; - -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.niuan.erp.common.annotation.ApiLog; -import com.niuan.erp.common.annotation.ModuleLog; -import com.niuan.erp.common.base.BaseDeleteBody; -import com.niuan.erp.common.base.BasePageReqParams; -import com.niuan.erp.common.base.BaseResult; -import com.niuan.erp.common.base.CommonValidateGroup.*; -import com.niuan.erp.common.base.OperationType; -import com.niuan.erp.module.warehouse.controller.dto.StockDto; -import com.niuan.erp.module.warehouse.entity.Stock; -import com.niuan.erp.module.warehouse.service.StockService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.util.StringUtils; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -@Tag(name = "Stock") -@ModuleLog("Stock管理") -@RestController -@RequestMapping("/warehouse/stock") -@RequiredArgsConstructor -public class StockByWarehouseController { - - private final StockService stockService; - - @Operation(summary = "分页查询Stock数据", operationId = "getStockPage") - @GetMapping("/getStockPage") - @PreAuthorize("hasAuthority('stock:index')") - public BaseResult> getStockPage(@Validated BasePageReqParams pageParams, - @Validated(Get.class) StockDto searchParams) { - var wrapper = new LambdaQueryWrapper(); - if (searchParams != null) { - if (StringUtils.hasText(searchParams.partNumber())) { - wrapper.like(Stock::getPartNumber, searchParams.partNumber()); - } - } - return BaseResult.successWithData(stockService.getStockPage(pageParams, wrapper)); - } - - - @ApiLog(type = OperationType.ADD, remark = "新增一条Stock记录") - @Operation(summary = "新增Stock", operationId = "addStock") - @PostMapping("/addStock") - @PreAuthorize("hasAuthority('stock:add')") - public BaseResult addStock(@Validated(Add.class) @RequestBody StockDto dto) { - stockService.addStock(dto); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.UPDATE, remark = "更新一条Stock记录") - @Operation(summary = "更新Stock", operationId = "updateStock") - @PostMapping("/updateStock") - @PreAuthorize("hasAuthority('stock:update')") - public BaseResult updateStock(@Validated(Update.class) @RequestBody StockDto dto) { - stockService.updateStock(dto); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.DELETE, remark = "删除一条Stock记录") - @Operation(summary = "删除Stock", operationId = "deleteStock") - @PostMapping("/deleteStock") - @PreAuthorize("hasAuthority('stock:delete')") - public BaseResult deleteStock(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) { - stockService.deleteStock(req.id()); - return BaseResult.success(); - } - - @ApiLog(type = OperationType.DELETE, remark = "批量删除Stock记录") - @Operation(summary = "批量删除Stock", operationId = "deleteStockBatch") - @PostMapping("/deleteStockBatch") - @PreAuthorize("hasAuthority('stock:deleteBatch')") - public BaseResult deleteStockBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) { - stockService.deleteBatch(req.ids()); - return BaseResult.success(); - } -} diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/StockController.java b/src/main/java/com/niuan/erp/module/warehouse/controller/StockController.java new file mode 100644 index 0000000..1d7bf7e --- /dev/null +++ b/src/main/java/com/niuan/erp/module/warehouse/controller/StockController.java @@ -0,0 +1,32 @@ +package com.niuan.erp.module.warehouse.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.niuan.erp.common.annotation.ModuleLog; +import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.common.base.BaseResult; +import com.niuan.erp.common.base.CommonValidateGroup.*; +import com.niuan.erp.module.warehouse.controller.dto.StockDto; +import com.niuan.erp.module.warehouse.service.StockService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +@Tag(name = "Stock") +@RestController +@RequestMapping("/warehouse/stock") +@RequiredArgsConstructor +public class StockController { + + private final StockService stockService; + + @Operation(summary = "分页查询库存数据", operationId = "getStockPage") + @GetMapping("/getStockPage") + @PreAuthorize("hasAuthority('stock_by_type:index')") + public BaseResult> getStockByTypePage(@Validated BasePageReqParams pageParams, + @Validated(Get.class) StockDto searchParams) { + return BaseResult.successWithData(stockService.getStockPage(pageParams, searchParams)); + } +} diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/StockTransferOrderController.java b/src/main/java/com/niuan/erp/module/warehouse/controller/StockTransferOrderController.java index 82b918e..14fdc61 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/controller/StockTransferOrderController.java +++ b/src/main/java/com/niuan/erp/module/warehouse/controller/StockTransferOrderController.java @@ -10,6 +10,7 @@ import com.niuan.erp.common.base.BaseResult; import com.niuan.erp.common.base.CommonValidateGroup.*; import com.niuan.erp.common.base.OperationType; import com.niuan.erp.module.common.entity.Document; +import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderAddDto; import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderDto; import com.niuan.erp.module.warehouse.service.StockTransferOrderService; import io.swagger.v3.oas.annotations.Operation; @@ -48,7 +49,7 @@ public class StockTransferOrderController { @Operation(summary = "新增StockTransferOrder", operationId = "addStockTransferOrder") @PostMapping("/addStockTransferOrder") @PreAuthorize("hasAuthority('stocktransferorder:add')") - public BaseResult addStockTransferOrder(@Validated(Add.class) @RequestBody StockTransferOrderDto dto) { + public BaseResult addStockTransferOrder(@Validated(Add.class) @RequestBody StockTransferOrderAddDto dto) { stockTransferOrderService.addStockTransferOrder(dto); return BaseResult.success(); } diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/WarehouseController.java b/src/main/java/com/niuan/erp/module/warehouse/controller/WarehouseController.java index 5b93e2b..a5767d7 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/controller/WarehouseController.java +++ b/src/main/java/com/niuan/erp/module/warehouse/controller/WarehouseController.java @@ -4,11 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.niuan.erp.common.annotation.ApiLog; import com.niuan.erp.common.annotation.ModuleLog; -import com.niuan.erp.common.base.BaseDeleteBody; -import com.niuan.erp.common.base.BasePageReqParams; -import com.niuan.erp.common.base.BaseResult; +import com.niuan.erp.common.base.*; import com.niuan.erp.common.base.CommonValidateGroup.*; -import com.niuan.erp.common.base.OperationType; import com.niuan.erp.module.warehouse.controller.dto.WarehouseDto; import com.niuan.erp.module.warehouse.entity.Warehouse; import com.niuan.erp.module.warehouse.service.WarehouseService; @@ -20,8 +17,10 @@ import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -@Tag(name = "Warehouse") -@ModuleLog("Warehouse管理") +import java.util.List; + +@Tag(name = "仓库管理") +@ModuleLog("仓库管理") @RestController @RequestMapping("/warehouse/warehouse") @RequiredArgsConstructor @@ -29,7 +28,14 @@ public class WarehouseController { private final WarehouseService warehouseService; - @Operation(summary = "分页查询Warehouse数据", operationId = "getWarehousePage") + @Operation(summary = "查询仓库列表", operationId = "getWarehouseSelectList") + @GetMapping("/getWarehouseSelectList") + @PreAuthorize("hasAnyAuthority('stock_by_warehouse:index', 'production_plan:add')") + public BaseResult> getWarehouseSelectList() { + return BaseResult.successWithData(warehouseService.getWarehouseSelectList()); + } + + @Operation(summary = "分页查询仓库数据", operationId = "getWarehousePage") @GetMapping("/getWarehousePage") @PreAuthorize("hasAuthority('warehouse:index')") public BaseResult> getWarehousePage(@Validated BasePageReqParams pageParams, @@ -37,7 +43,7 @@ public class WarehouseController { var wrapper = new LambdaQueryWrapper(); if (searchParams != null) { if (StringUtils.hasText(searchParams.searchCode())) { - wrapper.like(Warehouse::getSearchCode, searchParams.searchCode()); + wrapper.like(Warehouse::getStoreNo, searchParams.searchCode()); } } return BaseResult.successWithData(warehouseService.getWarehousePage(pageParams, wrapper)); diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/WarehouseItemController.java b/src/main/java/com/niuan/erp/module/warehouse/controller/WarehouseItemController.java index 3a3a9a4..3647c47 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/controller/WarehouseItemController.java +++ b/src/main/java/com/niuan/erp/module/warehouse/controller/WarehouseItemController.java @@ -4,22 +4,22 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.niuan.erp.common.annotation.ApiLog; import com.niuan.erp.common.annotation.ModuleLog; -import com.niuan.erp.common.base.BaseDeleteBody; -import com.niuan.erp.common.base.BasePageReqParams; -import com.niuan.erp.common.base.BaseResult; +import com.niuan.erp.common.base.*; import com.niuan.erp.common.base.CommonValidateGroup.*; -import com.niuan.erp.common.base.OperationType; import com.niuan.erp.module.warehouse.controller.dto.WarehouseItemDto; import com.niuan.erp.module.warehouse.entity.WarehouseItem; import com.niuan.erp.module.warehouse.service.WarehouseItemService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.List; + @Tag(name = "WarehouseItem") @ModuleLog("WarehouseItem管理") @RestController @@ -29,6 +29,20 @@ public class WarehouseItemController { private final WarehouseItemService warehouseItemService; + @Operation(summary = "查询物料规格列表", operationId = "getProductTypeSelectList") + @GetMapping("/getProductTypeSelectList") + @PreAuthorize("hasAuthority('stock_by_type:index')") + public BaseResult> getProductTypeSelectList() { + return BaseResult.successWithData(warehouseItemService.getProductTypeSelectList()); + } + + @Operation(summary = "查询物料品牌列表", operationId = "getProductBrandSelectList") + @GetMapping("/getProductBrandSelectList") + @PreAuthorize("hasAuthority('stock_by_brand:index')") + public BaseResult> getProductBrandSelectList() { + return BaseResult.successWithData(warehouseItemService.getProductBrandSelectList()); + } + @Operation(summary = "分页查询WarehouseItem数据", operationId = "getWarehouseItemPage") @GetMapping("/getWarehouseItemPage") @PreAuthorize("hasAuthority('warehouseitem:index')") @@ -37,7 +51,7 @@ public class WarehouseItemController { var wrapper = new LambdaQueryWrapper(); if (searchParams != null) { if (StringUtils.hasText(searchParams.searchCode())) { - wrapper.like(WarehouseItem::getSearchCode, searchParams.searchCode()); + wrapper.like(WarehouseItem::getPartNumber, searchParams.searchCode()); } } return BaseResult.successWithData(warehouseItemService.getWarehouseItemPage(pageParams, wrapper)); @@ -79,4 +93,13 @@ public class WarehouseItemController { warehouseItemService.deleteBatch(req.ids()); return BaseResult.success(); } + + @Operation(summary = "判断 partNumber 的物料是否存在仓库", operationId = "existsWarehouseItem") + @GetMapping("/existsWarehouseItem") + @PreAuthorize("hasAnyAuthority('bom:add')") + public BaseResult existsWarehouseItem(@Validated + @NotNull(message = "warehouse.warehouse_item.part_number.not_null") + @RequestParam("partNumber") String partNumber) { + return BaseResult.successWithData(warehouseItemService.existsWarehouseItemByPartNumber(partNumber)); + } } diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockDto.java b/src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockDto.java index b2dd772..98607be 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockDto.java +++ b/src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockDto.java @@ -1,21 +1,17 @@ package com.niuan.erp.module.warehouse.controller.dto; -import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonInclude; +@JsonInclude(JsonInclude.Include.NON_NULL) public record StockDto( - Long id, - Integer status, - LocalDateTime createDate, - Long createUserId, - String createUserName, - LocalDateTime updateDate, - Long updateUserId, - String updateUserName, - Integer storeNo, - String storeName, - String partNumber, - Integer productCount, - String storageMark, - Integer reserve1, - String reserve2, - Integer productOccupyTotal) {} \ No newline at end of file + String storeName, + String productType, + String partNumber, + String productSpecs, + Integer productPacking, + String productBrand, + String productPackSize, + Integer productCount, + Integer storeId, + String searchCode) { +} \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockTransferOrderAddDto.java b/src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockTransferOrderAddDto.java new file mode 100644 index 0000000..1c307d8 --- /dev/null +++ b/src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockTransferOrderAddDto.java @@ -0,0 +1,39 @@ +package com.niuan.erp.module.warehouse.controller.dto; + +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * 添加调拨单的 Dto + * @param formCode + * @param formName + * @param formMark + * @param storeNo 入库仓库 ID + * @param storeName 入库仓库名称 + * @param outStoreNo 出库仓库 ID + * @param outStoreName 出库仓库名称 + * @param transferOrderItems + */ +public record StockTransferOrderAddDto( + @NotNull(message = "warehouse.stock_transfer_order.validate.form_code.not_null") + String formCode, + @NotNull(message = "warehouse.stock_transfer_order.validate.form_name.not_null") + String formName, + String formMark, + + // 入库 + @NotNull(message = "warehouse.stock_transfer_order.validate.store_no.not_null") + Integer storeNo, + @NotNull(message = "warehouse.stock_transfer_order.validate.store_name.not_null") + String storeName, + + // 出库 + @NotNull(message = "warehouse.stock_transfer_order.validate.out_store_no.not_null") + Integer outStoreNo, + @NotNull(message = "warehouse.stock_transfer_order.validate.out_store_name.not_null") + String outStoreName, + + @NotNull(message = "warehouse.stock_transfer_order.validate.transfer_order_items.not_null") + List transferOrderItems +) {} diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockTransferOrderItemAddDto.java b/src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockTransferOrderItemAddDto.java new file mode 100644 index 0000000..fa9942d --- /dev/null +++ b/src/main/java/com/niuan/erp/module/warehouse/controller/dto/StockTransferOrderItemAddDto.java @@ -0,0 +1,23 @@ +package com.niuan.erp.module.warehouse.controller.dto; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +/** + * 调拨明细 Dto + * @param partNumber + * @param productSpec + * @param productCount 调拨数量 + * @param partId product ID + */ +public record StockTransferOrderItemAddDto( + @NotNull(message = "warehouse.stock_transfer_order.validate.part_number.not_null") + String partNumber, + @NotNull(message = "warehouse.stock_transfer_order.validate.product_spec.not_null") + String productSpec, + @NotNull(message = "warehouse.stock_transfer_order.validate.product_count.not_null") + @Min(value = 1, message = "warehouse.stock_transfer_order.validate.product_count.min") + Integer productCount, + @NotNull(message = "warehouse.stock_transfer_order.validate.part_id.not_null") + Long partId +) {} diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/dto/WarehouseDto.java b/src/main/java/com/niuan/erp/module/warehouse/controller/dto/WarehouseDto.java index bd4e01c..400b6bb 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/controller/dto/WarehouseDto.java +++ b/src/main/java/com/niuan/erp/module/warehouse/controller/dto/WarehouseDto.java @@ -17,4 +17,5 @@ public record WarehouseDto( Integer reserve1, String reserve2, Long projectId, - Integer customerId) {} \ No newline at end of file + Integer customerId, + String searchCode) {} \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/warehouse/controller/dto/WarehouseItemDto.java b/src/main/java/com/niuan/erp/module/warehouse/controller/dto/WarehouseItemDto.java index 42ff26a..5d0d3ad 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/controller/dto/WarehouseItemDto.java +++ b/src/main/java/com/niuan/erp/module/warehouse/controller/dto/WarehouseItemDto.java @@ -29,4 +29,5 @@ public record WarehouseItemDto( Integer reserve1, String reserve2, Integer productOccupyTotal, - Integer customerId) {} \ No newline at end of file + Integer customerId, + String searchCode) {} \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/warehouse/converter/StockTransferOrderConverter.java b/src/main/java/com/niuan/erp/module/warehouse/converter/StockTransferOrderConverter.java index 0a96a70..198c0c7 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/converter/StockTransferOrderConverter.java +++ b/src/main/java/com/niuan/erp/module/warehouse/converter/StockTransferOrderConverter.java @@ -1,7 +1,11 @@ package com.niuan.erp.module.warehouse.converter; import com.niuan.erp.module.common.entity.Document; +import com.niuan.erp.module.common.entity.DocumentMaterial; +import com.niuan.erp.module.common.mapper.DocumentMapper; +import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderAddDto; import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderDto; +import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderItemAddDto; import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; @@ -10,6 +14,10 @@ import java.util.List; @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) public interface StockTransferOrderConverter { Document toEntity(StockTransferOrderDto dto); + Document toEntity(StockTransferOrderAddDto dto); StockTransferOrderDto toDto(Document entity); List toDtoList(List entities); + + DocumentMaterial toEntity(StockTransferOrderItemAddDto dto); + List toEntityList(List dtoList); } \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/warehouse/mapper/StockMapper.java b/src/main/java/com/niuan/erp/module/warehouse/mapper/StockMapper.java index 3fb60f2..862a841 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/mapper/StockMapper.java +++ b/src/main/java/com/niuan/erp/module/warehouse/mapper/StockMapper.java @@ -1,7 +1,14 @@ package com.niuan.erp.module.warehouse.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.module.warehouse.controller.dto.StockDto; import com.niuan.erp.module.warehouse.entity.Stock; +import org.apache.ibatis.annotations.Arg; +import org.apache.ibatis.annotations.ConstructorArgs; +import org.apache.ibatis.type.JdbcType; /** *

@@ -13,4 +20,6 @@ import com.niuan.erp.module.warehouse.entity.Stock; */ public interface StockMapper extends BaseMapper { + IPage selectPageByParams(Page t, StockDto searchParams, Long userId); + } diff --git a/src/main/java/com/niuan/erp/module/warehouse/mapper/WarehouseItemMapper.java b/src/main/java/com/niuan/erp/module/warehouse/mapper/WarehouseItemMapper.java index 5beaeb5..19cefa5 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/mapper/WarehouseItemMapper.java +++ b/src/main/java/com/niuan/erp/module/warehouse/mapper/WarehouseItemMapper.java @@ -2,6 +2,10 @@ package com.niuan.erp.module.warehouse.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.niuan.erp.module.warehouse.entity.WarehouseItem; +import org.apache.ibatis.annotations.MapKey; + +import java.util.List; +import java.util.Map; /** *

@@ -13,4 +17,11 @@ import com.niuan.erp.module.warehouse.entity.WarehouseItem; */ public interface WarehouseItemMapper extends BaseMapper { + List getProductTypeSelectList(); + + List getProductBrandSelectList(); + + @MapKey("partNumber") + Map> getWarehouseItemStockListByPartNumbers(List partNumbers); + } diff --git a/src/main/java/com/niuan/erp/module/warehouse/mapper/WarehouseMapper.java b/src/main/java/com/niuan/erp/module/warehouse/mapper/WarehouseMapper.java index ea985cc..1f32307 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/mapper/WarehouseMapper.java +++ b/src/main/java/com/niuan/erp/module/warehouse/mapper/WarehouseMapper.java @@ -1,8 +1,11 @@ package com.niuan.erp.module.warehouse.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.niuan.erp.common.base.BaseSelectDto; import com.niuan.erp.module.warehouse.entity.Warehouse; +import java.util.List; + /** *

* Mapper 接口 @@ -13,4 +16,6 @@ import com.niuan.erp.module.warehouse.entity.Warehouse; */ public interface WarehouseMapper extends BaseMapper { + List getWarehouseSelectList(); + } diff --git a/src/main/java/com/niuan/erp/module/warehouse/service/StockService.java b/src/main/java/com/niuan/erp/module/warehouse/service/StockService.java index 1b2603a..d27148e 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/service/StockService.java +++ b/src/main/java/com/niuan/erp/module/warehouse/service/StockService.java @@ -10,14 +10,6 @@ import java.util.List; public interface StockService { - IPage getStockPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper); - - void addStock(StockDto dto); - - void updateStock(StockDto dto); - - void deleteStock(long id); - - void deleteBatch(List ids); + IPage getStockPage(BasePageReqParams pageParams, StockDto searchParams); } diff --git a/src/main/java/com/niuan/erp/module/warehouse/service/StockTransferOrderService.java b/src/main/java/com/niuan/erp/module/warehouse/service/StockTransferOrderService.java index ddd3513..acbc7a9 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/service/StockTransferOrderService.java +++ b/src/main/java/com/niuan/erp/module/warehouse/service/StockTransferOrderService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.module.common.entity.Document; +import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderAddDto; import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderDto; import java.util.List; @@ -12,7 +13,7 @@ public interface StockTransferOrderService { IPage getStockTransferOrderPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper); - void addStockTransferOrder(StockTransferOrderDto dto); + void addStockTransferOrder(StockTransferOrderAddDto dto); void updateStockTransferOrder(StockTransferOrderDto dto); diff --git a/src/main/java/com/niuan/erp/module/warehouse/service/WarehouseItemService.java b/src/main/java/com/niuan/erp/module/warehouse/service/WarehouseItemService.java index 9063447..4e9b33d 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/service/WarehouseItemService.java +++ b/src/main/java/com/niuan/erp/module/warehouse/service/WarehouseItemService.java @@ -3,6 +3,8 @@ package com.niuan.erp.module.warehouse.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.common.base.BaseSelectDto; +import com.niuan.erp.common.base.BaseTree; import com.niuan.erp.module.warehouse.controller.dto.WarehouseItemDto; import com.niuan.erp.module.warehouse.entity.WarehouseItem; @@ -10,6 +12,10 @@ import java.util.List; public interface WarehouseItemService { + List getProductTypeSelectList(); + + List getProductBrandSelectList(); + IPage getWarehouseItemPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper); void addWarehouseItem(WarehouseItemDto dto); @@ -20,4 +26,6 @@ public interface WarehouseItemService { void deleteBatch(List ids); + boolean existsWarehouseItemByPartNumber(String partNumber); + } diff --git a/src/main/java/com/niuan/erp/module/warehouse/service/WarehouseService.java b/src/main/java/com/niuan/erp/module/warehouse/service/WarehouseService.java index b1f20b2..e58796a 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/service/WarehouseService.java +++ b/src/main/java/com/niuan/erp/module/warehouse/service/WarehouseService.java @@ -3,6 +3,8 @@ package com.niuan.erp.module.warehouse.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.common.base.BaseSelectDto; +import com.niuan.erp.common.base.BaseTree; import com.niuan.erp.module.warehouse.controller.dto.WarehouseDto; import com.niuan.erp.module.warehouse.entity.Warehouse; @@ -10,6 +12,8 @@ import java.util.List; public interface WarehouseService { + List getWarehouseSelectList(); + IPage getWarehousePage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper); void addWarehouse(WarehouseDto dto); diff --git a/src/main/java/com/niuan/erp/module/warehouse/service/impl/StockServiceImpl.java b/src/main/java/com/niuan/erp/module/warehouse/service/impl/StockServiceImpl.java index d96b2e8..2655b17 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/service/impl/StockServiceImpl.java +++ b/src/main/java/com/niuan/erp/module/warehouse/service/impl/StockServiceImpl.java @@ -28,38 +28,9 @@ public class StockServiceImpl extends ServiceImpl implements private final StockConverter stockConverter; @Override - public IPage getStockPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper) { - IPage result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); - return result.convert(stockConverter::toDto); - } - - @Override - public void addStock(StockDto dto) { - Stock entity = stockConverter.toEntity(dto); - entity.setCreateUserId(SecurityUtils.getUserId()); - entity.setCreateUserName(SecurityUtils.getUserName()); - entity.setCreateDate(LocalDateTime.now()); - entity.setStatus(0); - this.baseMapper.insert(entity); - } - - @Override - public void updateStock(StockDto dto) { - Stock entity = stockConverter.toEntity(dto); - entity.setUpdateUserId(SecurityUtils.getUserId()); - entity.setUpdateUserName(SecurityUtils.getUserName()); - entity.setUpdateDate(LocalDateTime.now()); - this.baseMapper.updateById(entity); - } - - @Override - public void deleteStock(long id) { - this.baseMapper.deleteById(id); - } - - @Override - public void deleteBatch(List ids) { - this.baseMapper.deleteByIds(ids); + public IPage getStockPage(BasePageReqParams pageParams, StockDto searchParams) { + return this.baseMapper.selectPageByParams(new Page<>(pageParams.page(), pageParams.pageSize()), + searchParams, SecurityUtils.getUserId()); } } \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/warehouse/service/impl/StockTransferOrderServiceImpl.java b/src/main/java/com/niuan/erp/module/warehouse/service/impl/StockTransferOrderServiceImpl.java index 79564c1..8629f8d 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/service/impl/StockTransferOrderServiceImpl.java +++ b/src/main/java/com/niuan/erp/module/warehouse/service/impl/StockTransferOrderServiceImpl.java @@ -7,9 +7,16 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.niuan.erp.common.base.BasePageReqParams; import com.niuan.erp.common.utils.SecurityUtils; import com.niuan.erp.module.common.entity.Document; +import com.niuan.erp.module.common.entity.DocumentMaterial; +import com.niuan.erp.module.common.enums.DocumentType; import com.niuan.erp.module.common.mapper.DocumentMapper; +import com.niuan.erp.module.common.mapper.DocumentMaterialMapper; +import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderAddDto; import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderDto; +import com.niuan.erp.module.warehouse.controller.dto.StockTransferOrderItemAddDto; import com.niuan.erp.module.warehouse.converter.StockTransferOrderConverter; +import com.niuan.erp.module.warehouse.entity.WarehouseItem; +import com.niuan.erp.module.warehouse.mapper.WarehouseItemMapper; import com.niuan.erp.module.warehouse.service.StockTransferOrderService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -17,6 +24,7 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.List; +import java.util.Map; @Service @@ -27,6 +35,10 @@ public class StockTransferOrderServiceImpl extends ServiceImpl getStockTransferOrderPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper) { IPage result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); @@ -34,13 +46,34 @@ public class StockTransferOrderServiceImpl extends ServiceImpl materials = stockTransferOrderConverter.toEntityList(dto.transferOrderItems()); + + Map> warehouseItems = + warehouseItemMapper.getWarehouseItemStockListByPartNumbers(materials.stream() + .map(DocumentMaterial::getPartNumber) + .toList()); + + materials.forEach(m -> { + m.setDocumentNo(entity.getId().intValue()); + m.setCreateUserId(SecurityUtils.getUserId()); + m.setCreateUserName(SecurityUtils.getUserName()); + m.setCreateDate(LocalDateTime.now()); + m.setStatus(0); + + m.setDemandCount(((Long) warehouseItems.get(m.getPartNumber()).get("productCount")).intValue()); + }); + + documentMaterialMapper.insert(materials); } @Override diff --git a/src/main/java/com/niuan/erp/module/warehouse/service/impl/WarehouseItemServiceImpl.java b/src/main/java/com/niuan/erp/module/warehouse/service/impl/WarehouseItemServiceImpl.java index 2bd5542..46d849e 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/service/impl/WarehouseItemServiceImpl.java +++ b/src/main/java/com/niuan/erp/module/warehouse/service/impl/WarehouseItemServiceImpl.java @@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.common.base.BaseSelectDto; +import com.niuan.erp.common.base.BaseTree; import com.niuan.erp.common.utils.SecurityUtils; import com.niuan.erp.module.warehouse.controller.dto.WarehouseItemDto; import com.niuan.erp.module.warehouse.converter.WarehouseItemConverter; @@ -27,6 +29,20 @@ public class WarehouseItemServiceImpl extends ServiceImpl getProductTypeSelectList() { + return this.baseMapper.getProductTypeSelectList().stream() + .map(s -> new BaseSelectDto(s, s)) + .toList(); + } + + @Override + public List getProductBrandSelectList() { + return this.baseMapper.getProductBrandSelectList().stream() + .map(s -> new BaseSelectDto(s, s)) + .toList(); + } + @Override public IPage getWarehouseItemPage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper) { IPage result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); @@ -62,4 +78,10 @@ public class WarehouseItemServiceImpl extends ServiceImpl().eq(WarehouseItem::getPartNumber, partNumber); + return this.baseMapper.selectCount(wrapper) > 0; + } + } \ No newline at end of file diff --git a/src/main/java/com/niuan/erp/module/warehouse/service/impl/WarehouseServiceImpl.java b/src/main/java/com/niuan/erp/module/warehouse/service/impl/WarehouseServiceImpl.java index 582ed44..7a6518a 100644 --- a/src/main/java/com/niuan/erp/module/warehouse/service/impl/WarehouseServiceImpl.java +++ b/src/main/java/com/niuan/erp/module/warehouse/service/impl/WarehouseServiceImpl.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.niuan.erp.common.base.BasePageReqParams; +import com.niuan.erp.common.base.BaseSelectDto; import com.niuan.erp.common.utils.SecurityUtils; import com.niuan.erp.module.warehouse.controller.dto.WarehouseDto; import com.niuan.erp.module.warehouse.converter.WarehouseConverter; @@ -27,6 +28,11 @@ public class WarehouseServiceImpl extends ServiceImpl getWarehouseSelectList() { + return this.baseMapper.getWarehouseSelectList(); + } + @Override public IPage getWarehousePage(BasePageReqParams pageParams, LambdaQueryWrapper wrapper) { IPage result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 0eb8883..164b70c 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -12,6 +12,12 @@ springdoc: api-docs: path: /v3/api-docs group-configs: - - group: 'default' + - group: '权限控制' paths-to-match: '/**' - packages-to-scan: com.niuan.erp.module.sys.controller \ No newline at end of file + packages-to-scan: com.niuan.erp.module.auth.controller + - group: '系统设置' + paths-to-match: '/**' + packages-to-scan: com.niuan.erp.module.sys.controller + - group: '生产管理' + paths-to-match: '/**' + packages-to-scan: com.niuan.erp.module.production.controller \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3bd4db1..0c20a6f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -13,7 +13,7 @@ spring: # mybatis 设置 mybatis-plus: - type-aliases-package: com.niuan.erp.module.*.entity + type-aliases-package: com.niuan.erp.module.*.entity,com.niuan.erp.module.*.controller.dto,com.niuan.erp.common.base configuration: map-underscore-to-camel-case: false log-impl: org.apache.ibatis.logging.stdout.StdOutImpl diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties index 6bbb461..7d97aa4 100644 --- a/src/main/resources/i18n/messages.properties +++ b/src/main/resources/i18n/messages.properties @@ -12,8 +12,68 @@ validation.common.pageParams.pageSize.notNull=页数不能为空 validation.common.pageParams.page.min=页数不能小于0 validation.common.pageParams.pageSize.min=页数不能小于0 +warehouse.warehouse_item.part_number.not_null=编号不能为空 + +# ==========>> 仓库管理 + +warehouse.stock_transfer_order.validate.form_code.not_null=调拨单编号不能为空 +warehouse.stock_transfer_order.validate.form_name.not_null=调拨单名称不能为空 +warehouse.stock_transfer_order.validate.store_no.not_null=入库仓库 ID 不能为空 +warehouse.stock_transfer_order.validate.store_name.not_null=入库仓库名称不能为空 +warehouse.stock_transfer_order.validate.out_store_no.not_null=出库仓库 ID 不能为空 +warehouse.stock_transfer_order.validate.out_store_name.not_null=出库仓库名称不能为空 +warehouse.stock_transfer_order.validate.transfer_order_items.not_null=调拨单明细不能为空 +warehouse.stock_transfer_order.validate.part_number.not_null=物料编号不能为空 +warehouse.stock_transfer_order.validate.product_spec.not_null=物料型号不能为空 +warehouse.stock_transfer_order.validate.product_count.not_null=调拨数量不能为空 +warehouse.stock_transfer_order.validate.product_count.min=调拨数量不能小于 1 +warehouse.stock_transfer_order.validate.part_id.not_null=物料 ID 不能为空 + + +# ==========>> 生产管理 + +production.bom.validate.bom_id.not_null=BOM Id 不能为空 +production.bom.validate.bom_no.not_null=BOM 编号不能为空 +production.bom.validate.bom_name.not_null=BOM 名称不能为空 +production.bom.validate.manufacturer.not_null=厂家 / 型号不能为空 +production.bom.validate.spec.not_null=封装规格不能为空 +production.bom.validate.brand_name.not_null=品牌不能为空 +production.bom.validate.part_number.not_null=物料编号不能为空 +production.bom.validate.manufacture_count.not_null=用量不能为空 +production.bom.validate.manufacture_count.min=用量最小为 1 +production.bom.validate.item_position.not_null=位号不能为空 +production.bom.exception.duplicate_bom_name=BOM 名字重复 +production.bom.exception.duplicate_bom_item=BOM 明细重复 +production.bom.exception.unpair_position_count=BOM 明细中存在位点和数量不一致 +production.bom.exception.unexists_bom_item=BOM 物料有不存在的物料 + +production.production_plan.validate.ids.not_null=生产计划 ID 不能为空 +production.production_plan.validate.issue.not_null=发料单数据不能为空 +production.production_plan.validate.form_code.not_null=发料单编号不能为空 +production.production_plan.validate.store_no.not_null=发料仓库 ID 不能为空 +production.production_plan.validate.store_name.not_null=发料仓库名称不能为空 +production.production_plan.validate.items.not_null=发料单明细不能为空 +production.production_plan.validate.part_number.not_null=物料编号不能为空 +production.production_plan.validate.product_count.not_null=实发数量不能为空 +production.production_plan.validate.product_count.min=实发数量不能小于 1 +production.production_plan.validate.demand_count.not_null=需求数量不能为空 +production.production_plan.validate.demand_count.min=需求数量不能小于 1 +production.production_plan.exception.must_no_complete=选中的行其中有不是未完成的状态 +production.production_plan.exception.more_than_one_warehouse=选中的行不能有多个仓库 + sys.operationType.codeNotExists=编号不存在 +# ==========>> 采购管理 + +purchase.purchase_plan.validate.plan_no.not_null=采购计划编号不能为空 +purchase.purchase_plan.validate.store_no.not_null=收货仓库 ID 不能为空 +purchase.purchase_plan.validate.store_name.not_null=收货仓库名称不能为空 +purchase.purchase_plan.validate.plan_name.not_null=采购计划名称不能为空 +purchase.purchase_plan.validate.part_number.not_null=物料编号不能为空 +purchase.purchase_plan.validate.part_id.not_null=物料 ID 不能为空 +purchase.purchase_plan.validate.purchase_count.not_null=购买数量不能为空 +purchase.purchase_plan.validate.purchase_count.min=购买数量不能小于 0 + # ==========> 类型 loginName.notNull=登录名称不能为空 diff --git a/src/main/resources/mapper/production/BomItemMapper.xml b/src/main/resources/mapper/production/BomItemMapper.xml index 7c47151..7e74ea0 100644 --- a/src/main/resources/mapper/production/BomItemMapper.xml +++ b/src/main/resources/mapper/production/BomItemMapper.xml @@ -21,4 +21,22 @@ + + + + diff --git a/src/main/resources/mapper/production/BomMapper.xml b/src/main/resources/mapper/production/BomMapper.xml index 30823e6..21402bb 100644 --- a/src/main/resources/mapper/production/BomMapper.xml +++ b/src/main/resources/mapper/production/BomMapper.xml @@ -2,25 +2,25 @@ - - - - - - - - - - - - - - - - - - - - + + + diff --git a/src/main/resources/mapper/production/ProductionPlanMapper.xml b/src/main/resources/mapper/production/ProductionPlanMapper.xml index 1775945..a9046f2 100644 --- a/src/main/resources/mapper/production/ProductionPlanMapper.xml +++ b/src/main/resources/mapper/production/ProductionPlanMapper.xml @@ -29,4 +29,83 @@ + + + + + + + diff --git a/src/main/resources/mapper/sys/RolePermissionMapper.xml b/src/main/resources/mapper/sys/RolePermissionMapper.xml new file mode 100644 index 0000000..719e921 --- /dev/null +++ b/src/main/resources/mapper/sys/RolePermissionMapper.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/main/resources/mapper/sys/SysPermissionMapper.xml b/src/main/resources/mapper/sys/SysPermissionMapper.xml new file mode 100644 index 0000000..0c3d9ae --- /dev/null +++ b/src/main/resources/mapper/sys/SysPermissionMapper.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/mapper/warehouse/StockMapper.xml b/src/main/resources/mapper/warehouse/StockMapper.xml index ba8c13e..b07a95a 100644 --- a/src/main/resources/mapper/warehouse/StockMapper.xml +++ b/src/main/resources/mapper/warehouse/StockMapper.xml @@ -22,4 +22,30 @@ + + diff --git a/src/main/resources/mapper/warehouse/StockTransferOrderMapper.xml b/src/main/resources/mapper/warehouse/StockTransferOrderMapper.xml deleted file mode 100644 index e76f564..0000000 --- a/src/main/resources/mapper/warehouse/StockTransferOrderMapper.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/mapper/warehouse/WarehouseItemMapper.xml b/src/main/resources/mapper/warehouse/WarehouseItemMapper.xml index 5c37c9a..4b23b49 100644 --- a/src/main/resources/mapper/warehouse/WarehouseItemMapper.xml +++ b/src/main/resources/mapper/warehouse/WarehouseItemMapper.xml @@ -32,5 +32,25 @@ + + + + + + diff --git a/src/main/resources/mapper/warehouse/WarehouseMapper.xml b/src/main/resources/mapper/warehouse/WarehouseMapper.xml index adb5ab6..b2c3bd0 100644 --- a/src/main/resources/mapper/warehouse/WarehouseMapper.xml +++ b/src/main/resources/mapper/warehouse/WarehouseMapper.xml @@ -21,4 +21,8 @@ + + diff --git a/src/main/resources/sql/dev/permission-data.sql b/src/main/resources/sql/dev/permission-data.sql new file mode 100644 index 0000000..194d018 --- /dev/null +++ b/src/main/resources/sql/dev/permission-data.sql @@ -0,0 +1,15 @@ +INSERT INTO sys_permission ( + id, parent_id, permission_name, permission_i18n, permission_type, page_link, + view_link, permission_code, event_name, class_name, icon_name, sort +) SELECT + c.Id, c.ParentId, c.ChannelName, c.EventName, + CASE + WHEN c.IsMenuShow = 1 THEN 0 + WHEN c.IsMenuShow = 0 and (c.EventName = 'add' or c.EventName = 'import') THEN 1 + WHEN c.IsMenuShow = 0 and (c.EventName = 'enable' or c.EventName = 'disable') THEN 3 + ELSE 2 + END, + c.EventName, c.ChannelLink, c.EventName, c.EventName, + NULL, NULL, c.Sort +FROM yy_syschannel c; + diff --git a/src/main/resources/sql/dev/permission-schema.sql b/src/main/resources/sql/dev/permission-schema.sql new file mode 100644 index 0000000..5c69924 --- /dev/null +++ b/src/main/resources/sql/dev/permission-schema.sql @@ -0,0 +1,37 @@ +CREATE TABLE IF NOT EXISTS sys_permission ( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + parent_id BIGINT NOT NULL DEFAULT 0 COMMENT '父权限ID,0表示根节点', + status INT NOT NULL DEFAULT 0 COMMENT '状态:0-禁用,1-启用', + hidden BOOL NOT NULL DEFAULT FALSE COMMENT '是否隐藏', + create_date DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + create_user_id BIGINT NULL COMMENT '创建人ID', + create_user_name VARCHAR(50) NULL COMMENT '创建人姓名', + update_date DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间', + update_user_id BIGINT NULL COMMENT '更新人ID', + update_user_name VARCHAR(50) NULL COMMENT '更新人姓名', + permission_name VARCHAR(100) NOT NULL COMMENT '权限名字,没有 i18n 时,作为显示名称', + permission_i18n VARCHAR(100) DEFAULT NULL COMMENT '权限 i18n 键,用于前端多语言取值', + permission_type TINYINT NOT NULL COMMENT '权限类型,关系到权限的位置:0-菜单;1-Table 上方按钮;2-Table 操作栏按钮;3-状态栏按钮', + page_link VARCHAR(100) DEFAULT NULL COMMENT '前端页面路由地址', + view_link VARCHAR(100) DEFAULT NULL COMMENT '前端 Vue 组件路径', + permission_code VARCHAR(50) DEFAULT NULL COMMENT '后端鉴权用的权限编码', + event_name VARCHAR(50) DEFAULT NULL COMMENT '前端按钮绑定的方法名', + class_name VARCHAR(30) DEFAULT NULL COMMENT '前端样式类名', + icon_name VARCHAR(30) DEFAULT NULL COMMENT '前端图标名称', + sort INT NOT NULL DEFAULT 0 COMMENT '排序值,越小越靠前' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统权限表'; + +CREATE TABLE IF NOT EXISTS role_permission ( + role_id BIGINT NOT NULL COMMENT '角色ID', + permission_id BIGINT NOT NULL COMMENT '权限ID', + + -- 联合主键:确保 (role_id, permission_id) 唯一,避免重复授权 + PRIMARY KEY (role_id, permission_id), + + -- 外键约束(可选但推荐):确保引用的角色和权限真实存在 + CONSTRAINT fk_role_permission_role + FOREIGN KEY (role_id) REFERENCES yy_sysrole(Id) ON DELETE CASCADE, + + CONSTRAINT fk_role_permission_permission + FOREIGN KEY (permission_id) REFERENCES sys_permission(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色-权限关联表,用的是原有框架的 yy_sysrole'; \ No newline at end of file