初始化项目

main
HUOJIN\92525 2025-03-14 16:54:25 +08:00
commit fe1ed442a2
675 changed files with 46282 additions and 0 deletions

25
.gitignore vendored 100644
View File

@ -0,0 +1,25 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### front ###
**/dist
**/node_modules
**/.vscode

21
LICENSE 100644
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 1024-lab
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

81
README.md 100644
View File

@ -0,0 +1,81 @@
### **SmartAdmin**
**SmartAdmin** 由 **中国·洛阳** [1024创新实验室](https://www.1024lab.net/) 基于SpringBoot2/3+Sa-Token+Mybatis-Plus 和 Vue3+Ant Design Vue+Uni-App+Uni-UI并以 <font color="#DC143C">**「高质量代码」为核心,「简洁、高效、安全」**</font>的快速开发平台。
**<font color="#DC143C">国内首个满足《网络安全-三级等保》、《数据安全》</font>** 功能要求,支持登录限制、接口国产加解密、数据脱敏等一系列安全要求。
前端提供 **<font color="#DC143C">JavaScript和TypeScript双版本</font>**,后端提供 **<font color="#DC143C">Java8+SpringBoot2.X和Java17+SpringBoot3.X 双版本</font>**。
同时 **<font color="#DC143C">重磅开源</font>** 开源六年来 **<font color="#DC143C">千余家企业验证过且正在使用</font>** 的代码规范: **<font color="#DC143C">《高质量代码思想》、《Vue3规范》、《Java规范》</font>** ,让大家在这浮躁的世界里感受到一股把代码写好的清流!同时又能节省大量时间,减少加班,快乐工作,保持谦逊,保持学习,**<font color="#DC143C">热爱代码,更热爱生活</font>**
### **技术体系**
- 前端JavaScript/TypeScript + Vue3 + Vite5 + Pinia + Ant Design Vue 4.X
- 移动端uniapp (vue3版本) + uni-ui + 同时支持APP、小程序、H5
- 后端Java8/17 + SpringBoot2/3 + Sa Token + Mybatis-plus + 多种数据库
- 电脑在线预览:[https://preview.smartadmin.vip](https://preview.smartadmin.vip)
- 官方文档:[https://smartadmin.vip](https://smartadmin.vip)
- 移动端在线预览:[https://app.smartadmin.vip](https://app.smartadmin.vip/#/pages/login/login)
### **理念与思想**
- 我们分享的不是徒劳无功的各种功能,而是必须有的功能,如:数据变动记录、系统说明文档、版本更新记录、意见反馈、日志、心跳、单号生成器等等。
- 我们分享的还有经过上百家公司验证过的前端、后端、vue3等代码规范好的规范能让我敲下的每行代码更铿锵有力
- **我们推崇高质量的代码,身为开发,代码即利剑,键盘上一套行云流水,宛如侠客,事了拂衣去,深藏身与名。**
- **我们推崇团队的高度配合默契、互相帮助,从不加班,而不是一看到别人的代码就头皮发麻,留其 [996.ICU](https://baike.baidu.com/item/996.ICU) 加班。**
- **我们主动思考,保持谦逊,保持学习,热爱代码,更热爱生活。**
- **<font color="#DC143C">我们希望你希望你能花费3分钟认真阅读下面的每一个点让你感受从未有过的技术体验</font>**
### **功能亮点图**
<table>
<tr>
<td><img src="https://img.smartadmin.1024lab.net/smart-admin-v3/login/login-bg.png"/></td>
<td><img src="https://img.smartadmin.1024lab.net/smart-admin-v3/cut/home.png"/></td>
</tr>
<tr>
<td><img src="https://img.smartadmin.1024lab.net/smart-admin-v3/login/login-fail-log.png"/></td>
<td><img src="https://img.smartadmin.1024lab.net/smart-admin-v3/cut/doc.png"/></td>
</tr>
<tr>
<td><img src="https://img.smartadmin.1024lab.net/smart-admin-v3/cut/code.png"/></td>
<td><img src="https://img.smartadmin.1024lab.net/smart-admin-v3/cut/git-diff.png"/></td>
</tr>
<tr>
<td><img src="https://img.smartadmin.1024lab.net/smart-app/app1.png"/></td>
<td><img src="https://img.smartadmin.1024lab.net/smart-app/app2.png"/></td>
</tr>
<tr>
<td><img src="https://img.smartadmin.1024lab.net/smart-admin-v3/cut/front.png"/></td>
<td><img src="https://img.smartadmin.1024lab.net/smart-admin-v3/cut/back.png"/></td>
</tr>
</table>
### **功能亮点**
- **<font color="#DC143C">安全体系</font>**:满足国家三级等保要求,如双因子登录、密码加密、密码复杂度要求、登录错误次数锁定、登录超时退出、数据脱敏等网络安全和数据安全功能
- **<font color="#DC143C">接口加解密</font>**:支持请求参数和返回内容进行加解密操作,支持国产加密算法和其他国外加密算法
- **表格自定义列**:支持用户自定义列,并能将用户自定义列持久化到数据库
- **数据变更记录**支持基于git diff插件的数据变更记录查看数据变化更直观方便
- **在线文档**:支持右侧帮助文档(类似阿里云控制台右侧帮助文档效果)、支持意见反馈、版本记录 等功能
- **OA办公**:公司信息(发票、银行、员工等)、通知公告(阅读记录、次数等)
- **日志、监控**服务器心跳日志、登录日志、操作日志IP、浏览器、操作系统等设备信息
- **系统功能**:员工、部门、角色、权限、菜单、水印、文件管理、系统参数、数据字典、单号生成 等
- **代码生成** 基于每个表的配置、在线预览代码、下载 等
- **以上只是一些举例,更多灿若繁星的惊喜和细节,等待着你的发现!**[SmartAdmin 业内独有功能亮点](https://smartadmin.vip)
### **代码亮点**
- **【前端-双版本】:** 提供 js 和 ts 双版本,目录结构及其清晰
- **【前端-常量维护】:** vue-enum拒绝出现魔法数字常量枚举不可维护的现象
- **【前端-命名】:** 业内最好的api、常量等命名和写法
- **【前端-多环境支持】:** 独有的本地、开发、测试、预发布、生产 5个env环境配置文件
- **【前端-layout代码】** 业内代码最清晰的layout布局写法小白都能看懂
- **【前端-main.js】** 业内可能只有我们把main.js中的router加载方式写对了
- ----华丽前后端分割线----
- **【后端-独有目录结构】:** 业内独有的高质量的 Java代码分包结构适合大、中、小型项目结构非常清晰
- **【后端-公共配置文件】:** 业内独有的共用配置文件维护,简化共同配置
- **【后端-返回码维护】:** 业内独创的请求返回码维护,非常值得一看
- **【后端-四层架构】:** 四层架构controller, service, manager, dao为什么要有四层
- **【后端-多环境】:** maven多环境开发、测试、预发布、生产 环境配置
- **【后端-系统钩子】:** smart-reload为系统预留钩子动态加载在不重启程序前提下执行一些代码
- 以上只是沧海一粟,更多的细节等待你的发现![去查看](https://smartadmin.vip)

View File

@ -0,0 +1,431 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.1024lab</groupId>
<artifactId>sa-parent</artifactId>
<version>3.0.0</version>
<packaging>pom</packaging>
<name>sa-parent</name>
<description>SmartAdmin project</description>
<modules>
<module>sa-base</module>
<module>sa-admin</module>
</modules>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<springboot.version>3.3.1</springboot.version>
<spring-mock.version>2.0.8</spring-mock.version>
<spring-security-crypto.version>6.4.3</spring-security-crypto.version>
<mybatis-plus.version>3.5.7</mybatis-plus.version>
<p6spy.version>3.9.1</p6spy.version>
<knife4j.version>4.4.0</knife4j.version>
<fastjson.version>2.0.52</fastjson.version>
<druid.version>1.2.23</druid.version>
<google-linkedhashmap.version>1.4.2</google-linkedhashmap.version>
<google-guava.version>20.0</google-guava.version>
<user-agent-utils.version>1.21</user-agent-utils.version>
<reflections.version>0.9.11</reflections.version>
<commons-io.version>2.15.0</commons-io.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<commons-collections4.version>4.4</commons-collections4.version>
<commons-compress.version>1.26.0</commons-compress.version>
<commons-codec.version>1.13</commons-codec.version>
<commons-text.version>1.9</commons-text.version>
<xerces.version>2.12.0</xerces.version>
<fast-excel.version>1.0.0</fast-excel.version>
<poi.version>5.2.4</poi.version>
<ooxml-schemas.version>1.4</ooxml-schemas.version>
<aws-java-sdk.version>1.11.842</aws-java-sdk.version>
<log4j-spring-boot.version>2.23.1</log4j-spring-boot.version>
<hutool.version>5.8.29</hutool.version>
<velocity-engine-core.version>2.3</velocity-engine-core.version>
<jjwt.version>0.9.1</jjwt.version>
<jwks-rsa.version>0.9.0</jwks-rsa.version>
<velocity-tools.version>3.1</velocity-tools.version>
<sa-token.version>1.37.0</sa-token.version>
<ip2region.version>2.7.0</ip2region.version>
<bcprov.version>1.80</bcprov.version>
<jackson-datatype-jsr310.version>2.13.4</jackson-datatype-jsr310.version>
<jackson-dataformat-yaml.version>2.16.1</jackson-dataformat-yaml.version>
<smartdb.version>1.2.0</smartdb.version>
<redisson.version>3.25.0</redisson.version>
<snakeyaml.version>2.2</snakeyaml.version>
<freemarker.version>2.3.33</freemarker.version>
<jsoup.version>1.18.1</jsoup.version>
<tika.version>3.1.0</tika.version>
</properties>
<dependencyManagement>
<dependencies>
<!--BOM begin-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--BOM end-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
<version>${spring-security-crypto.version}</version>
</dependency>
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>${p6spy.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
<artifactId>concurrentlinkedhashmap-lru</artifactId>
<version>${google-linkedhashmap.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${google-guava.version}</version>
</dependency>
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>${user-agent-utils.version}</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>${commons-compress.version}</version>
</dependency>
<dependency>
<artifactId>commons-codec</artifactId>
<groupId>commons-codec</groupId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>${aws-java-sdk.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>${commons-text.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>jwks-rsa</artifactId>
<version>${jwks-rsa.version}</version>
</dependency>
<!--velocity begin-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity-engine-core.version}</version>
</dependency>
<dependency>
<groupId>org.apache.velocity.tools</groupId>
<artifactId>velocity-tools-generic</artifactId>
<version>${velocity-tools.version}</version>
</dependency>
<!--velocity end-->
<!-- Sa-Token 权限认证在线文档https://sa-token.cc -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- sa-token end -->
<!--ip 地址-->
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>${ip2region.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>${bcprov.version}</version>
</dependency>
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>${fast-excel.version}</version>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>${ooxml-schemas.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson-datatype-jsr310.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson-dataformat-yaml.version}</version>
</dependency>
<dependency>
<groupId>net.1024lab</groupId>
<artifactId>smartdb</artifactId>
<version>${smartdb.version}</version>
</dependency>
<!-- redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson.version}</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml.version}</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>${tika.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>${project.name}-${profiles.active}-${project.version}</finalName>
<resources>
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
<excludes>
<exclude>dev/*</exclude>
<exclude>test/*</exclude>
<exclude>pre/*</exclude>
<exclude>prod/*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources/${profiles.active}</directory>
<filtering>true</filtering>
<includes>
<include>*.yaml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources/${profiles.active}</directory>
<filtering>false</filtering>
<includes>
<include>*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<compilerArgument>-parameters</compilerArgument>
<source>17</source>
<target>17</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
</plugin>
</plugins>
</build>
<profiles>
<!--开发环境-->
<profile>
<id>dev</id>
<properties>
<profiles.active>dev</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--测试环境-->
<profile>
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
</properties>
</profile>
<!--预发布环境-->
<profile>
<id>pre</id>
<properties>
<profiles.active>pre</profiles.active>
</properties>
</profile>
<!--生产环境-->
<profile>
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
</properties>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,47 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.1024lab</groupId>
<artifactId>sa-parent</artifactId>
<version>3.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>sa-admin</artifactId>
<version>3.0.0</version>
<packaging>jar</packaging>
<name>sa-admin</name>
<description>sa-admin project</description>
<dependencies>
<dependency>
<groupId>net.1024lab</groupId>
<artifactId>sa-base</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>net.lab1024.sa.admin.AdminApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,40 @@
package net.lab1024.sa.admin;
import net.lab1024.sa.base.listener.Ip2RegionListener;
import net.lab1024.sa.base.listener.LogVariableListener;
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* SmartAdmin
*
* @Author 1024-:
* @Date 2022-08-29 21:00:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@EnableCaching
@EnableScheduling
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@ComponentScan(AdminApplication.COMPONENT_SCAN)
@MapperScan(value = AdminApplication.COMPONENT_SCAN, annotationClass = Mapper.class)
@SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class})
public class AdminApplication {
public static final String COMPONENT_SCAN = "net.lab1024.sa";
public static void main(String[] args) {
SpringApplication application = new SpringApplication(AdminApplication.class);
// 添加 日志监听器,使 log4j2-spring.xml 可以间接读取到配置文件的属性
application.addListeners(new LogVariableListener(), new Ip2RegionListener());
application.run(args);
}
}

View File

@ -0,0 +1,41 @@
package net.lab1024.sa.admin.config;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.interceptor.AdminInterceptor;
import net.lab1024.sa.base.config.SwaggerConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* web
*
* @Author 1024-:
* @Date 2021-09-02 20:21:10
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Resource
private AdminInterceptor adminInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(adminInterceptor)
.excludePathPatterns(SwaggerConfig.SWAGGER_WHITELIST)
.addPathPatterns("/**");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}

View File

@ -0,0 +1,28 @@
package net.lab1024.sa.admin.config;
import net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect;
import net.lab1024.sa.base.module.support.operatelog.core.OperateLogConfig;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @Author 1024:
* @Date 2022-05-30 21:22:12
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Configuration
public class OperateLogAspectConfig extends OperateLogAspect{
/**
*
*/
@Override
public OperateLogConfig getOperateLogConfig() {
return OperateLogConfig.builder().corePoolSize(1).queueCapacity(10000).build();
}
}

View File

@ -0,0 +1,66 @@
package net.lab1024.sa.admin.constant;
import net.lab1024.sa.base.constant.CacheKeyConst;
/**
* key
*
* @Author 1024-:
* @Date 2022-01-07 18:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
public class AdminCacheConst extends CacheKeyConst {
public static class Department {
/**
*
*/
public static final String DEPARTMENT_LIST_CACHE = "department_list_cache";
/**
* map
*/
public static final String DEPARTMENT_MAP_CACHE = "department_map_cache";
/**
*
*/
public static final String DEPARTMENT_TREE_CACHE = "department_tree_cache";
/**
* id
*/
public static final String DEPARTMENT_SELF_CHILDREN_CACHE = "department_self_children_cache";
/**
*
*/
public static final String DEPARTMENT_PATH_CACHE = "department_path_cache";
}
/**
*
*/
public static class Category {
public static final String CATEGORY_ENTITY = "category_cache";
public static final String CATEGORY_SUB = "category_sub_cache";
public static final String CATEGORY_TREE = "category_tree_cache";
}
/**
*
*/
public static class Base {
public static final String AREA_ENTITY = "area_cache";
public static final String LOCATION_ENTITY = "location_cache";
}
}

View File

@ -0,0 +1,17 @@
package net.lab1024.sa.admin.constant;
import net.lab1024.sa.base.constant.RedisKeyConst;
/**
* redis key
*
* @Author 1024-:
* @Date 2022-01-07 18:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
public class AdminRedisKeyConst extends RedisKeyConst {
}

View File

@ -0,0 +1,57 @@
package net.lab1024.sa.admin.constant;
import net.lab1024.sa.base.constant.SwaggerTagConst;
/**
* swagger
*
* @Author 1024:
* @Date 2022-01-07 18:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
public class AdminSwaggerTagConst extends SwaggerTagConst {
public static class Business {
public static final String MANAGER_CATEGORY = "ERP进销存-分类管理";
public static final String MANAGER_GOODS = "ERP进销存-商品管理";
public static final String OA_BANK = "OA办公-银行卡信息";
public static final String OA_ENTERPRISE = "OA办公-企业";
public static final String OA_INVOICE = "OA办公-发票信息";
public static final String OA_NOTICE = "OA办公-通知公告";
}
public static class System {
public static final String SYSTEM_LOGIN = "系统-员工登录";
public static final String SYSTEM_EMPLOYEE = "系统-员工管理";
public static final String SYSTEM_DEPARTMENT = "系统-部门管理";
public static final String SYSTEM_MENU = "系统-菜单";
public static final String SYSTEM_DATA_SCOPE = "系统-系统-数据范围";
public static final String SYSTEM_ROLE = "系统-角色";
public static final String SYSTEM_ROLE_DATA_SCOPE = "系统-角色-数据范围";
public static final String SYSTEM_ROLE_EMPLOYEE = "系统-角色-员工";
public static final String SYSTEM_ROLE_MENU = "系统-角色-菜单";
public static final String SYSTEM_POSITION = "系统-职务管理";
}
}

View File

@ -0,0 +1,23 @@
package net.lab1024.sa.admin.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.lab1024.sa.base.common.enumeration.BaseEnum;
@AllArgsConstructor
@Getter
public enum UsageStatusEnum implements BaseEnum {
/**
*
*/
FREE("FREE", "空闲"),
/**
*
*/
USED("USED", "占用");
private final String value;
private final String desc;
}

View File

@ -0,0 +1,148 @@
package net.lab1024.sa.admin.interceptor;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.strategy.SaStrategy;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
import net.lab1024.sa.admin.module.system.login.service.LoginService;
import net.lab1024.sa.base.common.annoation.NoNeedLogin;
import net.lab1024.sa.base.common.code.SystemErrorCode;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.common.util.SmartResponseUtil;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import java.lang.reflect.Method;
/**
* admin
*
* @Author 1024-:
* @Date 2023/7/26 20:20:33
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>Since 2012
*/
@Component
@Slf4j
public class AdminInterceptor implements HandlerInterceptor {
@Resource
private LoginService loginService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// OPTIONS请求直接return
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
response.setStatus(HttpStatus.NO_CONTENT.value());
return false;
}
boolean isHandler = handler instanceof HandlerMethod;
if (!isHandler) {
return true;
}
try {
// --------------- 第一步: 根据token 获取用户 ---------------
String tokenValue = StpUtil.getTokenValue();
String loginId = (String) StpUtil.getLoginIdByToken(tokenValue);
RequestEmployee requestEmployee = loginService.getLoginEmployee(loginId, request);
// --------------- 第二步: 校验 登录 ---------------
Method method = ((HandlerMethod) handler).getMethod();
NoNeedLogin noNeedLogin = ((HandlerMethod) handler).getMethodAnnotation(NoNeedLogin.class);
if (noNeedLogin != null) {
checkActiveTimeout(requestEmployee);
return true;
}
if (requestEmployee == null) {
SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID));
return false;
}
// 检测token 活跃频率
checkActiveTimeout(requestEmployee);
// --------------- 第三步: 校验 权限 ---------------
SmartRequestUtil.setRequestUser(requestEmployee);
if (SaStrategy.instance.isAnnotationPresent.apply(method, SaIgnore.class)) {
return true;
}
// 如果是超级管理员的话,不需要校验权限
if (requestEmployee.getAdministratorFlag()) {
return true;
}
SaStrategy.instance.checkMethodAnnotation.accept(method);
} catch (SaTokenException e) {
/*
* sa-token
* https://sa-token.cc/doc.html#/fun/exception-code
*/
int code = e.getCode();
if (code == 11041 || code == 11051) {
SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.NO_PERMISSION));
} else if (code == 11016) {
SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.LOGIN_ACTIVE_TIMEOUT));
} else if (code >= 11011 && code <= 11015) {
SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID));
} else {
SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.PARAM_ERROR));
}
return false;
} catch (Throwable e) {
SmartResponseUtil.write(response, ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR));
log.error(e.getMessage(), e);
return false;
}
// 通过验证
return true;
}
/**
* token token 访
*/
private void checkActiveTimeout(RequestEmployee requestEmployee) {
// 用户不在线,也不用检测
if (requestEmployee == null) {
return;
}
StpUtil.checkActiveTimeout();
StpUtil.updateLastActiveToNow();
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 清除上下文
SmartRequestUtil.remove();
}
}

View File

@ -0,0 +1,24 @@
package net.lab1024.sa.admin.listener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
/**
* admin
*
* @Author 1024-:
* @Date 2021-08-26 18:46:32
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Slf4j
@Component
public class AdminStartupRunner implements CommandLineRunner {
@Override
public void run(String... args) {
}
}

View File

@ -0,0 +1,86 @@
package net.lab1024.sa.admin.module.business.base.area.controller;
import net.lab1024.sa.admin.module.business.base.area.domain.entity.AreaEntity;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaAddForm;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaQueryForm;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaSelect;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaUpdateForm;
import net.lab1024.sa.admin.module.business.base.area.domain.vo.AreaVO;
import net.lab1024.sa.admin.module.business.base.area.service.AreaQueryService;
import net.lab1024.sa.admin.module.business.base.area.service.AreaService;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.domain.ValidateList;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import org.springframework.web.bind.annotation.*;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.PageResult;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import java.util.List;
/**
* Controller
*
* @Author hj
* @Date 2025-03-11 11:12:36
* @Copyright
*/
@RestController
@Tag(name = "库区信息")
public class AreaController {
@Resource
private AreaQueryService areaQueryService;
@Resource
private AreaService areaService;
@Operation(summary = "分页查询 @author hj")
@PostMapping("/area/queryPage")
@SaCheckPermission("area:query")
public ResponseDTO<PageResult<AreaVO>> queryPage(@RequestBody @Valid AreaQueryForm queryForm) {
return areaQueryService.queryPage(queryForm);
}
@Operation(summary = "添加 @author hj")
@PostMapping("/area/add")
@SaCheckPermission("area:add")
public ResponseDTO<String> add(@RequestBody @Valid AreaAddForm addForm) {
RequestUser requestUser = SmartRequestUtil.getRequestUser();
addForm.setCreateUserId(requestUser.getUserId());
addForm.setCreateUserName(requestUser.getUserName());
return areaService.add(addForm);
}
@Operation(summary = "更新 @author hj")
@PostMapping("/area/update")
@SaCheckPermission("area:update")
public ResponseDTO<String> update(@RequestBody @Valid AreaUpdateForm updateForm) {
return areaService.update(updateForm);
}
@Operation(summary = "批量删除 @author hj")
@PostMapping("/area/batchDelete")
@SaCheckPermission("area:batchDelete")
public ResponseDTO<String> batchDelete(@RequestBody ValidateList<Long> idList) {
return areaService.batchDelete(idList);
}
@Operation(summary = "单个删除 @author hj")
@GetMapping("/area/delete")
@SaCheckPermission("area:delete")
public ResponseDTO<String> batchDelete(@RequestParam Long areaId) {
return areaService.delete(areaId);
}
@Operation(summary = "库区下拉查询")
@PostMapping("/area/queryArea")
public ResponseDTO<List<AreaEntity>> queryArea(@RequestBody AreaSelect areaSelect) {
return ResponseDTO.ok(areaQueryService.queryArea(areaSelect));
}
}

View File

@ -0,0 +1,36 @@
package net.lab1024.sa.admin.module.business.base.area.dao;
import java.util.List;
import net.lab1024.sa.admin.module.business.base.area.domain.entity.AreaEntity;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaQueryForm;
import net.lab1024.sa.admin.module.business.base.area.domain.vo.AreaVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;
/**
* Dao
*
* @Author hj
* @Date 2025-03-11 11:12:36
* @Copyright
*/
@Mapper
@Component
public interface AreaDao extends BaseMapper<AreaEntity> {
/**
*
*
* @param page
* @param queryForm
* @return
*/
List<AreaVO> queryPage(Page page, @Param("queryForm") AreaQueryForm queryForm);
}

View File

@ -0,0 +1,71 @@
package net.lab1024.sa.admin.module.business.base.area.domain.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
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 java.time.LocalDateTime;
import lombok.Data;
/**
*
*
* @Author hj
* @Date 2025-03-11 11:12:36
* @Copyright
*/
@Data
@TableName("t_area")
public class AreaEntity {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long areaId;
/**
*
*/
private String areaCode;
/**
*
*/
private String areaName;
/**
*
*/
private String remark;
/**
*
*/
private Boolean disabledFlag;
/**
* ID
*/
private Long createUserId;
/**
*
*/
private String createUserName;
/**
*
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
*
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,43 @@
package net.lab1024.sa.admin.module.business.base.area.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import lombok.Data;
/**
*
*
* @Author hj
* @Date 2025-03-11 11:12:36
* @Copyright
*/
@Data
public class AreaAddForm {
@Schema(description = "库区编码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "库区编码 不能为空")
private String areaCode;
@Schema(description = "库区名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "库区名称 不能为空")
private String areaName;
@Schema(description = "禁用状态")
@NotNull(message = "禁用状态不能为空")
private Boolean disabledFlag;
@Schema(description = "备注|可选")
private String remark;
@Schema(hidden = true)
private Long createUserId;
@Schema(hidden = true)
private String createUserName;
}

View File

@ -0,0 +1,26 @@
package net.lab1024.sa.admin.module.business.base.area.domain.form;
import net.lab1024.sa.base.common.domain.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
*
* @Author hj
* @Date 2025-03-11 11:12:36
* @Copyright
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class AreaQueryForm extends PageParam {
@Schema(description = "库区ID")
private Long areaId;
@Schema(description = "是否启用")
private Boolean disabledFlag;
}

View File

@ -0,0 +1,13 @@
package net.lab1024.sa.admin.module.business.base.area.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class AreaSelect {
@Schema(description = "库区名称集合")
List<String> areaNames;
}

View File

@ -0,0 +1,22 @@
package net.lab1024.sa.admin.module.business.base.area.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
*
*
* @Author hj
* @Date 2025-03-11 11:12:36
* @Copyright
*/
@Data
public class AreaUpdateForm extends AreaAddForm{
@Schema(description = "库区id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "库区id 不能为空")
private Long areaId;
}

View File

@ -0,0 +1,37 @@
package net.lab1024.sa.admin.module.business.base.area.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.Data;
/**
* VO
*
* @Author hj
* @Date 2025-03-11 11:12:36
* @Copyright
*/
@Data
public class AreaVO {
@Schema(description = "库区ID")
private Long areaId;
@Schema(description = "库区编码")
private String areaCode;
@Schema(description = "库区名称")
private String areaName;
@Schema(description = "备注")
private String remark;
@Schema(description = "是否禁用")
private Boolean disabledFlag;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,45 @@
package net.lab1024.sa.admin.module.business.base.area.manager;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminCacheConst;
import net.lab1024.sa.admin.module.business.base.area.domain.entity.AreaEntity;
import net.lab1024.sa.admin.module.business.base.area.dao.AreaDao;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
* Manager
*
* @Author hj
* @Date 2025-03-11 11:12:36
* @Copyright
*/
@Service
@Slf4j
public class AreaManager extends ServiceImpl<AreaDao, AreaEntity> {
@Resource
private AreaDao areaDao;
/**
* id
*/
@CacheEvict(value = {AdminCacheConst.Base.AREA_ENTITY}, allEntries = true)
public void removeCache() {
log.info("clear AREA_ENTITY");
}
/**
*
*/
@Cacheable(AdminCacheConst.Base.AREA_ENTITY)
public AreaEntity queryArea(Long areaId) {
return areaDao.selectById(areaId);
}
}

View File

@ -0,0 +1,87 @@
package net.lab1024.sa.admin.module.business.base.area.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.base.area.dao.AreaDao;
import net.lab1024.sa.admin.module.business.base.area.domain.entity.AreaEntity;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaQueryForm;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaSelect;
import net.lab1024.sa.admin.module.business.base.area.domain.vo.AreaVO;
import net.lab1024.sa.admin.module.business.base.area.manager.AreaManager;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class AreaQueryService {
@Resource
private AreaDao areaDao;
@Resource
private AreaManager areaManager;
/**
*
*
* @param queryForm
* @return PageResult<AreaVO>
*/
public ResponseDTO<PageResult<AreaVO>> queryPage(AreaQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<AreaVO> list = areaDao.queryPage(page, queryForm);
PageResult<AreaVO> pageResult = SmartPageUtil.convert2PageResult(page, list);
if (pageResult.getEmptyFlag()) {
return ResponseDTO.ok(pageResult);
}
return ResponseDTO.ok(pageResult);
}
/**
*
*/
public List<AreaEntity> queryArea(AreaSelect areaSelect) {
LambdaQueryWrapper<AreaEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AreaEntity::getDisabledFlag, Boolean.TRUE);
if (areaSelect != null && areaSelect.getAreaNames() != null) {
queryWrapper.in(AreaEntity::getAreaName, areaSelect.getAreaNames());
}
return areaDao.selectList(queryWrapper);
}
public Map<Long, AreaEntity> queryAreaList(List<Long> areaIdList) {
if (CollectionUtils.isEmpty(areaIdList)) {
return Collections.emptyMap();
}
areaIdList = areaIdList.stream().distinct().collect(Collectors.toList());
Map<Long, AreaEntity> areaMap = Maps.newHashMap();
for (Long areaId : areaIdList) {
AreaEntity area = areaManager.queryArea(areaId);
if (area != null) {
areaMap.put(areaId, area);
}
}
return areaMap;
}
/**
*
*
* @param areaName
* @return AreaEntity
*/
public AreaEntity queryByAreaName(String areaName) {
LambdaQueryWrapper<AreaEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AreaEntity::getAreaName, areaName);
return areaDao.selectOne(queryWrapper);
}
}

View File

@ -0,0 +1,137 @@
package net.lab1024.sa.admin.module.business.base.area.service;
import java.util.*;
import com.alibaba.fastjson.JSONObject;
import net.lab1024.sa.admin.module.business.base.area.dao.AreaDao;
import net.lab1024.sa.admin.module.business.base.area.domain.entity.AreaEntity;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaAddForm;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaUpdateForm;
import net.lab1024.sa.admin.module.business.base.area.manager.AreaManager;
import net.lab1024.sa.admin.module.business.base.location.service.LocationQueryService;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
/**
* Service
*
* @Author hj
* @Date 2025-03-11 11:12:36
* @Copyright
*/
@Service
public class AreaService {
@Resource
private AreaDao areaDao;
@Resource
private AreaManager areaManager;
@Resource
private AreaQueryService areaQueryService;
@Resource
private LocationQueryService locationQueryService;
/**
*
*/
public ResponseDTO<String> add(AreaAddForm addForm) {
AreaEntity existingArea = areaQueryService.queryByAreaName(addForm.getAreaName());
if (existingArea != null) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
AreaEntity areaEntity = SmartBeanUtil.copy(addForm, AreaEntity.class);
areaDao.insert(areaEntity);
//更新缓存
areaManager.removeCache();
return ResponseDTO.ok();
}
/**
*
*
* @param updateForm
* @return
*/
public ResponseDTO<String> update(AreaUpdateForm updateForm) {
AreaEntity existingArea = areaQueryService.queryByAreaName(updateForm.getAreaName());
if (existingArea != null && !existingArea.getAreaId().equals(updateForm.getAreaId())) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
AreaEntity areaEntity = SmartBeanUtil.copy(updateForm, AreaEntity.class);
areaDao.updateById(areaEntity);
//更新缓存
areaManager.removeCache();
return ResponseDTO.ok();
}
/**
*
*
* @param idList
* @return
*/
public ResponseDTO<String> batchDelete(List<Long> idList) {
if (CollectionUtils.isEmpty(idList)) {
return ResponseDTO.error(UserErrorCode.PARAM_ERROR, UserErrorCode.PARAM_ERROR.getMsg());
}
JoinerResult joiner = JoinerResult.createJoiner();
int sussCount = joiner.getSussCount();
List<Long> idsToDelete = new ArrayList<>();
for (Long id : idList) {
AreaEntity area = areaManager.queryArea(id);
if (!locationQueryService.checkLocationExist(id)) {
joiner.getErrorMsg().add(area.getAreaName() + "已关联库位,无法删除");
} else {
idsToDelete.add(id);
joiner.getSussMsg().add(area.getAreaName() + "删除成功");
joiner.setSussCount(sussCount++);
}
}
//删除库区
if (CollectionUtils.isNotEmpty(idsToDelete)) {
areaDao.deleteBatchIds(idsToDelete);
//更新缓存
areaManager.removeCache();
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("success", joiner.getSussCount() == idList.size() ? "删除成功" : joiner.getSussMsg().toString());
jsonObject.put("error", joiner.getErrorMsg().toString());
return ResponseDTO.ok(jsonObject.toString());
}
/**
*
*/
public ResponseDTO<String> delete(Long areaId) {
if (null == areaId) {
return ResponseDTO.error(UserErrorCode.PARAM_ERROR, UserErrorCode.PARAM_ERROR.getMsg());
}
AreaEntity area = areaManager.queryArea(areaId);
if (!locationQueryService.checkLocationExist(areaId)) {
String msg = area.getAreaName() + "已关联库位,无法删除";
return ResponseDTO.error(UserErrorCode.BAD_ERROR, msg);
}
areaDao.deleteById(areaId);
//更新缓存
areaManager.removeCache();
return ResponseDTO.ok();
}
}

View File

@ -0,0 +1,22 @@
# 默认是按前端工程文件的 /views/business 文件夹的路径作为前端组件路径,如果你没把生成的 .vue 前端代码放在 /views/business 下,
# 那就根据自己实际情况修改下面 SQL 的 path,component 字段值,避免执行 SQL 后菜单无法访问。
# 如果你一切都是按照默认,那么下面的 SQL 基本不用改
INSERT INTO t_menu ( menu_name, menu_type, parent_id, path, component, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, create_user_id )
VALUES ( '库区信息', 2, 0, '/area/list', '/business/area/area-list.vue', false, false, true, false, 1, 1 );
# 按菜单名称查询该菜单的 menu_id 作为按钮权限的 父菜单ID 与 功能点关联菜单ID
SET @parent_id = NULL;
SELECT t_menu.menu_id INTO @parent_id FROM t_menu WHERE t_menu.menu_name = '库区信息';
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '查询', 3, @parent_id, false, true, true, false, 'area:query', 1, @parent_id, 1 );
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '添加', 3, @parent_id, false, true, true, false, 'area:add', 1, @parent_id, 1 );
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '更新', 3, @parent_id, false, true, true, false, 'area:update', 1, @parent_id, 1 );
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '删除', 3, @parent_id, false, true, true, false, 'area:delete', 1, @parent_id, 1 );

View File

@ -0,0 +1,71 @@
package net.lab1024.sa.admin.module.business.base.item.controller;
import net.lab1024.sa.admin.module.business.base.item.domain.form.ItemAddForm;
import net.lab1024.sa.admin.module.business.base.item.domain.form.ItemQueryForm;
import net.lab1024.sa.admin.module.business.base.item.domain.form.ItemUpdateForm;
import net.lab1024.sa.admin.module.business.base.item.domain.vo.ItemVO;
import net.lab1024.sa.admin.module.business.base.item.service.ItemService;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ValidateList;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
/**
* Controller
*
* @Author
* @Date 2024-11-25 17:08:18
* @Copyright
*/
@RestController
@Tag(name = "物料信息")
public class ItemController {
@Resource
private ItemService itemService;
@Operation(summary = "分页查询 @author 霍锦")
@PostMapping("/item/queryPage")
@SaCheckPermission("item:query")
public ResponseDTO<PageResult<ItemVO>> queryPage(@RequestBody @Valid ItemQueryForm queryForm) {
return ResponseDTO.ok(itemService.queryPage(queryForm));
}
@Operation(summary = "添加 @author 霍锦")
@PostMapping("/item/add")
@SaCheckPermission("item:add")
public ResponseDTO<String> add(@RequestBody @Valid ItemAddForm addForm) {
return itemService.add(addForm);
}
@Operation(summary = "更新 @author 霍锦")
@PostMapping("/item/update")
@SaCheckPermission("item:update")
public ResponseDTO<String> update(@RequestBody @Valid ItemUpdateForm updateForm) {
return itemService.update(updateForm);
}
@Operation(summary = "批量删除 @author 霍锦")
@PostMapping("/item/batchDelete")
@SaCheckPermission("item:delete")
public ResponseDTO<String> batchDelete(@RequestBody ValidateList<Long> idList) {
return itemService.batchDelete(idList);
}
@Operation(summary = "单个删除 @author 霍锦")
@GetMapping("/item/delete/{itemId}")
@SaCheckPermission("item:delete")
public ResponseDTO<String> batchDelete(@PathVariable Long itemId) {
return itemService.delete(itemId);
}
}

View File

@ -0,0 +1,34 @@
package net.lab1024.sa.admin.module.business.base.item.dao;
import java.util.List;
import net.lab1024.sa.admin.module.business.base.item.domain.entity.ItemEntity;
import net.lab1024.sa.admin.module.business.base.item.domain.form.ItemQueryForm;
import net.lab1024.sa.admin.module.business.base.item.domain.vo.ItemVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
/**
* Dao
*
* @Author
* @Date 2024-11-25 17:08:18
* @Copyright
*/
@Mapper
@Component
public interface ItemDao extends BaseMapper<ItemEntity> {
/**
*
*
* @param page
* @param queryForm
* @return
*/
List<ItemVO> queryPage(Page page, @Param("queryForm") ItemQueryForm queryForm);
}

View File

@ -0,0 +1,87 @@
package net.lab1024.sa.admin.module.business.base.item.domain.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
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 java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Data;
/**
*
*
* @Author
* @Date 2024-11-25 17:08:18
* @Copyright
*/
@Data
@TableName("t_item")
public class ItemEntity {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long itemId;
/**
*
*/
private String itemCode;
/**
*
*/
private String itemName;
/**
*
*/
private String unit;
/**
*
*/
private BigDecimal packFactor;
/**
*
*/
private Boolean disabledFlag;
/**
*
*/
private String itemType;
/**
*
*/
private String remark;
/**
* ID
*/
private Long createUserId;
/**
*
*/
private String createUserName;
/**
*
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
*
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,56 @@
package net.lab1024.sa.admin.module.business.base.item.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import lombok.Data;
/**
*
*
* @Author
* @Date 2024-11-25 17:08:18
* @Copyright
*/
@Data
public class ItemAddForm {
@Schema(description = "物料id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "物料id 不能为空")
private Long itemId;
@Schema(description = "物料编码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "物料编码 不能为空")
private String itemCode;
@Schema(description = "物料名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "物料名称 不能为空")
private String itemName;
@Schema(description = "是否禁用", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "是否禁用 不能为空")
private Boolean disabledFlag;
@Schema(description = "物料类型", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "物料类型 不能为空")
private String itemType;
@Schema(description = "创建人ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "创建人ID 不能为空")
private Long createUserId;
@Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "创建人 不能为空")
private String createUserName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "创建时间 不能为空")
private LocalDateTime createTime;
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "更新时间 不能为空")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,26 @@
package net.lab1024.sa.admin.module.business.base.item.domain.form;
import net.lab1024.sa.base.common.domain.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
*
* @Author
* @Date 2024-11-25 17:08:18
* @Copyright
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class ItemQueryForm extends PageParam {
@Schema(description = "物料编码")
private String itemCode;
@Schema(description = "物料名称")
private String itemName;
}

View File

@ -0,0 +1,56 @@
package net.lab1024.sa.admin.module.business.base.item.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import lombok.Data;
/**
*
*
* @Author
* @Date 2024-11-25 17:08:18
* @Copyright
*/
@Data
public class ItemUpdateForm {
@Schema(description = "物料id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "物料id 不能为空")
private Long itemId;
@Schema(description = "物料编码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "物料编码 不能为空")
private String itemCode;
@Schema(description = "物料名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "物料名称 不能为空")
private String itemName;
@Schema(description = "是否禁用", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "是否禁用 不能为空")
private Boolean disabledFlag;
@Schema(description = "物料类型", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "物料类型 不能为空")
private String itemType;
@Schema(description = "创建人ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "创建人ID 不能为空")
private Long createUserId;
@Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "创建人 不能为空")
private String createUserName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "创建时间 不能为空")
private LocalDateTime createTime;
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "更新时间 不能为空")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,47 @@
package net.lab1024.sa.admin.module.business.base.item.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Data;
/**
* VO
*
* @Author
* @Date 2024-11-25 17:08:18
* @Copyright
*/
@Data
public class ItemVO {
@Schema(description = "物料id")
private Long itemId;
@Schema(description = "物料编码")
private String itemCode;
@Schema(description = "物料名称")
private String itemName;
@Schema(description = "单位")
private String unit;
@Schema(description = "包装系数")
private BigDecimal packFactor;
@Schema(description = "是否禁用")
private Boolean disabledFlag;
@Schema(description = "物料类型")
private String itemType;
@Schema(description = "备注")
private String remark;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,20 @@
package net.lab1024.sa.admin.module.business.base.item.manager;
import net.lab1024.sa.admin.module.business.base.item.dao.ItemDao;
import net.lab1024.sa.admin.module.business.base.item.domain.entity.ItemEntity;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* Manager
*
* @Author
* @Date 2024-11-25 17:08:18
* @Copyright
*/
@Service
public class ItemManager extends ServiceImpl<ItemDao, ItemEntity> {
}

View File

@ -0,0 +1,94 @@
package net.lab1024.sa.admin.module.business.base.item.service;
import java.util.List;
import net.lab1024.sa.admin.module.business.base.item.dao.ItemDao;
import net.lab1024.sa.admin.module.business.base.item.domain.entity.ItemEntity;
import net.lab1024.sa.admin.module.business.base.item.domain.form.ItemAddForm;
import net.lab1024.sa.admin.module.business.base.item.domain.form.ItemQueryForm;
import net.lab1024.sa.admin.module.business.base.item.domain.form.ItemUpdateForm;
import net.lab1024.sa.admin.module.business.base.item.domain.vo.ItemVO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.PageResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
/**
* Service
*
* @Author
* @Date 2024-11-25 17:08:18
* @Copyright
*/
@Service
public class ItemService {
@Resource
private ItemDao itemDao;
/**
*
*
* @param queryForm
* @return
*/
public PageResult<ItemVO> queryPage(ItemQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<ItemVO> list = itemDao.queryPage(page, queryForm);
PageResult<ItemVO> pageResult = SmartPageUtil.convert2PageResult(page, list);
return pageResult;
}
/**
*
*/
public ResponseDTO<String> add(ItemAddForm addForm) {
ItemEntity itemEntity = SmartBeanUtil.copy(addForm, ItemEntity.class);
itemDao.insert(itemEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param updateForm
* @return
*/
public ResponseDTO<String> update(ItemUpdateForm updateForm) {
ItemEntity itemEntity = SmartBeanUtil.copy(updateForm, ItemEntity.class);
itemDao.updateById(itemEntity);
return ResponseDTO.ok();
}
/**
*
*
* @param idList
* @return
*/
public ResponseDTO<String> batchDelete(List<Long> idList) {
if (CollectionUtils.isEmpty(idList)){
return ResponseDTO.ok();
}
itemDao.deleteBatchIds(idList);
return ResponseDTO.ok();
}
/**
*
*/
public ResponseDTO<String> delete(Long itemId) {
if (null == itemId){
return ResponseDTO.ok();
}
itemDao.deleteById(itemId);
return ResponseDTO.ok();
}
}

View File

@ -0,0 +1,22 @@
# 默认是按前端工程文件的 /views/business 文件夹的路径作为前端组件路径,如果你没把生成的 .vue 前端代码放在 /views/business 下,
# 那就根据自己实际情况修改下面 SQL 的 path,component 字段值,避免执行 SQL 后菜单无法访问。
# 如果你一切都是按照默认,那么下面的 SQL 基本不用改
INSERT INTO t_menu ( menu_name, menu_type, parent_id, path, component, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, create_user_id )
VALUES ( '物料信息', 2, 0, '/item/list', '/business/item/item-list.vue', false, false, true, false, 1, 1 );
# 按菜单名称查询该菜单的 menu_id 作为按钮权限的 父菜单ID 与 功能点关联菜单ID
SET @parent_id = NULL;
SELECT t_menu.menu_id INTO @parent_id FROM t_menu WHERE t_menu.menu_name = '物料信息';
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '查询', 3, @parent_id, false, false, true, false, 'item:query', 1, @parent_id, 1 );
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '添加', 3, @parent_id, false, false, true, false, 'item:add', 1, @parent_id, 1 );
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '更新', 3, @parent_id, false, false, true, false, 'item:update', 1, @parent_id, 1 );
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '删除', 3, @parent_id, false, false, true, false, 'item:delete', 1, @parent_id, 1 );

View File

@ -0,0 +1,90 @@
package net.lab1024.sa.admin.module.business.base.location.controller;
import net.lab1024.sa.admin.module.business.base.location.domain.form.*;
import net.lab1024.sa.admin.module.business.base.location.domain.vo.LocationVO;
import net.lab1024.sa.admin.module.business.base.location.service.LocationQueryService;
import net.lab1024.sa.admin.module.business.base.location.service.LocationService;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.domain.ValidateList;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import org.springframework.web.bind.annotation.*;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.PageResult;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import java.util.List;
/**
* Controller
*
* @Author
* @Date 2024-11-18 14:17:31
* @Copyright
*/
@RestController
@Tag(name = "库位信息")
public class LocationController {
@Resource
private LocationService locationService;
@Resource
private LocationQueryService locationQueryService;
@Operation(summary = "分页查询 @author 霍锦")
@PostMapping("/location/queryPage")
@SaCheckPermission("location:query")
public ResponseDTO<PageResult<LocationVO>> queryPage(@RequestBody @Valid LocationQueryForm queryForm) {
return locationQueryService.queryPage(queryForm);
}
@Operation(summary = "添加 @author 霍锦")
@PostMapping("/location/add")
@SaCheckPermission("location:add")
public ResponseDTO<String> add(@RequestBody @Valid LocationAddForm addForm) {
RequestUser requestUser = SmartRequestUtil.getRequestUser();
addForm.setCreateUserId(requestUser.getUserId());
addForm.setCreateUserName(requestUser.getUserName());
return locationService.add(addForm);
}
@Operation(summary = "更新 @author 霍锦")
@PostMapping("/location/update")
@SaCheckPermission("location:update")
public ResponseDTO<String> update(@RequestBody @Valid LocationUpdateForm updateForm) {
return locationService.update(updateForm);
}
@Operation(summary = "批量删除 @author 霍锦")
@PostMapping("/location/batchDelete")
@SaCheckPermission("location:batchDelete")
public ResponseDTO<String> batchDelete(@RequestBody ValidateList<Long> idList) {
return locationService.batchDelete(idList);
}
@Operation(summary = "单个删除 @author 霍锦")
@GetMapping("/location/delete")
@SaCheckPermission("location:delete")
public ResponseDTO<String> batchDelete(@RequestParam Long locationId) {
return locationService.delete(locationId);
}
@Operation(summary = "库位下拉查询")
@PostMapping("/location/queryLocation")
public ResponseDTO<List<LocationVO>> queryLocation(@RequestBody LocationSelect locationSelect) {
return ResponseDTO.ok(locationQueryService.queryLocation(locationSelect));
}
@Operation(summary = "批量调整 霍锦")
@PostMapping("/location/multipleAdjust")
@SaCheckPermission("location:multipleAdjust")
public ResponseDTO<String> multipleAdjust(@RequestBody MultipleAdjust multipleAdjust) {
return locationService.multipleAdjust(multipleAdjust);
}
}

View File

@ -0,0 +1,34 @@
package net.lab1024.sa.admin.module.business.base.location.dao;
import java.util.List;
import net.lab1024.sa.admin.module.business.base.location.domain.entity.LocationEntity;
import net.lab1024.sa.admin.module.business.base.location.domain.form.LocationQueryForm;
import net.lab1024.sa.admin.module.business.base.location.domain.vo.LocationVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
/**
* Dao
*
* @Author
* @Date 2024-11-18 14:17:31
* @Copyright
*/
@Mapper
@Component
public interface LocationDao extends BaseMapper<LocationEntity> {
/**
*
*
* @param page
* @param queryForm
* @return
*/
List<LocationVO> queryPage(Page page, @Param("queryForm") LocationQueryForm queryForm);
}

View File

@ -0,0 +1,101 @@
package net.lab1024.sa.admin.module.business.base.location.domain.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
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 java.time.LocalDateTime;
import lombok.Data;
/**
*
*
* @Author
* @Date 2024-11-18 14:17:31
* @Copyright
*/
@Data
@TableName("t_location")
public class LocationEntity {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long locationId;
/**
*
*/
private String locationCode;
/**
*
*/
private String locationName;
/**
*
*/
private String status;
/**
* ID
*/
private Long areaId;
/**
*
*/
private Boolean disabledFlag;
/**
*
*/
private Long locationRow;
/**
*
*/
private Long locationLine;
/**
*
*/
private Long locationCow;
/**
*
*/
private String locationType;
/**
*
*/
private String remark;
/**
* ID
*/
private Long createUserId;
/**
*
*/
private String createUserName;
/**
*
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
*
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,61 @@
package net.lab1024.sa.admin.module.business.base.location.domain.form;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import lombok.Data;
import net.lab1024.sa.admin.constant.UsageStatusEnum;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.base.common.json.deserializer.DictValueVoDeserializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
/**
*
*
* @Author
* @Date 2024-11-18 14:17:31
* @Copyright
*/
@Data
public class LocationAddForm {
@Schema(description = "库位编码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "库位编码 不能为空")
private String locationCode;
@Schema(description = "库位名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "库位名称 不能为空")
private String locationName;
@Schema(description = "库位类型")
@NotBlank(message = "库位类型 不能为空 ")
@JsonDeserialize(using = DictValueVoDeserializer.class)
private String locationType;
@SchemaEnum(UsageStatusEnum.class)
@CheckEnum(message = "商品状态错误", value = UsageStatusEnum.class, required = true)
private String status;
@Schema(description = "库区", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "库区 不能为空")
private Long areaId;
@Schema(description = "禁用状态")
@NotNull(message = "禁用状态不能为空")
private Boolean disabledFlag;
@Schema(hidden = true)
private Long createUserId;
@Schema(hidden = true)
private String createUserName;
}

View File

@ -0,0 +1,38 @@
package net.lab1024.sa.admin.module.business.base.location.domain.form;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import net.lab1024.sa.admin.constant.UsageStatusEnum;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.base.common.domain.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import net.lab1024.sa.base.common.json.deserializer.DictValueVoDeserializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
/**
*
*
* @Author
* @Date 2024-11-18 14:17:31
* @Copyright
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class LocationQueryForm extends PageParam {
@Schema(description = "库区")
private Long areaId;
@Schema(description = "库位")
private Long locationId;
@Schema(description = "状态")
private String status;
@Schema(description = "是否启用")
private String disabledFlag;
}

View File

@ -0,0 +1,23 @@
package net.lab1024.sa.admin.module.business.base.location.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class LocationSelect {
@Schema(description = "库区名称集合")
List<String> areaNames;
@Schema(description = "库位类型")
String locationType;
@Schema(description = "库位状态")
String status;
@Schema(description = "是否启用")
Boolean disabledFlag;
}

View File

@ -0,0 +1,24 @@
package net.lab1024.sa.admin.module.business.base.location.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
*
*
* @Author
* @Date 2024-11-18 14:17:31
* @Copyright
*/
@Data
public class LocationUpdateForm extends LocationAddForm{
@Schema(description = "库位id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "库位id 不能为空")
private Long locationId;
}

View File

@ -0,0 +1,18 @@
package net.lab1024.sa.admin.module.business.base.location.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class MultipleAdjust {
@Schema(description = "库位集合")
List<Long> locationIds;
@Schema(description = "状态;true:空闲;false:占用")
Boolean status;
@Schema(description = "是否启用")
Boolean disabledFlag;
}

View File

@ -0,0 +1,65 @@
package net.lab1024.sa.admin.module.business.base.location.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import net.lab1024.sa.admin.constant.UsageStatusEnum;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
/**
* VO
*
* @Author
* @Date 2024-11-18 14:17:31
* @Copyright
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class LocationVO {
@Schema(description = "库位ID")
private Long locationId;
@Schema(description = "库位编码")
private String locationCode;
@SchemaEnum(UsageStatusEnum.class)
private String status;
@Schema(description = "库区ID")
private Long areaId;
@Schema(description = "库区名称")
private String areaName;
@Schema(description = "是否禁用")
private Boolean disabledFlag;
@Schema(description = "排")
private Long locationRow;
@Schema(description = "列")
private Long locationLine;
@Schema(description = "层")
private Long locationCow;
@Schema(description = "类型")
private String locationType;
@Schema(description = "备注")
private String remark;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,47 @@
package net.lab1024.sa.admin.module.business.base.location.manager;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminCacheConst;
import net.lab1024.sa.admin.module.business.base.area.dao.AreaDao;
import net.lab1024.sa.admin.module.business.base.area.domain.entity.AreaEntity;
import net.lab1024.sa.admin.module.business.base.location.dao.LocationDao;
import net.lab1024.sa.admin.module.business.base.location.domain.entity.LocationEntity;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
* Manager
*
* @Author
* @Date 2024-11-18 14:17:31
* @Copyright
*/
@Service
@Slf4j
public class LocationManager extends ServiceImpl<LocationDao, LocationEntity> {
@Resource
private LocationDao locationDao;
/**
* id
*/
@CacheEvict(value = {AdminCacheConst.Base.LOCATION_ENTITY}, allEntries = true)
public void removeCache() {
log.info("clear LOCATION_ENTITY");
}
/**
*
*/
@Cacheable(AdminCacheConst.Base.LOCATION_ENTITY)
public LocationEntity queryLocation(Long locationId) {
return locationDao.selectById(locationId);
}
}

View File

@ -0,0 +1,164 @@
package net.lab1024.sa.admin.module.business.base.location.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.base.area.domain.entity.AreaEntity;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaSelect;
import net.lab1024.sa.admin.module.business.base.area.manager.AreaManager;
import net.lab1024.sa.admin.module.business.base.area.service.AreaQueryService;
import net.lab1024.sa.admin.module.business.base.location.dao.LocationDao;
import net.lab1024.sa.admin.module.business.base.location.domain.entity.LocationEntity;
import net.lab1024.sa.admin.module.business.base.location.domain.form.LocationQueryForm;
import net.lab1024.sa.admin.module.business.base.location.domain.form.LocationSelect;
import net.lab1024.sa.admin.module.business.base.location.domain.vo.LocationVO;
import net.lab1024.sa.admin.module.business.base.location.manager.LocationManager;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class LocationQueryService {
@Resource
private LocationDao locationDao;
@Resource
private AreaManager areaManager;
@Resource
private LocationManager locationManager;
@Resource
private AreaQueryService areaQueryService;
/**
*
*
* @param queryForm
* @return PageResult<LocationVO>
*/
public ResponseDTO<PageResult<LocationVO>> queryPage(LocationQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<LocationVO> list = locationDao.queryPage(page, queryForm);
PageResult<LocationVO> pageResult = SmartPageUtil.convert2PageResult(page, list);
if (pageResult.getEmptyFlag()) {
return ResponseDTO.ok(pageResult);
}
// 查询库区名称
List<Long> categoryIdList = list.stream().map(LocationVO::getAreaId).distinct().collect(Collectors.toList());
Map<Long, AreaEntity> areaMap = areaQueryService.queryAreaList(categoryIdList);
list.forEach(area -> {
AreaEntity areaEntity = areaMap.get(area.getAreaId());
if (areaEntity != null) {
area.setAreaName(areaEntity.getAreaName());
}
});
return ResponseDTO.ok(pageResult);
}
//转实体转VO
public LocationVO entityToVO(LocationEntity entity) {
AreaEntity area = areaManager.queryArea(entity.getAreaId());
return LocationVO.builder()
.locationId(entity.getLocationId())
.locationCode(entity.getLocationCode())
.status(entity.getStatus())
.areaId(entity.getAreaId())
.areaName(area == null ? null : area.getAreaName())
.disabledFlag(entity.getDisabledFlag())
.locationRow(entity.getLocationRow())
.locationLine(entity.getLocationLine())
.locationCow(entity.getLocationCow())
.locationType(entity.getLocationType())
.remark(entity.getRemark())
.createTime(entity.getCreateTime())
.build();
}
/**
*
*/
public List<LocationVO> queryLocation(LocationSelect locationSelect) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
//是否启用
if (locationSelect.getDisabledFlag() != null) {
queryWrapper.eq(LocationEntity::getDisabledFlag, locationSelect.getDisabledFlag());
}
//库区
if (CollectionUtils.isNotEmpty(locationSelect.getAreaNames())) {
AreaSelect areaSelect = new AreaSelect();
areaSelect.setAreaNames(locationSelect.getAreaNames());
List<AreaEntity> areaList = areaQueryService.queryArea(areaSelect);
if (CollectionUtils.isNotEmpty(areaList)) {
List<Long> areaIdList = areaList.stream().map(AreaEntity::getAreaId).collect(Collectors.toList());
queryWrapper.in(LocationEntity::getAreaId, areaIdList);
}
}
//库位类型
if (StringUtils.isNotBlank(locationSelect.getLocationType())) {
queryWrapper.eq(LocationEntity::getLocationType, locationSelect.getLocationType());
}
//库位状态
if (StringUtils.isNotBlank(locationSelect.getStatus())) {
queryWrapper.eq(LocationEntity::getStatus, locationSelect.getStatus());
}
List<LocationEntity> list = locationDao.selectList(queryWrapper);
return list.stream().map(this::entityToVO).collect(Collectors.toList());
}
public Map<Long, LocationEntity> queryLocationList(List<Long> locationIdList) {
if (CollectionUtils.isEmpty(locationIdList)) {
return Collections.emptyMap();
}
locationIdList = locationIdList.stream().distinct().collect(Collectors.toList());
Map<Long, LocationEntity> locationMap = Maps.newHashMap();
for (Long locationId : locationIdList) {
LocationEntity location = locationManager.queryLocation(locationId);
if (location != null) {
locationMap.put(locationId, location);
}
}
return locationMap;
}
/**
*
*
* @param areaId
*/
public Boolean checkLocationExist(Long areaId) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(LocationEntity::getAreaId, areaId);
List<LocationEntity> list = locationDao.selectList(queryWrapper);
return list.isEmpty();
}
/**
*
*
* @param locationCode
* @return LocationEntity
*/
public LocationEntity queryByLocationCode(String locationCode) {
LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(LocationEntity::getLocationCode, locationCode);
return locationDao.selectOne(queryWrapper);
}
}

View File

@ -0,0 +1,154 @@
package net.lab1024.sa.admin.module.business.base.location.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import net.lab1024.sa.admin.constant.UsageStatusEnum;
import net.lab1024.sa.admin.module.business.base.area.domain.entity.AreaEntity;
import net.lab1024.sa.admin.module.business.base.area.manager.AreaManager;
import net.lab1024.sa.admin.module.business.base.area.service.AreaQueryService;
import net.lab1024.sa.admin.module.business.base.area.service.AreaService;
import net.lab1024.sa.admin.module.business.base.location.dao.LocationDao;
import net.lab1024.sa.admin.module.business.base.location.domain.entity.LocationEntity;
import net.lab1024.sa.admin.module.business.base.location.domain.form.LocationAddForm;
import net.lab1024.sa.admin.module.business.base.location.domain.form.LocationQueryForm;
import net.lab1024.sa.admin.module.business.base.location.domain.form.LocationUpdateForm;
import net.lab1024.sa.admin.module.business.base.location.domain.form.MultipleAdjust;
import net.lab1024.sa.admin.module.business.base.location.domain.vo.LocationVO;
import net.lab1024.sa.admin.module.business.base.location.manager.LocationManager;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsExcelVO;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.PageResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
/**
* Service
*
* @Author
* @Date 2024-11-18 14:17:31
* @Copyright
*/
@Service
public class LocationService {
@Resource
private LocationDao locationDao;
@Resource
private LocationManager locationManager;
@Resource
private LocationQueryService locationQueryService;
/**
*
*/
public ResponseDTO<String> add(LocationAddForm addForm) {
LocationEntity existingLocation = locationQueryService.queryByLocationCode(addForm.getLocationCode());
if (existingLocation != null) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
LocationEntity locationEntity = SmartBeanUtil.copy(addForm, LocationEntity.class);
locationDao.insert(locationEntity);
//更新缓存
locationManager.removeCache();
return ResponseDTO.ok();
}
/**
*
*/
public ResponseDTO<String> update(LocationUpdateForm updateForm) {
LocationEntity existingLocation = locationQueryService.queryByLocationCode(updateForm.getLocationCode());
if (existingLocation != null && !existingLocation.getLocationId().equals(updateForm.getLocationId())) {
return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, UserErrorCode.ALREADY_EXIST.getMsg());
}
LocationEntity locationEntity = SmartBeanUtil.copy(updateForm, LocationEntity.class);
locationDao.updateById(locationEntity);
//更新缓存
locationManager.removeCache();
return ResponseDTO.ok();
}
/**
*
*/
public ResponseDTO<String> batchDelete(List<Long> idList) {
if (CollectionUtils.isEmpty(idList)) {
return ResponseDTO.ok();
}
locationDao.deleteBatchIds(idList);
//更新缓存
locationManager.removeCache();
return ResponseDTO.ok();
}
/**
*
*/
public ResponseDTO<String> delete(Long locationId) {
if (null == locationId) {
return ResponseDTO.ok();
}
locationDao.deleteById(locationId);
//更新缓存
locationManager.removeCache();
return ResponseDTO.ok();
}
/**
*
*
* @param multipleAdjust
* @return ResponseDTO<String>
*/
public ResponseDTO<String> multipleAdjust(MultipleAdjust multipleAdjust) {
if (CollectionUtils.isEmpty(multipleAdjust.getLocationIds())) {
return ResponseDTO.error(UserErrorCode.PARAM_ERROR, UserErrorCode.PARAM_ERROR.getMsg());
}
//查询库位
Map<Long, LocationEntity> locationEntityMap = locationQueryService.queryLocationList(multipleAdjust.getLocationIds());
//批量更新
List<LocationEntity> updateToLocation = new ArrayList<>();
//调整状态true:空闲;false:占用
String status = multipleAdjust.getStatus() ? UsageStatusEnum.FREE.getValue() : UsageStatusEnum.USED.getValue();
//是否启用true:启用;false:禁用
Boolean disabledFlag = multipleAdjust.getDisabledFlag();
//更新状态
locationEntityMap.forEach((locationId, location) -> {
location.setStatus(status);
location.setDisabledFlag(disabledFlag);
updateToLocation.add(location);
});
if (CollectionUtils.isNotEmpty(updateToLocation)) {
locationManager.updateBatchById(updateToLocation);
}
//更新缓存
locationManager.removeCache();
return ResponseDTO.ok();
}
}

View File

@ -0,0 +1,22 @@
# 默认是按前端工程文件的 /views/business 文件夹的路径作为前端组件路径,如果你没把生成的 .vue 前端代码放在 /views/business 下,
# 那就根据自己实际情况修改下面 SQL 的 path,component 字段值,避免执行 SQL 后菜单无法访问。
# 如果你一切都是按照默认,那么下面的 SQL 基本不用改
INSERT INTO t_menu ( menu_name, menu_type, parent_id, path, component, frame_flag, cache_flag, visible_flag, disabled_flag, perms_type, create_user_id )
VALUES ( '库位信息', 2, 0, '/location/list', '/business/location/location-list.vue', false, false, true, false, 1, 1 );
# 按菜单名称查询该菜单的 menu_id 作为按钮权限的 父菜单ID 与 功能点关联菜单ID
SET @parent_id = NULL;
SELECT t_menu.menu_id INTO @parent_id FROM t_menu WHERE t_menu.menu_name = '库位信息';
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '查询', 3, @parent_id, false, true, true, false, 'location:query', 1, @parent_id, 1 );
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '添加', 3, @parent_id, false, true, true, false, 'location:add', 1, @parent_id, 1 );
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '更新', 3, @parent_id, false, true, true, false, 'location:update', 1, @parent_id, 1 );
INSERT INTO t_menu ( menu_name, menu_type, parent_id, frame_flag, cache_flag, visible_flag, disabled_flag, api_perms, perms_type, context_menu_id, create_user_id )
VALUES ( '删除', 3, @parent_id, false, true, true, false, 'location:delete', 1, @parent_id, 1 );

View File

@ -0,0 +1,36 @@
package net.lab1024.sa.admin.module.business.category.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.lab1024.sa.base.common.enumeration.BaseEnum;
/**
*
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@AllArgsConstructor
@Getter
public enum CategoryTypeEnum implements BaseEnum {
/**
* 1
*/
GOODS(1, "商品"),
/**
* 2
*/
CUSTOM(2, "自定义"),
;
private final Integer value;
private final String desc;
}

View File

@ -0,0 +1,69 @@
package net.lab1024.sa.admin.module.business.category.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryAddForm;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryTreeQueryForm;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryUpdateForm;
import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO;
import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryVO;
import net.lab1024.sa.admin.module.business.category.service.CategoryService;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@RestController
@Tag(name = AdminSwaggerTagConst.Business.MANAGER_CATEGORY)
public class CategoryController {
@Resource
private CategoryService categoryService;
@Operation(summary = "添加类目 @author 胡克")
@PostMapping("/category/add")
@SaCheckPermission("category:add")
public ResponseDTO<String> add(@RequestBody @Valid CategoryAddForm addForm) {
return categoryService.add(addForm);
}
@Operation(summary = "更新类目 @author 胡克")
@PostMapping("/category/update")
@SaCheckPermission("category:update")
public ResponseDTO<String> update(@RequestBody @Valid CategoryUpdateForm updateForm) {
return categoryService.update(updateForm);
}
@Operation(summary = "查询类目详情 @author 胡克")
@GetMapping("/category/{categoryId}")
public ResponseDTO<CategoryVO> queryDetail(@PathVariable Long categoryId) {
return categoryService.queryDetail(categoryId);
}
@Operation(summary = "查询类目层级树 @author 胡克")
@PostMapping("/category/tree")
@SaCheckPermission("category:tree")
public ResponseDTO<List<CategoryTreeVO>> queryTree(@RequestBody @Valid CategoryTreeQueryForm queryForm) {
return categoryService.queryTree(queryForm);
}
@Operation(summary = "删除类目 @author 胡克")
@GetMapping("/category/delete/{categoryId}")
@SaCheckPermission("category:delete")
public ResponseDTO<String> delete(@PathVariable Long categoryId) {
return categoryService.delete(categoryId);
}
}

View File

@ -0,0 +1,63 @@
package net.lab1024.sa.admin.module.business.category.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* dao
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Component
@Mapper
public interface CategoryDao extends BaseMapper<CategoryEntity> {
/**
* id
*
* @param parentIdList id
* @param deletedFlag
* @return
*/
List<CategoryEntity> queryByParentId(@Param("parentIdList") List<Long> parentIdList,
@Param("deletedFlag") Boolean deletedFlag);
/**
* id
*
* @param parentIdList id
* @param categoryType {@link CategoryTypeEnum}
* @param deletedFlag
* @return
*/
List<CategoryEntity> queryByParentIdAndType(@Param("parentIdList") List<Long> parentIdList,
@Param("categoryType") Integer categoryType,
@Param("deletedFlag") Boolean deletedFlag);
/**
*
*/
List<CategoryEntity> queryByType(@Param("categoryType") Integer categoryType,
@Param("deletedFlag") Boolean deletedFlag);
/**
* id
*/
CategoryEntity selectByTypeAndId(@Param("categoryType") Integer categoryType, @Param("categoryId") Long categoryId);
/**
* sql
*/
CategoryEntity selectOne(CategoryEntity entity);
}

View File

@ -0,0 +1,43 @@
package net.lab1024.sa.admin.module.business.category.domain.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import org.hibernate.validator.constraints.Length;
/**
* DTO
*
* @author
* @date 2021/1/20 16:17
*/
@Data
public class CategoryBaseDTO {
@Schema(description = "类目名称", required = true)
@NotBlank(message = "类目名称不能为空")
@Length(max = 20, message = "类目名称最多20字符")
private String categoryName;
@SchemaEnum(desc = "分类类型", value = CategoryTypeEnum.class)
@CheckEnum(value = CategoryTypeEnum.class, required = true, message = "分类错误")
private Integer categoryType;
@Schema(description = "父级类目id|可选")
private Long parentId;
@Schema(description = "排序|可选")
private Integer sort;
@Schema(description = "备注|可选")
@Length(max = 200, message = "备注最多200字符")
private String remark;
@Schema(description = "禁用状态")
@NotNull(message = "禁用状态不能为空")
private Boolean disabledFlag;
}

View File

@ -0,0 +1,26 @@
package net.lab1024.sa.admin.module.business.category.domain.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* DTO
*
* @author
* @date 2021/1/20 16:17
*/
@Data
public class CategorySimpleDTO {
@Schema(description = "类目id")
private Long categoryId;
@Schema(description = "类目名称")
private String categoryName;
@Schema(description = "类目层级全称")
private String categoryFullName;
@Schema(description = "父级id")
private Long parentId;
}

View File

@ -0,0 +1,67 @@
package net.lab1024.sa.admin.module.business.category.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import java.time.LocalDateTime;
/**
*
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
@TableName("t_category")
public class CategoryEntity {
@TableId(type = IdType.AUTO)
private Long categoryId;
/**
*
*/
private String categoryName;
/**
*
*
* @see CategoryTypeEnum
*/
private Integer categoryType;
/**
* id
*/
private Long parentId;
/**
*
*/
private Boolean disabledFlag;
/**
*
*/
private Integer sort;
/**
*
*/
private Boolean deletedFlag;
/**
*
*/
private String remark;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}

View File

@ -0,0 +1,47 @@
package net.lab1024.sa.admin.module.business.category.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import org.hibernate.validator.constraints.Length;
/**
*
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class CategoryAddForm {
@Schema(description = "类目名称", required = true)
@NotBlank(message = "类目名称不能为空")
@Length(max = 20, message = "类目名称最多20字符")
private String categoryName;
@SchemaEnum(desc = "分类类型", value = CategoryTypeEnum.class)
@CheckEnum(value = CategoryTypeEnum.class, required = true, message = "分类错误")
private Integer categoryType;
@Schema(description = "父级类目id|可选")
private Long parentId;
@Schema(description = "排序|可选")
private Integer sort;
@Schema(description = "备注|可选")
@Length(max = 200, message = "备注最多200字符")
private String remark;
@Schema(description = "禁用状态")
@NotNull(message = "禁用状态不能为空")
private Boolean disabledFlag;
}

View File

@ -0,0 +1,25 @@
package net.lab1024.sa.admin.module.business.category.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
/**
*
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class CategoryTreeQueryForm {
@SchemaEnum(desc = "分类类型|可选", value = CategoryTypeEnum.class)
private Integer categoryType;
@Schema(description = "父级类目id|可选")
private Long parentId;
}

View File

@ -0,0 +1,22 @@
package net.lab1024.sa.admin.module.business.category.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
*
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class CategoryUpdateForm extends CategoryAddForm {
@Schema(description = "类目id")
@NotNull(message = "类目id不能为空")
private Long categoryId;
}

View File

@ -0,0 +1,40 @@
package net.lab1024.sa.admin.module.business.category.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* vo
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class CategoryTreeVO {
@Schema(description = "类目id")
private Long categoryId;
@Schema(description = "类目名称")
private String categoryName;
@Schema(description = "类目层级全称")
private String categoryFullName;
@Schema(description = "父级id")
private Long parentId;
@Schema(description = "类目id")
private Long value;
@Schema(description = "类目名称")
private String label;
@Schema(description = "子类")
private List<CategoryTreeVO> children;
}

View File

@ -0,0 +1,46 @@
package net.lab1024.sa.admin.module.business.category.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import java.time.LocalDateTime;
/**
*
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class CategoryVO {
@Schema(description = "类目名称", required = true)
private String categoryName;
@SchemaEnum(desc = "分类类型", value = CategoryTypeEnum.class)
private Integer categoryType;
@Schema(description = "父级类目id|可选")
private Long parentId;
@Schema(description = "排序|可选")
private Integer sort;
@Schema(description = "备注|可选")
private String remark;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "类目id")
private Long categoryId;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}

View File

@ -0,0 +1,113 @@
package net.lab1024.sa.admin.module.business.category.manager;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminCacheConst;
import net.lab1024.sa.admin.module.business.category.dao.CategoryDao;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO;
import net.lab1024.sa.base.common.constant.StringConst;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Service
@Slf4j
public class CategoryCacheManager {
@Resource
private CategoryDao categoryDao;
/**
* id
*/
@CacheEvict(value = {AdminCacheConst.Category.CATEGORY_ENTITY, AdminCacheConst.Category.CATEGORY_SUB, AdminCacheConst.Category.CATEGORY_TREE}, allEntries = true)
public void removeCache() {
log.info("clear CATEGORY ,CATEGORY_SUB ,CATEGORY_TREE");
}
/**
*
*
*/
@Cacheable(AdminCacheConst.Category.CATEGORY_ENTITY)
public CategoryEntity queryCategory(Long categoryId) {
return categoryDao.selectById(categoryId);
}
/**
*
*
*/
@Cacheable(AdminCacheConst.Category.CATEGORY_SUB)
public List<CategoryEntity> querySubCategory(Long categoryId) {
return categoryDao.queryByParentId(Lists.newArrayList(categoryId), false);
}
/**
*
*
*/
@Cacheable(AdminCacheConst.Category.CATEGORY_TREE)
public List<CategoryTreeVO> queryCategoryTree(Long parentId, Integer categoryType) {
List<CategoryEntity> allCategoryEntityList = categoryDao.queryByType(categoryType, false);
List<CategoryEntity> categoryEntityList = allCategoryEntityList.stream().filter(e -> e.getParentId().equals(parentId)).collect(Collectors.toList());
List<CategoryTreeVO> treeList = SmartBeanUtil.copyList(categoryEntityList, CategoryTreeVO.class);
treeList.forEach(e -> {
e.setLabel(e.getCategoryName());
e.setValue(e.getCategoryId());
e.setCategoryFullName(e.getCategoryName());
});
// 递归设置子类
this.queryAndSetSubCategory(treeList, allCategoryEntityList);
return treeList;
}
/**
*
*
*
*/
private void queryAndSetSubCategory(List<CategoryTreeVO> treeList, List<CategoryEntity> allCategoryEntityList) {
if (CollectionUtils.isEmpty(treeList)) {
return;
}
List<Long> parentIdList = treeList.stream().map(CategoryTreeVO::getValue).collect(Collectors.toList());
List<CategoryEntity> categoryEntityList = allCategoryEntityList.stream().filter(e -> parentIdList.contains(e.getParentId())).collect(Collectors.toList());
Map<Long, List<CategoryEntity>> categorySubMap = categoryEntityList.stream().collect(Collectors.groupingBy(CategoryEntity::getParentId));
treeList.forEach(e -> {
List<CategoryEntity> childrenEntityList = categorySubMap.getOrDefault(e.getValue(), Lists.newArrayList());
List<CategoryTreeVO> childrenVOList = SmartBeanUtil.copyList(childrenEntityList, CategoryTreeVO.class);
childrenVOList.forEach(item -> {
item.setLabel(item.getCategoryName());
item.setValue(item.getCategoryId());
item.setCategoryFullName(e.getCategoryFullName() + StringConst.SEPARATOR_SLASH + item.getCategoryName());
});
// 递归查询
this.queryAndSetSubCategory(childrenVOList, allCategoryEntityList);
e.setChildren(childrenVOList);
});
}
}

View File

@ -0,0 +1,188 @@
package net.lab1024.sa.admin.module.business.category.service;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.category.domain.dto.CategorySimpleDTO;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import net.lab1024.sa.admin.module.business.category.manager.CategoryCacheManager;
import net.lab1024.sa.base.common.constant.StringConst;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Service
@Slf4j
public class CategoryQueryService {
private static final Long DEFAULT_CATEGORY_PARENT_ID = 0L;
@Resource
private CategoryCacheManager categoryCacheManager;
/**
* id
*
* @param categoryId
* @return null
*/
public Optional<CategoryEntity> queryCategory(Long categoryId) {
if (null == categoryId) {
return Optional.empty();
}
CategoryEntity entity = categoryCacheManager.queryCategory(categoryId);
if (null == entity || entity.getDeletedFlag()) {
return Optional.empty();
}
return Optional.of(entity);
}
/**
* id
*/
public Map<Long, CategoryEntity> queryCategoryList(List<Long> categoryIdList) {
if (CollectionUtils.isEmpty(categoryIdList)) {
return Collections.emptyMap();
}
categoryIdList = categoryIdList.stream().distinct().collect(Collectors.toList());
Map<Long, CategoryEntity> categoryEntityMap = Maps.newHashMap();
for (Long categoryId : categoryIdList) {
CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId);
if (categoryEntity != null) {
categoryEntityMap.put(categoryId, categoryEntity);
}
}
return categoryEntityMap;
}
/**
* id idid
*
*
*/
public List<Long> queryCategorySubId(List<Long> categoryIdList) {
if (CollectionUtils.isEmpty(categoryIdList)) {
return Collections.emptyList();
}
//所有子类
List<CategoryEntity> categoryEntityList = Lists.newArrayList();
categoryIdList.forEach(e -> {
categoryEntityList.addAll(categoryCacheManager.querySubCategory(e));
});
Map<Long, List<CategoryEntity>> subTypeMap = categoryEntityList.stream().collect(Collectors.groupingBy(CategoryEntity::getCategoryId));
// 递归查询子类
categoryIdList = subTypeMap.values().stream().flatMap(Collection::stream).map(CategoryEntity::getCategoryId).distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(categoryIdList)) {
return Lists.newArrayList();
}
categoryIdList.addAll(this.queryCategorySubId(categoryIdList));
return categoryIdList;
}
/**
*
*/
public List<String> queryCategoryName(List<Long> categoryIdList) {
if (CollectionUtils.isEmpty(categoryIdList)) {
return null;
}
Map<Long, CategoryEntity> categoryMap = this.queryCategoryList(categoryIdList);
List<String> categoryNameList = Lists.newArrayList();
categoryIdList.forEach(e -> {
CategoryEntity categoryEntity = categoryMap.get(e);
if (categoryEntity != null) {
categoryNameList.add(categoryMap.get(e).getCategoryName());
}
});
return categoryNameList;
}
/**
* id
*/
public String queryCategoryName(Long categoryId) {
CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId);
if (null == categoryEntity || categoryEntity.getDeletedFlag()) {
return null;
}
return categoryEntity.getCategoryName();
}
/**
* id //
*/
public CategorySimpleDTO queryCategoryInfo(Long categoryId) {
CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId);
if (null == categoryEntity || categoryEntity.getDeletedFlag()) {
return null;
}
String fullName = this.queryFullName(categoryId);
// 返回DTO
CategorySimpleDTO categoryDTO = new CategorySimpleDTO();
categoryDTO.setCategoryId(categoryId);
categoryDTO.setCategoryName(categoryEntity.getCategoryName());
categoryDTO.setCategoryFullName(fullName);
categoryDTO.setParentId(categoryEntity.getParentId());
return categoryDTO;
}
/**
*
* ps:
*/
public List<CategoryEntity> queryCategoryAndParent(Long categoryId) {
List<CategoryEntity> parentCategoryList = Lists.newArrayList();
CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId);
if (null == categoryEntity || categoryEntity.getDeletedFlag()) {
return parentCategoryList;
}
// 父级始终放在第一位
parentCategoryList.add(0, categoryEntity);
Long parentId = categoryEntity.getParentId();
if (Objects.equals(DEFAULT_CATEGORY_PARENT_ID, parentId)) {
return parentCategoryList;
}
parentCategoryList.addAll(0, this.queryCategoryAndParent(parentId));
return parentCategoryList;
}
/**
* //
*/
public String queryFullName(Long categoryId) {
List<CategoryEntity> parentCategoryList = this.queryCategoryAndParent(categoryId);
// 拼接父级类目名称 斜杠分隔返回
List<String> nameList = parentCategoryList.stream().map(CategoryEntity::getCategoryName).collect(Collectors.toList());
return StrUtil.join(StringConst.SEPARATOR_SLASH, nameList);
}
/**
* //
*/
public Map<Long, String> queryFullName(List<Long> categoryIdList) {
if (CollectionUtils.isEmpty(categoryIdList)) {
return Maps.newHashMap();
}
// 循环内查询的缓存 还ok
return categoryIdList.stream().collect(Collectors.toMap(Function.identity(), this::queryFullName));
}
}

View File

@ -0,0 +1,206 @@
package net.lab1024.sa.admin.module.business.category.service;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.category.dao.CategoryDao;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryAddForm;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryTreeQueryForm;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryUpdateForm;
import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO;
import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryVO;
import net.lab1024.sa.admin.module.business.category.manager.CategoryCacheManager;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
*
*
* @Author 1024:
* @Date 2021/08/05 21:26:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Service
public class CategoryService {
@Resource
private CategoryDao categoryDao;
@Resource
private CategoryQueryService categoryQueryService;
@Resource
private CategoryCacheManager categoryCacheManager;
/**
*
*/
public ResponseDTO<String> add(CategoryAddForm addForm) {
// 校验类目
CategoryEntity categoryEntity = SmartBeanUtil.copy(addForm, CategoryEntity.class);
ResponseDTO<String> res = this.checkCategory(categoryEntity, false);
if (!res.getOk()) {
return res;
}
// 没有父类则使用默认父类
Long parentId = null == addForm.getParentId() ? NumberUtils.LONG_ZERO : addForm.getParentId();
categoryEntity.setParentId(parentId);
categoryEntity.setSort(null == addForm.getSort() ? 0 : addForm.getSort());
categoryEntity.setDeletedFlag(false);
// 保存数据
categoryDao.insert(categoryEntity);
// 更新缓存
categoryCacheManager.removeCache();
return ResponseDTO.ok();
}
/**
*
*
*
*/
public ResponseDTO<String> update(CategoryUpdateForm updateForm) {
// 校验类目
Long categoryId = updateForm.getCategoryId();
Optional<CategoryEntity> optional = categoryQueryService.queryCategory(categoryId);
if (!optional.isPresent()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
}
CategoryEntity categoryEntity = SmartBeanUtil.copy(updateForm, CategoryEntity.class);
/*
id
*/
Integer categoryType = optional.get().getCategoryType();
categoryEntity.setCategoryType(categoryType);
categoryEntity.setParentId(optional.get().getParentId());
ResponseDTO<String> responseDTO = this.checkCategory(categoryEntity, true);
if (!responseDTO.getOk()) {
return responseDTO;
}
categoryDao.updateById(categoryEntity);
// 更新缓存
categoryCacheManager.removeCache();
return ResponseDTO.ok();
}
/**
* /
*
*/
private ResponseDTO<String> checkCategory(CategoryEntity categoryEntity, boolean isUpdate) {
// 校验父级是否存在
Long parentId = categoryEntity.getParentId();
Integer categoryType = categoryEntity.getCategoryType();
if (null != parentId) {
if (Objects.equals(categoryEntity.getCategoryId(), parentId)) {
return ResponseDTO.userErrorParam("父级类目怎么和自己相同了");
}
if (!Objects.equals(parentId, NumberUtils.LONG_ZERO)) {
Optional<CategoryEntity> optional = categoryQueryService.queryCategory(parentId);
if (!optional.isPresent()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST, "父级类目不存在~");
}
CategoryEntity parent = optional.get();
if (!Objects.equals(categoryType, parent.getCategoryType())) {
return ResponseDTO.userErrorParam("与父级类目类型不一致");
}
}
} else {
// 如果没有父类 使用默认父类
parentId = NumberUtils.LONG_ZERO;
}
// 校验同父类下 名称是否重复
CategoryEntity queryEntity = new CategoryEntity();
queryEntity.setParentId(parentId);
queryEntity.setCategoryType(categoryType);
queryEntity.setCategoryName(categoryEntity.getCategoryName());
queryEntity.setDeletedFlag(false);
queryEntity = categoryDao.selectOne(queryEntity);
if (null != queryEntity) {
if (isUpdate) {
if (!Objects.equals(queryEntity.getCategoryId(), categoryEntity.getCategoryId())) {
return ResponseDTO.userErrorParam("同级下已存在相同类目~");
}
} else {
return ResponseDTO.userErrorParam("同级下已存在相同类目~");
}
}
return ResponseDTO.ok();
}
/**
*
*
*/
public ResponseDTO<CategoryVO> queryDetail(Long categoryId) {
Optional<CategoryEntity> optional = categoryQueryService.queryCategory(categoryId);
if (!optional.isPresent()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
}
CategoryVO adminVO = SmartBeanUtil.copy(optional.get(), CategoryVO.class);
return ResponseDTO.ok(adminVO);
}
/**
* id
* id
*
*/
public ResponseDTO<List<CategoryTreeVO>> queryTree(CategoryTreeQueryForm queryForm) {
if (null == queryForm.getParentId()) {
if (null == queryForm.getCategoryType()) {
return ResponseDTO.userErrorParam("类目类型不能为空");
}
queryForm.setParentId(NumberUtils.LONG_ZERO);
}
List<CategoryTreeVO> treeList = categoryCacheManager.queryCategoryTree(queryForm.getParentId(), queryForm.getCategoryType());
return ResponseDTO.ok(treeList);
}
/**
*
*
*
*/
public ResponseDTO<String> delete(Long categoryId) {
Optional<CategoryEntity> optional = categoryQueryService.queryCategory(categoryId);
if (!optional.isPresent()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
}
List<Long> categorySubId = categoryQueryService.queryCategorySubId(Lists.newArrayList(categoryId));
if (CollectionUtils.isNotEmpty(categorySubId)) {
return ResponseDTO.userErrorParam("请先删除子级类目");
}
// 更新数据
CategoryEntity categoryEntity = new CategoryEntity();
categoryEntity.setCategoryId(categoryId);
categoryEntity.setDeletedFlag(true);
categoryDao.updateById(categoryEntity);
// 更新缓存
categoryCacheManager.removeCache();
return ResponseDTO.ok();
}
}

View File

@ -0,0 +1,42 @@
package net.lab1024.sa.admin.module.business.goods.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.lab1024.sa.base.common.enumeration.BaseEnum;
/**
*
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@AllArgsConstructor
@Getter
public enum GoodsStatusEnum implements BaseEnum {
/**
* 1
*/
APPOINTMENT(1, "预约中"),
/**
* 2
*/
SELL(2, "售卖中"),
/**
* 3
*/
SELL_OUT(3, "售罄"),
;
private final Integer value;
private final String desc;
}

View File

@ -0,0 +1,94 @@
package net.lab1024.sa.admin.module.business.goods.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsAddForm;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsUpdateForm;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsExcelVO;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO;
import net.lab1024.sa.admin.module.business.goods.service.GoodsService;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.ValidateList;
import net.lab1024.sa.base.common.util.SmartExcelUtil;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
/**
*
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@RestController
@Tag(name = AdminSwaggerTagConst.Business.MANAGER_GOODS)
public class GoodsController {
@Resource
private GoodsService goodsService;
@Operation(summary = "分页查询 @author 胡克")
@PostMapping("/goods/query")
@SaCheckPermission("goods:query")
public ResponseDTO<PageResult<GoodsVO>> query(@RequestBody @Valid GoodsQueryForm queryForm) {
return goodsService.query(queryForm);
}
@Operation(summary = "添加商品 @author 胡克")
@PostMapping("/goods/add")
@SaCheckPermission("goods:add")
public ResponseDTO<String> add(@RequestBody @Valid GoodsAddForm addForm) {
return goodsService.add(addForm);
}
@Operation(summary = "更新商品 @author 胡克")
@PostMapping("/goods/update")
@SaCheckPermission("goods:update")
public ResponseDTO<String> update(@RequestBody @Valid GoodsUpdateForm updateForm) {
return goodsService.update(updateForm);
}
@Operation(summary = "删除 @author 卓大")
@GetMapping("/goods/delete/{goodsId}")
@SaCheckPermission("goods:delete")
public ResponseDTO<String> delete(@PathVariable Long goodsId) {
return goodsService.delete(goodsId);
}
@Operation(summary = "批量 @author 卓大")
@PostMapping("/goods/batchDelete")
@SaCheckPermission("goods:batchDelete")
public ResponseDTO<String> batchDelete(@RequestBody @Valid ValidateList<Long> idList) {
return goodsService.batchDelete(idList);
}
// --------------- 导出和导入 -------------------
@Operation(summary = "导入 @author 卓大")
@PostMapping("/goods/importGoods")
@SaCheckPermission("goods:importGoods")
public ResponseDTO<String> importGoods(@RequestParam MultipartFile file) {
return goodsService.importGoods(file);
}
@Operation(summary = "导出 @author 卓大")
@GetMapping("/goods/exportGoods")
@SaCheckPermission("goods:exportGoods")
public void exportGoods(HttpServletResponse response) throws IOException {
List<GoodsExcelVO> goodsList = goodsService.getAllGoods();
SmartExcelUtil.exportExcel(response,"商品列表.xlsx","商品",GoodsExcelVO.class, goodsList);
}
}

View File

@ -0,0 +1,38 @@
package net.lab1024.sa.admin.module.business.goods.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
*
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Mapper
@Component
public interface GoodsDao extends BaseMapper<GoodsEntity> {
/**
*
*
*/
List<GoodsVO> query(Page page, @Param("query") GoodsQueryForm query);
/**
*
*/
void batchUpdateDeleted(@Param("goodsIdList")List<Long> goodsIdList,@Param("deletedFlag")Boolean deletedFlag);
}

View File

@ -0,0 +1,71 @@
package net.lab1024.sa.admin.module.business.goods.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
*
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
@TableName("t_goods")
public class GoodsEntity {
@TableId(type = IdType.AUTO)
private Long goodsId;
/**
* :[1:,2:,3:]
*/
private Integer goodsStatus;
/**
*
*/
private Long categoryId;
/**
*
*/
private String goodsName;
/**
*
*/
private String place;
/**
*
*/
private BigDecimal price;
/**
*
*/
private Boolean shelvesFlag;
/**
*
*/
private Boolean deletedFlag;
/**
*
*/
private String remark;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}

View File

@ -0,0 +1,56 @@
package net.lab1024.sa.admin.module.business.goods.domain.form;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.base.common.json.deserializer.DictValueVoDeserializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import java.math.BigDecimal;
/**
*
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class GoodsAddForm {
@Schema(description = "商品分类")
@NotNull(message = "商品分类不能为空")
private Long categoryId;
@Schema(description = "商品名称")
@NotBlank(message = "商品名称不能为空")
private String goodsName;
@SchemaEnum(GoodsStatusEnum.class)
@CheckEnum(message = "商品状态错误", value = GoodsStatusEnum.class, required = true)
private Integer goodsStatus;
@Schema(description = "产地")
@NotBlank(message = "产地 不能为空 ")
@JsonDeserialize(using = DictValueVoDeserializer.class)
private String place;
@Schema(description = "商品价格")
@NotNull(message = "商品价格不能为空")
@DecimalMin(value = "0", message = "商品价格最低0")
private BigDecimal price;
@Schema(description = "上架状态")
@NotNull(message = "上架状态不能为空")
private Boolean shelvesFlag;
@Schema(description = "备注|可选")
private String remark;
}

View File

@ -0,0 +1,37 @@
package net.lab1024.sa.admin.module.business.goods.domain.form;
import cn.idev.excel.annotation.ExcelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
*
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class GoodsImportForm {
@ExcelProperty("商品分类")
private String categoryName;
@ExcelProperty("商品名称")
private String goodsName;
@ExcelProperty("商品状态错误")
private String goodsStatus;
@ExcelProperty("产地")
private String place;
@ExcelProperty("商品价格")
private BigDecimal price;
@ExcelProperty("备注")
private String remark;
}

View File

@ -0,0 +1,45 @@
package net.lab1024.sa.admin.module.business.goods.domain.form;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.base.common.domain.PageParam;
import net.lab1024.sa.base.common.json.deserializer.DictValueVoDeserializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import org.hibernate.validator.constraints.Length;
/**
*
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class GoodsQueryForm extends PageParam {
@Schema(description = "商品分类")
private Integer categoryId;
@Schema(description = "搜索词")
@Length(max = 30, message = "搜索词最多30字符")
private String searchWord;
@SchemaEnum(GoodsStatusEnum.class)
@CheckEnum(message = "商品状态错误", value = GoodsStatusEnum.class, required = false)
private Integer goodsStatus;
@Schema(description = "产地")
@JsonDeserialize(using = DictValueVoDeserializer.class)
private String place;
@Schema(description = "上架状态")
private Boolean shelvesFlag;
@Schema(hidden = true)
private Boolean deletedFlag;
}

View File

@ -0,0 +1,22 @@
package net.lab1024.sa.admin.module.business.goods.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
*
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class GoodsUpdateForm extends GoodsAddForm {
@Schema(description = "商品id")
@NotNull(message = "商品id不能为空")
private Long goodsId;
}

View File

@ -0,0 +1,44 @@
package net.lab1024.sa.admin.module.business.goods.domain.vo;
import cn.idev.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* excel
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class GoodsExcelVO {
@ExcelProperty("商品分类")
private String categoryName;
@ExcelProperty("商品名称")
private String goodsName;
@ExcelProperty("商品状态错误")
private String goodsStatus;
@ExcelProperty("产地")
private String place;
@ExcelProperty("商品价格")
private BigDecimal price;
@ExcelProperty("备注")
private String remark;
}

View File

@ -0,0 +1,54 @@
package net.lab1024.sa.admin.module.business.goods.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
*
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class GoodsVO {
@Schema(description = "商品分类")
private Long categoryId;
@Schema(description = "商品名称")
private String goodsName;
@SchemaEnum(GoodsStatusEnum.class)
private Integer goodsStatus;
@Schema(description = "产地")
private String place;
@Schema(description = "商品价格")
private BigDecimal price;
@Schema(description = "上架状态")
private Boolean shelvesFlag;
@Schema(description = "备注|可选")
private String remark;
@Schema(description = "商品id")
private Long goodsId;
@Schema(description = "商品分类")
private String categoryName;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}

View File

@ -0,0 +1,212 @@
package net.lab1024.sa.admin.module.business.goods.service;
import cn.idev.excel.FastExcel;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import net.lab1024.sa.admin.module.business.category.service.CategoryQueryService;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.admin.module.business.goods.dao.GoodsDao;
import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsAddForm;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsImportForm;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsUpdateForm;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsExcelVO;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.exception.BusinessException;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartEnumUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
import net.lab1024.sa.base.module.support.dict.service.DictCacheService;
import net.lab1024.sa.base.module.support.dict.service.DictService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
*
*
* @Author 1024:
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Service
@Slf4j
public class GoodsService {
@Resource
private GoodsDao goodsDao;
@Resource
private CategoryQueryService categoryQueryService;
@Resource
private DataTracerService dataTracerService;
@Resource
private DictCacheService dictCacheService;
/**
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(GoodsAddForm addForm) {
// 商品校验
ResponseDTO<String> res = this.checkGoods(addForm);
if (!res.getOk()) {
return res;
}
GoodsEntity goodsEntity = SmartBeanUtil.copy(addForm, GoodsEntity.class);
goodsEntity.setDeletedFlag(Boolean.FALSE);
goodsDao.insert(goodsEntity);
dataTracerService.insert(goodsEntity.getGoodsId(), DataTracerTypeEnum.GOODS);
return ResponseDTO.ok();
}
/**
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(GoodsUpdateForm updateForm) {
// 商品校验
ResponseDTO<String> res = this.checkGoods(updateForm);
if (!res.getOk()) {
return res;
}
GoodsEntity originEntity = goodsDao.selectById(updateForm.getGoodsId());
GoodsEntity goodsEntity = SmartBeanUtil.copy(updateForm, GoodsEntity.class);
goodsDao.updateById(goodsEntity);
dataTracerService.update(updateForm.getGoodsId(), DataTracerTypeEnum.GOODS, originEntity, goodsEntity);
return ResponseDTO.ok();
}
/**
* /
*/
private ResponseDTO<String> checkGoods(GoodsAddForm addForm) {
// 校验类目id
Long categoryId = addForm.getCategoryId();
Optional<CategoryEntity> optional = categoryQueryService.queryCategory(categoryId);
if (!optional.isPresent() || !CategoryTypeEnum.GOODS.equalsValue(optional.get().getCategoryType())) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST, "商品类目不存在~");
}
return ResponseDTO.ok();
}
/**
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long goodsId) {
GoodsEntity goodsEntity = goodsDao.selectById(goodsId);
if (goodsEntity == null) {
return ResponseDTO.userErrorParam("商品不存在");
}
if (!goodsEntity.getGoodsStatus().equals(GoodsStatusEnum.SELL_OUT.getValue())) {
return ResponseDTO.userErrorParam("只有售罄的商品才可以删除");
}
batchDelete(Collections.singletonList(goodsId));
dataTracerService.batchDelete(Collections.singletonList(goodsId), DataTracerTypeEnum.GOODS);
return ResponseDTO.ok();
}
/**
*
*/
public ResponseDTO<String> batchDelete(List<Long> goodsIdList) {
if (CollectionUtils.isEmpty(goodsIdList)) {
return ResponseDTO.ok();
}
goodsDao.batchUpdateDeleted(goodsIdList, Boolean.TRUE);
return ResponseDTO.ok();
}
/**
*
*/
public ResponseDTO<PageResult<GoodsVO>> query(GoodsQueryForm queryForm) {
queryForm.setDeletedFlag(false);
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<GoodsVO> list = goodsDao.query(page, queryForm);
PageResult<GoodsVO> pageResult = SmartPageUtil.convert2PageResult(page, list);
if (pageResult.getEmptyFlag()) {
return ResponseDTO.ok(pageResult);
}
// 查询分类名称
List<Long> categoryIdList = list.stream().map(GoodsVO::getCategoryId).distinct().collect(Collectors.toList());
Map<Long, CategoryEntity> categoryMap = categoryQueryService.queryCategoryList(categoryIdList);
list.forEach(e -> {
CategoryEntity categoryEntity = categoryMap.get(e.getCategoryId());
if (categoryEntity != null) {
e.setCategoryName(categoryEntity.getCategoryName());
}
});
return ResponseDTO.ok(pageResult);
}
/**
*
*
* @param file
* @return
*/
public ResponseDTO<String> importGoods(MultipartFile file) {
List<GoodsImportForm> dataList;
try {
dataList = FastExcel.read(file.getInputStream()).head(GoodsImportForm.class)
.sheet()
.doReadSync();
} catch (IOException e) {
log.error(e.getMessage(), e);
throw new BusinessException("数据格式存在问题,无法读取");
}
if (CollectionUtils.isEmpty(dataList)) {
return ResponseDTO.userErrorParam("数据为空");
}
return ResponseDTO.okMsg("成功导入" + dataList.size() + "条,具体数据为:" + JSON.toJSONString(dataList));
}
/**
*
*/
public List<GoodsExcelVO> getAllGoods() {
List<GoodsEntity> goodsEntityList = goodsDao.selectList(null);
String keyCode="GODOS_PLACE";
return goodsEntityList.stream()
.map(e ->
GoodsExcelVO.builder()
.goodsStatus(SmartEnumUtil.getEnumDescByValue(e.getGoodsStatus(), GoodsStatusEnum.class))
.categoryName(categoryQueryService.queryCategoryName(e.getCategoryId()))
.place(Arrays.stream(e.getPlace().split(",")).map(code -> dictCacheService.selectValueNameByValueCode(keyCode,code)).collect(Collectors.joining(",")))
.price(e.getPrice())
.goodsName(e.getGoodsName())
.remark(e.getRemark())
.build()
)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,74 @@
package net.lab1024.sa.admin.module.business.oa.bank;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankCreateForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankUpdateForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankVO;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* OA-OA
*
* @Author 1024:
* @Date 2022/6/23 21:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@RestController
@Tag(name = AdminSwaggerTagConst.Business.OA_BANK)
public class BankController {
@Resource
private BankService bankService;
@Operation(summary = "分页查询银行信息 @author 善逸")
@PostMapping("/oa/bank/page/query")
public ResponseDTO<PageResult<BankVO>> queryByPage(@RequestBody @Valid BankQueryForm queryForm) {
return bankService.queryByPage(queryForm);
}
@Operation(summary = "根据企业ID查询银行信息列表 @author 善逸")
@GetMapping("/oa/bank/query/list/{enterpriseId}")
public ResponseDTO<List<BankVO>> queryList(@PathVariable Long enterpriseId) {
return bankService.queryList(enterpriseId);
}
@Operation(summary = "查询银行信息详情 @author 善逸")
@GetMapping("/oa/bank/get/{bankId}")
public ResponseDTO<BankVO> getDetail(@PathVariable Long bankId) {
return bankService.getDetail(bankId);
}
@Operation(summary = "新建银行信息 @author 善逸")
@PostMapping("/oa/bank/create")
public ResponseDTO<String> createBank(@RequestBody @Valid BankCreateForm createVO) {
RequestUser requestUser = SmartRequestUtil.getRequestUser();
createVO.setCreateUserId(requestUser.getUserId());
createVO.setCreateUserName(requestUser.getUserName());
return bankService.createBank(createVO);
}
@Operation(summary = "编辑银行信息 @author 善逸")
@PostMapping("/oa/bank/update")
public ResponseDTO<String> updateBank(@RequestBody @Valid BankUpdateForm updateVO) {
return bankService.updateBank(updateVO);
}
@Operation(summary = "删除银行信息 @author 善逸")
@GetMapping("/oa/bank/delete/{bankId}")
public ResponseDTO<String> deleteBank(@PathVariable Long bankId) {
return bankService.deleteBank(bankId);
}
}

View File

@ -0,0 +1,48 @@
package net.lab1024.sa.admin.module.business.oa.bank;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankEntity;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* OA-OA
*
* @Author 1024:
* @Date 2022/6/23 21:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Mapper
@Component
public interface BankDao extends BaseMapper<BankEntity> {
/**
*
*/
BankEntity queryByAccountNumber(@Param("enterpriseId") Long enterpriseId, @Param("accountNumber") String accountNumber, @Param("excludeBankId") Long excludeBankId, @Param("deletedFlag") Boolean deletedFlag);
/**
*
*
*/
void deleteBank(@Param("bankId") Long bankId, @Param("deletedFlag") Boolean deletedFlag);
/**
*
*
*/
List<BankVO> queryPage(Page page, @Param("queryForm") BankQueryForm queryForm);
/**
*
*/
BankVO getDetail(@Param("bankId") Long bankId, @Param("deletedFlag") Boolean deletedFlag);
}

View File

@ -0,0 +1,145 @@
package net.lab1024.sa.admin.module.business.oa.bank;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.oa.bank.domain.*;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseDao;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerConst;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Objects;
/**
* OA-OA
*
* @Author 1024:
* @Date 2022/6/23 21:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Service
@Slf4j
public class BankService {
@Resource
private BankDao bankDao;
@Resource
private EnterpriseDao enterpriseDao;
@Resource
private DataTracerService dataTracerService;
/**
*
*/
public ResponseDTO<PageResult<BankVO>> queryByPage(BankQueryForm queryForm) {
queryForm.setDeletedFlag(Boolean.FALSE);
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<BankVO> bankList = bankDao.queryPage(page, queryForm);
PageResult<BankVO> pageResult = SmartPageUtil.convert2PageResult(page, bankList);
return ResponseDTO.ok(pageResult);
}
/**
* ID
*/
public ResponseDTO<List<BankVO>> queryList(Long enterpriseId) {
BankQueryForm queryForm = new BankQueryForm();
queryForm.setEnterpriseId(enterpriseId);
queryForm.setDeletedFlag(Boolean.FALSE);
List<BankVO> bankList = bankDao.queryPage(null, queryForm);
return ResponseDTO.ok(bankList);
}
/**
*
*/
public ResponseDTO<BankVO> getDetail(Long bankId) {
// 校验银行信息是否存在
BankVO bankVO = bankDao.getDetail(bankId, Boolean.FALSE);
if (Objects.isNull(bankVO)) {
return ResponseDTO.userErrorParam("银行信息不存在");
}
return ResponseDTO.ok(bankVO);
}
/**
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> createBank(BankCreateForm createVO) {
Long enterpriseId = createVO.getEnterpriseId();
// 校验企业是否存在
EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId);
if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("企业不存在");
}
// 验证银行信息账号是否重复
BankEntity validateBank = bankDao.queryByAccountNumber(enterpriseId, createVO.getAccountNumber(), null, Boolean.FALSE);
if (Objects.nonNull(validateBank)) {
return ResponseDTO.userErrorParam("银行信息账号重复");
}
// 数据插入
BankEntity insertBank = SmartBeanUtil.copy(createVO, BankEntity.class);
bankDao.insert(insertBank);
dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "新增银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(insertBank));
return ResponseDTO.ok();
}
/**
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> updateBank(BankUpdateForm updateVO) {
Long enterpriseId = updateVO.getEnterpriseId();
// 校验企业是否存在
EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId);
if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("企业不存在");
}
Long bankId = updateVO.getBankId();
// 校验银行信息是否存在
BankEntity bankDetail = bankDao.selectById(bankId);
if (Objects.isNull(bankDetail) || bankDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("银行信息不存在");
}
// 验证银行信息账号是否重复
BankEntity validateBank = bankDao.queryByAccountNumber(updateVO.getEnterpriseId(), updateVO.getAccountNumber(), bankId, Boolean.FALSE);
if (Objects.nonNull(validateBank)) {
return ResponseDTO.userErrorParam("银行信息账号重复");
}
// 数据编辑
BankEntity updateBank = SmartBeanUtil.copy(updateVO, BankEntity.class);
bankDao.updateById(updateBank);
dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "更新银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(bankDetail, updateBank));
return ResponseDTO.ok();
}
/**
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> deleteBank(Long bankId) {
// 校验银行信息是否存在
BankEntity bankDetail = bankDao.selectById(bankId);
if (Objects.isNull(bankDetail) || bankDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("银行信息不存在");
}
bankDao.deleteBank(bankId, Boolean.TRUE);
dataTracerService.addTrace(bankDetail.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE, "删除银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(bankDetail));
return ResponseDTO.ok();
}
}

View File

@ -0,0 +1,57 @@
package net.lab1024.sa.admin.module.business.oa.bank.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
/**
* OA-
*
* @Author 1024:
* @Date 2022/6/23 21:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class BankCreateForm {
@Schema(description = "开户银行")
@NotBlank(message = "开户银行不能为空")
@Length(max = 200, message = "开户银行最多200字符")
private String bankName;
@Schema(description = "账户名称")
@NotBlank(message = "账户名称不能为空")
@Length(max = 200, message = "账户名称最多200字符")
private String accountName;
@Schema(description = "账号")
@NotBlank(message = "账号不能为空")
@Length(max = 200, message = "账号最多200字符")
private String accountNumber;
@Schema(description = "备注")
@Length(max = 500, message = "备注最多500字符")
private String remark;
@Schema(description = "是否对公")
@NotNull(message = "是否对公不能为空")
private Boolean businessFlag;
@Schema(description = "企业")
@NotNull(message = "企业不能为空")
private Long enterpriseId;
@Schema(description = "禁用状态")
@NotNull(message = "禁用状态不能为空")
private Boolean disabledFlag;
@Schema(hidden = true)
private Long createUserId;
@Schema(hidden = true)
private String createUserName;
}

View File

@ -0,0 +1,95 @@
package net.lab1024.sa.admin.module.business.oa.bank.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldLabel;
import java.time.LocalDateTime;
/**
* OA-OA
*
* @Author 1024:
* @Date 2022/6/23 21:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
@TableName("t_oa_bank")
public class BankEntity {
/**
* ID
*/
@TableId(type = IdType.AUTO)
@DataTracerFieldLabel("银行信息ID")
private Long bankId;
/**
*
*/
@DataTracerFieldLabel("开户银行")
private String bankName;
/**
*
*/
@DataTracerFieldLabel("账户名称")
private String accountName;
/**
*
*/
@DataTracerFieldLabel("账号")
private String accountNumber;
/**
*
*/
@DataTracerFieldLabel("备注")
private String remark;
/**
*
*/
@DataTracerFieldLabel("是否对公")
private Boolean businessFlag;
/**
* ID
*/
private Long enterpriseId;
/**
*
*/
@DataTracerFieldLabel("禁用状态")
private Boolean disabledFlag;
/**
*
*/
private Boolean deletedFlag;
/**
* ID
*/
private Long createUserId;
/**
* ID
*/
private String createUserName;
/**
*
*/
private LocalDateTime createTime;
/**
*
*/
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,40 @@
package net.lab1024.sa.admin.module.business.oa.bank.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
import org.hibernate.validator.constraints.Length;
import java.time.LocalDate;
/**
* OA-OA
*
* @Author 1024:
* @Date 2022/6/23 21:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class BankQueryForm extends PageParam {
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "关键字")
@Length(max = 200, message = "关键字最多200字符")
private String keywords;
@Schema(description = "开始时间")
private LocalDate startTime;
@Schema(description = "结束时间")
private LocalDate endTime;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "删除状态", hidden = true)
private Boolean deletedFlag;
}

View File

@ -0,0 +1,22 @@
package net.lab1024.sa.admin.module.business.oa.bank.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* OA-
*
* @Author 1024:
* @Date 2022/6/23 21:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class BankUpdateForm extends BankCreateForm {
@Schema(description = "银行信息ID")
@NotNull(message = "银行信息ID不能为空")
private Long bankId;
}

View File

@ -0,0 +1,58 @@
package net.lab1024.sa.admin.module.business.oa.bank.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* OA-OA
*
* @Author 1024:
* @Date 2022/6/23 21:59:22
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class BankVO {
@Schema(description = "银行信息ID")
private Long bankId;
@Schema(description = "开户银行")
private String bankName;
@Schema(description = "账户名称")
private String accountName;
@Schema(description = "账号")
private String accountNumber;
@Schema(description = "备注")
private String remark;
@Schema(description = "是否对公")
private Boolean businessFlag;
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "企业名称")
private String enterpriseName;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "创建人ID")
private Long createUserId;
@Schema(description = "创建人名称")
private String createUserName;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,134 @@
package net.lab1024.sa.admin.module.business.oa.enterprise;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.*;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
import net.lab1024.sa.admin.util.AdminRequestUtil;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.*;
import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Slf4j
@RestController
@Tag(name = AdminSwaggerTagConst.Business.OA_ENTERPRISE)
@OperateLog
public class EnterpriseController {
@Resource
private EnterpriseService enterpriseService;
@Operation(summary = "分页查询企业模块 @author 开云")
@PostMapping("/oa/enterprise/page/query")
@SaCheckPermission("oa:enterprise:query")
public ResponseDTO<PageResult<EnterpriseVO>> queryByPage(@RequestBody @Valid EnterpriseQueryForm queryForm) {
return enterpriseService.queryByPage(queryForm);
}
@Operation(summary = "导出企业信息 @author 卓大")
@PostMapping("/oa/enterprise/exportExcel")
public void exportExcel(@RequestBody @Valid EnterpriseQueryForm queryForm, HttpServletResponse response) throws IOException {
List<EnterpriseExcelVO> data = enterpriseService.getExcelExportData(queryForm);
if (CollectionUtils.isEmpty(data)) {
SmartResponseUtil.write(response, ResponseDTO.userErrorParam("暂无数据"));
return;
}
String watermark = AdminRequestUtil.getRequestUser().getActualName();
watermark += SmartLocalDateUtil.format(LocalDateTime.now(), SmartDateFormatterEnum.YMD_HMS);
SmartExcelUtil.exportExcelWithWatermark(response,"企业基本信息.xlsx","企业信息",EnterpriseExcelVO.class,data,watermark);
}
@Operation(summary = "查询企业详情 @author 开云")
@GetMapping("/oa/enterprise/get/{enterpriseId}")
@SaCheckPermission("oa:enterprise:detail")
public ResponseDTO<EnterpriseVO> getDetail(@PathVariable Long enterpriseId) {
return ResponseDTO.ok(enterpriseService.getDetail(enterpriseId));
}
@Operation(summary = "新建企业 @author 开云")
@PostMapping("/oa/enterprise/create")
@SaCheckPermission("oa:enterprise:add")
public ResponseDTO<String> createEnterprise(@RequestBody @Valid EnterpriseCreateForm createVO) {
RequestUser requestUser = SmartRequestUtil.getRequestUser();
createVO.setCreateUserId(requestUser.getUserId());
createVO.setCreateUserName(requestUser.getUserName());
return enterpriseService.createEnterprise(createVO);
}
@Operation(summary = "编辑企业 @author 开云")
@PostMapping("/oa/enterprise/update")
@SaCheckPermission("oa:enterprise:update")
public ResponseDTO<String> updateEnterprise(@RequestBody @Valid EnterpriseUpdateForm updateVO) {
return enterpriseService.updateEnterprise(updateVO);
}
@Operation(summary = "删除企业 @author 开云")
@GetMapping("/oa/enterprise/delete/{enterpriseId}")
@SaCheckPermission("oa:enterprise:delete")
public ResponseDTO<String> deleteEnterprise(@PathVariable Long enterpriseId) {
return enterpriseService.deleteEnterprise(enterpriseId);
}
@Operation(summary = "按照类型查询企业 @author 开云")
@GetMapping("/oa/enterprise/query/list")
public ResponseDTO<List<EnterpriseListVO>> queryList(@RequestParam(value = "type", required = false) Integer type) {
return enterpriseService.queryList(type);
}
@Operation(summary = "企业添加员工 @author 罗伊")
@PostMapping("/oa/enterprise/employee/add")
@SaCheckPermission("oa:enterprise:addEmployee")
public ResponseDTO<String> addEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) {
return enterpriseService.addEmployee(enterpriseEmployeeForm);
}
@Operation(summary = "查询企业全部员工 @author 罗伊")
@PostMapping("/oa/enterprise/employee/list")
public ResponseDTO<List<EnterpriseEmployeeVO>> employeeList(@RequestBody @Valid List<Long> enterpriseIdList) {
return ResponseDTO.ok(enterpriseService.employeeList(enterpriseIdList));
}
@Operation(summary = "分页查询企业员工 @author 卓大")
@PostMapping("/oa/enterprise/employee/queryPage")
public ResponseDTO<PageResult<EnterpriseEmployeeVO>> queryPageEmployeeList(@RequestBody @Valid EnterpriseEmployeeQueryForm queryForm) {
return ResponseDTO.ok(enterpriseService.queryPageEmployeeList(queryForm));
}
@Operation(summary = "企业删除员工 @author 罗伊")
@PostMapping("/oa/enterprise/employee/delete")
@SaCheckPermission("oa:enterprise:deleteEmployee")
public ResponseDTO<String> deleteEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) {
return enterpriseService.deleteEmployee(enterpriseEmployeeForm);
}
}

View File

@ -0,0 +1,19 @@
package net.lab1024.sa.admin.module.business.oa.enterprise;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity;
import org.springframework.stereotype.Service;
/**
* manager
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Service
public class EnterpriseEmployeeManager extends ServiceImpl<EnterpriseEmployeeDao, EnterpriseEmployeeEntity> {
}

View File

@ -0,0 +1,238 @@
package net.lab1024.sa.admin.module.business.oa.enterprise;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseDao;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.*;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
import net.lab1024.sa.admin.module.system.department.service.DepartmentService;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.domain.form.DataTracerForm;
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Service
@Slf4j
public class EnterpriseService {
@Resource
private EnterpriseDao enterpriseDao;
@Resource
private EnterpriseEmployeeDao enterpriseEmployeeDao;
@Resource
private EnterpriseEmployeeManager enterpriseEmployeeManager;
@Resource
private DataTracerService dataTracerService;
@Resource
private DepartmentService departmentService;
/**
*
*
*/
public ResponseDTO<PageResult<EnterpriseVO>> queryByPage(EnterpriseQueryForm queryForm) {
queryForm.setDeletedFlag(Boolean.FALSE);
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<EnterpriseVO> enterpriseList = enterpriseDao.queryPage(page, queryForm);
PageResult<EnterpriseVO> pageResult = SmartPageUtil.convert2PageResult(page, enterpriseList);
return ResponseDTO.ok(pageResult);
}
/**
*
*/
public List<EnterpriseExcelVO> getExcelExportData(EnterpriseQueryForm queryForm) {
queryForm.setDeletedFlag(false);
return enterpriseDao.selectExcelExportData(queryForm);
}
/**
*
*
*/
public EnterpriseVO getDetail(Long enterpriseId) {
return enterpriseDao.getDetail(enterpriseId, Boolean.FALSE);
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> createEnterprise(EnterpriseCreateForm createVO) {
// 验证企业名称是否重复
EnterpriseEntity validateEnterprise = enterpriseDao.queryByEnterpriseName(createVO.getEnterpriseName(), null, Boolean.FALSE);
if (Objects.nonNull(validateEnterprise)) {
return ResponseDTO.userErrorParam("企业名称重复");
}
// 数据插入
EnterpriseEntity insertEnterprise = SmartBeanUtil.copy(createVO, EnterpriseEntity.class);
enterpriseDao.insert(insertEnterprise);
dataTracerService.insert(insertEnterprise.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE);
return ResponseDTO.ok();
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> updateEnterprise(EnterpriseUpdateForm updateVO) {
Long enterpriseId = updateVO.getEnterpriseId();
// 校验企业是否存在
EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId);
if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("企业不存在");
}
// 验证企业名称是否重复
EnterpriseEntity validateEnterprise = enterpriseDao.queryByEnterpriseName(updateVO.getEnterpriseName(), enterpriseId, Boolean.FALSE);
if (Objects.nonNull(validateEnterprise)) {
return ResponseDTO.userErrorParam("企业名称重复");
}
// 数据编辑
EnterpriseEntity updateEntity = SmartBeanUtil.copy(enterpriseDetail, EnterpriseEntity.class);
SmartBeanUtil.copyProperties(updateVO, updateEntity);
enterpriseDao.updateById(updateEntity);
//变更记录
DataTracerForm dataTracerForm = DataTracerForm.builder()
.dataId(updateVO.getEnterpriseId())
.type(DataTracerTypeEnum.OA_ENTERPRISE)
.content("修改企业信息")
.diffOld(dataTracerService.getChangeContent(enterpriseDetail))
.diffNew(dataTracerService.getChangeContent(updateEntity))
.build();
dataTracerService.addTrace(dataTracerForm);
return ResponseDTO.ok();
}
/**
*
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> deleteEnterprise(Long enterpriseId) {
// 校验企业是否存在
EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId);
if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("企业不存在");
}
enterpriseDao.deleteEnterprise(enterpriseId, Boolean.TRUE);
dataTracerService.delete(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE);
return ResponseDTO.ok();
}
/**
*
*/
public ResponseDTO<List<EnterpriseListVO>> queryList(Integer type) {
List<EnterpriseListVO> enterpriseList = enterpriseDao.queryList(type, Boolean.FALSE, Boolean.FALSE);
return ResponseDTO.ok(enterpriseList);
}
//----------------------------------------- 以下为员工相关--------------------------------------------
/**
*
*
*/
public synchronized ResponseDTO<String> addEmployee(EnterpriseEmployeeForm enterpriseEmployeeForm) {
Long enterpriseId = enterpriseEmployeeForm.getEnterpriseId();
EnterpriseEntity enterpriseEntity = enterpriseDao.selectById(enterpriseId);
if (enterpriseEntity == null || enterpriseEntity.getDeletedFlag()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
}
//过滤掉已存在的员工
List<Long> waitAddEmployeeIdList = enterpriseEmployeeForm.getEmployeeIdList();
List<EnterpriseEmployeeEntity> enterpriseEmployeeEntityList = enterpriseEmployeeDao.selectByEnterpriseAndEmployeeIdList(enterpriseId, waitAddEmployeeIdList);
if (CollectionUtils.isNotEmpty(enterpriseEmployeeEntityList)) {
List<Long> existEmployeeIdList = enterpriseEmployeeEntityList.stream().map(EnterpriseEmployeeEntity::getEmployeeId).collect(Collectors.toList());
waitAddEmployeeIdList = waitAddEmployeeIdList.stream().filter(e -> !existEmployeeIdList.contains(e)).collect(Collectors.toList());
}
if (CollectionUtils.isEmpty(waitAddEmployeeIdList)) {
return ResponseDTO.ok();
}
List<EnterpriseEmployeeEntity> batchAddList = Lists.newArrayList();
for (Long employeeId : waitAddEmployeeIdList) {
EnterpriseEmployeeEntity enterpriseEmployeeEntity = new EnterpriseEmployeeEntity();
enterpriseEmployeeEntity.setEnterpriseId(enterpriseId);
enterpriseEmployeeEntity.setEmployeeId(employeeId);
batchAddList.add(enterpriseEmployeeEntity);
}
enterpriseEmployeeManager.saveBatch(batchAddList);
return ResponseDTO.ok();
}
/**
*
*
*/
public synchronized ResponseDTO<String> deleteEmployee(EnterpriseEmployeeForm enterpriseEmployeeForm) {
Long enterpriseId = enterpriseEmployeeForm.getEnterpriseId();
EnterpriseEntity enterpriseEntity = enterpriseDao.selectById(enterpriseId);
if (enterpriseEntity == null || enterpriseEntity.getDeletedFlag()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
}
List<Long> waitDeleteEmployeeIdList = enterpriseEmployeeForm.getEmployeeIdList();
enterpriseEmployeeDao.deleteByEnterpriseAndEmployeeIdList(enterpriseId, waitDeleteEmployeeIdList);
return ResponseDTO.ok();
}
/**
*
*
*/
public List<EnterpriseEmployeeVO> employeeList(List<Long> enterpriseIdList) {
if (CollectionUtils.isEmpty(enterpriseIdList)) {
return Lists.newArrayList();
}
return enterpriseEmployeeDao.selectByEnterpriseIdList(enterpriseIdList);
}
/**
*
*
*/
public PageResult<EnterpriseEmployeeVO> queryPageEmployeeList(EnterpriseEmployeeQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<EnterpriseEmployeeVO> enterpriseEmployeeVOList = enterpriseEmployeeDao.queryPageEmployeeList(page, queryForm);
for (EnterpriseEmployeeVO enterpriseEmployeeVO : enterpriseEmployeeVOList) {
enterpriseEmployeeVO.setDepartmentName(departmentService.getDepartmentPath(enterpriseEmployeeVO.getDepartmentId()));
}
return SmartPageUtil.convert2PageResult(page, enterpriseEmployeeVOList);
}
}

View File

@ -0,0 +1,46 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.constant;
import net.lab1024.sa.base.common.enumeration.BaseEnum;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
public enum EnterpriseTypeEnum implements BaseEnum {
/**
*
*/
NORMAL(1, "有限企业"),
/**
*
*/
FOREIGN(2, "外资企业"),
;
private Integer value;
private String desc;
EnterpriseTypeEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
@Override
public Integer getValue() {
return value;
}
@Override
public String getDesc() {
return desc;
}
}

View File

@ -0,0 +1,65 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.EnterpriseQueryForm;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Mapper
@Component
public interface EnterpriseDao extends BaseMapper<EnterpriseEntity> {
/**
*
*
*/
EnterpriseEntity queryByEnterpriseName(@Param("enterpriseName") String enterpriseName, @Param("excludeEnterpriseId") Long excludeEnterpriseId, @Param("deletedFlag") Boolean deletedFlag);
/**
*
*/
void deleteEnterprise(@Param("enterpriseId") Long enterpriseId, @Param("deletedFlag") Boolean deletedFlag);
/**
*
*
*/
List<EnterpriseVO> queryPage(Page page, @Param("queryForm") EnterpriseQueryForm queryForm);
/**
*
*
*/
List<EnterpriseExcelVO> selectExcelExportData(@Param("queryForm") EnterpriseQueryForm queryForm);
/**
*
*
*/
EnterpriseVO getDetail(@Param("enterpriseId") Long enterpriseId, @Param("deletedFlag") Boolean deletedFlag);
/**
*
*
*/
List<EnterpriseListVO> queryList(@Param("type") Integer type, @Param("disabledFlag") Boolean disabledFlag, @Param("deletedFlag") Boolean deletedFlag);
}

View File

@ -0,0 +1,70 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.EnterpriseEmployeeQueryForm;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.List;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Mapper
@Component
public interface EnterpriseEmployeeDao extends BaseMapper<EnterpriseEmployeeEntity> {
/**
*
*/
List<EnterpriseEmployeeVO> selectByEmployeeIdList(@Param("employeeIdList")Collection<Long> employeeIdList);
/**
*
*/
List<Long> selectEnterpriseIdByEmployeeId(@Param("employeeId")Long employeeId);
/**
*
*/
List<EnterpriseEmployeeVO> selectByEnterpriseIdList(@Param("enterpriseIdList")Collection<Long> enterpriseIdList);
/**
*
*/
List<EnterpriseEmployeeEntity> selectByEnterpriseId(@Param("enterpriseId")Long enterpriseId);
/**
* id
*/
List<Long> selectEmployeeIdByEnterpriseIdList(@Param("enterpriseIdList")Collection<Long> enterpriseIdList);
/**
*
*/
void deleteByEnterpriseAndEmployeeIdList(@Param("enterpriseId")Long enterpriseId, @Param("employeeIdList")Collection<Long> employeeIdList);
/**
*
*/
List<EnterpriseEmployeeEntity> selectByEnterpriseAndEmployeeIdList(@Param("enterpriseId")Long enterpriseId, @Param("employeeIdList")Collection<Long> employeeIdList);
/**
*
*/
void deleteByEmployeeId(@Param("employeeId")Long employeeId);
/**
*
*/
List<EnterpriseEmployeeVO> queryPageEmployeeList(Page<?> page,@Param("queryForm") EnterpriseEmployeeQueryForm queryForm);
}

View File

@ -0,0 +1,51 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
@TableName("t_oa_enterprise_employee")
@NoArgsConstructor
public class EnterpriseEmployeeEntity {
@TableId(type = IdType.AUTO)
private Long enterpriseEmployeeId;
/**
* ID
*/
private Long enterpriseId;
/**
*
*/
private Long employeeId;
/**
*
*/
private LocalDateTime createTime;
/**
*
*/
private LocalDateTime updateTime;
public EnterpriseEmployeeEntity(Long enterpriseId, Long employeeId) {
this.enterpriseId = enterpriseId;
this.employeeId = employeeId;
}
}

View File

@ -0,0 +1,153 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldEnum;
import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldLabel;
import java.time.LocalDateTime;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
@TableName("t_oa_enterprise")
public class EnterpriseEntity {
/**
* ID
*/
@TableId(type = IdType.AUTO)
private Long enterpriseId;
/**
*
*/
@DataTracerFieldLabel("企业名称")
private String enterpriseName;
/**
* logo
*/
@DataTracerFieldLabel("企业logo")
private String enterpriseLogo;
/**
*
*/
@DataTracerFieldLabel("统一社会信用代码")
private String unifiedSocialCreditCode;
/**
*
*
* @see EnterpriseTypeEnum
*/
@DataTracerFieldLabel("类型")
@DataTracerFieldEnum(enumClass = EnterpriseTypeEnum.class)
private Integer type;
/**
*
*/
@DataTracerFieldLabel("联系人")
private String contact;
/**
*
*/
@DataTracerFieldLabel("联系人电话")
private String contactPhone;
/**
*
*/
@DataTracerFieldLabel("邮箱")
private String email;
/**
*
*/
private Integer province;
/**
*
*/
@DataTracerFieldLabel("省份名称")
private String provinceName;
/**
*
*/
private Integer city;
/**
*
*/
@DataTracerFieldLabel("城市名称")
private String cityName;
/**
*
*/
private Integer district;
/**
*
*/
@DataTracerFieldLabel("区县名称")
private String districtName;
/**
*
*/
@DataTracerFieldLabel("详细地址")
private String address;
/**
*
*/
@DataTracerFieldLabel("营业执照")
private String businessLicense;
/**
*
*/
@DataTracerFieldLabel("禁用状态")
private Boolean disabledFlag;
/**
*
*/
@DataTracerFieldLabel("删除状态")
private Boolean deletedFlag;
/**
* ID
*/
private Long createUserId;
/**
* ID
*/
private String createUserName;
/**
*
*/
private LocalDateTime createTime;
/**
*
*/
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,100 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum;
import net.lab1024.sa.base.common.json.deserializer.FileKeyVoDeserializer;
import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.util.SmartVerificationUtil;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import org.hibernate.validator.constraints.Length;
/**
* OA
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class EnterpriseCreateForm {
@Schema(description = "企业名称")
@NotBlank(message = "企业名称不能为空")
@Length(max = 200, message = "企业名称最多200字符")
private String enterpriseName;
@Schema(description = "企业logo")
@JsonSerialize(using = FileKeyVoSerializer.class)
@JsonDeserialize(using = FileKeyVoDeserializer.class)
private String enterpriseLogo;
@Schema(description = "统一社会信用代码")
@NotBlank(message = "统一社会信用代码不能为空")
@Length(max = 200, message = "统一社会信用代码最多200字符")
private String unifiedSocialCreditCode;
@Schema(description = "联系人")
@NotBlank(message = "联系人不能为空")
@Length(max = 100, message = "联系人最多100字符")
private String contact;
@Schema(description = "联系人电话")
@NotBlank(message = "联系人电话不能为空")
@Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确")
private String contactPhone;
@SchemaEnum(desc = "类型", value = EnterpriseTypeEnum.class)
@CheckEnum(message = "类型不正确", value = EnterpriseTypeEnum.class)
private Integer type;
@Schema(description = "邮箱")
@Pattern(regexp = SmartVerificationUtil.EMAIL, message = "邮箱格式不正确")
private String email;
@Schema(description = "省份")
private Integer province;
@Schema(description = "省份名称")
private String provinceName;
@Schema(description = "城市")
private Integer city;
@Schema(description = "城市名称")
private String cityName;
@Schema(description = "区县")
private Integer district;
@Schema(description = "区县名称")
private String districtName;
@Schema(description = "详细地址")
@Length(max = 500, message = "详细地址最多500字符")
private String address;
@Schema(description = "营业执照")
@JsonSerialize(using = FileKeyVoSerializer.class)
@JsonDeserialize(using = FileKeyVoDeserializer.class)
private String businessLicense;
@Schema(description = "禁用状态")
@NotNull(message = "禁用状态不能为空")
private Boolean disabledFlag;
@Schema(description = "创建人", hidden = true)
private Long createUserId;
@Schema(description = "创建人", hidden = true)
private String createUserName;
}

View File

@ -0,0 +1,29 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class EnterpriseEmployeeForm {
@Schema(description = "企业id")
@NotNull(message = "企业id不能为空")
private Long enterpriseId;
@Schema(description = "员工信息id")
@NotEmpty(message = "员工信息id不能为空")
private List<Long> employeeIdList;
}

View File

@ -0,0 +1,32 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
import org.hibernate.validator.constraints.Length;
/**
*
*
* @Author 1024:
* @Date 2021-12-20 21:06:49
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class EnterpriseEmployeeQueryForm extends PageParam {
@Schema(description = "搜索词")
@Length(max = 20, message = "搜索词最多20字符")
private String keyword;
@Schema(description = "公司Id")
@NotNull(message = "公司id 不能为空")
private Long enterpriseId;
@Schema(description = "删除标识", hidden = true)
private Boolean deletedFlag;
}

View File

@ -0,0 +1,38 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
import org.hibernate.validator.constraints.Length;
import java.time.LocalDate;
/**
* OA
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class EnterpriseQueryForm extends PageParam {
@Schema(description = "关键字")
@Length(max = 200, message = "关键字最多200字符")
private String keywords;
@Schema(description = "开始时间")
private LocalDate startTime;
@Schema(description = "结束时间")
private LocalDate endTime;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "删除状态", hidden = true)
private Boolean deletedFlag;
}

View File

@ -0,0 +1,22 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* OA
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class EnterpriseUpdateForm extends EnterpriseCreateForm {
@Schema(description = "企业ID")
@NotNull(message = "企业ID不能为空")
private Long enterpriseId;
}

View File

@ -0,0 +1,47 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class EnterpriseEmployeeVO {
private Long enterpriseEmployeeId;
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "企业名称")
private String enterpriseName;
@Schema(description = "员工")
private Long employeeId;
@Schema(description = "登录账号")
private String loginName;
@Schema(description = "员工名称")
private String actualName;
@Schema(description = "手机号码")
private String phone;
@Schema(description = "部门id")
private Long departmentId;
@Schema(description = "是否被禁用")
private Boolean disabledFlag;
@Schema(description = "部门名称")
private String departmentName;
}

View File

@ -0,0 +1,48 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo;
import cn.idev.excel.annotation.ExcelProperty;
import lombok.Data;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class EnterpriseExcelVO {
@ExcelProperty("企业名称")
private String enterpriseName;
@ExcelProperty("统一社会信用代码")
private String unifiedSocialCreditCode;
@ExcelProperty("企业类型")
private String typeName;
@ExcelProperty("联系人")
private String contact;
@ExcelProperty("联系人电话")
private String contactPhone;
@ExcelProperty("邮箱")
private String email;
@ExcelProperty("省份名称")
private String provinceName;
@ExcelProperty("城市名称")
private String cityName;
@ExcelProperty("区县名称")
private String districtName;
@ExcelProperty("详细地址")
private String address;
}

View File

@ -0,0 +1,20 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* OA
*
* @author lihaifan
* @date 2022/6/23 14:31
*/
@Data
public class EnterpriseListVO {
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "企业名称")
private String enterpriseName;
}

View File

@ -0,0 +1,89 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum;
import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import java.time.LocalDateTime;
/**
*
*
* @Author 1024:
* @Date 2022/7/28 20:37:15
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Data
public class EnterpriseVO {
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "企业名称")
private String enterpriseName;
@Schema(description = "企业logo")
@JsonSerialize(using = FileKeyVoSerializer.class)
private String enterpriseLogo;
@Schema(description = "统一社会信用代码")
private String unifiedSocialCreditCode;
@SchemaEnum(desc = "类型", value = EnterpriseTypeEnum.class)
private Integer type;
@Schema(description = "联系人")
private String contact;
@Schema(description = "联系人电话")
private String contactPhone;
@Schema(description = "邮箱")
private String email;
@Schema(description = "省份")
private Integer province;
@Schema(description = "省份名称")
private String provinceName;
@Schema(description = "城市")
private Integer city;
@Schema(description = "城市名称")
private String cityName;
@Schema(description = "区县")
private Integer district;
@Schema(description = "区县名称")
private String districtName;
@Schema(description = "详细地址")
private String address;
@Schema(description = "营业执照")
@JsonSerialize(using = FileKeyVoSerializer.class)
private String businessLicense;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "创建人ID")
private Long createUserId;
@Schema(description = "创建人名称")
private String createUserName;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,80 @@
package net.lab1024.sa.admin.module.business.oa.invoice;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceAddForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceUpdateForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceVO;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* OA
*
* @Author 1024:
* @Date 2022-06-23 19:32:59
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024</a>
*/
@Slf4j
@RestController
@Tag(name = AdminSwaggerTagConst.Business.OA_INVOICE)
public class InvoiceController {
@Resource
private InvoiceService invoiceService;
@Operation(summary = "分页查询发票信息 @author 善逸")
@PostMapping("/oa/invoice/page/query")
public ResponseDTO<PageResult<InvoiceVO>> queryByPage(@RequestBody @Valid InvoiceQueryForm queryForm) {
return invoiceService.queryByPage(queryForm);
}
@Operation(summary = "查询发票信息详情 @author 善逸")
@GetMapping("/oa/invoice/get/{invoiceId}")
public ResponseDTO<InvoiceVO> getDetail(@PathVariable Long invoiceId) {
return invoiceService.getDetail(invoiceId);
}
@Operation(summary = "新建发票信息 @author 善逸")
@PostMapping("/oa/invoice/create")
public ResponseDTO<String> createInvoice(@RequestBody @Valid InvoiceAddForm createVO) {
RequestUser requestUser = SmartRequestUtil.getRequestUser();
createVO.setCreateUserId(requestUser.getUserId());
createVO.setCreateUserName(requestUser.getUserName());
return invoiceService.createInvoice(createVO);
}
@Operation(summary = "编辑发票信息 @author 善逸")
@PostMapping("/oa/invoice/update")
@OperateLog
public ResponseDTO<String> updateInvoice(@RequestBody @Valid InvoiceUpdateForm updateVO) {
return invoiceService.updateInvoice(updateVO);
}
@Operation(summary = "删除发票信息 @author 善逸")
@GetMapping("/invoice/delete/{invoiceId}")
public ResponseDTO<String> deleteInvoice(@PathVariable Long invoiceId) {
return invoiceService.deleteInvoice(invoiceId);
}
@Operation(summary = "查询列表 @author lidoudou")
@GetMapping("/oa/invoice/query/list/{enterpriseId}")
public ResponseDTO<List<InvoiceVO>> queryList(@PathVariable Long enterpriseId) {
return invoiceService.queryList(enterpriseId);
}
}

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