生成的全部功能代码,非常粗糙,每个功能都需要进行更改。

This commit is contained in:
c
2026-02-12 13:58:35 +08:00
commit 6d609f8156
287 changed files with 11535 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
package com.niuan.erp;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
@MapperScan(basePackages = "com.niuan.erp.module.*.mapper")
public class ErpApplication {
public static void main(String[] args) {
SpringApplication.run(ErpApplication.class, args);
}
}

View File

@@ -0,0 +1,19 @@
package com.niuan.erp.common.annotation;
import com.niuan.erp.common.base.OperationType;
import java.lang.annotation.*;
/**
* 记录接口 API 的日志,包含类型和备注,记录功能模块的使用 {@link com.niuan.erp.common.annotation.ModuleLog}
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiLog {
OperationType type();
String remark() default "";
}

View File

@@ -0,0 +1,14 @@
package com.niuan.erp.common.annotation;
import java.lang.annotation.*;
/**
* 记录日志中的功能模块,记录 API 接口的使用 {@link com.niuan.erp.common.annotation.ApiLog}
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModuleLog {
String value();
}

View File

@@ -0,0 +1,8 @@
package com.niuan.erp.common.base;
import java.util.List;
public record BaseDeleteBody(
Long id,
List<Long> ids
) {}

View File

@@ -0,0 +1,17 @@
package com.niuan.erp.common.base;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
@Schema(description = "分页请求参数")
public record BasePageReqParams(
@Schema(description = "页码,从 0 开始", example = "0")
@NotNull(message = "validation.common.pageParams.page.notNull")
@Min(value = 0, message = "validation.common.pageParams.page.min")
int page,
@Schema(description = "页面大小", example = "10")
@NotNull(message = "validation.common.pageParams.pageSize.notNull")
@Min(value = 0, message = "validation.common.pageParams.pageSize.min")
int pageSize
) {}

View File

@@ -0,0 +1,27 @@
package com.niuan.erp.common.base;
import com.niuan.erp.common.utils.MessageUtils;
public record BaseResult<T>(int code, String msg, T data) {
public static <T> BaseResult<T> success() {
return success(MessageUtils.get("result.success"));
}
public static <T> BaseResult<T> successWithData(T data) {
return new BaseResult<T>(0, MessageUtils.get("result.success"), data);
}
public static <T> BaseResult<T> success(String msg) {
return new BaseResult<T>(0, msg, null);
}
public static <T> BaseResult<T> error() {
return BaseResult.error(500, MessageUtils.get("result.error"));
}
public static <T> BaseResult<T> error(int code, String msg) {
return new BaseResult<T>(code, msg, null);
}
}

View File

@@ -0,0 +1,31 @@
package com.niuan.erp.common.base;
import com.baomidou.mybatisplus.annotation.IEnum;
import lombok.Getter;
@Getter
public enum BaseStatus implements IEnum<Integer> {
ENABLE(0, "启用"),
DISABLE(1, "禁用");
final int code;
final String description;
BaseStatus(int code, String description) {
this.code = code;
this.description = description;
}
/**
* code 只能是 0 和 1
* @param code
* @return
*/
public static BaseStatus fromCode(int code) {
return BaseStatus.values()[code];
}
@Override
public Integer getValue() {
return code;
}
}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.common.base;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
public record BaseStatusBody(
@NotNull(message = "validation.common.status.idNull")
Long id,
@NotNull(message = "validation.common.status.notNull")
@Max(value = 1, message = "validation.common.status.valueError")
@Min(value = 0, message = "validation.common.status.valueError")
Integer status
) {
}

View File

@@ -0,0 +1,14 @@
package com.niuan.erp.common.base;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
@Data
@AllArgsConstructor
public class BaseTree {
Object id;
String label;
List<BaseTree> children;
}

View File

@@ -0,0 +1,14 @@
package com.niuan.erp.common.base;
public interface CommonValidateGroup {
interface Get {}
interface Add {}
interface Update {}
interface DeleteOne {}
interface DeleteBatch {}
}

View File

@@ -0,0 +1,41 @@
package com.niuan.erp.common.base;
import com.niuan.erp.module.sys.entity.SysRole;
import com.niuan.erp.module.sys.entity.SysUser;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
@Getter
@Setter
@Builder
@ToString
public class LoginUser implements UserDetails {
private SysUser user;
private List<SysRole> roleList;
private List<GrantedAuthority> authorities;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return user.getPassWord();
}
@Override
public String getUsername() {
return user.getUserName();
}
}

View File

@@ -0,0 +1,44 @@
package com.niuan.erp.common.base;
import com.baomidou.mybatisplus.annotation.IEnum;
import com.niuan.erp.common.exception.BusinessException;
import lombok.Getter;
import java.util.Arrays;
/**
* 接口日志中辨别操作的枚举
*/
@Getter
public enum OperationType implements IEnum<Integer> {
ADD(1, "添加"),
UPDATE(2, "修改"),
DELETE(3, "删除"),
ENABLE(4, "启用"),
DISABLE(5, "禁用"),
RECYCLE(6, "回收"),
RESTORE(7, "还原"),
LOGIN(8, "登录"),
LOGOUT(9, "退出"),
OTHER(10, "其他");
final int code;
final String description;
OperationType(int code, String description) {
this.code = code;
this.description = description;
}
public static OperationType fromCode(int code) {
return Arrays.stream(OperationType.values())
.filter(e -> e.getCode() == code)
.findFirst()
.orElseThrow(() -> new BusinessException("sys.operationType.codeNotExists"));
}
@Override
public Integer getValue() {
return code;
}
}

View File

@@ -0,0 +1,34 @@
package com.niuan.erp.common.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HexFormat;
@Component
public class Md5PasswordEncoder implements PasswordEncoder {
@Value("${erp.encrypt.md5-salt}")
private String md5Salt;
private final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
public Md5PasswordEncoder() throws NoSuchAlgorithmException {
}
@Override
public String encode(CharSequence rawPassword) {
byte[] md5 = messageDigest.digest("%s_%s".formatted(md5Salt, rawPassword).getBytes(StandardCharsets.UTF_8));
return HexFormat.of().formatHex(md5);
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
System.out.printf("对比密码:未加密密码[%s],加密后[%s],对比的加密码[%s]%n", rawPassword, encode(rawPassword), encodedPassword);
return encodedPassword.equals(encode(rawPassword));
}
}

View File

@@ -0,0 +1,116 @@
package com.niuan.erp.common.bean;
import com.niuan.erp.common.annotation.ApiLog;
import com.niuan.erp.common.annotation.ModuleLog;
import com.niuan.erp.common.utils.OperationContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jspecify.annotations.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
@Component
public class SysLogInterceptor implements HandlerInterceptor {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
if (handler instanceof HandlerMethod hm) {
ModuleLog module = hm.getBeanType().getAnnotation(ModuleLog.class);
ApiLog methodLog = hm.getMethodAnnotation(ApiLog.class);
if (module != null && methodLog != null) {
OperationContext.set(module.value(), methodLog.type(), methodLog.remark(), getClientIpAddress(request));
}
}
}
private String getClientIpAddress(HttpServletRequest request) {
// 常见的代理头字段,按优先级顺序
List<String> headers = Arrays.asList(
"X-Forwarded-For",
"X-Real-IP",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_CLIENT_IP",
"HTTP_X_FORWARDED_FOR"
);
String ip = null;
// 1. 从请求头中逐个尝试获取
for (String header : headers) {
ip = request.getHeader(header);
if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
// X-Forwarded-For 可能是逗号分隔的多个 IP取第一个非 unknown 的
for (String candidate : ip.split(",")) {
candidate = candidate.trim();
if (isValidIPv4(candidate)) {
return candidate;
}
}
}
}
// 2. 如果头里没有有效 IPv4尝试 getRemoteAddr()
ip = request.getRemoteAddr();
if (isValidIPv4(ip)) {
return ip;
}
// 3. 如果是 IPv6比如 ::1 或 0:0:0:0:0:0:0:1尝试映射或忽略
if ("0:0:0:0:0:0:0:1".equals(ip) || "::1".equals(ip)) {
return "127.0.0.1";
}
// 4. 尝试解析为 InetAddress 并检查是否为 IPv4
try {
InetAddress address = InetAddress.getByName(ip);
if (address instanceof Inet4Address) {
return address.getHostAddress();
}
} catch (UnknownHostException ignored) {
// ignore
}
// 5. 实在找不到合法 IPv4返回 unknown
return "unknown";
}
/**
* 判断字符串是否为合法的 IPv4 地址(不含端口)
*/
private boolean isValidIPv4(String ip) {
if (ip == null || ip.isEmpty()) return false;
// 快速排除明显非法字符
if (!ip.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")) {
return false;
}
String[] parts = ip.split("\\.");
if (parts.length != 4) return false;
for (String part : parts) {
try {
int num = Integer.parseInt(part);
if (num < 0 || num > 255) {
return false;
}
// 防止前导零(如 "01" 不是标准写法,但有些系统接受)
// 如果严格要求可加if (!String.valueOf(num).equals(part)) return false;
} catch (NumberFormatException e) {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,77 @@
package com.niuan.erp.common.bean;
import com.niuan.erp.common.base.BaseStatus;
import com.niuan.erp.common.utils.OperationContext;
import com.niuan.erp.common.utils.SecurityUtils;
import com.niuan.erp.module.sys.entity.SysRecord;
import com.niuan.erp.module.sys.service.SysRecordService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;
import org.zalando.logbook.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
@Component
@RequiredArgsConstructor
public class SysLogSink implements Sink {
private final SysRecordService sysRecordService;
@Override
public void write(Precorrelation precorrelation, HttpRequest request) throws IOException {
}
@Override
public void write(Correlation correlation, HttpRequest request, HttpResponse response) throws IOException {
try {
if (OperationContext.getOperationType() != null)
sysRecordService.addSysRecord(buildRecord(request, response));
} catch (Exception e) {
throw e;
} finally {
OperationContext.clear();
}
}
public SysRecord buildRecord(HttpRequest request, HttpResponse response) {
var record = new SysRecord();
// 用户信息 和 预处理
record.setCreateUserId(SecurityUtils.getUserId());
record.setCreateUserName(SecurityUtils.getUserName());
record.setCreateDate(LocalDateTime.now());
record.setStatus(BaseStatus.ENABLE.getCode());
// record 信息
record.setChannelName(OperationContext.getModuleName());
record.setRecordType(OperationContext.getOperationType().getCode());
record.setRemark(OperationContext.getRemark());
record.setIp(OperationContext.getIp());
record.setLinkUrl(request.getPath());
record.setRequestParams(extractParams(request));
record.setIsSuccess(response.getStatus() >= 200 && response.getStatus() < 400);
return record;
}
@SneakyThrows
private String extractParams(HttpRequest request) {
String params;
// Query 参数
params = request.getQuery();
// BodyJSON
if (request.getContentType() != null &&
request.getContentType().contains("application/json")) {
params = new String(request.getBody(), StandardCharsets.UTF_8);
}
return params;
}
}

View File

@@ -0,0 +1,51 @@
package com.niuan.erp.common.bean;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jspecify.annotations.Nullable;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import java.util.function.Supplier;
@Slf4j
@Component
@RequiredArgsConstructor
public class UrlPermissionAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public @Nullable AuthorizationDecision check(Supplier<Authentication> authentication,
RequestAuthorizationContext context) {
HttpServletRequest request = context.getRequest();
String requestURI = request.getRequestURI();
if (antPathMatcher.match("/auth/user/me", requestURI)) {
return new AuthorizationDecision(true);
}
Authentication auth = authentication.get();
log.info("数据库鉴权:{}", auth);
if (auth == null || !auth.isAuthenticated()) {
return new AuthorizationDecision(false);
}
Object principal = auth.getPrincipal();
if (principal instanceof UserDetails userDetails) {
for (GrantedAuthority grantedAuthority : userDetails.getAuthorities()) {
if (antPathMatcher.match(grantedAuthority.getAuthority(), requestURI)) {
return new AuthorizationDecision(true);
}
}
}
return new AuthorizationDecision(false);
}
}

View File

@@ -0,0 +1,20 @@
package com.niuan.erp.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import java.util.Locale;
@Component
public class I18nConfig {
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(Locale.CHINESE);
return localeResolver;
}
}

View File

@@ -0,0 +1,29 @@
package com.niuan.erp.common.config;
import com.baomidou.mybatisplus.annotation.DbType;
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 org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
@Bean
public MybatisPlusPropertiesCustomizer mybatisPlusPropertiesCustomizer() {
return properties -> {
properties.getGlobalConfig()
.getDbConfig()
.setIdType(IdType.AUTO);
};
}
}

View File

@@ -0,0 +1,156 @@
package com.niuan.erp.common.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.niuan.erp.common.base.BaseResult;
import com.niuan.erp.common.base.LoginUser;
import com.niuan.erp.common.bean.UrlPermissionAuthorizationManager;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.session.ConcurrentSessionFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.List;
@Configuration
@EnableWebSecurity // 启用 Web 安全
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final UrlPermissionAuthorizationManager urlPermissionAuthorizationManager;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, SessionRegistry sessionRegistry) throws Exception {
http
// 👇 1. 启用 CSRF
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
// 👇 2. 设置 Session
.sessionManagement(session -> session
.maximumSessions(1)
.maxSessionsPreventsLogin(false)
.sessionRegistry(sessionRegistry))
// 👇 3. 请求授权规则
.authorizeHttpRequests(authz -> authz
.requestMatchers(
"/v3/api-docs/**", "/v3/api-docs",
"/swagger-ui/**",
"/swagger-ui.html",
"/webjars/**",
"/doc.html",
"/favicon.ico").permitAll()
.anyRequest().authenticated()
)
//
.formLogin(form -> form
.loginProcessingUrl("/auth/login") // 指定登录提交地址
.successHandler((request, response, authentication) -> {
// 登录成功:返回 JSON
response.setContentType("application/json;charset=UTF-8");
LoginUser user = (LoginUser) authentication.getPrincipal();
response.getWriter().write(new ObjectMapper().writeValueAsString(BaseResult.success()));
})
.failureHandler((request, response, exception) -> {
// 登录失败:返回 JSON
response.setStatus(HttpStatus.OK.value());
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(new ObjectMapper().writeValueAsString(BaseResult.error(3, exception.getMessage())));
})
)
.logout(logout -> logout
.logoutUrl("/auth/logout")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.clearAuthentication(true)
.logoutSuccessHandler((request, response, authentication) -> {
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(new ObjectMapper().writeValueAsString(BaseResult.success()));
})
)
// 👇 6. 异常处理(认证失败 / 权限不足)
.exceptionHandling(ex -> ex
.authenticationEntryPoint((request, response, authException) -> {
response.setStatus(401);
response.getWriter().write("Unauthorized: " + authException.getMessage());
})
.accessDeniedHandler((request, response, accessDeniedException) -> {
response.setStatus(403);
response.getWriter().write("Forbidden: " + accessDeniedException.getMessage());
})
);
return http.build();
}
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
@Bean
public ConcurrentSessionFilter concurrentSessionFilter(SessionRegistry sessionRegistry) {
return new ConcurrentSessionFilter(sessionRegistry);
}
// 👇 提供 CORS 配置(生产环境请严格限制 origin
@Bean
@Primary
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
// ✅ 允许的前端 origin必须是具体地址不能 *
configuration.setAllowedOriginPatterns(List.of("http://localhost:*", "http://127.0.0.1:*"));
// ⚠️ 注意Spring Boot 2.4+ 用 allowedOriginPatterns 支持通配符
// ✅ 允许凭证Cookie
configuration.setAllowCredentials(true);
// 允许的方法和头
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setExposedHeaders(List.of("Authorization", "Content-Disposition"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
// 👇 密码编码器(必须)
// @Bean
// public PasswordEncoder passwordEncoder() {
// return md5PasswordEncoder;
// }
// 👇 AuthenticationProvider用于 DaoAuthenticationProvider
// @Bean
// public AuthenticationProvider authenticationProvider() {
// DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
// authProvider.setUserDetailsService(userDetailsService);
// authProvider.setPasswordEncoder(passwordEncoder());
// return authProvider;
// }
// 👇 AuthenticationManager用于登录时 authenticate
// @Bean
// public AuthenticationManager authenticationManager(
// org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration config)
// throws Exception {
// return config.getAuthenticationManager();
// }
}

View File

@@ -0,0 +1,27 @@
package com.niuan.erp.common.config;
import jakarta.validation.Validator;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
@Configuration
public class ValidationConfig {
@Bean
public LocalValidatorFactoryBean validator(MessageSource messageSource) {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource);
return bean;
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor(Validator validator) {
MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
processor.setValidator(validator);
return processor;
}
}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.common.config;
import com.niuan.erp.common.bean.SysLogInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SysLogInterceptor());
}
}

View File

@@ -0,0 +1,7 @@
package com.niuan.erp.common.exception;
public class BusinessException extends RuntimeException {
public BusinessException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,7 @@
package com.niuan.erp.common.exception;
public class SystemException extends RuntimeException {
public SystemException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,97 @@
package com.niuan.erp.common.handler;
import com.niuan.erp.common.base.BaseResult;
import com.niuan.erp.common.exception.BusinessException;
import com.niuan.erp.common.exception.SystemException;
import lombok.RequiredArgsConstructor;
import org.springframework.context.MessageSource;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@RestControllerAdvice
@RequiredArgsConstructor
public class GlobalExceptionHandler {
private final MessageSource messageSource;
/**
* 未传参数错误
* @param e
* @param locale
* @return
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<?> handleHttpMessageNotReadableException(
HttpMessageNotReadableException e,
Locale locale){
return ResponseEntity.badRequest().body(
new BaseResult<>(1,
messageSource.getMessage("httpMessage.notNull", null, locale),
null));
}
/**
* 参数错误
* @param e
* @param locale
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handleMethodArgumentNotValidException(
MethodArgumentNotValidException e,
Locale locale) {
Map<String, String> errors = new HashMap<>();
e.getBindingResult().getFieldErrors().forEach((fieldError) -> {
String msg = messageSource.getMessage(fieldError.getDefaultMessage(), null, fieldError.getDefaultMessage(), locale);
errors.put(fieldError.getField(), msg);
});
return ResponseEntity.badRequest().body(
new BaseResult<>(2,
messageSource.getMessage("validated.error", null, locale),
errors));
}
/**
* 业务错误
* @param e
* @param locale
* @return
*/
@ExceptionHandler(BusinessException.class)
public ResponseEntity<?> handleBusinessException(BusinessException e, Locale locale) {
return ResponseEntity.ok().body(
BaseResult.error(3, messageSource.getMessage(e.getMessage(), null, locale)));
}
/**
* 系统错误
* @param e
* @param locale
* @return
*/
@ExceptionHandler(SystemException.class)
public ResponseEntity<?> handleSystemException(SystemException e, Locale locale) {
return ResponseEntity.ok().body(
BaseResult.error(4, messageSource.getMessage(e.getMessage(), null, locale)));
}
// /**
// * 通用错误
// * @param e
// * @param locale
// * @return
// */
// @ExceptionHandler(Exception.class)
// public ResponseEntity<?> handleException(Exception e, Locale locale) {
// return ResponseEntity.badRequest().body(
// BaseResult.error(-1, e.getMessage()));
// }
}

View File

@@ -0,0 +1,24 @@
package com.niuan.erp.common.utils;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Component;
import java.util.Locale;
@Component
public class MessageUtils {
private static MessageSource messageSource;
public MessageUtils(MessageSource messageSource) {
MessageUtils.messageSource = messageSource;
}
public static String get(String code, Object... args) {
try {
return messageSource.getMessage(code, args, Locale.getDefault());
} catch (Exception ignored) {}
return code;
}
}

View File

@@ -0,0 +1,36 @@
package com.niuan.erp.common.utils;
import com.niuan.erp.common.base.OperationType;
public class OperationContext {
private static final ThreadLocal<Context> contextHolder = new ThreadLocal<>();
public static void set(String moduleName, OperationType operationType, String remark, String ip) {
contextHolder.set(new Context(moduleName, operationType, remark, ip));
}
public static String getModuleName() {
return contextHolder.get().moduleName;
}
public static OperationType getOperationType() {
return contextHolder.get() == null ? null : contextHolder.get().operationType;
}
public static String getRemark() {
return contextHolder.get().remark;
}
public static String getIp() {
return contextHolder.get().ip;
}
public static void clear() {
contextHolder.remove();
}
public record Context(String moduleName, OperationType operationType, String remark, String ip) {}
}

View File

@@ -0,0 +1,32 @@
package com.niuan.erp.common.utils;
import com.niuan.erp.common.base.LoginUser;
import com.niuan.erp.common.exception.BusinessException;
import com.niuan.erp.common.exception.SystemException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
public class SecurityUtils {
public static LoginUser getLoginUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
throw new BusinessException("auth.unLogin");
}
Object principal = authentication.getPrincipal();
System.out.println(principal);
if (principal instanceof LoginUser user) {
return user;
}
throw new SystemException("auth.userDetailsError");
}
public static Long getUserId(){
return getLoginUser().getUser().getId();
}
public static String getUserName(){
return getLoginUser().getUsername();
}
}

View File

@@ -0,0 +1,176 @@
package com.niuan.erp.common.utils;
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 java.util.*;
/**
* 生成数据库菜单对应的前端菜单数据
*/
public class SystemAuthFactory {
private static final Long ROOT_ID = 0L;
private static final Integer MENU_TYPE = 0;
private static final Integer BUTTON_TYPE = 1;
/**
* 生成 Teek 框架的前端动态菜单数据
* @param sysChannels
* @return
*/
public static List<RouterConfigRaw> generateTeekFrameMenu(List<SysChannel> sysChannels) {
List<RouterConfigRaw> configList = new ArrayList<>();
HashMap<Long, RouterConfigRaw> configMap = new HashMap<>();
resolveTeekMenu(sysChannels, configList, configMap);
resolveButtonAuth(sysChannels, configMap);
improveRouteConfig(configList, "");
return configList;
}
/**
* 解析权限表内的按钮权限,要在解析完菜单才能执行
* @param sysChannels
* @param configMap
*/
private static void resolveButtonAuth(List<SysChannel> sysChannels, HashMap<Long, RouterConfigRaw> configMap) {
sysChannels.stream().filter(s -> Objects.equals(s.getChannelType(), BUTTON_TYPE))
.forEach(sysChannel -> {
var buttonProp = convertToButtonProp(sysChannel);
var menuConfig = configMap.get(sysChannel.getParentId());
if (menuConfig != null) {
if (sysChannel.getIsButtonShow()) {
saveInButtonAuthList(menuConfig.getMeta().getButtonAuth(), buttonProp);
}
if (sysChannel.getIsToolShow()) {
saveInButtonAuthList(menuConfig.getMeta().getToolButtonAuth(), buttonProp);
}
}
});
}
/**
* 解析权限表里的菜单权限,将其生成前端 TeekFrame 框架的菜单树
* @param sysChannels
* @param configList
* @param configMap
*/
private static void resolveTeekMenu(List<SysChannel> sysChannels,
List<RouterConfigRaw> configList,
Map<Long, RouterConfigRaw> configMap) {
sysChannels.stream().filter(s -> Objects.equals(s.getChannelType(), MENU_TYPE))
.forEach(sysChannel -> {
var config = convertToRouterConfigRaw(sysChannel);
if (Objects.equals(sysChannel.getParentId(), ROOT_ID)) {
// 如果是顶级节点则加入最后结果
configList.add(config);
// 将自身添加进 Map 中
saveInConfigMap(config, sysChannel.getId(), configMap);
} else {
// 如果不是是顶级节点则说明有上级节点
// 先添加到父组件
if (configMap.containsKey(sysChannel.getParentId())) {
// 如果 Map 里有保存这个内容,说明已经被作为父组件
var parentConfig = configMap.get(sysChannel.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(sysChannel.getParentId(), parentConfig);
}
// 接着将自身添加进 Map 中
saveInConfigMap(config, sysChannel.getId(), configMap);
}
});
}
/**
* 完善路径和组件模块
* @param configList
* @param path
*/
private static void improveRouteConfig(List<RouterConfigRaw> configList, String path) {
configList.forEach(config -> {
if (config.getChildren() == null) {
// 设置组件
config.setComponent("%s/%s".formatted(path, config.getPath()));
} else {
improveRouteConfig(config.getChildren(), "%s/%s".formatted(path, config.getName()));
}
// 设置路径
config.setPath("%s/%s".formatted(path, config.getName()));
});
}
private static void saveInButtonAuthList(List<ButtonProp> buttonList, ButtonProp buttonProp) {
if (buttonList.isEmpty()) {
buttonList.add(buttonProp);
} else {
for (int i = 0; i < buttonList.size(); i++) {
if (buttonList.get(i).getRank() > buttonProp.getRank()) {
buttonList.add(i, buttonProp);
return;
}
}
buttonList.add(buttonProp);
}
}
private static void saveInConfigMap(RouterConfigRaw config, long id, Map<Long, RouterConfigRaw> configMap) {
if (configMap.containsKey(id)) {
// 如果 Map 里有保存自身,则说明自身已经是别人的父节点,将子节点的数据保存
var tempConfig = configMap.get(id);
config.setChildren(tempConfig.getChildren());
}
configMap.put(id, config);
}
/**
* 转化成权限按钮属性,里面包含按钮的各项属性
* @param sysChannel
* @return
*/
private static ButtonProp convertToButtonProp(SysChannel sysChannel) {
ButtonProp buttonProp = new ButtonProp();
buttonProp.setButtonName(sysChannel.getChannelLink());
buttonProp.setText(sysChannel.getChannelName());
buttonProp.setEventName(sysChannel.getEventName());
buttonProp.setColorType(TeekFrameMappingUtils.getTeekButtonType(sysChannel.getClassName()));
buttonProp.setIcon(TeekFrameMappingUtils.getTeekFrameIcon(sysChannel.getIconName()));
buttonProp.setRank(sysChannel.getSort());
return buttonProp;
}
/**
* 转化成 初始化的 RouterConfigRaw需要进一步完善才能匹配前端框架
* @param sysChannel
* @return
*/
private static RouterConfigRaw convertToRouterConfigRaw(SysChannel sysChannel) {
// 使用 channelLink 和 eventName 来作为菜单路径和名字
RouterConfigRaw config = new RouterConfigRaw(sysChannel.getChannelLink(), sysChannel.getEventName());
RouterConfigRawMeta meta = new RouterConfigRawMeta();
// 设置 i18n 的位置
meta.setTitle("{{ _route.%s }}".formatted(sysChannel.getEventName()));
// 设置排序
meta.setRank(sysChannel.getSort());
// 设置图标
meta.setIcon(TeekFrameMappingUtils.getTeekFrameIcon(sysChannel.getIconName()));
// 设置是否隐藏图标
meta.setHideInMenu(!sysChannel.getIsMenuShow());
config.setMeta(meta);
return config;
}
}

View File

@@ -0,0 +1,26 @@
package com.niuan.erp.common.utils;
import java.util.HashMap;
import java.util.Map;
public class TeekFrameMappingUtils {
private static final Map<String, String> ICON_MAP = new HashMap<>();
private static final Map<String, String> BUTTON_TYPE_MAP = new HashMap<>();
static {
BUTTON_TYPE_MAP.put("layui-btn-danger", "danger");
}
public static String getTeekFrameIcon(String databaseIcon) {
if (ICON_MAP.containsKey(databaseIcon)) return ICON_MAP.get(databaseIcon);
return databaseIcon;
}
public static String getTeekButtonType(String databaseButtonType) {
if (BUTTON_TYPE_MAP.containsKey(databaseButtonType)) return BUTTON_TYPE_MAP.get(databaseButtonType);
return databaseButtonType;
}
}

View File

@@ -0,0 +1,48 @@
package com.niuan.erp.common.utils;
import com.niuan.erp.common.base.BaseTree;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.function.Function;
public class TreeUtils {
public static <T> List<BaseTree> generateTree(List<T> nodeList,
Function<T, Object> getIdFunc,
Function<T, String> getLabelFunc,
Function<T, Object> getParentIdFunc,
Object rootId) {
HashMap<Object, BaseTree> map = new HashMap<>();
List<BaseTree> rootList = new ArrayList<>();
nodeList.forEach(node -> {
Object id = getIdFunc.apply(node);
String label = getLabelFunc.apply(node);
Object parentId = getParentIdFunc.apply(node);
BaseTree treeNode = new BaseTree(id, label, null);
// 检查是不是顶级 Node
if (rootId.equals(parentId)) {
rootList.add(treeNode);
}
// 添加父节点
if (map.containsKey(parentId)) {
if (map.get(parentId).getChildren() != null) map.get(parentId).getChildren().add(treeNode);
else map.get(parentId).setChildren(new ArrayList<>(List.of(treeNode)));
} else {
map.put(parentId, new BaseTree(parentId, null, new ArrayList<>(List.of(treeNode))));
}
// 判断自己
if (!map.containsKey(id)) {
map.put(id, treeNode);
} else {
treeNode.setChildren(map.get(id).getChildren());
map.put(id, treeNode);
}
});
System.out.println(rootList);
return rootList;
}
}

View File

@@ -0,0 +1,18 @@
package com.niuan.erp.module.auth.controller;
import com.niuan.erp.common.base.BaseResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/auth")
@RestController
public class LoginController {
@GetMapping("/user/me")
public BaseResult<?> getCurrentUser() {
return BaseResult.success();
}
}

View File

@@ -0,0 +1,22 @@
package com.niuan.erp.module.auth.controller;
import com.niuan.erp.common.base.BaseResult;
import com.niuan.erp.module.auth.service.SystemAuthService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class SystemAuthController {
private final SystemAuthService systemAuthService;
@GetMapping("/getRouterConfigRawList")
public BaseResult<?> getRouterConfigRawList() {
return BaseResult.successWithData(systemAuthService.getRouterConfigRawList());
}
}

View File

@@ -0,0 +1,31 @@
package com.niuan.erp.module.auth.controller.dto;
import lombok.Data;
@Data
public class ButtonProp {
/**
* 按钮文本
*/
private String text;
/**
* 按钮名称
*/
private String buttonName;
/**
* 事件名称
*/
private String eventName;
/**
* 按钮类型
*/
private String colorType;
/**
* 按钮标签
*/
private String icon;
/**
* 排序
*/
private Integer rank;
}

View File

@@ -0,0 +1,10 @@
package com.niuan.erp.module.auth.controller.dto;
import jakarta.validation.constraints.NotNull;
public record LoginDto(
@NotNull(message = "{loginName.notNull}")
String loginName,
@NotNull(message = "{password.notNull}")
String password
) {}

View File

@@ -0,0 +1,57 @@
package com.niuan.erp.module.auth.controller.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 前端路由配置项
*/
@Getter
@Setter
public class RouterConfigRaw {
/**
* 路由地址,必须设置
*/
private String path;
/**
* 路由名字,必须设置
*/
private String name;
/**
* 重定向
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private String redirect;
/**
* 视图文件路径
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private String component;
/**
* 菜单信息
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private RouterConfigRawMeta meta;
/**
* 子菜单
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private List<RouterConfigRaw> children;
private RouterConfigRaw() {}
public RouterConfigRaw(String path, String name) {
this.path = path;
this.name = name;
}
}

View File

@@ -0,0 +1,139 @@
package com.niuan.erp.module.auth.controller.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 菜单信息
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class RouterConfigRawMeta {
/**
* 可访问该页面的权限数组,会影响子路由
*/
private List<String> roles;
/**
* 路由内的按钮权限
*/
private List<String> auths;
/**
* 如果使用 {{ 字段 }} 表示,则前端会使用该字段的 i18n
*/
private String title;
/**
* 菜单图标
*/
private String icon;
/**
* 是否允许点击面包屑,如果是 true则不允许点击默认 false
*/
private Boolean notClickBread;
/**
* 不放在面包屑里,默认为 false
*/
private Boolean hideInBread;
/**
* 不添加在左侧菜单栏,默认为 false
*/
private Boolean hideInMenu;
/**
* 是否渲染为菜单,如果为 true一级菜单永远是下拉菜单
* 如果是 false只有一个二级菜单时不显示一级菜单直接显示二级菜单。
* 默认为 false
*/
private Boolean alwaysShowRoot;
/**
* 不渲染 Layout 布局,只渲染当前路由组件
*/
private Boolean isFull;
/**
* Restful 路由搭配使用(未使用)
*/
private Boolean activeMenu;
/**
* (未使用)
*/
private Boolean beforeCloseName;
/**
* 排序,没有时根据顺序
*/
private Integer rank;
/**
* IFrame 链接(未使用)
*/
private String iframeSrc;
/**
* 是否开启首次加载动画,默认 true未使用
*/
private Boolean iframeLoading;
// IFrame 页是否开启缓存(默认 false
private Boolean iframeKeepAlive;
// IFrame 页是否开新标签页打开true 以新标签页打开false 不打开(默认 false
private Boolean iframeOpen;
// 页面加载动画,即 Transition 组件的 Props有两种形式一种直接采用 vue 内置的 transitions 动画,另一种是使用 animate.css 写进、离场动画)
private Object transitionProps;
// 是否不添加到标签栏,默认 false
private Boolean hideInTab;
// 动态路由可打开的最大数量,默认为空
private Integer dynamicLevel;
// 是否开启 i18n。默认读取全局的 routeUseI18nsrc/config/base-config.ts
private Boolean useI18n;
// 菜单的文字超出后,是否使用 el-toolTip 提示,仅针对二级路由及以上生效。默认读取全局的 routeUseTooltipsrc/config/base-config.ts
private Boolean useTooltip;
// 自定义 Render 菜单元素TSX 语法)
private Object render;
// 菜单标签,使用 ElTag 组件
private String tagText;
// 菜单标签的属性,即 ElTag 组件的 props
private Object tagProps;
// 是否显示点标记
private Boolean pointTag;
// 点标记的属性,即 PointTag 组件的 props
private String pointTagProps;
// 菜单可以看到,但是访问会被重定向到 403
private Boolean menuVisibleWithForbidden;
// 查询参数Teek 不做任何处理,自行取出处理
private String query;
/**
* 表头 Button 权限
*/
private List<ButtonProp> buttonAuth = new ArrayList<>();
/**
* 操作栏 Button 权限
*/
private List<ButtonProp> toolButtonAuth = new ArrayList<>();
}

View File

@@ -0,0 +1,72 @@
package com.niuan.erp.module.auth.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.benmanes.caffeine.cache.Caffeine;
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.SysRole;
import com.niuan.erp.module.sys.entity.SysUser;
import com.niuan.erp.module.sys.mapper.SysChannelMapper;
import com.niuan.erp.module.sys.mapper.SysRoleMapper;
import com.niuan.erp.module.sys.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.Duration;
import java.util.List;
@Service
@Transactional
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {
private final SysUserMapper sysUserMapper;
private final SysChannelMapper sysChannelMapper;
private final SysRoleMapper sysRoleMapper;
private final LoadingCache<String, UserDetails> userCache = Caffeine.newBuilder()
.maximumSize(100)
.expireAfterWrite(Duration.ofMinutes(10))
.build(this::loadUserFromDatabase);
@Override
public UserDetails loadUserByUsername(String loginName) throws UsernameNotFoundException {
return userCache.get(loginName);
}
private UserDetails loadUserFromDatabase(String loginName) {
SysUser user = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getLoginName, loginName)
.eq(SysUser::getStatus, 1));
if (user == null) {
throw new BusinessException("");
}
List<SysRole> roleList = sysRoleMapper.selectByUserId(user.getId());
List<SysChannel> channelList = sysChannelMapper.selectByUserId(user.getId());
List<String> authorityList = channelList.stream()
.map(SysChannel::getChannelLink)
.filter(StringUtils::hasText)
.toList();
return LoginUser.builder()
.user(user)
.roleList(roleList)
.authorities(List.of(new SimpleGrantedAuthority("vendor:index")))
.build();
}
public void evictUserCache(String loginName) {
userCache.invalidate(loginName);
}
}

View File

@@ -0,0 +1,11 @@
package com.niuan.erp.module.auth.service;
import com.niuan.erp.module.auth.controller.dto.RouterConfigRaw;
import java.util.List;
public interface SystemAuthService {
List<RouterConfigRaw> getRouterConfigRawList();
}

View File

@@ -0,0 +1,27 @@
package com.niuan.erp.module.auth.service.impl;
import com.niuan.erp.common.base.LoginUser;
import com.niuan.erp.common.utils.SecurityUtils;
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.mapper.SysChannelMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class SystemAuthServiceImpl implements SystemAuthService {
private final SysChannelMapper sysChannelMapper;
@Override
public List<RouterConfigRaw> getRouterConfigRawList() {
LoginUser loginUser = SecurityUtils.getLoginUser();
List<SysChannel> sysChannels = sysChannelMapper.selectByUserId(loginUser.getUser().getId());
return SystemAuthFactory.generateTeekFrameMenu(sysChannels);
}
}

View File

@@ -0,0 +1,68 @@
package com.niuan.erp.module.common.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.module.common.controller.dto.QtCodeDto;
import com.niuan.erp.module.common.entity.QtCode;
import com.niuan.erp.module.common.service.QtCodeService;
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 = "QtCode")
@RestController
@RequestMapping("/common/qtcode")
@RequiredArgsConstructor
public class QtCodeController {
private final QtCodeService qtCodeService;
@Operation(summary = "分页查询QtCode数据", operationId = "getQtCodePage")
@GetMapping("/getQtCodePage")
@PreAuthorize("hasAuthority('qtcode:index')")
public BaseResult<IPage<QtCodeDto>> getQtCodePage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) QtCodeDto searchParams) {
var wrapper = new LambdaQueryWrapper<QtCode>();
return BaseResult.successWithData(qtCodeService.getQtCodePage(pageParams, wrapper));
}
@Operation(summary = "新增QtCode", operationId = "addQtCode")
@PostMapping("/addQtCode")
@PreAuthorize("hasAuthority('qtcode:add')")
public BaseResult<?> addQtCode(@Validated(Add.class) @RequestBody QtCodeDto dto) {
qtCodeService.addQtCode(dto);
return BaseResult.success();
}
@Operation(summary = "更新QtCode", operationId = "updateQtCode")
@PostMapping("/updateQtCode")
@PreAuthorize("hasAuthority('qtcode:update')")
public BaseResult<?> updateQtCode(@Validated(Update.class) @RequestBody QtCodeDto dto) {
qtCodeService.updateQtCode(dto);
return BaseResult.success();
}
@Operation(summary = "删除QtCode", operationId = "deleteQtCode")
@PostMapping("/deleteQtCode")
@PreAuthorize("hasAuthority('qtcode:delete')")
public BaseResult<?> deleteQtCode(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
qtCodeService.deleteQtCode(req.id());
return BaseResult.success();
}
@Operation(summary = "批量删除QtCode", operationId = "deleteQtCodeBatch")
@PostMapping("/deleteQtCodeBatch")
@PreAuthorize("hasAuthority('qtcode:deleteBatch')")
public BaseResult<?> deleteQtCodeBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
qtCodeService.deleteBatch(req.ids());
return BaseResult.success();
}
}

View File

@@ -0,0 +1,10 @@
package com.niuan.erp.module.common.controller.dto;
public record QtCodeDto(
Integer id,
String printCode,
Integer partNumber,
String productPacking,
String datecode,
String vendCode,
String brandCode) {}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.common.converter;
import com.niuan.erp.module.common.controller.dto.QtCodeDto;
import com.niuan.erp.module.common.entity.QtCode;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface QtCodeConverter {
QtCode toEntity(QtCodeDto dto);
QtCodeDto toDto(QtCode entity);
List<QtCodeDto> toDtoList(List<QtCode> entities);
}

View File

@@ -0,0 +1,101 @@
package com.niuan.erp.module.common.entity;
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 lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
*
* </p>
*
* @author
* @since 2026-02-11
*/
@Getter
@Setter
@ToString
@TableName("productionform")
public class Document implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "Id", type = IdType.AUTO)
private Long id;
@TableField("Status")
private Integer status;
@TableField("CreateDate")
private LocalDateTime createDate;
@TableField("CreateUserId")
private Long createUserId;
@TableField("CreateUserName")
private String createUserName;
@TableField("UpdateDate")
private LocalDateTime updateDate;
@TableField("UpdateUserId")
private Long updateUserId;
@TableField("UpdateUserName")
private String updateUserName;
@TableField("StoreNo")
private Integer storeNo;
@TableField("StoreName")
private String storeName;
@TableField("FormType")
private Integer formType;
@TableField("FormCode")
private String formCode;
@TableField("FormName")
private String formName;
@TableField("FormStatus")
private Integer formStatus;
@TableField("FormMark")
private String formMark;
@TableField("reserve1")
private Integer reserve1;
@TableField("reserve2")
private String reserve2;
@TableField("VendorNo")
private Integer vendorNo;
@TableField("VendorName")
private String vendorName;
@TableField("TotalValue")
private Double totalValue;
@TableField("OutStoreNo")
private Integer outStoreNo;
@TableField("OutStoreName")
private String outStoreName;
@TableField("GroupId")
private Integer groupId;
@TableField("CustomerId")
private Integer customerId;
}

View File

@@ -0,0 +1,83 @@
package com.niuan.erp.module.common.entity;
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 lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
*
* </p>
*
* @author
* @since 2026-02-11
*/
@Getter
@Setter
@ToString
@TableName("materialinout")
public class DocumentMaterial implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "Id", type = IdType.AUTO)
private Long id;
@TableField("Status")
private Integer status;
@TableField("CreateDate")
private LocalDateTime createDate;
@TableField("CreateUserId")
private Long createUserId;
@TableField("CreateUserName")
private String createUserName;
@TableField("UpdateDate")
private LocalDateTime updateDate;
@TableField("UpdateUserId")
private Long updateUserId;
@TableField("UpdateUserName")
private String updateUserName;
@TableField("DocumentNo")
private Integer documentNo;
@TableField("PartNumber")
private String partNumber;
@TableField("OriginalCount")
private Integer originalCount;
@TableField("ProductCount")
private Integer productCount;
@TableField("ProductMark")
private String productMark;
@TableField("reserve1")
private Integer reserve1;
@TableField("reserve2")
private String reserve2;
@TableField("StoreNo")
private Integer storeNo;
@TableField("DemandCount")
private Integer demandCount;
@TableField("PartId")
private Long partId;
}

View File

@@ -0,0 +1,49 @@
package com.niuan.erp.module.common.entity;
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 lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author
* @since 2026-02-11
*/
@Getter
@Setter
@ToString
@TableName("printcodelist")
public class QtCode implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField("printCode")
private String printCode;
@TableField("PartNumber")
private Integer partNumber;
@TableField("ProductPacking")
private String productPacking;
@TableField("datecode")
private String datecode;
@TableField("vendCode")
private String vendCode;
@TableField("brandCode")
private String brandCode;
}

View File

@@ -0,0 +1,30 @@
package com.niuan.erp.module.common.enums;
import lombok.Getter;
/**
* 单据类型枚举
* code 对应业务编号:
* 1.采购订单 2.销售订单 3.仓库入库单 4.仓库出库单(修正重复项)
* 5.生产发料单 6.生产退料单 7.成品出货单 8.仓库调拨单 9.库存盘点单
*/
@Getter
public enum DocumentType {
PURCHASE_ORDER(1, "采购订单"),
SALES_ORDER(2, "销售订单"),
WAREHOUSE_RECEIPT(3, "仓库入库单"),
WAREHOUSE_ISSUE(4, "仓库出库单"), // 修正原第4项应为出库单
PRODUCTION_ISSUE(5, "生产发料单"),
PRODUCTION_RETURN(6, "生产退料单"),
FINISHED_PRODUCT_SHIPMENT(7, "成品出货单"),
STOCK_TRANSFER_ORDER(8, "仓库调拨单"),
INVENTORY_COUNT(9, "库存盘点单");
final int code;
final String description;
DocumentType(int code, String description) {
this.code = code;
this.description = description;
}
}

View File

@@ -0,0 +1,16 @@
package com.niuan.erp.module.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.niuan.erp.module.common.entity.Document;
/**
* <p>
* Mapper 接口
* </p>
*
* @author
* @since 2026-02-11
*/
public interface DocumentMapper extends BaseMapper<Document> {
}

View File

@@ -0,0 +1,16 @@
package com.niuan.erp.module.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.niuan.erp.module.common.entity.DocumentMaterial;
/**
* <p>
* Mapper 接口
* </p>
*
* @author
* @since 2026-02-11
*/
public interface DocumentMaterialMapper extends BaseMapper<DocumentMaterial> {
}

View File

@@ -0,0 +1,16 @@
package com.niuan.erp.module.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.niuan.erp.module.common.entity.QtCode;
/**
* <p>
* Mapper 接口
* </p>
*
* @author
* @since 2026-02-11
*/
public interface QtCodeMapper extends BaseMapper<QtCode> {
}

View File

@@ -0,0 +1,23 @@
package com.niuan.erp.module.common.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.common.controller.dto.QtCodeDto;
import com.niuan.erp.module.common.entity.QtCode;
import java.util.List;
public interface QtCodeService {
IPage<QtCodeDto> getQtCodePage(BasePageReqParams pageParams, LambdaQueryWrapper<QtCode> wrapper);
void addQtCode(QtCodeDto dto);
void updateQtCode(QtCodeDto dto);
void deleteQtCode(long id);
void deleteBatch(List<Long> ids);
}

View File

@@ -0,0 +1,58 @@
package com.niuan.erp.module.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.utils.SecurityUtils;
import com.niuan.erp.module.common.controller.dto.QtCodeDto;
import com.niuan.erp.module.common.converter.QtCodeConverter;
import com.niuan.erp.module.common.entity.QtCode;
import com.niuan.erp.module.common.mapper.QtCodeMapper;
import com.niuan.erp.module.common.service.QtCodeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
@Transactional
@RequiredArgsConstructor
public class QtCodeServiceImpl extends ServiceImpl<QtCodeMapper, QtCode> implements QtCodeService {
private final QtCodeConverter qtCodeConverter;
@Override
public IPage<QtCodeDto> getQtCodePage(BasePageReqParams pageParams, LambdaQueryWrapper<QtCode> wrapper) {
IPage<QtCode> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper);
return result.convert(qtCodeConverter::toDto);
}
@Override
public void addQtCode(QtCodeDto dto) {
QtCode entity = qtCodeConverter.toEntity(dto);
this.baseMapper.insert(entity);
}
@Override
public void updateQtCode(QtCodeDto dto) {
QtCode entity = qtCodeConverter.toEntity(dto);
this.baseMapper.updateById(entity);
}
@Override
public void deleteQtCode(long id) {
this.baseMapper.deleteById(id);
}
@Override
public void deleteBatch(List<Long> ids) {
this.baseMapper.deleteByIds(ids);
}
}

View File

@@ -0,0 +1,85 @@
package com.niuan.erp.module.production.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.production.controller.dto.BomDto;
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 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")
@ModuleLog("Bom管理")
@RestController
@RequestMapping("/production/bom")
@RequiredArgsConstructor
public class BomController {
private final BomService bomService;
@Operation(summary = "分页查询Bom数据", operationId = "getBomPage")
@GetMapping("/getBomPage")
@PreAuthorize("hasAuthority('bom:index')")
public BaseResult<IPage<BomDto>> getBomPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) BomDto searchParams) {
var wrapper = new LambdaQueryWrapper<Bom>();
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());
}
}
return BaseResult.successWithData(bomService.getBomPage(pageParams, wrapper));
}
@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) {
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();
}
}

View File

@@ -0,0 +1,76 @@
package com.niuan.erp.module.production.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.production.controller.dto.BomItemDto;
import com.niuan.erp.module.production.entity.BomItem;
import com.niuan.erp.module.production.service.BomItemService;
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 = "BomItem")
@ModuleLog("BomItem管理")
@RestController
@RequestMapping("/production/bomitem")
@RequiredArgsConstructor
public class BomItemController {
private final BomItemService bomItemService;
@Operation(summary = "分页查询BomItem数据", operationId = "getBomItemPage")
@GetMapping("/getBomItemPage")
@PreAuthorize("hasAuthority('bomitem:index')")
public BaseResult<IPage<BomItemDto>> getBomItemPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) BomItemDto searchParams) {
var wrapper = new LambdaQueryWrapper<BomItem>();
return BaseResult.successWithData(bomItemService.getBomItemPage(pageParams, wrapper));
}
@ApiLog(type = OperationType.ADD, remark = "新增一条BomItem记录")
@Operation(summary = "新增BomItem", operationId = "addBomItem")
@PostMapping("/addBomItem")
@PreAuthorize("hasAuthority('bomitem:add')")
public BaseResult<?> addBomItem(@Validated(Add.class) @RequestBody BomItemDto dto) {
bomItemService.addBomItem(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.UPDATE, remark = "更新一条BomItem记录")
@Operation(summary = "更新BomItem", operationId = "updateBomItem")
@PostMapping("/updateBomItem")
@PreAuthorize("hasAuthority('bomitem:update')")
public BaseResult<?> updateBomItem(@Validated(Update.class) @RequestBody BomItemDto dto) {
bomItemService.updateBomItem(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "删除一条BomItem记录")
@Operation(summary = "删除BomItem", operationId = "deleteBomItem")
@PostMapping("/deleteBomItem")
@PreAuthorize("hasAuthority('bomitem:delete')")
public BaseResult<?> deleteBomItem(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
bomItemService.deleteBomItem(req.id());
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "批量删除BomItem记录")
@Operation(summary = "批量删除BomItem", operationId = "deleteBomItemBatch")
@PostMapping("/deleteBomItemBatch")
@PreAuthorize("hasAuthority('bomitem:deleteBatch')")
public BaseResult<?> deleteBomItemBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
bomItemService.deleteBatch(req.ids());
return BaseResult.success();
}
}

View File

@@ -0,0 +1,76 @@
package com.niuan.erp.module.production.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.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.FinishedProductReceiptDto;
import com.niuan.erp.module.production.service.FinishedProductReceiptService;
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 = "FinishedProductReceipt")
@ModuleLog("FinishedProductReceipt管理")
@RestController
@RequestMapping("/production/finishedproductreceipt")
@RequiredArgsConstructor
public class FinishedProductReceiptController {
private final FinishedProductReceiptService finishedProductReceiptService;
@Operation(summary = "分页查询FinishedProductReceipt数据", operationId = "getFinishedProductReceiptPage")
@GetMapping("/getFinishedProductReceiptPage")
@PreAuthorize("hasAuthority('finishedproductreceipt:index')")
public BaseResult<IPage<FinishedProductReceiptDto>> getFinishedProductReceiptPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) FinishedProductReceiptDto searchParams) {
var wrapper = new LambdaQueryWrapper<Document>();
return BaseResult.successWithData(finishedProductReceiptService.getFinishedProductReceiptPage(pageParams, wrapper));
}
@ApiLog(type = OperationType.ADD, remark = "新增一条FinishedProductReceipt记录")
@Operation(summary = "新增FinishedProductReceipt", operationId = "addFinishedProductReceipt")
@PostMapping("/addFinishedProductReceipt")
@PreAuthorize("hasAuthority('finishedproductreceipt:add')")
public BaseResult<?> addFinishedProductReceipt(@Validated(Add.class) @RequestBody FinishedProductReceiptDto dto) {
finishedProductReceiptService.addFinishedProductReceipt(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.UPDATE, remark = "更新一条FinishedProductReceipt记录")
@Operation(summary = "更新FinishedProductReceipt", operationId = "updateFinishedProductReceipt")
@PostMapping("/updateFinishedProductReceipt")
@PreAuthorize("hasAuthority('finishedproductreceipt:update')")
public BaseResult<?> updateFinishedProductReceipt(@Validated(Update.class) @RequestBody FinishedProductReceiptDto dto) {
finishedProductReceiptService.updateFinishedProductReceipt(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "删除一条FinishedProductReceipt记录")
@Operation(summary = "删除FinishedProductReceipt", operationId = "deleteFinishedProductReceipt")
@PostMapping("/deleteFinishedProductReceipt")
@PreAuthorize("hasAuthority('finishedproductreceipt:delete')")
public BaseResult<?> deleteFinishedProductReceipt(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
finishedProductReceiptService.deleteFinishedProductReceipt(req.id());
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "批量删除FinishedProductReceipt记录")
@Operation(summary = "批量删除FinishedProductReceipt", operationId = "deleteFinishedProductReceiptBatch")
@PostMapping("/deleteFinishedProductReceiptBatch")
@PreAuthorize("hasAuthority('finishedproductreceipt:deleteBatch')")
public BaseResult<?> deleteFinishedProductReceiptBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
finishedProductReceiptService.deleteBatch(req.ids());
return BaseResult.success();
}
}

View File

@@ -0,0 +1,76 @@
package com.niuan.erp.module.production.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.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.FinishedProductShipmentDto;
import com.niuan.erp.module.production.service.FinishedProductShipmentService;
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 = "FinishedProductShipment")
@ModuleLog("FinishedProductShipment管理")
@RestController
@RequestMapping("/production/finishedproductshipment")
@RequiredArgsConstructor
public class FinishedProductShipmentController {
private final FinishedProductShipmentService finishedProductShipmentService;
@Operation(summary = "分页查询FinishedProductShipment数据", operationId = "getFinishedProductShipmentPage")
@GetMapping("/getFinishedProductShipmentPage")
@PreAuthorize("hasAuthority('finishedproductshipment:index')")
public BaseResult<IPage<FinishedProductShipmentDto>> getFinishedProductShipmentPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) FinishedProductShipmentDto searchParams) {
var wrapper = new LambdaQueryWrapper<Document>();
return BaseResult.successWithData(finishedProductShipmentService.getFinishedProductShipmentPage(pageParams, wrapper));
}
@ApiLog(type = OperationType.ADD, remark = "新增一条FinishedProductShipment记录")
@Operation(summary = "新增FinishedProductShipment", operationId = "addFinishedProductShipment")
@PostMapping("/addFinishedProductShipment")
@PreAuthorize("hasAuthority('finishedproductshipment:add')")
public BaseResult<?> addFinishedProductShipment(@Validated(Add.class) @RequestBody FinishedProductShipmentDto dto) {
finishedProductShipmentService.addFinishedProductShipment(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.UPDATE, remark = "更新一条FinishedProductShipment记录")
@Operation(summary = "更新FinishedProductShipment", operationId = "updateFinishedProductShipment")
@PostMapping("/updateFinishedProductShipment")
@PreAuthorize("hasAuthority('finishedproductshipment:update')")
public BaseResult<?> updateFinishedProductShipment(@Validated(Update.class) @RequestBody FinishedProductShipmentDto dto) {
finishedProductShipmentService.updateFinishedProductShipment(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "删除一条FinishedProductShipment记录")
@Operation(summary = "删除FinishedProductShipment", operationId = "deleteFinishedProductShipment")
@PostMapping("/deleteFinishedProductShipment")
@PreAuthorize("hasAuthority('finishedproductshipment:delete')")
public BaseResult<?> deleteFinishedProductShipment(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
finishedProductShipmentService.deleteFinishedProductShipment(req.id());
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "批量删除FinishedProductShipment记录")
@Operation(summary = "批量删除FinishedProductShipment", operationId = "deleteFinishedProductShipmentBatch")
@PostMapping("/deleteFinishedProductShipmentBatch")
@PreAuthorize("hasAuthority('finishedproductshipment:deleteBatch')")
public BaseResult<?> deleteFinishedProductShipmentBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
finishedProductShipmentService.deleteBatch(req.ids());
return BaseResult.success();
}
}

View File

@@ -0,0 +1,76 @@
package com.niuan.erp.module.production.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.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.ProductionIssueDto;
import com.niuan.erp.module.production.service.ProductionIssueService;
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 = "ProductionIssue")
@ModuleLog("ProductionIssue管理")
@RestController
@RequestMapping("/production/productionissue")
@RequiredArgsConstructor
public class ProductionIssueController {
private final ProductionIssueService productionIssueService;
@Operation(summary = "分页查询ProductionIssue数据", operationId = "getProductionIssuePage")
@GetMapping("/getProductionIssuePage")
@PreAuthorize("hasAuthority('productionissue:index')")
public BaseResult<IPage<ProductionIssueDto>> getProductionIssuePage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) ProductionIssueDto searchParams) {
var wrapper = new LambdaQueryWrapper<Document>();
return BaseResult.successWithData(productionIssueService.getProductionIssuePage(pageParams, wrapper));
}
@ApiLog(type = OperationType.ADD, remark = "新增一条ProductionIssue记录")
@Operation(summary = "新增ProductionIssue", operationId = "addProductionIssue")
@PostMapping("/addProductionIssue")
@PreAuthorize("hasAuthority('productionissue:add')")
public BaseResult<?> addProductionIssue(@Validated(Add.class) @RequestBody ProductionIssueDto dto) {
productionIssueService.addProductionIssue(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.UPDATE, remark = "更新一条ProductionIssue记录")
@Operation(summary = "更新ProductionIssue", operationId = "updateProductionIssue")
@PostMapping("/updateProductionIssue")
@PreAuthorize("hasAuthority('productionissue:update')")
public BaseResult<?> updateProductionIssue(@Validated(Update.class) @RequestBody ProductionIssueDto dto) {
productionIssueService.updateProductionIssue(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "删除一条ProductionIssue记录")
@Operation(summary = "删除ProductionIssue", operationId = "deleteProductionIssue")
@PostMapping("/deleteProductionIssue")
@PreAuthorize("hasAuthority('productionissue:delete')")
public BaseResult<?> deleteProductionIssue(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
productionIssueService.deleteProductionIssue(req.id());
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "批量删除ProductionIssue记录")
@Operation(summary = "批量删除ProductionIssue", operationId = "deleteProductionIssueBatch")
@PostMapping("/deleteProductionIssueBatch")
@PreAuthorize("hasAuthority('productionissue:deleteBatch')")
public BaseResult<?> deleteProductionIssueBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
productionIssueService.deleteBatch(req.ids());
return BaseResult.success();
}
}

View File

@@ -0,0 +1,85 @@
package com.niuan.erp.module.production.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.production.controller.dto.ProductionPlanDto;
import com.niuan.erp.module.production.entity.ProductionPlan;
import com.niuan.erp.module.production.service.ProductionPlanService;
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 = "ProductionPlan")
@ModuleLog("ProductionPlan管理")
@RestController
@RequestMapping("/production/productionplan")
@RequiredArgsConstructor
public class ProductionPlanController {
private final ProductionPlanService productionPlanService;
@Operation(summary = "分页查询ProductionPlan数据", operationId = "getProductionPlanPage")
@GetMapping("/getProductionPlanPage")
@PreAuthorize("hasAuthority('productionplan:index')")
public BaseResult<IPage<ProductionPlanDto>> getProductionPlanPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) ProductionPlanDto searchParams) {
var wrapper = new LambdaQueryWrapper<ProductionPlan>();
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());
}
}
return BaseResult.successWithData(productionPlanService.getProductionPlanPage(pageParams, wrapper));
}
@ApiLog(type = OperationType.ADD, remark = "新增一条ProductionPlan记录")
@Operation(summary = "新增ProductionPlan", operationId = "addProductionPlan")
@PostMapping("/addProductionPlan")
@PreAuthorize("hasAuthority('productionplan: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")
@PostMapping("/updateProductionPlan")
@PreAuthorize("hasAuthority('productionplan: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")
@PostMapping("/deleteProductionPlan")
@PreAuthorize("hasAuthority('productionplan: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());
return BaseResult.success();
}
}

View File

@@ -0,0 +1,76 @@
package com.niuan.erp.module.production.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.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.ProductionReturnDto;
import com.niuan.erp.module.production.service.ProductionReturnService;
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 = "ProductionReturn")
@ModuleLog("ProductionReturn管理")
@RestController
@RequestMapping("/production/productionreturn")
@RequiredArgsConstructor
public class ProductionReturnController {
private final ProductionReturnService productionReturnService;
@Operation(summary = "分页查询ProductionReturn数据", operationId = "getProductionReturnPage")
@GetMapping("/getProductionReturnPage")
@PreAuthorize("hasAuthority('productionreturn:index')")
public BaseResult<IPage<ProductionReturnDto>> getProductionReturnPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) ProductionReturnDto searchParams) {
var wrapper = new LambdaQueryWrapper<Document>();
return BaseResult.successWithData(productionReturnService.getProductionReturnPage(pageParams, wrapper));
}
@ApiLog(type = OperationType.ADD, remark = "新增一条ProductionReturn记录")
@Operation(summary = "新增ProductionReturn", operationId = "addProductionReturn")
@PostMapping("/addProductionReturn")
@PreAuthorize("hasAuthority('productionreturn:add')")
public BaseResult<?> addProductionReturn(@Validated(Add.class) @RequestBody ProductionReturnDto dto) {
productionReturnService.addProductionReturn(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.UPDATE, remark = "更新一条ProductionReturn记录")
@Operation(summary = "更新ProductionReturn", operationId = "updateProductionReturn")
@PostMapping("/updateProductionReturn")
@PreAuthorize("hasAuthority('productionreturn:update')")
public BaseResult<?> updateProductionReturn(@Validated(Update.class) @RequestBody ProductionReturnDto dto) {
productionReturnService.updateProductionReturn(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "删除一条ProductionReturn记录")
@Operation(summary = "删除ProductionReturn", operationId = "deleteProductionReturn")
@PostMapping("/deleteProductionReturn")
@PreAuthorize("hasAuthority('productionreturn:delete')")
public BaseResult<?> deleteProductionReturn(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
productionReturnService.deleteProductionReturn(req.id());
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "批量删除ProductionReturn记录")
@Operation(summary = "批量删除ProductionReturn", operationId = "deleteProductionReturnBatch")
@PostMapping("/deleteProductionReturnBatch")
@PreAuthorize("hasAuthority('productionreturn:deleteBatch')")
public BaseResult<?> deleteProductionReturnBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
productionReturnService.deleteBatch(req.ids());
return BaseResult.success();
}
}

View File

@@ -0,0 +1,23 @@
package com.niuan.erp.module.production.controller.dto;
import java.time.LocalDateTime;
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) {}

View File

@@ -0,0 +1,18 @@
package com.niuan.erp.module.production.controller.dto;
public record BomItemDto(
Long id,
Integer bomId,
String projectName,
String partNumber,
String itemPosition,
Integer manufactureCount,
Integer sameUseCount,
String sameUseNum1,
String sameUseNum2,
String sameUseNum3,
Integer loseRate,
Integer manufactureSpec,
String productMark,
Integer reserve1,
String reserve2) {}

View File

@@ -0,0 +1,29 @@
package com.niuan.erp.module.production.controller.dto;
import java.time.LocalDateTime;
public record FinishedProductReceiptDto(
Long id,
Integer status,
LocalDateTime createDate,
Long createUserId,
String createUserName,
LocalDateTime updateDate,
Long updateUserId,
String updateUserName,
Integer storeNo,
String storeName,
Integer formType,
String formCode,
String formName,
Integer formStatus,
String formMark,
Integer reserve1,
String reserve2,
Integer vendorNo,
String vendorName,
Double totalValue,
Integer outStoreNo,
String outStoreName,
Integer groupId,
Integer customerId) {}

View File

@@ -0,0 +1,29 @@
package com.niuan.erp.module.production.controller.dto;
import java.time.LocalDateTime;
public record FinishedProductShipmentDto(
Long id,
Integer status,
LocalDateTime createDate,
Long createUserId,
String createUserName,
LocalDateTime updateDate,
Long updateUserId,
String updateUserName,
Integer storeNo,
String storeName,
Integer formType,
String formCode,
String formName,
Integer formStatus,
String formMark,
Integer reserve1,
String reserve2,
Integer vendorNo,
String vendorName,
Double totalValue,
Integer outStoreNo,
String outStoreName,
Integer groupId,
Integer customerId) {}

View File

@@ -0,0 +1,29 @@
package com.niuan.erp.module.production.controller.dto;
import java.time.LocalDateTime;
public record ProductionIssueDto(
Long id,
Integer status,
LocalDateTime createDate,
Long createUserId,
String createUserName,
LocalDateTime updateDate,
Long updateUserId,
String updateUserName,
Integer storeNo,
String storeName,
Integer formType,
String formCode,
String formName,
Integer formStatus,
String formMark,
Integer reserve1,
String reserve2,
Integer vendorNo,
String vendorName,
Double totalValue,
Integer outStoreNo,
String outStoreName,
Integer groupId,
Integer customerId) {}

View File

@@ -0,0 +1,29 @@
package com.niuan.erp.module.production.controller.dto;
import java.time.LocalDateTime;
public record ProductionPlanDto(
Long id,
Integer status,
LocalDateTime createDate,
Long createUserId,
String createUserName,
LocalDateTime updateDate,
Long updateUserId,
String updateUserName,
String productionNum,
String projectName,
Integer projectId,
Integer productionCount,
Integer productionStatus,
String productionNote,
String productionReport,
String productionMark,
String reserve1,
String reserve2,
Integer storeNo,
String storeName,
Integer groupId,
String groupName,
Integer customerId,
String customerName) {}

View File

@@ -0,0 +1,29 @@
package com.niuan.erp.module.production.controller.dto;
import java.time.LocalDateTime;
public record ProductionReturnDto(
Long id,
Integer status,
LocalDateTime createDate,
Long createUserId,
String createUserName,
LocalDateTime updateDate,
Long updateUserId,
String updateUserName,
Integer storeNo,
String storeName,
Integer formType,
String formCode,
String formName,
Integer formStatus,
String formMark,
Integer reserve1,
String reserve2,
Integer vendorNo,
String vendorName,
Double totalValue,
Integer outStoreNo,
String outStoreName,
Integer groupId,
Integer customerId) {}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.production.converter;
import com.niuan.erp.module.production.controller.dto.BomDto;
import com.niuan.erp.module.production.entity.Bom;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface BomConverter {
Bom toEntity(BomDto dto);
BomDto toDto(Bom entity);
List<BomDto> toDtoList(List<Bom> entities);
}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.production.converter;
import com.niuan.erp.module.production.controller.dto.BomItemDto;
import com.niuan.erp.module.production.entity.BomItem;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface BomItemConverter {
BomItem toEntity(BomItemDto dto);
BomItemDto toDto(BomItem entity);
List<BomItemDto> toDtoList(List<BomItem> entities);
}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.production.converter;
import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.FinishedProductReceiptDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface FinishedProductReceiptConverter {
Document toEntity(FinishedProductReceiptDto dto);
FinishedProductReceiptDto toDto(Document entity);
List<FinishedProductReceiptDto> toDtoList(List<Document> entities);
}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.production.converter;
import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.FinishedProductShipmentDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface FinishedProductShipmentConverter {
Document toEntity(FinishedProductShipmentDto dto);
FinishedProductShipmentDto toDto(Document entity);
List<FinishedProductShipmentDto> toDtoList(List<Document> entities);
}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.production.converter;
import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.ProductionIssueDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface ProductionIssueConverter {
Document toEntity(ProductionIssueDto dto);
ProductionIssueDto toDto(Document entity);
List<ProductionIssueDto> toDtoList(List<Document> entities);
}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.production.converter;
import com.niuan.erp.module.production.controller.dto.ProductionPlanDto;
import com.niuan.erp.module.production.entity.ProductionPlan;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface ProductionPlanConverter {
ProductionPlan toEntity(ProductionPlanDto dto);
ProductionPlanDto toDto(ProductionPlan entity);
List<ProductionPlanDto> toDtoList(List<ProductionPlan> entities);
}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.production.converter;
import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.ProductionReturnDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface ProductionReturnConverter {
Document toEntity(ProductionReturnDto dto);
ProductionReturnDto toDto(Document entity);
List<ProductionReturnDto> toDtoList(List<Document> entities);
}

View File

@@ -0,0 +1,80 @@
package com.niuan.erp.module.production.entity;
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 lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
*
* </p>
*
* @author
* @since 2026-02-11
*/
@Getter
@Setter
@ToString
@TableName("bom_list")
public class Bom implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "Id", type = IdType.AUTO)
private Long id;
@TableField("Status")
private Integer status;
@TableField("CreateDate")
private LocalDateTime createDate;
@TableField("CreateUserId")
private Long createUserId;
@TableField("CreateUserName")
private String createUserName;
@TableField("UpdateDate")
private LocalDateTime updateDate;
@TableField("UpdateUserId")
private Long updateUserId;
@TableField("UpdateUserName")
private String updateUserName;
@TableField("ParentId")
private Long parentId;
@TableField("BomNo")
private String bomNo;
@TableField("Manufacturer")
private String manufacturer;
@TableField("BomName")
private String bomName;
@TableField("Spec")
private String spec;
@TableField("BrandName")
private String brandName;
@TableField("FormMark")
private String formMark;
@TableField("customerName")
private String customerName;
@TableField("CustomerId")
private Integer customerId;
}

View File

@@ -0,0 +1,73 @@
package com.niuan.erp.module.production.entity;
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 lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author
* @since 2026-02-11
*/
@Getter
@Setter
@ToString
@TableName("bom")
public class BomItem implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "Id", type = IdType.AUTO)
private Long id;
@TableField("BomId")
private Integer bomId;
@TableField("ProjectName")
private String projectName;
@TableField("PartNumber")
private String partNumber;
@TableField("ItemPosition")
private String itemPosition;
@TableField("ManufactureCount")
private Integer manufactureCount;
@TableField("SameUseCount")
private Integer sameUseCount;
@TableField("SameUseNum1")
private String sameUseNum1;
@TableField("SameUseNum2")
private String sameUseNum2;
@TableField("SameUseNum3")
private String sameUseNum3;
@TableField("LoseRate")
private Integer loseRate;
@TableField("ManufactureSpec")
private Integer manufactureSpec;
@TableField("ProductMark")
private String productMark;
@TableField("reserve1")
private Integer reserve1;
@TableField("reserve2")
private String reserve2;
}

View File

@@ -0,0 +1,98 @@
package com.niuan.erp.module.production.entity;
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 lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
*
* </p>
*
* @author
* @since 2026-02-11
*/
@Getter
@Setter
@ToString
@TableName("produceorder")
public class ProductionPlan implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "Id", type = IdType.AUTO)
private Long id;
@TableField("Status")
private Integer status;
@TableField("CreateDate")
private LocalDateTime createDate;
@TableField("CreateUserId")
private Long createUserId;
@TableField("CreateUserName")
private String createUserName;
@TableField("UpdateDate")
private LocalDateTime updateDate;
@TableField("UpdateUserId")
private Long updateUserId;
@TableField("UpdateUserName")
private String updateUserName;
@TableField("ProductionNum")
private String productionNum;
@TableField("ProjectName")
private String projectName;
@TableField("ProjectId")
private Integer projectId;
@TableField("ProductionCount")
private Integer productionCount;
@TableField("ProductionStatus")
private Integer productionStatus;
@TableField("ProductionNote")
private String productionNote;
@TableField("ProductionReport")
private String productionReport;
@TableField("ProductionMark")
private String productionMark;
@TableField("reserve1")
private String reserve1;
@TableField("reserve2")
private String reserve2;
@TableField("StoreNo")
private Integer storeNo;
@TableField("StoreName")
private String storeName;
@TableField("GroupId")
private Integer groupId;
@TableField("GroupName")
private String groupName;
@TableField("CustomerId")
private Integer customerId;
}

View File

@@ -0,0 +1,16 @@
package com.niuan.erp.module.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.niuan.erp.module.production.entity.BomItem;
/**
* <p>
* Mapper 接口
* </p>
*
* @author
* @since 2026-02-11
*/
public interface BomItemMapper extends BaseMapper<BomItem> {
}

View File

@@ -0,0 +1,16 @@
package com.niuan.erp.module.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.niuan.erp.module.production.entity.Bom;
/**
* <p>
* Mapper 接口
* </p>
*
* @author
* @since 2026-02-11
*/
public interface BomMapper extends BaseMapper<Bom> {
}

View File

@@ -0,0 +1,16 @@
package com.niuan.erp.module.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.niuan.erp.module.production.entity.ProductionPlan;
/**
* <p>
* Mapper 接口
* </p>
*
* @author
* @since 2026-02-11
*/
public interface ProductionPlanMapper extends BaseMapper<ProductionPlan> {
}

View File

@@ -0,0 +1,23 @@
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.BomItemDto;
import com.niuan.erp.module.production.entity.BomItem;
import java.util.List;
public interface BomItemService {
IPage<BomItemDto> getBomItemPage(BasePageReqParams pageParams, LambdaQueryWrapper<BomItem> wrapper);
void addBomItem(BomItemDto dto);
void updateBomItem(BomItemDto dto);
void deleteBomItem(long id);
void deleteBatch(List<Long> ids);
}

View File

@@ -0,0 +1,23 @@
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.BomDto;
import com.niuan.erp.module.production.entity.Bom;
import java.util.List;
public interface BomService {
IPage<BomDto> getBomPage(BasePageReqParams pageParams, LambdaQueryWrapper<Bom> wrapper);
void addBom(BomDto dto);
void updateBom(BomDto dto);
void deleteBom(long id);
void deleteBatch(List<Long> ids);
}

View File

@@ -0,0 +1,23 @@
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.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.FinishedProductReceiptDto;
import java.util.List;
public interface FinishedProductReceiptService {
IPage<FinishedProductReceiptDto> getFinishedProductReceiptPage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper);
void addFinishedProductReceipt(FinishedProductReceiptDto dto);
void updateFinishedProductReceipt(FinishedProductReceiptDto dto);
void deleteFinishedProductReceipt(long id);
void deleteBatch(List<Long> ids);
}

View File

@@ -0,0 +1,23 @@
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.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.FinishedProductShipmentDto;
import java.util.List;
public interface FinishedProductShipmentService {
IPage<FinishedProductShipmentDto> getFinishedProductShipmentPage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper);
void addFinishedProductShipment(FinishedProductShipmentDto dto);
void updateFinishedProductShipment(FinishedProductShipmentDto dto);
void deleteFinishedProductShipment(long id);
void deleteBatch(List<Long> ids);
}

View File

@@ -0,0 +1,23 @@
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.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.ProductionIssueDto;
import java.util.List;
public interface ProductionIssueService {
IPage<ProductionIssueDto> getProductionIssuePage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper);
void addProductionIssue(ProductionIssueDto dto);
void updateProductionIssue(ProductionIssueDto dto);
void deleteProductionIssue(long id);
void deleteBatch(List<Long> ids);
}

View File

@@ -0,0 +1,23 @@
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.ProductionPlanDto;
import com.niuan.erp.module.production.entity.ProductionPlan;
import java.util.List;
public interface ProductionPlanService {
IPage<ProductionPlanDto> getProductionPlanPage(BasePageReqParams pageParams, LambdaQueryWrapper<ProductionPlan> wrapper);
void addProductionPlan(ProductionPlanDto dto);
void updateProductionPlan(ProductionPlanDto dto);
void deleteProductionPlan(long id);
void deleteBatch(List<Long> ids);
}

View File

@@ -0,0 +1,23 @@
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.common.entity.Document;
import com.niuan.erp.module.production.controller.dto.ProductionReturnDto;
import java.util.List;
public interface ProductionReturnService {
IPage<ProductionReturnDto> getProductionReturnPage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper);
void addProductionReturn(ProductionReturnDto dto);
void updateProductionReturn(ProductionReturnDto dto);
void deleteProductionReturn(long id);
void deleteBatch(List<Long> ids);
}

View File

@@ -0,0 +1,56 @@
package com.niuan.erp.module.production.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.module.production.controller.dto.BomItemDto;
import com.niuan.erp.module.production.converter.BomItemConverter;
import com.niuan.erp.module.production.entity.BomItem;
import com.niuan.erp.module.production.mapper.BomItemMapper;
import com.niuan.erp.module.production.service.BomItemService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
@RequiredArgsConstructor
public class BomItemServiceImpl extends ServiceImpl<BomItemMapper, BomItem> implements BomItemService {
private final BomItemConverter bomItemConverter;
@Override
public IPage<BomItemDto> getBomItemPage(BasePageReqParams pageParams, LambdaQueryWrapper<BomItem> wrapper) {
IPage<BomItem> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper);
return result.convert(bomItemConverter::toDto);
}
@Override
public void addBomItem(BomItemDto dto) {
BomItem entity = bomItemConverter.toEntity(dto);
this.baseMapper.insert(entity);
}
@Override
public void updateBomItem(BomItemDto dto) {
BomItem entity = bomItemConverter.toEntity(dto);
this.baseMapper.updateById(entity);
}
@Override
public void deleteBomItem(long id) {
this.baseMapper.deleteById(id);
}
@Override
public void deleteBatch(List<Long> ids) {
this.baseMapper.deleteByIds(ids);
}
}

View File

@@ -0,0 +1,65 @@
package com.niuan.erp.module.production.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.utils.SecurityUtils;
import com.niuan.erp.module.production.controller.dto.BomDto;
import com.niuan.erp.module.production.converter.BomConverter;
import com.niuan.erp.module.production.entity.Bom;
import com.niuan.erp.module.production.mapper.BomMapper;
import com.niuan.erp.module.production.service.BomService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
@Transactional
@RequiredArgsConstructor
public class BomServiceImpl extends ServiceImpl<BomMapper, Bom> implements BomService {
private final BomConverter bomConverter;
@Override
public IPage<BomDto> getBomPage(BasePageReqParams pageParams, LambdaQueryWrapper<Bom> wrapper) {
IPage<Bom> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper);
return result.convert(bomConverter::toDto);
}
@Override
public void addBom(BomDto dto) {
Bom entity = bomConverter.toEntity(dto);
entity.setCreateUserId(SecurityUtils.getUserId());
entity.setCreateUserName(SecurityUtils.getUserName());
entity.setCreateDate(LocalDateTime.now());
entity.setStatus(0);
this.baseMapper.insert(entity);
}
@Override
public void updateBom(BomDto dto) {
Bom entity = bomConverter.toEntity(dto);
entity.setUpdateUserId(SecurityUtils.getUserId());
entity.setUpdateUserName(SecurityUtils.getUserName());
entity.setUpdateDate(LocalDateTime.now());
this.baseMapper.updateById(entity);
}
@Override
public void deleteBom(long id) {
this.baseMapper.deleteById(id);
}
@Override
public void deleteBatch(List<Long> ids) {
this.baseMapper.deleteByIds(ids);
}
}

View File

@@ -0,0 +1,65 @@
package com.niuan.erp.module.production.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.utils.SecurityUtils;
import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.common.mapper.DocumentMapper;
import com.niuan.erp.module.production.controller.dto.FinishedProductReceiptDto;
import com.niuan.erp.module.production.converter.FinishedProductReceiptConverter;
import com.niuan.erp.module.production.service.FinishedProductReceiptService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
@Transactional
@RequiredArgsConstructor
public class FinishedProductReceiptServiceImpl extends ServiceImpl<DocumentMapper, Document> implements FinishedProductReceiptService {
private final FinishedProductReceiptConverter finishedProductReceiptConverter;
@Override
public IPage<FinishedProductReceiptDto> getFinishedProductReceiptPage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper) {
IPage<Document> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper);
return result.convert(finishedProductReceiptConverter::toDto);
}
@Override
public void addFinishedProductReceipt(FinishedProductReceiptDto dto) {
Document entity = finishedProductReceiptConverter.toEntity(dto);
entity.setCreateUserId(SecurityUtils.getUserId());
entity.setCreateUserName(SecurityUtils.getUserName());
entity.setCreateDate(LocalDateTime.now());
entity.setStatus(0);
this.baseMapper.insert(entity);
}
@Override
public void updateFinishedProductReceipt(FinishedProductReceiptDto dto) {
Document entity = finishedProductReceiptConverter.toEntity(dto);
entity.setUpdateUserId(SecurityUtils.getUserId());
entity.setUpdateUserName(SecurityUtils.getUserName());
entity.setUpdateDate(LocalDateTime.now());
this.baseMapper.updateById(entity);
}
@Override
public void deleteFinishedProductReceipt(long id) {
this.baseMapper.deleteById(id);
}
@Override
public void deleteBatch(List<Long> ids) {
this.baseMapper.deleteByIds(ids);
}
}

View File

@@ -0,0 +1,65 @@
package com.niuan.erp.module.production.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.utils.SecurityUtils;
import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.common.mapper.DocumentMapper;
import com.niuan.erp.module.production.controller.dto.FinishedProductShipmentDto;
import com.niuan.erp.module.production.converter.FinishedProductShipmentConverter;
import com.niuan.erp.module.production.service.FinishedProductShipmentService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
@Transactional
@RequiredArgsConstructor
public class FinishedProductShipmentServiceImpl extends ServiceImpl<DocumentMapper, Document> implements FinishedProductShipmentService {
private final FinishedProductShipmentConverter finishedProductShipmentConverter;
@Override
public IPage<FinishedProductShipmentDto> getFinishedProductShipmentPage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper) {
IPage<Document> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper);
return result.convert(finishedProductShipmentConverter::toDto);
}
@Override
public void addFinishedProductShipment(FinishedProductShipmentDto dto) {
Document entity = finishedProductShipmentConverter.toEntity(dto);
entity.setCreateUserId(SecurityUtils.getUserId());
entity.setCreateUserName(SecurityUtils.getUserName());
entity.setCreateDate(LocalDateTime.now());
entity.setStatus(0);
this.baseMapper.insert(entity);
}
@Override
public void updateFinishedProductShipment(FinishedProductShipmentDto dto) {
Document entity = finishedProductShipmentConverter.toEntity(dto);
entity.setUpdateUserId(SecurityUtils.getUserId());
entity.setUpdateUserName(SecurityUtils.getUserName());
entity.setUpdateDate(LocalDateTime.now());
this.baseMapper.updateById(entity);
}
@Override
public void deleteFinishedProductShipment(long id) {
this.baseMapper.deleteById(id);
}
@Override
public void deleteBatch(List<Long> ids) {
this.baseMapper.deleteByIds(ids);
}
}

View File

@@ -0,0 +1,65 @@
package com.niuan.erp.module.production.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.utils.SecurityUtils;
import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.common.mapper.DocumentMapper;
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 lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
@Transactional
@RequiredArgsConstructor
public class ProductionIssueServiceImpl extends ServiceImpl<DocumentMapper, Document> implements ProductionIssueService {
private final ProductionIssueConverter productionIssueConverter;
@Override
public IPage<ProductionIssueDto> getProductionIssuePage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper) {
IPage<Document> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper);
return result.convert(productionIssueConverter::toDto);
}
@Override
public void addProductionIssue(ProductionIssueDto dto) {
Document entity = productionIssueConverter.toEntity(dto);
entity.setCreateUserId(SecurityUtils.getUserId());
entity.setCreateUserName(SecurityUtils.getUserName());
entity.setCreateDate(LocalDateTime.now());
entity.setStatus(0);
this.baseMapper.insert(entity);
}
@Override
public void updateProductionIssue(ProductionIssueDto dto) {
Document entity = productionIssueConverter.toEntity(dto);
entity.setUpdateUserId(SecurityUtils.getUserId());
entity.setUpdateUserName(SecurityUtils.getUserName());
entity.setUpdateDate(LocalDateTime.now());
this.baseMapper.updateById(entity);
}
@Override
public void deleteProductionIssue(long id) {
this.baseMapper.deleteById(id);
}
@Override
public void deleteBatch(List<Long> ids) {
this.baseMapper.deleteByIds(ids);
}
}

View File

@@ -0,0 +1,65 @@
package com.niuan.erp.module.production.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.utils.SecurityUtils;
import com.niuan.erp.module.production.controller.dto.ProductionPlanDto;
import com.niuan.erp.module.production.converter.ProductionPlanConverter;
import com.niuan.erp.module.production.entity.ProductionPlan;
import com.niuan.erp.module.production.mapper.ProductionPlanMapper;
import com.niuan.erp.module.production.service.ProductionPlanService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
@Transactional
@RequiredArgsConstructor
public class ProductionPlanServiceImpl extends ServiceImpl<ProductionPlanMapper, ProductionPlan> implements ProductionPlanService {
private final ProductionPlanConverter productionPlanConverter;
@Override
public IPage<ProductionPlanDto> getProductionPlanPage(BasePageReqParams pageParams, LambdaQueryWrapper<ProductionPlan> wrapper) {
IPage<ProductionPlan> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper);
return result.convert(productionPlanConverter::toDto);
}
@Override
public void addProductionPlan(ProductionPlanDto dto) {
ProductionPlan entity = productionPlanConverter.toEntity(dto);
entity.setCreateUserId(SecurityUtils.getUserId());
entity.setCreateUserName(SecurityUtils.getUserName());
entity.setCreateDate(LocalDateTime.now());
entity.setStatus(0);
this.baseMapper.insert(entity);
}
@Override
public void updateProductionPlan(ProductionPlanDto dto) {
ProductionPlan entity = productionPlanConverter.toEntity(dto);
entity.setUpdateUserId(SecurityUtils.getUserId());
entity.setUpdateUserName(SecurityUtils.getUserName());
entity.setUpdateDate(LocalDateTime.now());
this.baseMapper.updateById(entity);
}
@Override
public void deleteProductionPlan(long id) {
this.baseMapper.deleteById(id);
}
@Override
public void deleteBatch(List<Long> ids) {
this.baseMapper.deleteByIds(ids);
}
}

View File

@@ -0,0 +1,65 @@
package com.niuan.erp.module.production.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.utils.SecurityUtils;
import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.common.mapper.DocumentMapper;
import com.niuan.erp.module.production.controller.dto.ProductionReturnDto;
import com.niuan.erp.module.production.converter.ProductionReturnConverter;
import com.niuan.erp.module.production.service.ProductionReturnService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Service
@Transactional
@RequiredArgsConstructor
public class ProductionReturnServiceImpl extends ServiceImpl<DocumentMapper, Document> implements ProductionReturnService {
private final ProductionReturnConverter productionReturnConverter;
@Override
public IPage<ProductionReturnDto> getProductionReturnPage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper) {
IPage<Document> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper);
return result.convert(productionReturnConverter::toDto);
}
@Override
public void addProductionReturn(ProductionReturnDto dto) {
Document entity = productionReturnConverter.toEntity(dto);
entity.setCreateUserId(SecurityUtils.getUserId());
entity.setCreateUserName(SecurityUtils.getUserName());
entity.setCreateDate(LocalDateTime.now());
entity.setStatus(0);
this.baseMapper.insert(entity);
}
@Override
public void updateProductionReturn(ProductionReturnDto dto) {
Document entity = productionReturnConverter.toEntity(dto);
entity.setUpdateUserId(SecurityUtils.getUserId());
entity.setUpdateUserName(SecurityUtils.getUserName());
entity.setUpdateDate(LocalDateTime.now());
this.baseMapper.updateById(entity);
}
@Override
public void deleteProductionReturn(long id) {
this.baseMapper.deleteById(id);
}
@Override
public void deleteBatch(List<Long> ids) {
this.baseMapper.deleteByIds(ids);
}
}

View File

@@ -0,0 +1,76 @@
package com.niuan.erp.module.purchase.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.common.entity.Document;
import com.niuan.erp.module.purchase.controller.dto.PurchaseOrderDto;
import com.niuan.erp.module.purchase.service.PurchaseOrderService;
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 = "PurchaseOrder")
@ModuleLog("PurchaseOrder管理")
@RestController
@RequestMapping("/purchase/purchaseorder")
@RequiredArgsConstructor
public class PurchaseOrderController {
private final PurchaseOrderService purchaseOrderService;
@Operation(summary = "分页查询PurchaseOrder数据", operationId = "getPurchaseOrderPage")
@GetMapping("/getPurchaseOrderPage")
@PreAuthorize("hasAuthority('purchaseorder:index')")
public BaseResult<IPage<PurchaseOrderDto>> getPurchaseOrderPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) PurchaseOrderDto searchParams) {
var wrapper = new LambdaQueryWrapper<Document>();
return BaseResult.successWithData(purchaseOrderService.getPurchaseOrderPage(pageParams, wrapper));
}
@ApiLog(type = OperationType.ADD, remark = "新增一条PurchaseOrder记录")
@Operation(summary = "新增PurchaseOrder", operationId = "addPurchaseOrder")
@PostMapping("/addPurchaseOrder")
@PreAuthorize("hasAuthority('purchaseorder:add')")
public BaseResult<?> addPurchaseOrder(@Validated(Add.class) @RequestBody PurchaseOrderDto dto) {
purchaseOrderService.addPurchaseOrder(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.UPDATE, remark = "更新一条PurchaseOrder记录")
@Operation(summary = "更新PurchaseOrder", operationId = "updatePurchaseOrder")
@PostMapping("/updatePurchaseOrder")
@PreAuthorize("hasAuthority('purchaseorder:update')")
public BaseResult<?> updatePurchaseOrder(@Validated(Update.class) @RequestBody PurchaseOrderDto dto) {
purchaseOrderService.updatePurchaseOrder(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "删除一条PurchaseOrder记录")
@Operation(summary = "删除PurchaseOrder", operationId = "deletePurchaseOrder")
@PostMapping("/deletePurchaseOrder")
@PreAuthorize("hasAuthority('purchaseorder:delete')")
public BaseResult<?> deletePurchaseOrder(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
purchaseOrderService.deletePurchaseOrder(req.id());
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "批量删除PurchaseOrder记录")
@Operation(summary = "批量删除PurchaseOrder", operationId = "deletePurchaseOrderBatch")
@PostMapping("/deletePurchaseOrderBatch")
@PreAuthorize("hasAuthority('purchaseorder:deleteBatch')")
public BaseResult<?> deletePurchaseOrderBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
purchaseOrderService.deleteBatch(req.ids());
return BaseResult.success();
}
}

View File

@@ -0,0 +1,82 @@
package com.niuan.erp.module.purchase.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.purchase.controller.dto.PurchasePlanDto;
import com.niuan.erp.module.purchase.entity.PurchasePlan;
import com.niuan.erp.module.purchase.service.PurchasePlanService;
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 = "PurchasePlan")
@ModuleLog("PurchasePlan管理")
@RestController
@RequestMapping("/purchase/purchaseplan")
@RequiredArgsConstructor
public class PurchasePlanController {
private final PurchasePlanService purchasePlanService;
@Operation(summary = "分页查询PurchasePlan数据", operationId = "getPurchasePlanPage")
@GetMapping("/getPurchasePlanPage")
@PreAuthorize("hasAuthority('purchaseplan:index')")
public BaseResult<IPage<PurchasePlanDto>> getPurchasePlanPage(@Validated BasePageReqParams pageParams,
@Validated(Get.class) PurchasePlanDto searchParams) {
var wrapper = new LambdaQueryWrapper<PurchasePlan>();
if (searchParams != null) {
if (StringUtils.hasText(searchParams.vendorName())) {
wrapper.like(PurchasePlan::getVendorName, searchParams.vendorName());
}
}
return BaseResult.successWithData(purchasePlanService.getPurchasePlanPage(pageParams, wrapper));
}
@ApiLog(type = OperationType.ADD, remark = "新增一条PurchasePlan记录")
@Operation(summary = "新增PurchasePlan", operationId = "addPurchasePlan")
@PostMapping("/addPurchasePlan")
@PreAuthorize("hasAuthority('purchaseplan:add')")
public BaseResult<?> addPurchasePlan(@Validated(Add.class) @RequestBody PurchasePlanDto dto) {
purchasePlanService.addPurchasePlan(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.UPDATE, remark = "更新一条PurchasePlan记录")
@Operation(summary = "更新PurchasePlan", operationId = "updatePurchasePlan")
@PostMapping("/updatePurchasePlan")
@PreAuthorize("hasAuthority('purchaseplan:update')")
public BaseResult<?> updatePurchasePlan(@Validated(Update.class) @RequestBody PurchasePlanDto dto) {
purchasePlanService.updatePurchasePlan(dto);
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "删除一条PurchasePlan记录")
@Operation(summary = "删除PurchasePlan", operationId = "deletePurchasePlan")
@PostMapping("/deletePurchasePlan")
@PreAuthorize("hasAuthority('purchaseplan:delete')")
public BaseResult<?> deletePurchasePlan(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
purchasePlanService.deletePurchasePlan(req.id());
return BaseResult.success();
}
@ApiLog(type = OperationType.DELETE, remark = "批量删除PurchasePlan记录")
@Operation(summary = "批量删除PurchasePlan", operationId = "deletePurchasePlanBatch")
@PostMapping("/deletePurchasePlanBatch")
@PreAuthorize("hasAuthority('purchaseplan:deleteBatch')")
public BaseResult<?> deletePurchasePlanBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
purchasePlanService.deleteBatch(req.ids());
return BaseResult.success();
}
}

View File

@@ -0,0 +1,29 @@
package com.niuan.erp.module.purchase.controller.dto;
import java.time.LocalDateTime;
public record PurchaseOrderDto(
Long id,
Integer status,
LocalDateTime createDate,
Long createUserId,
String createUserName,
LocalDateTime updateDate,
Long updateUserId,
String updateUserName,
Integer storeNo,
String storeName,
Integer formType,
String formCode,
String formName,
Integer formStatus,
String formMark,
Integer reserve1,
String reserve2,
Integer vendorNo,
String vendorName,
Double totalValue,
Integer outStoreNo,
String outStoreName,
Integer groupId,
Integer customerId) {}

View File

@@ -0,0 +1,25 @@
package com.niuan.erp.module.purchase.controller.dto;
import java.time.LocalDateTime;
public record PurchaseOrderItemDto(
Long id,
Integer status,
LocalDateTime createDate,
Long createUserId,
String createUserName,
LocalDateTime updateDate,
Long updateUserId,
String updateUserName,
Integer documentNo,
String documentCode,
String projectName,
String partNumber,
Integer purchaseCount,
Double price,
Double totalPrice,
String purchaseMark,
Integer reserve1,
String reserve2,
Integer receiptCount,
Long partId) {}

View File

@@ -0,0 +1,21 @@
package com.niuan.erp.module.purchase.controller.dto;
import java.time.LocalDateTime;
public record PurchasePlanDto(
Long id,
Long createUserId,
String createUserName,
LocalDateTime createDate,
LocalDateTime updateDate,
Integer updateUserId,
LocalDateTime updateUserName,
Integer status,
String planNo,
Long vendorId,
String vendorName,
Long storeNo,
Integer planStatus,
String storeName,
String remask,
String planName) {}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.purchase.controller.dto;
import java.math.BigDecimal;
public record PurchasePlanItemDto(
Long id,
Long planId,
String partNumber,
BigDecimal price,
Integer purchaseCount,
BigDecimal totalPrice,
Integer completeCount,
Integer currentCount,
Integer completeStatus,
Long partId) {}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.purchase.converter;
import com.niuan.erp.module.common.entity.Document;
import com.niuan.erp.module.purchase.controller.dto.PurchaseOrderDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface PurchaseOrderConverter {
Document toEntity(PurchaseOrderDto dto);
PurchaseOrderDto toDto(Document entity);
List<PurchaseOrderDto> toDtoList(List<Document> entities);
}

View File

@@ -0,0 +1,15 @@
package com.niuan.erp.module.purchase.converter;
import com.niuan.erp.module.purchase.controller.dto.PurchaseOrderItemDto;
import com.niuan.erp.module.purchase.entity.PurchaseOrderItem;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface PurchaseOrderItemConverter {
PurchaseOrderItem toEntity(PurchaseOrderItemDto dto);
PurchaseOrderItemDto toDto(PurchaseOrderItem entity);
List<PurchaseOrderItemDto> toDtoList(List<PurchaseOrderItem> entities);
}

Some files were not shown because too many files have changed in this diff Show More