功能完成

main
王宇航 2023-11-27 09:51:57 +08:00
parent 2ed2056775
commit 4d7432786d
183 changed files with 11979 additions and 34 deletions

147
.gitignore vendored Normal file
View File

@ -0,0 +1,147 @@
# Created by .ignore support plugin (hsz.mobi)
### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
.idea
.editorconfig
.sdkmanrc
### Java template
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Example user template template
### Example user template
# IntelliJ project files
.idea
*.iml
out
gen
### macOS template
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 hb730
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.

View File

@ -1,34 +0,0 @@
# Boot-Admin V5
基于Java17,SpringBoot3,Spring security6,Mysql8,MybatisPlus的前后端分离的后台管理系统
| | | |
|---------------------------------------------------------------------------------|--------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
| ![](https://github.com/hb0730/boot-admin/raw/v5/doc/asset/boot-admin_v5_1.png) | ![](https://github.com/hb0730/boot-admin/raw/v5/doc/asset/boot-admin_v5_2.png) | ![](https://github.com/hb0730/boot-admin/raw/v5/doc/asset/boot-admin_v5_2.png) |
| ![](https://github.com/hb0730/boot-admin/raw/v5/doc/asset/boot-admin_v5_3.png) | ![](https://github.com/hb0730/boot-admin/raw/v5/doc/asset/boot-admin_v5_5.png) | ![](https://github.com/hb0730/boot-admin/raw/v5/doc/asset/boot-admin_v5_6.png) |
## 开源地址
| | 后端 | 前端 |
|--------|--------------------------------------|------------------------------------------|
| Github | https://github.com/hb0730/boot-admin | https://github.com/hb0730/boot-admin-ui |
| Gitee | https://gitee.com/hb0730/boot-admin/ | https://gitee.com/hb0730/boot-admin-ui |
## 特征
* 前端采用vue-pure-admin (Vue3,Element-Plus,Vite)
* 支持动态菜单与路由
* 自定义权限认证与Security的结合使用
## 在线预览
https://boot.hb0730.com/next
**admin/123456 能不能访问凭运气,Java Server: HK,Redis Server: HK,Mysql Server:HK**
## SQL 所在地
> doc/sql/boot-admin.sql
## question
* 为什么实时请求routes
>1. 首先我们后端已经缓存了当前用户路由
>2. 我们采用EventListener,当管理者更改了用户权限能够实时响应,
>3. 如果要前端缓存,可以开启前端配置: `CachingAsyncRoutes`

19
docker/Dockerfile Normal file
View File

@ -0,0 +1,19 @@
FROM eclipse-temurin:17-jre as builder
WORKDIR application
ARG JAR_FILE=*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract
FROM eclipse-temurin:17-jre
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
ENV JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xmn512m -XX:MaxMetaspaceSize=512m" \
TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENTRYPOINT java $JAVA_OPTS org.springframework.boot.loader.JarLauncher

View File

@ -0,0 +1,25 @@
version: '3'
services:
mysql8_server:
image: mysql:8
container_name: boot_admin_mysql8_server
ports:
- 3306:3306
volumes:
- ./data/mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: 1234
MYSQL_DATABASE: boot-admin
TZ: Asia/Shanghai
redis_server:
image: redis:alpine
container_name: boot_admin_redis_server
ports:
- 6379:6379
volumes:
# redis配置
- ./conf/redis:/usr/local/etc/redis
# redis 数据挂载
- ./data/redis:/data
command: redis-server /usr/local/etc/redis/redis.conf

12
docker/docker-compose.yml Normal file
View File

@ -0,0 +1,12 @@
version: '3'
services:
next_boot-admin:
image: boot-admin:v5
container_name: next_boot-admin
ports:
- '8089:8088'
environment:
JAVA_OPTS: '-server -Dspring.profiles.active=prod -Dspring.config.additional-location=/application/conf/'
TZ: "Asia/Shanghai"
volumes:
- ./conf:/application/conf

192
pom.xml Normal file
View File

@ -0,0 +1,192 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hb0730</groupId>
<artifactId>boot-admin</artifactId>
<version>5.0.0-SNAPSHOT</version>
<name>boot-admin</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<hutool.version>5.8.11</hutool.version>
<bouncycastle.version>1.72</bouncycastle.version>
<!-- <lombok.version>1.18.24</lombok.version>-->
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
<hb0730-jsons.version>1.0.3</hb0730-jsons.version>
<knife4j.version>4.1.0</knife4j.version>
<jwt.version>4.2.2</jwt.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<!--jwt-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-extra</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15to18</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<!--jsons-->
<dependency>
<groupId>com.hb0730</groupId>
<artifactId>jsons</artifactId>
<version>${hb0730-jsons.version}</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<dependency>
<groupId>cn.mrzin</groupId>
<artifactId>tool-wx</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>14</source>
<target>14</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${project.parent.version}</version>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.json</include>
<include>**/*.ftl</include>
</includes>
</resource>
</resources>
</build>
</project>

View File

@ -0,0 +1,24 @@
package com.hb0730.boot.admin;
import cn.hutool.extra.spring.EnableSpringUtil;
import com.hb0730.boot.admin.base.BootAdminApp;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
@SpringBootApplication
@EnableSpringUtil
@EnableAsync
public class BootAdminApplication extends BootAdminApp {
public static void main(String[] args) {
bootstrap(BootAdminApplication.class, args);
}
@Override
protected void doSomethingAfterBooted() {
}
}

View File

@ -0,0 +1,62 @@
package com.hb0730.boot.admin.base;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.Environment;
/**
* SPRING
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
@Slf4j
public class BootAdminApp implements ApplicationContextAware, ApplicationRunner {
private ApplicationContext context;
public static void bootstrap(Class<?> clazz, String... args) {
log.debug("{} 启动开始 ...", clazz.getCanonicalName());
SpringApplication application = new SpringApplication(clazz);
application.setBannerMode(Banner.Mode.CONSOLE);
application.run(args);
log.debug("{} 启动完成 ...", clazz.getCanonicalName());
}
@Override
public void run(ApplicationArguments args) throws Exception {
//启动后做点啥
doSomethingAfterBooted();
//输出启动完成信息
doShowBootedInfs();
}
/**
*
*/
protected void doSomethingAfterBooted() {
}
/**
*
*/
protected void doShowBootedInfs() {
Environment env = context.getEnvironment();
log.info("启动完成 -> {}:{}",
env.getProperty("server.servlet.context-path"),
env.getProperty("server.port")
);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
}

View File

@ -0,0 +1,17 @@
package com.hb0730.boot.admin.base;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/30
*/
public interface BootAdminConst {
String CHARSET_NAME_UTF8 = "utf-8";
/**
* 访
*/
String X_ACCESS_TOKEN = "X-Access-Token";
}

View File

@ -0,0 +1,37 @@
package com.hb0730.boot.admin.base;
import cn.hutool.extra.spring.SpringUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.lang.annotation.Annotation;
import java.util.Map;
/**
* Spring ApplicationContext
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
@Component
public class BootAdminContext extends SpringUtil {
/**
* HttpServletRequest
*/
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
/**
* BEANBEAN
*
* @param annotationType BEAN
* @return BEANS
*/
public static Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) {
return getApplicationContext().getBeansWithAnnotation(annotationType);
}
}

View File

@ -0,0 +1,239 @@
package com.hb0730.boot.admin.base;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
@Data
@EqualsAndHashCode
public class R<T> implements Serializable {
public static final Integer OK_200 = 200;
public static final Integer SERVER_ERROR_500 = 500;
/**
*
*/
public static final Integer SUC_0 = 0;
/**
*
*/
public static final Integer SUC_1 = 1;
/**
*
*/
@Schema(description = "成功标识")
private boolean success = true;
/**
*
*/
@Schema(description = "返回处理消息")
private String message = "操作成功!";
/**
*
*/
@Schema(description = "返回代码")
private Integer code = 0;
/**
* data
*/
@Schema(description = "返回数据对象")
private T result;
/**
*
*/
@Schema(description = "时间戳")
private long timestamp = System.currentTimeMillis();
public R() {
}
public R(T result) {
this.code = SUC_1;
this.result = result;
}
public R(boolean success, String message) {
this.success = success;
this.message = message;
if (success) {
this.code = SUC_1;
} else {
this.code = SUC_0;
}
}
/**
* :
*
* @param message
* @return :
*/
public R<T> success(String message) {
this.message = message;
this.code = OK_200;
this.success = true;
return this;
}
/**
* :code: 500
*
* @param message
* @return :
*/
public R<T> error(String message) {
return error(SERVER_ERROR_500, message);
}
/**
* :
*
* @param code
* @param message
* @param <T> .
* @return :
*/
public static <T> R<T> error(int code, String message) {
R<T> r = new R<>();
r.setCode(code);
r.setMessage(message);
r.setSuccess(false);
return r;
}
/**
* :
*
* @param <T> .
* @return :
*/
public static <T> R<T> OK() {
return OK("成功!", null);
}
/**
* :
*
* @param data
* @param <T> .
* @return :
*/
public static <T> R<T> OK(T data) {
return OK("成功", data);
}
/**
* :
*
* @param code
* @param message
* @param <T> .
* @return :
*/
public static <T> R<T> OK(int code, String message) {
return OK(code, message, null);
}
/**
* :
*
* @param message
* @param <T> .
* @return :
*/
public static <T> R<T> OK(String message) {
return OK(OK_200, message, null);
}
/**
* :
*
* @param message
* @param data
* @param <T> .
* @return :
*/
public static <T> R<T> OK(String message, T data) {
return OK(OK_200, message, data);
}
/**
* :
*
* @param code
* @param message
* @param data
* @param <T> .
* @return :
*/
public static <T> R<T> OK(int code, String message, T data) {
R<T> r = new R<>();
r.setSuccess(true);
r.setCode(code);
r.setMessage(message);
r.setResult(data);
return r;
}
/**
* :
*
* @param message
* @param <T> .
* @return :
*/
public static <T> R<T> NG(String message) {
return NG(message, null);
}
/**
* :
*
* @param message
* @param data
* @param <T> .
* @return :
*/
public static <T> R<T> NG(String message, T data) {
return NG(SERVER_ERROR_500, message, data);
}
/**
* :
*
* @param code
* @param message
* @param <T> .
* @return :
*/
public static <T> R<T> NG(int code, String message) {
return NG(code, message, null);
}
/**
* :
*
* @param code
* @param message
* @param data
* @param <T> .
* @return :
*/
public static <T> R<T> NG(int code, String message, T data) {
R<T> r = new R<>();
r.setSuccess(false);
r.setCode(code);
r.setMessage(message);
r.setResult(data);
return r;
}
}

View File

@ -0,0 +1,29 @@
package com.hb0730.boot.admin.base.exception;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/30
*/
public class BootAdminException extends RuntimeException {
public BootAdminException() {
super();
}
public BootAdminException(String message) {
super(message);
}
public BootAdminException(String message, Throwable cause) {
super(message, cause);
}
public BootAdminException(Throwable cause) {
super(cause);
}
protected BootAdminException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,74 @@
package com.hb0730.boot.admin.base.util;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
import jakarta.annotation.Nonnull;
import lombok.Data;
import java.nio.charset.StandardCharsets;
/**
* AES
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/30
*/
public class AesEncryptUtil {
@Data
public static class SecKey {
public static String key = "1234567890adbcde"; // 长度为16个字符
public static String iv = "1234567890hjlkew"; // 长度为16个字符
}
/**
* 使
*
* @param data
* @return
*/
public static String encrypt(String data) {
return encrypt(data, SecKey.key, SecKey.iv);
}
/**
*
*
* @param data
* @param key
* @param iv
* @return
*/
public static String encrypt(String data, @Nonnull String key, @Nonnull String iv) {
AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, key.getBytes(StandardCharsets.UTF_8),
iv.getBytes(StandardCharsets.UTF_8));
return aes.encryptHex(data);
}
/**
*
*
* @param data
* @return
*/
public static String desEncrypt(String data) {
return desEncrypt(data, SecKey.key, SecKey.iv);
}
/**
*
*
* @param data
* @param key
* @param iv
* @return
*/
public static String desEncrypt(String data, @Nonnull String key, @Nonnull String iv) {
AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, key.getBytes(StandardCharsets.UTF_8),
iv.getBytes(StandardCharsets.UTF_8));
return aes.decryptStr(data);
}
}

View File

@ -0,0 +1,33 @@
package com.hb0730.boot.admin.base.util;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.hb0730.jsons.support.jackson.JacksonImpl;
/**
* json util
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
public class JsonUtil extends JacksonImpl {
public static JsonUtil DEFAULT = new JsonUtil();
public JsonUtil() {
ObjectMapper mapper = new ObjectMapper() {
{
//序列化时候,只序列化非空字段
//this.setSerializationInclusion(Inclusion.NON_NULL);
//or this.setSerializationConfig(this.getSerializationConfig().withSerializationInclusion(Inclusion.NON_NULL));
// 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
this.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
//this.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
}
};
setClient(mapper);
}
}

View File

@ -0,0 +1,110 @@
package com.hb0730.boot.admin.base.util;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.hb0730.boot.admin.base.BootAdminConst;
import com.hb0730.boot.admin.base.exception.BootAdminException;
import jakarta.annotation.Nullable;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* JWT util
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/30
*/
public class JwtUtil {
/**
* Token30tokenreids
*/
public static final long EXPIRE_TIME = 30 * 60 * 1000;
/**
* request token
*
* @param request .
* @return jwt_token
*/
public static String getTokenByRequest(HttpServletRequest request) {
String token = request.getParameter("token");
if (token == null) {
token = request.getHeader(BootAdminConst.X_ACCESS_TOKEN);
}
return token;
}
/**
* requesttoken
*
* @param request
* @return
*/
@Nullable
public static String getUserNameByToken(HttpServletRequest request) throws BootAdminException {
String accessToken = request.getHeader(BootAdminConst.X_ACCESS_TOKEN);
if (StrUtil.isBlank(accessToken)) {
return null;
}
String username = getUsername(accessToken);
if (StrUtil.isBlank(username)) {
throw new BootAdminException("未获取到用户");
}
return username;
}
/**
* tokensecret
*
* @return token
*/
public static String getUsername(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim("username").asString();
} catch (JWTDecodeException e) {
return null;
}
}
/**
* ,EXPIRE_TIME
*
* @param username
* @param secret
* @return token
*/
public static String sign(String username, String secret) {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(secret);
// 附带username信息
return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
}
/**
* token
*
* @param token
* @param secret
* @return
*/
public static boolean verify(String token, String username, String secret) {
try {
// 根据密码生成JWT效验器
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
// 效验TOKEN
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (Exception exception) {
return false;
}
}
}

View File

@ -0,0 +1,68 @@
package com.hb0730.boot.admin.base.util;
import jakarta.annotation.Nonnull;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/3
*/
public class PasswordUtil {
/**
* ,使{@link #defaultPasswordEncoder()}
*
* @param rawPassword
* @return
*/
public static String encoder(String rawPassword) {
return encoder(rawPassword, defaultPasswordEncoder());
}
/**
*
*
* @param rawPassword
* @param passwordEncoder
* @return
*/
public static String encoder(String rawPassword, @Nonnull PasswordEncoder passwordEncoder) {
return passwordEncoder.encode(rawPassword);
}
/**
* 使{@link #defaultPasswordEncoder()}
*
* @param rawPassword
* @param encodedPassword
* @return
*/
public static boolean matches(String rawPassword, String encodedPassword) {
return matches(rawPassword, encodedPassword, defaultPasswordEncoder());
}
/**
*
*
* @param rawPassword
* @param encodedPassword
* @param passwordEncoder
* @return
*/
public static boolean matches(String rawPassword, String encodedPassword,
@Nonnull PasswordEncoder passwordEncoder) {
return passwordEncoder.matches(rawPassword, encodedPassword);
}
/**
* 使 {@link BCryptPasswordEncoder}
*
* @return {@link BCryptPasswordEncoder}
*/
public static PasswordEncoder defaultPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}

View File

@ -0,0 +1,106 @@
package com.hb0730.boot.admin.base.util;
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.UtilityClass;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
/**
* ras util
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/5
*/
@UtilityClass
public class RsaUtil {
/**
*
*
* @param text
* @param publicKeyBase64
* @return base64
*/
public String encryptByPublicKey(String text, String publicKeyBase64) {
RSA rsa = new RSA();
PublicKey publicKey = KeyUtil.generateRSAPublicKey(Base64.decode(publicKeyBase64));
rsa.setPublicKey(publicKey);
return rsa.encryptBase64(text, KeyType.PublicKey);
}
/**
*
*
* @param text base64
* @param privateKeyBase64
* @return
*/
public String decryptByPrivateKey(String text, String privateKeyBase64) {
RSA rsa = new RSA();
PrivateKey privateKey = KeyUtil.generateRSAPrivateKey(Base64.decode(privateKeyBase64));
rsa.setPrivateKey(privateKey);
return rsa.decryptStr(text, KeyType.PrivateKey);
}
/**
*
*
* @param text
* @param privateKeyBase64
* @return , base64
*/
public String encryptByPrivateKey(String text, String privateKeyBase64) {
RSA rsa = new RSA();
PrivateKey privateKey = KeyUtil.generateRSAPrivateKey(Base64.decode(privateKeyBase64));
rsa.setPrivateKey(privateKey);
return rsa.encryptBase64(text, KeyType.PrivateKey);
}
/**
*
*
* @param text ,base64
* @param publicKeyBase64
* @return
*/
public String decryptByPublicKey(String text, String publicKeyBase64) {
RSA rsa = new RSA();
PublicKey publicKey = KeyUtil.generateRSAPublicKey(Base64.decode(publicKeyBase64));
rsa.setPublicKey(publicKey);
return rsa.decryptStr(text, KeyType.PublicKey);
}
/**
* RSA
*
* @return .
*/
public RsaKeyPair generateKey() {
KeyPair keyPair = KeyUtil.generateKeyPair("RSA", 1024);
String publicBase64Key = KeyUtil.toBase64(keyPair.getPublic());
String privateBase64Key = KeyUtil.toBase64(keyPair.getPrivate());
return new RsaKeyPair(publicBase64Key, privateBase64Key);
}
/**
* RSA
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class RsaKeyPair {
private String publicKeyBase64;
private String privateKeyBase64;
}
}

View File

@ -0,0 +1,260 @@
package com.hb0730.boot.admin.config.cache;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Nonnull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class BootAdminCache {
private final BootAdminProperties cacheProperties;
private final StringRedisTemplate redisTemplate;
/**
* KEY,<code>:</code>
*
* @param key key
* @return <code>"prefix:key"</code>
*/
public String normaliz(String key) {
if (StrUtil.isBlank(key)) {
return null;
}
return cacheProperties.getCache().getPrefix() + ":" + key;
}
/**
*
*
* @param key .
* @return .
*/
public boolean hasKey(String key) {
return Boolean.TRUE.equals(redisTemplate.hasKey(normaliz(key)));
}
/**
* keys
*
* @param key .
* @return .
*/
public Set<String> getKeys(String key) {
String normalizKey = normaliz(key);
return Optional.ofNullable(redisTemplate.keys(normalizKey))
.orElse(CollUtil.newHashSet());
}
/**
* /s
*
* @param key key: prefix+key
* @param timeout timeout /s
* @return .
*/
public boolean expire(final String key, long timeout) {
return expire(key, timeout, TimeUnit.SECONDS);
}
/**
*
*
* @param key key,{@link #normaliz(String)}
* @param timeout timeout
* @param unit time unit
* @return .
*/
public boolean expire(final String key, long timeout, TimeUnit unit) {
String _key = normaliz(key);
Boolean _res = this.redisTemplate.expire(_key, timeout, unit);
return Boolean.TRUE.equals(_res);
}
/**
* , /s
*
* @param key key,{@link #normaliz(String)}
* @return timeout
*/
public long getExpire(final String key) {
return getExpire(key, TimeUnit.SECONDS);
}
/**
*
*
* @param key key,{@link #normaliz(String)}
* @param unit time unit
* @return timeout
*/
public long getExpire(final String key, TimeUnit unit) {
String _key = normaliz(key);
return Optional.ofNullable(this.redisTemplate.getExpire(_key, unit)).orElse(0L);
}
/**
*
*
* @param key key,{@link #normaliz(String)}
* @param value .
* @return .
*/
public boolean set(final String key, String value) {
return set(key, value, -1);
}
/**
* ,/
*
* @param key key,{@link #normaliz(String)}
* @param value .
* @param timeout timeout,-l,
* @return .
*/
public boolean set(final String key, String value, long timeout) {
return set(key, value, timeout, TimeUnit.SECONDS);
}
/**
*
*
* @param key key,{@link #normaliz(String)}
* @param value .
* @param timeout timeout,-l,
* @param unit time unit
* @return .
*/
public boolean set(final String key, String value, long timeout, TimeUnit unit) {
if (StrUtil.isBlank(key)) {
log.warn("【boot-admin-cache】 set cache value warn, key missing");
return false;
}
String _key = normaliz(key);
log.debug("【boot-admin-cache】set cache value : key: {}, value: {},timeout: {}", _key, value, timeout);
if (timeout == -1) {
this.redisTemplate.opsForValue().set(_key, value);
} else {
this.redisTemplate.opsForValue().set(_key, value, timeout, unit);
}
return Boolean.TRUE;
}
/**
*
*
* @param key,{@link #normaliz(String)}
* @return .
*/
@Nonnull
public Optional<String> getStr(final String key) {
String _key = normaliz(key);
return Optional.ofNullable(this.redisTemplate.opsForValue().get(_key));
}
/**
*
*
* @param key key
* @return .
*/
public Optional<String> defaultGet(final String key) {
return Optional.ofNullable(this.redisTemplate.opsForValue().get(key));
}
/**
* hashKey
*
* @param key
* @return
*/
@Nonnull
public Optional<Map<String, String>> hmget(final String key) {
String _key = normaliz(key);
Map<Object, Object> entries = this.redisTemplate.opsForHash().entries(_key);
return Optional.of(entries).map(Map::entrySet).map(entries1 -> {
Map<String, String> map = new HashMap<>(entries1.size());
entries1.forEach(entry -> map.put(entry.getKey().toString(), entry.getValue().toString()));
return map;
});
}
/**
* hashKey
*
* @param key .
* @return .
*/
@Nonnull
public Optional<Set<String>> sGet(final String key) {
String _key = normaliz(key);
return Optional.ofNullable(this.redisTemplate.opsForSet().members(_key));
}
/**
* list, 0 -1
*
* @param key .
* @return .
*/
@Nonnull
public Optional<List<String>> lGet(final String key) {
return lGet(key, 0, -1);
}
/**
* list 0 -1
*
* @param key .
* @param start
* @param end
* @return .
*/
public Optional<List<String>> lGet(final String key, long start, long end) {
String _key = normaliz(key);
return Optional.ofNullable(this.redisTemplate.opsForList().range(_key, start, end));
}
/**
*
*
* @param keys .
* @return .
*/
public boolean del(Collection<String> keys) {
if (CollUtil.isEmpty(keys)) {
return Boolean.FALSE;
}
keys.forEach(this::del);
return Boolean.TRUE;
}
/**
*
*
* @param key,{@link #normaliz(String)}
* @return .
*/
public boolean del(final String key) {
String _key = normaliz(key);
return Boolean.TRUE.equals(this.redisTemplate.delete(_key));
}
}

View File

@ -0,0 +1,35 @@
package com.hb0730.boot.admin.config.cache;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
@Configuration
@ConfigurationProperties(prefix = "boot.admin")
@Data
public class BootAdminProperties {
/**
*
*/
private CacheProperties cache = new CacheProperties();
/**
* ,
* <p>
*
* </p>
*/
public Boolean refreshRoutes = false;
@Data
public static class CacheProperties {
/**
*
*/
private String prefix = "boot:admin:cache";
}
}

View File

@ -0,0 +1,37 @@
package com.hb0730.boot.admin.config.cache;
import java.util.Arrays;
import java.util.stream.Collectors;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/30
*/
public interface CacheUtil {
/**
* :
*/
String CACHE_SPLICE_COLON = ":";
/**
* KEY
*
* @param kv
* @param keys key
*/
default String getCacheKey(KeyValue kv, Object... keys) {
return buildKeys(kv, keys);
}
static String buildKeys(KeyValue kv, Object... keys) {
if (keys.length == 0) {
return kv.getPrefix();
}
return kv.getPrefix() + CACHE_SPLICE_COLON + concatKeys(keys);
}
static String concatKeys(Object... keys) {
return Arrays.stream(keys).map(String::valueOf).collect(Collectors.joining(CACHE_SPLICE_COLON));
}
}

View File

@ -0,0 +1,96 @@
package com.hb0730.boot.admin.config.cache;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/6
*/
public enum DefaultKeyValue implements KeyValue {
/**
*
* --------------------------------------------------------------------------------
* <p>sys_config</p>
* --------------------------------------------------------------------------------
*/
SYS_CONFIG("SYS",
EXPIRE_TIME_DEFAULT,
CacheType.STRING,
String.class,
"系统配置",
"SYS:key --> (String)value"),
;
/**
* KEY
*/
private final String prefix;
/**
*
*/
private final long expire;
/**
*
*/
private final Class<?> clazz;
/**
*
*/
private final String name;
/**
*
*/
private final String desc;
/**
* {JimDB getset 使}
*/
private CacheType type;
DefaultKeyValue(String prefix, long expire, CacheType type, Class<?> clazz, String name, String desc) {
this.prefix = prefix;
this.expire = expire;
this.clazz = clazz;
this.name = name;
this.desc = desc;
this.type = type;
}
@Override
public String getPrefix() {
return prefix;
}
@Override
public long getExpire() {
return expire;
}
@Override
public Class<?> getClazz() {
return clazz;
}
@Override
public String getName() {
return name;
}
@Override
public String getDesc() {
return desc;
}
public CacheType getType() {
return type;
}
/**
* JimDB
* <p> setget </p>
*/
public enum CacheType {
STRING, OBJECT, HASHMAP, SET, LIST
}
}

View File

@ -0,0 +1,65 @@
package com.hb0730.boot.admin.config.cache;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/30
*/
public interface KeyValue {
/**
* key
* <p> ==
* XXX: setObject-1
* <p>
*/
long EXPIRE_TIME_DEFAULT = -1;
/**
* 90
*/
long ORDER_TIME_OUT_LIMIT = 60 * 60 * 24 * 30;
/**
* KEY
*
* @return
*/
default String getPrefix() {
return "";
}
/**
*
*
* @return
*/
default long getExpire() {
return 0L;
}
/**
*
*
* @return
*/
default Class<?> getClazz() {
return null;
}
/**
*
*
* @return
*/
default String getName() {
return "";
}
/**
*
*/
default String getDesc() {
return "";
}
}

View File

@ -0,0 +1,28 @@
package com.hb0730.boot.admin.config.cors;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
@Configuration
public class CorsConfiguration {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
org.springframework.web.cors.CorsConfiguration config = new org.springframework.web.cors.CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}

View File

@ -0,0 +1,34 @@
package com.hb0730.boot.admin.config.handler;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hb0730.boot.admin.modules.api.buiness.model.PictureEntity;
import java.util.List;
/**
* JSON
* @author jianpòlan
* @version 1.0
**/
public class JsonHandler extends JacksonTypeHandler {
private final Class<Object> type;
public JsonHandler(Class<Object> type) {
super(type);
this.type = type;
}
@Override
protected Object parse(String json) {
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(json, new TypeReference<List<PictureEntity>>() { });
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,68 @@
package com.hb0730.boot.admin.config.jackson;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
/**
* jackson
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/12
*/
@Configuration
public class JacksonConfig {
private static final String DEFAULT_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
private static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> {
// 这一部分也可以在 yaml 中配置
builder
// 序列化时,对象为 null是否抛异常
.failOnEmptyBeans(false)
// 反序列化时json 中包含 pojo 不存在属性时,是否抛异常
.failOnUnknownProperties(false)
// 禁止将 java.util.Date, Calendar 序列化为数字(时间戳)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
// 设置 java.util.Date, Calendar 序列化、反序列化的格式
.dateFormat(new SimpleDateFormat(DEFAULT_DATETIME_PATTERN))
// 设置 java.util.Date、Calendar 序列化、反序列化的时区
.timeZone(TimeZone.getTimeZone("GMT+8"))
;
// Jackson 序列化 long类型为String解决后端返回的Long类型在前端精度丢失的问题
builder.serializerByType(BigInteger.class, ToStringSerializer.instance);
builder.serializerByType(Long.class, ToStringSerializer.instance);
builder.serializerByType(Long.TYPE, ToStringSerializer.instance);
// 配置 Jackson 反序列化 LocalDateTime、LocalDate、LocalTime 时使用的格式
builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATETIME_PATTERN)));
builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
builder.deserializerByType(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
// 配置 Jackson 序列化 LocalDateTime、LocalDate、LocalTime 时使用的格式
builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATETIME_PATTERN)));
builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
builder.serializers(new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
};
}
}

View File

@ -0,0 +1,29 @@
package com.hb0730.boot.admin.config.mybatis;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
@Configuration
@MapperScan(basePackages = "com.hb0730.boot.admin.**.mapper")
public class MybatisConfiguration {
/**
*
*
* @return .
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}
}

View File

@ -0,0 +1,54 @@
package com.hb0730.boot.admin.config.springdoc;
import com.hb0730.boot.admin.base.BootAdminConst;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/12
*/
@Configuration
public class SpringdocConfiguration {
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(getInfo()
).addSecurityItem(
new io.swagger.v3.oas.models.security.SecurityRequirement()
.addList(BootAdminConst.X_ACCESS_TOKEN)
).schemaRequirement(
BootAdminConst.X_ACCESS_TOKEN,
securityScheme()
).components(
new Components()
.addSecuritySchemes(BootAdminConst.X_ACCESS_TOKEN, securityScheme())
);
}
private Info getInfo() {
return new Info()
.title("boot-admin系统API")
.contact(
new Contact()
.name("hb0730")
.url("https://blog.hb0730.me")
.email("huangbing0730@gmail.com")
)
.version("v5.0.0")
;
}
private SecurityScheme securityScheme() {
SecurityScheme securityScheme = new SecurityScheme();
securityScheme.setType(SecurityScheme.Type.APIKEY);
securityScheme.setName(BootAdminConst.X_ACCESS_TOKEN);
securityScheme.setIn(SecurityScheme.In.HEADER);
return securityScheme;
}
}

View File

@ -0,0 +1,17 @@
package com.hb0730.boot.admin.core.service;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@Slf4j
public class BaseServiceImpl<
M extends BaseMapper<T>,
T
> extends ServiceImpl<M, T> implements IService<T> {
}

View File

@ -0,0 +1,52 @@
package com.hb0730.boot.admin.data.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@Data
@EqualsAndHashCode
@ToString
public class BaseEntity implements Serializable {
/**
* ID
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "id")
protected String id;
/**
*
*/
@Schema(description = "创建人")
protected String createdBy;
/**
*
*/
@Schema(description = "创建时间")
protected LocalDateTime created;
/**
*
*/
@Schema(description = "更新人")
protected String modifiedBy;
/**
*
*/
@Schema(description = "更新时间")
protected LocalDateTime modified;
}

View File

@ -0,0 +1,84 @@
package com.hb0730.boot.admin.data.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/28
*/
@Data
@EqualsAndHashCode
@ToString
public class BasePage<T> implements Serializable {
/**
*
*/
@Schema(description = "数据集合")
private List<T> records;
/**
*
*/
@Schema(description = "数据总数")
private long total;
/**
* size
*/
@Schema(description = "分页size")
private long size;
/**
*
*/
@Schema(description = "当前页码")
private long current;
public BasePage() {
this.records = Collections.emptyList();
this.total = 0L;
this.size = 0L;
this.current = 0L;
}
public BasePage(long current, long size) {
this(current, size, 0L);
}
public BasePage(long current, long size, long total) {
this(current, size, total, null);
}
public BasePage(long current, long size, long total, List<T> records) {
this.setCurrent(current)
.setSize(size)
.setTotal(total)
.setRecords(records);
}
public BasePage<T> setCurrent(long current) {
this.current = current;
return this;
}
public BasePage<T> setSize(long size) {
this.size = size;
return this;
}
public BasePage<T> setTotal(long total) {
this.total = total;
return this;
}
public BasePage<T> setRecords(List<T> records) {
this.records = records;
return this;
}
}

View File

@ -0,0 +1,27 @@
package com.hb0730.boot.admin.data.domain;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Serializable;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/12
*/
@Data
@EqualsAndHashCode
@ToString
public class BasePageQuery implements Serializable {
@Parameter(description = "分页size")
@Schema(description = "分页size")
private long size;
@Parameter(description = "当前页数")
@Schema(description = "当前页数")
private long current;
}

View File

@ -0,0 +1,42 @@
package com.hb0730.boot.admin.data.domain;
import java.io.Serializable;
import java.util.List;
/**
*
*
* @param <T> .
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/12
*/
public interface TreeData<T extends TreeData<T>> extends Serializable {
/**
* id
*
* @return .
*/
String getId();
/**
* parent id
*
* @return .
*/
String getParentId();
/**
* children
*
* @return .
*/
List<T> getChildren();
/**
* set children
*
* @param data .
* @return .
*/
TreeData<T> setChildren(List<T> data);
}

View File

@ -0,0 +1,29 @@
package com.hb0730.boot.admin.data.enums;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/12
*/
public enum ConfigTypeEnums implements ValueEnum<Integer> {
CONFIG_TYPE01(1, "系统配置"),
CONFIG_TYPE02(2, "业务配置"),
;
private final Integer value;
private final String name;
ConfigTypeEnums(Integer value, String name) {
this.value = value;
this.name = name;
}
@Override
public Integer getValue() {
return value;
}
public String getName() {
return name;
}
}

View File

@ -0,0 +1,38 @@
package com.hb0730.boot.admin.data.enums;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
public enum EnabledEnums implements ValueEnum<Integer> {
/**
* :1
*/
enabled("启用", "", 1),
/**
* :0
*/
un_enabled("禁用", "", 0);
private final String name;
private final String alias;
private final Integer value;
EnabledEnums(String name, String alias, Integer value) {
this.name = name;
this.alias = alias;
this.value = value;
}
public String getName() {
return name;
}
public String getAlias() {
return alias;
}
@Override
public Integer getValue() {
return value;
}
}

View File

@ -0,0 +1,45 @@
package com.hb0730.boot.admin.data.enums;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
public enum GenderEnums implements ValueEnum<Integer> {
/**
*
*/
unknown("未知", "保密", -1),
/**
*
*/
man("男", "先生", 0),
/**
*
*/
woman("女", "女士", 1),
;
private final String name;
private final String alias;
private final Integer value;
GenderEnums(String name, String alias, Integer value) {
this.name = name;
this.alias = alias;
this.value = value;
}
public String getName() {
return name;
}
public String getAlias() {
return alias;
}
@Override
public Integer getValue() {
return value;
}
}

View File

@ -0,0 +1,30 @@
package com.hb0730.boot.admin.data.enums;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/12
*/
public enum MenuTypeEnums implements ValueEnum<Integer> {
dir("目录", 0),
menu("菜单", 1),
permission("权限", 2),
;
private final String name;
private final Integer value;
MenuTypeEnums(String name, Integer value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
@Override
public Integer getValue() {
return value;
}
}

View File

@ -0,0 +1,52 @@
package com.hb0730.boot.admin.data.enums;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/12
*/
public enum OperateEnums implements ValueEnum<Integer> {
operate_null("", 0),
/**
*
*/
operate_query("查询", 1),
/**
*
*/
operate_add("添加", 2),
/**
*
*/
operate_edit("更新", 3),
/**
*
*/
operate_delete("删除", 4),
/**
*
*/
operate_export("导出", 5),
/**
*
*/
operate_import("导入", 6),
;
private final String name;
private final Integer value;
OperateEnums(String name, Integer value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
@Override
public Integer getValue() {
return value;
}
}

View File

@ -0,0 +1,62 @@
package com.hb0730.boot.admin.data.enums;
import java.util.stream.Stream;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/11
*/
public interface ValueEnum<T> {
/**
* Gets enum value.
*
* @return enum value
*/
T getValue();
/**
* Converts value to corresponding enum.
*
* @param enumType ,
* @param value
* @param <V>
* @param <E>
* @return corresponding enum
*/
static <V, E extends Enum<E> & ValueEnum<V>> E valueToEnum(Class<E> enumType, V value) {
return Stream.of(enumType.getEnumConstants())
.filter(item -> item.getValue().equals(value))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("unknown database value: " + value));
}
/**
* Converts value to corresponding enum.
*
* @param enumType ,
* @param value
* @param defaultValue
* @param <V>
* @param <E>
* @return corresponding enum
*/
static <V, E extends Enum<E> & ValueEnum<V>> E valueToEnum(Class<E> enumType, V value, E defaultValue) {
return Stream.of(enumType.getEnumConstants())
.filter(item -> item.getValue().equals(value))
.findFirst()
.orElse(defaultValue);
}
/**
*
*
* @param enumType
* @param value
* @param <V>
* @param <E>
* @return
*/
static <V, E extends Enum<E> & ValueEnum<V>> boolean hash(Class<E> enumType, V value) {
return Stream.of(enumType.getEnumConstants()).anyMatch(item -> item.getValue().equals(value));
}
}

View File

@ -0,0 +1,17 @@
package com.hb0730.boot.admin.job;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/13
*/
@Component
@Slf4j
public class MyTestJobService {
public void start(String params) {
log.info("MyTestJobService start {}", params);
}
}

View File

@ -0,0 +1,45 @@
package com.hb0730.boot.admin.job;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/12
* @see <a href="https://docs.spring.io/spring-boot/docs/current/reference/html/io.html#io.quartz">quartz</a
*/
@Slf4j
public class SampleInjectBeanJob extends QuartzJobBean {
private MyTestJobService myTestJobService;
/**
*
* <p>
* @Resource@Autowired
*
* @param myTestJobService .
* @see org.springframework.scheduling.quartz.SpringBeanJobFactory#createJobInstance(TriggerFiredBundle)
* getAutowireCapableBeanFactory
* </p>
*/
@Resource
public void setMyTestJobService(MyTestJobService myTestJobService) {
this.myTestJobService = myTestJobService;
}
@Override
protected void executeInternal(@NotNull JobExecutionContext context) throws JobExecutionException {
log.info("普通定时任务 SampleInjectBeanJob ! 时间: {}", myTestJobService);
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String parameter = jobDataMap.getString("parameter");
myTestJobService.start(parameter);
}
}

View File

@ -0,0 +1,21 @@
package com.hb0730.boot.admin.job;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/12
*/
@Slf4j
public class SampleJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info("普通定时任务 SampleJob ! 时间: {}", DateUtil.now());
}
}

View File

@ -0,0 +1,38 @@
package com.hb0730.boot.admin.job;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
/**
* JOB
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/12
*/
@Slf4j
public class SampleParamJob implements Job {
/**
*
*/
private String parameter;
/**
*
*
* @param parameter
*/
public void setParameter(String parameter) {
this.parameter = parameter;
}
//------------------------------------------------------------------------------------------------
@Override
public void execute(JobExecutionContext jobExecutionContext) {
log.info("welcome {}! 带参数定时任务 SampleParamJob ! 时间 :{}", this.parameter, DateUtil.now());
}
}

View File

@ -0,0 +1,34 @@
package com.hb0730.boot.admin.modules.api.buiness.controller;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.modules.api.buiness.service.OssService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@Tag(name = "系统:阿里云:上传")
@RestController
@RequestMapping("buiness/oss")
public class OssController {
@Autowired
OssService ossService;
//1、上传文件到oss 接收客户端上传的文件流和文件名称 上传到oss之后 返回上传成功的文件路径
@PostMapping("upload")
@Operation(summary = "上传文件")
public R uploadFile(@RequestBody MultipartFile file
) {
return ossService.uploadFile(file);
}
//2、删除oss中的文件
@DeleteMapping("delete")
@Operation(summary = "删除文件")
public R deleteFile(@RequestParam("path") String path
) {
return ossService.deleteFile(path);
}
}

View File

@ -0,0 +1,101 @@
package com.hb0730.boot.admin.modules.api.buiness.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.model.SysBox;
import com.hb0730.boot.admin.modules.api.buiness.model.SysShop;
import com.hb0730.boot.admin.modules.api.buiness.model.query.BoxQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.query.ShopQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.BoxVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.ShopVO;
import com.hb0730.boot.admin.modules.api.buiness.service.SysBoxService;
import com.hb0730.boot.admin.modules.api.buiness.service.SysShopService;
import com.hb0730.boot.admin.security.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@RestController
@RequestMapping("/buiness/box")
@Tag(name = "系统:包厢管理")
@RequiredArgsConstructor
public class SysBoxController {
private final SysBoxService sysBoxService;
@GetMapping("/query/page")
@Operation(summary = "分页查询")
public R<BasePage<BoxVO>> queryPage(HttpServletRequest request, @ParameterObject BoxQuery query) {
BasePage<BoxVO> res = this.sysBoxService.queryPage(query);
return R.OK(res);
}
// @GetMapping("/query/list")
// @Operation(summary = "列表查询")
// public R<List<UserVO>> queryList(HttpServletRequest request, @ParameterObject UserQuery query) {
// List<UserVO> res = this.sysShopService.queryList(query);
// return R.OK(res);
// }
//
// @GetMapping("/check/username")
// @Operation(summary = "检查用户名是否存在")
// public R<Boolean> checkUsername(HttpServletRequest request, @RequestParam String username) {
// return this.sysBoxService.hashUsername(username);
// }
////
@GetMapping("/")
@Operation(summary = "详情")
public R<BoxVO> detail(HttpServletRequest request, @Parameter(name = "id", description = "包厢ID",
required = true) @RequestParam String id) {
return this.sysBoxService.detail(id);
}
@PostMapping("/save")
@Operation(summary = "保存")
public R<BoxVO> save(HttpServletRequest request, @Validated @RequestBody BoxVO boxVO) {
return this.sysBoxService.saveShop(boxVO);
}
@PutMapping("/update/{id}")
@Operation(summary = "修改")
public R<BoxVO> update(HttpServletRequest request,@PathVariable String id,
@Validated @RequestBody BoxVO boxVO) {
SysBox byId = sysBoxService.getById(boxVO.getId());
boxVO.setModified(LocalDateTime.now());
boxVO.setModifiedBy(SecurityUtil.getCurrentUsername());
BeanUtils.copyProperties(boxVO,byId);
this.sysBoxService.updateById(byId);
return R.OK(boxVO);
}
@GetMapping("/delete")
@Operation(summary = "删除")
public R delete(HttpServletRequest request , @RequestParam String id) {
QueryWrapper<SysBox> wrapper = new QueryWrapper<>();
wrapper.eq(
"id",id
);
return R.OK(this.sysBoxService.remove(wrapper));
}
}

View File

@ -0,0 +1,102 @@
package com.hb0730.boot.admin.modules.api.buiness.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.model.SysBox;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCoupon;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCouponLog;
import com.hb0730.boot.admin.modules.api.buiness.model.query.BoxQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.query.CouponQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.BoxVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.GetCouponLogVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.ShopVO;
import com.hb0730.boot.admin.modules.api.buiness.service.SysBoxService;
import com.hb0730.boot.admin.modules.api.buiness.service.SysCouponService;
import com.hb0730.boot.admin.security.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@RestController
@RequestMapping("/buiness/coupon")
@Tag(name = "系统:优惠券管理")
@RequiredArgsConstructor
public class SysCouponController {
private final SysCouponService sysCouponService;
@GetMapping("/query/page")
@Operation(summary = "分页查询")
public R<BasePage<CouponVO>> queryPage(HttpServletRequest request, @ParameterObject CouponQuery query) {
BasePage<CouponVO> res = this.sysCouponService.queryPage(query);
return R.OK(res);
}
@GetMapping()
@Operation(summary = "详情")
public R<CouponVO> detail(HttpServletRequest request, @Parameter(name = "id", description = "优惠券ID",
required = true) @RequestParam String id) {
return this.sysCouponService.detail(id);
}
@PostMapping("/save")
@Operation(summary = "保存")
public R<CouponVO> save(HttpServletRequest request, @Validated @RequestBody CouponVO couponVO) {
return this.sysCouponService.saveShop(couponVO);
}
@PutMapping("/update/{id}")
@Operation(summary = "修改")
public R<CouponVO> update(HttpServletRequest request, @PathVariable String id,
@Validated @RequestBody CouponVO couponVO) {
couponVO.setModified(LocalDateTime.now());
couponVO.setModifiedBy(SecurityUtil.getCurrentUsername());
return this.sysCouponService.updateById(id, couponVO);
}
@GetMapping("/delete")
@Operation(summary = "删除")
public R delete(HttpServletRequest request , @RequestParam String id) {
QueryWrapper<SysCoupon> wrapper = new QueryWrapper<>();
wrapper.eq(
"id",id
);
return R.OK(this.sysCouponService.remove(wrapper));
}
@GetMapping("/getCoupon")
@Operation(summary = "领取取优惠券")
public R<GetCouponLogVO> getCoupon(HttpServletRequest request , @RequestParam("id") String id , @RequestParam String openId) {
return this.sysCouponService.getCoupon(id,openId);
}
@GetMapping("/verification")
@Operation(summary = "核销优惠券")
public R<String> verification(HttpServletRequest request ,@Parameter(name = "id", description = "领取记录表ID",
required = true) @RequestParam String id ,
@Parameter(name = "checkCode", description = "核销码",
required = true)@RequestParam String checkCode) {
return this.sysCouponService.verification(id,checkCode);
}
}

View File

@ -0,0 +1,82 @@
package com.hb0730.boot.admin.modules.api.buiness.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCoupon;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCouponLog;
import com.hb0730.boot.admin.modules.api.buiness.model.query.CouponQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponLogVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponVO;
import com.hb0730.boot.admin.modules.api.buiness.service.SysCouponLogService;
import com.hb0730.boot.admin.modules.api.buiness.service.SysCouponService;
import com.hb0730.boot.admin.security.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@RestController
@RequestMapping("/buiness/couponLog")
@Tag(name = "系统:优惠券领取记录管理")
@RequiredArgsConstructor
public class SysCouponLogController {
private final SysCouponLogService sysCouponLogService;
@GetMapping("/query/page")
@Operation(summary = "分页查询")
public R<BasePage<CouponLogVO>> queryPage(HttpServletRequest request, @ParameterObject CouponQuery query) {
BasePage<CouponLogVO> res = this.sysCouponLogService.queryPage(query);
return R.OK(res);
}
@GetMapping()
@Operation(summary = "详情")
public R<CouponLogVO> detail(HttpServletRequest request, @Parameter(name = "id", description = "优惠券ID",
required = true) @RequestParam String id) {
return this.sysCouponLogService.detail(id);
}
@PostMapping("/save")
@Operation(summary = "保存")
public R<CouponLogVO> save(HttpServletRequest request, @Validated @RequestBody CouponLogVO couponlogVO) {
return this.sysCouponLogService.saveShop(couponlogVO);
}
@PutMapping("/update/{id}")
@Operation(summary = "修改")
public R<CouponLogVO> update(HttpServletRequest request, @PathVariable String id,
@Validated @RequestBody CouponLogVO couponVO) {
couponVO.setModified(LocalDateTime.now());
couponVO.setModifiedBy(SecurityUtil.getCurrentUsername());
return this.sysCouponLogService.updateById(id, couponVO);
}
@GetMapping("/delete")
@Operation(summary = "删除")
public R delete(HttpServletRequest request , @RequestParam String id) {
QueryWrapper<SysCouponLog> wrapper = new QueryWrapper<>();
wrapper.eq(
"id",id
);
return R.OK(this.sysCouponLogService.remove(wrapper));
}
}

View File

@ -0,0 +1,103 @@
package com.hb0730.boot.admin.modules.api.buiness.controller;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.model.SysShop;
import com.hb0730.boot.admin.modules.api.buiness.model.query.ShopQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.HourVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.SeasonVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.ShopVO;
import com.hb0730.boot.admin.modules.api.buiness.service.SysShopService;
import com.hb0730.boot.admin.modules.sys.system.model.query.UserQuery;
import com.hb0730.boot.admin.modules.sys.system.model.vo.RestPasswdVO;
import com.hb0730.boot.admin.modules.sys.system.model.vo.UserVO;
import com.hb0730.boot.admin.modules.sys.system.service.SysUserService;
import com.hb0730.boot.admin.security.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@RestController
@RequestMapping("/buiness/shop")
@Tag(name = "系统:店铺管理")
@RequiredArgsConstructor
public class SysShopController {
private final SysShopService sysShopService;
@GetMapping("/query/page")
@Operation(summary = "分页查询")
public R<BasePage<ShopVO>> queryPage(HttpServletRequest request, @ParameterObject ShopQuery query) {
BasePage<ShopVO> res = this.sysShopService.queryPage(query);
return R.OK(res);
}
@GetMapping
@Operation(summary = "详情")
public R<ShopVO> detail(HttpServletRequest request, @Parameter(name = "id", description = "店铺ID",
required = true) @RequestParam String id) {
return this.sysShopService.detail(id);
}
@PostMapping("/save")
@Operation(summary = "保存")
public R<ShopVO> save(HttpServletRequest request, @Validated @RequestBody ShopVO shopVO) {
return this.sysShopService.saveShop(shopVO);
}
//
//
@PutMapping("/update/{id}")
@Operation(summary = "修改")
public R<ShopVO> update(HttpServletRequest request, @PathVariable String id,
@Validated @RequestBody ShopVO shopVO) {
shopVO.setModified(LocalDateTime.now());
shopVO.setModifiedBy(SecurityUtil.getCurrentUsername());
return this.sysShopService.updateById(id, shopVO);
}
@GetMapping("/delete")
@Operation(summary = "删除")
public R delete(HttpServletRequest request , @RequestParam String id) {
QueryWrapper<SysShop> wrapper = new QueryWrapper<>();
wrapper.eq(
"id",id
);
return R.OK(this.sysShopService.remove(wrapper));
}
@GetMapping("/getSeason")
@Operation(summary = "获取季节菜品")
public R<List<SeasonVO>> getSeason(HttpServletRequest request) {
return R.OK(this.sysShopService.getSeason());
}
@GetMapping("/getHour")
@Operation(summary = "获取小时菜品")
public R<List<HourVO>> getHour(HttpServletRequest request) {
return R.OK(this.sysShopService.getHour());
}
}

View File

@ -0,0 +1,19 @@
package com.hb0730.boot.admin.modules.api.buiness.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb0730.boot.admin.modules.api.buiness.model.SysBox;
import com.hb0730.boot.admin.modules.api.buiness.model.SysShop;
import com.hb0730.boot.admin.modules.api.buiness.model.query.BoxQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.query.ShopQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.BoxVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.ShopVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface SysBoxMapper extends BaseMapper<SysBox> {
List<SysBox> queryPage(Page<BoxVO> page, @Param("query") BoxQuery query);
}

View File

@ -0,0 +1,18 @@
package com.hb0730.boot.admin.modules.api.buiness.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCoupon;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCouponLog;
import com.hb0730.boot.admin.modules.api.buiness.model.query.CouponQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponLogVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface SysCouponLogMapper extends BaseMapper<SysCouponLog> {
List<SysCouponLog> queryPage(Page<CouponLogVO> page, @Param("query") CouponQuery query);
}

View File

@ -0,0 +1,21 @@
package com.hb0730.boot.admin.modules.api.buiness.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb0730.boot.admin.modules.api.buiness.model.SysBox;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCoupon;
import com.hb0730.boot.admin.modules.api.buiness.model.query.BoxQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.query.CouponQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.BoxVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface SysCouponMapper extends BaseMapper<SysCoupon> {
List<SysCoupon> queryPage(Page<CouponVO> page, @Param("query") CouponQuery query);
void updateNums(@Param("id")String id);
}

View File

@ -0,0 +1,22 @@
package com.hb0730.boot.admin.modules.api.buiness.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb0730.boot.admin.modules.api.buiness.model.SysShop;
import com.hb0730.boot.admin.modules.api.buiness.model.query.ShopQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.HourVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.SeasonVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.ShopVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface SysShopMapper extends BaseMapper<SysShop> {
List<SysShop> queryPage(Page<ShopVO> page, @Param("query") ShopQuery query);
List<SeasonVO> getSeason();
List<HourVO> getHour();
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hb0730.boot.admin.modules.api.buiness.mapper.SysBoxMapper">
<sql id="Base_sql">
t.id,
t.created_by,
t.created,
t.modified_by,
t.modified,
t.name,
t.min,
t.max,
t.images_url,
t.shop_id,
t.nums
</sql>
<select id="queryPage" resultType="com.hb0730.boot.admin.modules.api.buiness.model.SysBox">
SELECT
<include refid="Base_sql"/>,t.name as name
FROM `sys_box` t
WHERE 1=1
<if test="query.shopId!=null and query.shopId!=''">
AND t.shop_id = #{query.shopId}
</if>
</select>
</mapper>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hb0730.boot.admin.modules.api.buiness.mapper.SysCouponLogMapper">
<sql id="Base_sql">
t.id,
t.created_by,
t.created,
t.modified_by,
t.modified,
t.user_id,
t.coupon_id,
t.open_id,
t.check_code,
t.user_name,
t.gift_name
</sql>
<select id="queryPage" resultType="com.hb0730.boot.admin.modules.api.buiness.model.SysCouponLog">
SELECT
<include refid="Base_sql"/>
FROM `sys_coupon_log` t
where t.coupon_id = #{query.id}
ORDER BY t.modified ASC
</select>
</mapper>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hb0730.boot.admin.modules.api.buiness.mapper.SysCouponMapper">
<sql id="Base_sql">
t.id,
t.created_by,
t.created,
t.modified_by,
t.modified,
t.coupon_name,
t.nums,
t.title,
t.receive_date,
t.receive_time,
t.activity_rules,
t.activity_dec,
t.gift_name,
t.gift_image,
t.open_id,
t.tag_img
</sql>
<select id="queryPage" resultType="com.hb0730.boot.admin.modules.api.buiness.model.SysCoupon">
SELECT
<include refid="Base_sql"/>,t.coupon_name
FROM `sys_coupon` t
</select>
<update id="updateNums">
UPDATE sys_coupon SET nums = nums - 1 WHERE id = #{id};
</update>
</mapper>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hb0730.boot.admin.modules.api.buiness.mapper.SysShopMapper">
<sql id="Base_sql">
t.id,
t.created_by,
t.created,
t.modified_by,
t.modified,
t.name,
t.intro_chi as introChi,
t.intro_eng as introEng,
t.intro_jap as introJap,
t.phone,
t.start_time,
t.end_time,
t.tag_url,
t.logo_url,
t.picture_url,
t.floor,
t.vagetable_url,
t.is_enable as isEnable,
t.name_picture,
t.title,
t.season,
t.hour,
t.sort
</sql>
<select id="queryPage" resultType="com.hb0730.boot.admin.modules.api.buiness.model.SysShop">
SELECT
<include refid="Base_sql"/>,t.name as name
FROM `sys_shop` t
WHERE 1=1
<if test="query.name!=null and query.name!=''">
AND t.name LIKE CONCAT('%',#{query.name},'%')
</if>
ORDER BY t.sort Asc
</select>
<select id="getSeason" resultType="com.hb0730.boot.admin.modules.api.buiness.model.vo.SeasonVO">
select id , season , `sort` , modified from sys_shop ORDER BY sort Asc
</select>
<select id="getHour" resultType="com.hb0730.boot.admin.modules.api.buiness.model.vo.HourVO">
select id, `hour` , `sort` , modified from sys_shop ORDER BY sort Asc
</select>
</mapper>

View File

@ -0,0 +1,10 @@
package com.hb0730.boot.admin.modules.api.buiness.model;
import lombok.Data;
@Data
public class PictureEntity {
public String name;
public String url;
}

View File

@ -0,0 +1,45 @@
package com.hb0730.boot.admin.modules.api.buiness.model;
import com.baomidou.mybatisplus.annotation.TableName;
import com.hb0730.boot.admin.data.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
@TableName
public class SysBox extends BaseEntity {
/**
*
*/
private String name;
/**
*
*/
private Integer min;
/**
*
*/
private Integer max;
/**
*
*/
private String imagesUrl;
/**
* id
*/
private String shopId;
/**
*
*/
private Integer nums;
}

View File

@ -0,0 +1,51 @@
package com.hb0730.boot.admin.modules.api.buiness.model;
import com.baomidou.mybatisplus.annotation.TableName;
import com.hb0730.boot.admin.data.domain.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
@TableName(value = "sys_coupon",autoResultMap = true)
public class SysCoupon extends BaseEntity {
/**
*
*/
private String couponName;
/**
*
*/
private Integer nums;
private String userId;
private String title;
private String receiveDate;
private String receiveTime;
private String activityRules;
private String activityDec;
private String giftName;
private String giftImage;
private String openId;
private String tagImg;
}

View File

@ -0,0 +1,37 @@
package com.hb0730.boot.admin.modules.api.buiness.model;
import com.baomidou.mybatisplus.annotation.TableName;
import com.hb0730.boot.admin.data.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
@TableName(value = "sys_coupon_log")
public class SysCouponLog extends BaseEntity {
/**
*
*/
private String title;
private String userId;
private String couponId;
private String openId;
private String checkCode;
private String userName;
private String giftName;
}

View File

@ -0,0 +1,100 @@
package com.hb0730.boot.admin.modules.api.buiness.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.hb0730.boot.admin.config.handler.JsonHandler;
import com.hb0730.boot.admin.data.domain.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
@TableName(value = "sys_shop",autoResultMap = true)
public class SysShop extends BaseEntity {
/**
*
*/
private String name;
/**
*
*/
private String introChi;
/**
*
*/
private String introEng;
/**
*
*/
private String introJap;
/**
*
*/
private String phone;
/**
*
*/
private String startTime;
/**
*
*/
private String endTime;
/**
* url
*/
private String tagUrl;
/**
* logo url
*/
private String logoUrl;
/**
* url
*/
private String namePicture;
/**
* url
*/
@TableField(value = "picture_url")
private String pictureUrl;
@TableField(value = "vagetable_url")
private String vagetableUrl;
/**
*
*/
private Integer floor;
/**
* truefalse
*/
@TableField(value = "is_enable" )
private Boolean isEnable= false;
@TableField(value = "season" )
private String season;
@TableField(value = "title")
private String title;
@TableField(value = "hour")
private String hour;
@Schema(description = "排序")
@TableField(value = "sort")
private Integer sort;
}

View File

@ -0,0 +1,25 @@
package com.hb0730.boot.admin.modules.api.buiness.model.query;
import com.hb0730.boot.admin.data.domain.BasePageQuery;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/8
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
public class BoxQuery extends BasePageQuery {
/**
* id
*/
@Parameter(description = "店铺id")
private String shopId;
}

View File

@ -0,0 +1,22 @@
package com.hb0730.boot.admin.modules.api.buiness.model.query;
import com.hb0730.boot.admin.data.domain.BasePageQuery;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/8
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
public class CouponQuery extends BasePageQuery {
private String id;
}

View File

@ -0,0 +1,25 @@
package com.hb0730.boot.admin.modules.api.buiness.model.query;
import com.hb0730.boot.admin.data.domain.BasePageQuery;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/8
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
public class ShopQuery extends BasePageQuery {
/**
*
*/
@Parameter(description = "店铺名称")
private String name;
}

View File

@ -0,0 +1,80 @@
package com.hb0730.boot.admin.modules.api.buiness.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/8
*/
@Data
@EqualsAndHashCode
@ToString
public class BoxVO implements Serializable {
/**
* ID
*/
@Schema(description = "id")
protected String id;
/**
*
*/
@Schema(description = "创建人")
protected String createdBy;
/**
*
*/
@Schema(description = "创建时间")
protected LocalDateTime created;
/**
*
*/
@Schema(description = "更新人")
protected String modifiedBy;
/**
*
*/
@Schema(description = "更新时间")
protected LocalDateTime modified;
/**
* id
*/
@Schema(description = "更新时间")
private String shopId;
/**
*
*/
@Schema(description = "包厢名称")
private String name;
/**
*
*/
@Schema(description = "包厢最小人数")
private Integer min;
/**
*
*/
@Schema(description = "包厢最大人数")
private Integer max;
/**
*
*/
@Schema(description = "包厢图片路径")
private String imagesUrl;
@Schema(description = "包厢数量")
private Integer nums;
}

View File

@ -0,0 +1,98 @@
package com.hb0730.boot.admin.modules.api.buiness.model.vo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.hb0730.boot.admin.data.domain.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
@TableName
public class CouponLogVO extends BaseEntity {
/**
* ID
*/
@Schema(description = "id")
protected String id;
/**
*
*/
@Schema(description = "创建人")
protected String createdBy;
/**
*
*/
@Schema(description = "创建时间")
protected LocalDateTime created;
/**
*
*/
@Schema(description = "更新人")
protected String modifiedBy;
/**
*
*/
@Schema(description = "更新时间")
protected LocalDateTime modified;
/**
*
*/
@Schema(description = "优惠券名称")
private String couponName;
/**
* id
*/
@Schema(description = "用户id")
private String userId;
@Schema(description = "openId")
private String openId;
/**
*
*/
@Schema(description = "优惠券数量")
private Integer nums;
@Schema(description = "优惠券标题")
private String title;
@Schema(description = "优惠券领取日期")
private String receiveDate;
@Schema(description = "优惠券领取时间")
private String receiveTime;
@Schema(description = "活动规则")
private String activityRules;
@Schema(description = "活动说明")
private String activityDec;
@Schema(description = "礼品名称")
private String giftName;
@Schema(description = "礼品图片")
private String giftImage;
@Schema(description = "优惠券ID")
private String couponId;
private String checkCode;
}

View File

@ -0,0 +1,96 @@
package com.hb0730.boot.admin.modules.api.buiness.model.vo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.hb0730.boot.admin.data.domain.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
@TableName
public class CouponVO extends BaseEntity {
/**
* ID
*/
@Schema(description = "id")
protected String id;
/**
*
*/
@Schema(description = "创建人")
protected String createdBy;
/**
*
*/
@Schema(description = "创建时间")
protected LocalDateTime created;
/**
*
*/
@Schema(description = "更新人")
protected String modifiedBy;
/**
*
*/
@Schema(description = "更新时间")
protected LocalDateTime modified;
/**
*
*/
@Schema(description = "优惠券名称")
private String couponName;
/**
* id
*/
@Schema(description = "用户id")
private String userId;
@Schema(description = "openId")
private String openId;
/**
*
*/
@Schema(description = "优惠券数量")
private Integer nums;
@Schema(description = "优惠券标题")
private String title;
@Schema(description = "优惠券领取日期")
private String receiveDate;
@Schema(description = "优惠券领取时间")
private String receiveTime;
@Schema(description = "活动规则")
private String activityRules;
@Schema(description = "活动说明")
private String activityDec;
@Schema(description = "礼品名称")
private String giftName;
@Schema(description = "礼品图片")
private String giftImage;
@Schema(description = "标签图片")
private String tagImg;
}

View File

@ -0,0 +1,99 @@
package com.hb0730.boot.admin.modules.api.buiness.model.vo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.hb0730.boot.admin.data.domain.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/4
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
@TableName
public class GetCouponLogVO extends BaseEntity {
/**
* ID
*/
@Schema(description = "id")
protected String id;
/**
*
*/
@Schema(description = "创建人")
protected String createdBy;
/**
*
*/
@Schema(description = "创建时间")
protected LocalDateTime created;
/**
*
*/
@Schema(description = "更新人")
protected String modifiedBy;
/**
*
*/
@Schema(description = "更新时间")
protected LocalDateTime modified;
/**
*
*/
@Schema(description = "优惠券名称")
private String couponName;
/**
* id
*/
@Schema(description = "用户id")
private String userId;
@Schema(description = "openId")
private String openId;
/**
*
*/
@Schema(description = "优惠券数量")
private Integer nums;
@Schema(description = "优惠券标题")
private String title;
@Schema(description = "优惠券领取日期")
private String receiveDate;
@Schema(description = "优惠券领取时间")
private String receiveTime;
@Schema(description = "活动规则")
private String activityRules;
@Schema(description = "活动说明")
private String activityDec;
@Schema(description = "礼品名称")
private String giftName;
@Schema(description = "礼品图片")
private String giftImage;
@Schema(description = "优惠券ID")
private String couponId;
@Schema(description = "用户名称")
private String userName;
}

View File

@ -0,0 +1,12 @@
package com.hb0730.boot.admin.modules.api.buiness.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class HourVO {
@Schema(description = "id")
private String id;
@Schema(description = "小时菜品url")
private String hour;
}

View File

@ -0,0 +1,13 @@
package com.hb0730.boot.admin.modules.api.buiness.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class SeasonVO {
@Schema(description = "id")
private String id;
@Schema(description = "季节菜品url")
private String season;
}

View File

@ -0,0 +1,141 @@
package com.hb0730.boot.admin.modules.api.buiness.model.vo;
import cn.hutool.core.util.StrUtil;
import com.hb0730.boot.admin.base.util.AesEncryptUtil;
import com.hb0730.boot.admin.modules.api.buiness.model.PictureEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/8
*/
@Data
@EqualsAndHashCode
@ToString
public class ShopVO implements Serializable {
/**
* ID
*/
@Schema(description = "id")
protected String id;
/**
*
*/
@Schema(description = "创建人")
protected String createdBy;
/**
*
*/
@Schema(description = "创建时间")
protected LocalDateTime created;
/**
*
*/
@Schema(description = "更新人")
protected String modifiedBy;
/**
*
*/
@Schema(description = "更新时间")
protected LocalDateTime modified;
/**
*
*/
@Schema(description = "店铺名称")
private String name;
/**
*
*/
@Schema(description = "店铺介绍(中文)")
private String introChi;
/**
*
*/
@Schema(description = "店铺介绍(英文)")
private String introEng;
/**
*
*/
@Schema(description = "店铺介绍(日文")
private String introJap;
/**
*
*/
@Schema(description = "预约电话")
private String phone;
/**
*
*/
@Schema(description = "营业时间(开始时间)")
private String startTime;
/**
*
*/
@Schema(description = "营业时间(结束时间)")
private String endTime;
/**
* url
*/
@Schema(description = "标签图片url")
private String tagUrl;
/**
* logo url
*/
@Schema(description = "logo url")
private String logoUrl;
/**
* url
*/
@Schema(description = "轮播图url")
private String pictureUrl;
/**
*
*/
@Schema(description = "店铺楼层")
private Integer floor;
/**
* truefalse
*/
@Schema(description = "是否启用true启用false禁用")
private Boolean isEnable;
/**
* url
*/
@Schema(description = "名字url")
private String namePicture;
@Schema(description = "菜品url")
private String vagetableUrl;
@Schema(description = "季节菜品url")
private String season;
@Schema(description = "名字边上标题")
private String title;
@Schema(description = "小时菜品")
private String hour;
@Schema(description = "排序")
private Integer sort;
}

View File

@ -0,0 +1,12 @@
package com.hb0730.boot.admin.modules.api.buiness.service;
import com.hb0730.boot.admin.base.R;
import org.springframework.web.multipart.MultipartFile;
public interface OssService {
R uploadFile(MultipartFile file);
R deleteFile(String path);
}

View File

@ -0,0 +1,23 @@
package com.hb0730.boot.admin.modules.api.buiness.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.model.SysBox;
import com.hb0730.boot.admin.modules.api.buiness.model.SysShop;
import com.hb0730.boot.admin.modules.api.buiness.model.query.BoxQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.query.ShopQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.BoxVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.ShopVO;
import java.util.List;
public interface SysBoxService extends IService<SysBox> {
BasePage<BoxVO> queryPage(BoxQuery query);
R<BoxVO>detail(String id);
R<BoxVO> saveShop(BoxVO boxVO);
R<BoxVO> updateById(String id, BoxVO boxVO);
}

View File

@ -0,0 +1,21 @@
package com.hb0730.boot.admin.modules.api.buiness.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCoupon;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCouponLog;
import com.hb0730.boot.admin.modules.api.buiness.model.query.CouponQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponLogVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponVO;
public interface SysCouponLogService extends IService<SysCouponLog> {
BasePage<CouponLogVO> queryPage(CouponQuery query);
R<CouponLogVO> detail(String id);
R<CouponLogVO> saveShop(CouponLogVO couponlogVO);
R<CouponLogVO> updateById(String id, CouponLogVO couponVO);
}

View File

@ -0,0 +1,29 @@
package com.hb0730.boot.admin.modules.api.buiness.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.model.SysBox;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCoupon;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCouponLog;
import com.hb0730.boot.admin.modules.api.buiness.model.query.BoxQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.query.CouponQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.BoxVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.GetCouponLogVO;
import java.util.List;
public interface SysCouponService extends IService<SysCoupon> {
BasePage<CouponVO> queryPage(CouponQuery query);
R<CouponVO>detail(String id);
R<CouponVO> saveShop(CouponVO couponVO);
//
R<CouponVO> updateById(String id, CouponVO couponVO);
R<GetCouponLogVO> getCoupon(String id , String openId);
R<String> verification(String id, String checkCode);
}

View File

@ -0,0 +1,35 @@
package com.hb0730.boot.admin.modules.api.buiness.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.base.util.AesEncryptUtil;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.model.SysShop;
import com.hb0730.boot.admin.modules.api.buiness.model.query.ShopQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.HourVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.SeasonVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.ShopVO;
import com.hb0730.boot.admin.modules.sys.system.model.entity.SysUser;
import com.hb0730.boot.admin.modules.sys.system.model.vo.UserVO;
import java.util.HashSet;
import java.util.List;
public interface SysShopService extends IService<SysShop> {
BasePage<ShopVO> queryPage(ShopQuery query);
R<ShopVO> detail(String id);
R<ShopVO> updateById(String id, ShopVO vo);
R<ShopVO> saveShop(ShopVO shopVO);
List<SeasonVO> getSeason();
List<HourVO> getHour();
}

View File

@ -0,0 +1,59 @@
package com.hb0730.boot.admin.modules.api.buiness.service.impl;
import cn.hutool.core.date.DateTime;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.modules.api.buiness.service.OssService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
@Service("ossService")
public class OssServiceImpl implements OssService {
private static final String schema= "https://";
private static final String endpoint= "oss-cn-shanghai.aliyuncs.com";
private static final String accessKeyId= "LTAI5tMhBNyfJH7voue1VdD9";
private static final String accessKeySecret= "tdlSGtauAy154Yx1qX5peuZgpQVzWh";
private static final String bucketName= "huanqiuzhongxin";//huanqiuzhongxin
@Override
public R uploadFile(MultipartFile file) {
try {
//4、 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(schema + endpoint, accessKeyId, accessKeySecret);
String fileName = file.getOriginalFilename();//获取上传文件的名称
InputStream inputStream = file.getInputStream();
// 通过ossClient上传文件 参数1桶名 参数2上传后的文件路径+文件名 ,参数3要上传的文件流
String objectName = new DateTime().toString("yyyy/MM/dd/") +
UUID.randomUUID().toString().replace("-", "").substring(0, 16) +
"_" + fileName;//使用UUID+源文件名称后缀拼接生成objectName
ossClient.putObject(bucketName, objectName, inputStream);
// 关闭OSSClient。
ossClient.shutdown();
String path = schema + bucketName + "." + endpoint + "/" + objectName;//手动拼接上传成功的图片地址
System.out.println("path ======================================" + path);
return R.OK(path);
} catch (IOException e) {
throw new RuntimeException("图片上传失败");
}
}
@Override
public R deleteFile(String path) {
String host = schema + bucketName + "." + endpoint +"/";
String objectName = path.replace(host,"");
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
ossClient.deleteObject(bucketName, objectName.trim());
ossClient.shutdown();
return R.OK("删除成功");
}
}

View File

@ -0,0 +1,95 @@
package com.hb0730.boot.admin.modules.api.buiness.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.mapper.SysBoxMapper;
import com.hb0730.boot.admin.modules.api.buiness.mapper.SysShopMapper;
import com.hb0730.boot.admin.modules.api.buiness.model.SysBox;
import com.hb0730.boot.admin.modules.api.buiness.model.SysShop;
import com.hb0730.boot.admin.modules.api.buiness.model.query.BoxQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.query.ShopQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.BoxVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.ShopVO;
import com.hb0730.boot.admin.modules.api.buiness.service.SysBoxService;
import com.hb0730.boot.admin.modules.api.buiness.service.SysShopService;
import com.hb0730.boot.admin.security.util.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
public class SysBoxServiceImpl extends ServiceImpl<SysBoxMapper, SysBox> implements SysBoxService {
@Autowired
private SysShopMapper sysShopMapper;
@Override
public BasePage<BoxVO> queryPage(BoxQuery query) {
Page<BoxVO> page = new Page<>();
if ( query.getSize() == 0 || query.getCurrent() == 0) {
page = new Page<>(0, Integer.MAX_VALUE);
}else {
page = new Page<>(query.getCurrent(), query.getSize());
}
List<SysBox> boxes = baseMapper.queryPage(page, query);
List<BoxVO> collect = boxes.stream().map(box -> {
BoxVO boxVO = new BoxVO();
BeanUtils.copyProperties(box, boxVO);
return boxVO;
}).collect(Collectors.toList());
return new BasePage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
}
@Override
public R<BoxVO> detail(String id) {
LambdaQueryWrapper<SysBox> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysBox::getId, id);
SysBox box = this.baseMapper.selectOne(wrapper);
BoxVO boxVO = new BoxVO();
BeanUtil.copyProperties(box, boxVO);
return R.OK(boxVO);
}
@Override
public R<BoxVO> saveShop(BoxVO boxVO) {
SysBox box = new SysBox();
BeanUtils.copyProperties(boxVO,box);
box.setCreated(LocalDateTime.now());
box.setCreatedBy(SecurityUtil.getCurrentUsername());
box.setModified(LocalDateTime.now());
box.setModifiedBy(SecurityUtil.getCurrentUsername());
this.baseMapper.insert(box);
return R.OK(boxVO);
}
@Override
public R<BoxVO> updateById(String id, BoxVO boxVO) {
SysBox box = baseMapper.selectById(id);
if (null == box) {
return R.NG("包厢不存在");
}
BeanUtil.copyProperties(boxVO, box);
baseMapper.updateById(box);
return R.OK(boxVO);
}
}

View File

@ -0,0 +1,104 @@
package com.hb0730.boot.admin.modules.api.buiness.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.mapper.SysCouponLogMapper;
import com.hb0730.boot.admin.modules.api.buiness.mapper.SysCouponMapper;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCoupon;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCouponLog;
import com.hb0730.boot.admin.modules.api.buiness.model.query.CouponQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponLogVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponVO;
import com.hb0730.boot.admin.modules.api.buiness.service.SysCouponLogService;
import com.hb0730.boot.admin.modules.api.buiness.service.SysCouponService;
import com.hb0730.boot.admin.modules.sys.system.mapper.SysUserMapper;
import com.hb0730.boot.admin.modules.sys.system.model.entity.SysUser;
import com.hb0730.boot.admin.security.util.SecurityUtil;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
public class SysCouponLogServiceImpl extends ServiceImpl<SysCouponLogMapper, SysCouponLog> implements SysCouponLogService {
@Autowired
private SysCouponLogMapper sysCouponLogMapper;
@Autowired
private SysUserMapper sysUserMapper;
@Override
public BasePage<CouponLogVO> queryPage(CouponQuery query) {
Page<CouponLogVO> page = new Page<>();
if ( query.getSize() == 0 || query.getCurrent() == 0) {
page = new Page<>(0, Integer.MAX_VALUE);
}else {
page = new Page<>(query.getCurrent(), query.getSize());
}
List<SysCouponLog> coupons = sysCouponLogMapper.queryPage(page, query);
List<CouponLogVO> collect = coupons.stream().map(coupon -> {
CouponLogVO couponLogVO = new CouponLogVO();
BeanUtils.copyProperties(coupon, couponLogVO);
return couponLogVO;
}).collect(Collectors.toList());
return new BasePage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
}
@Override
public R<CouponLogVO> detail(String id) {
LambdaQueryWrapper<SysCouponLog> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysCouponLog::getId, id);
SysCouponLog sysCouponLog = this.baseMapper.selectOne(wrapper);
CouponLogVO couponVO = new CouponLogVO();
BeanUtil.copyProperties(sysCouponLog, couponVO);
return R.OK(couponVO);
}
@Override
public R<CouponLogVO> saveShop(CouponLogVO couponLogVO) {
SysCouponLog coupon = new SysCouponLog();
BeanUtils.copyProperties(couponLogVO,coupon);
coupon.setCreated(LocalDateTime.now());
coupon.setCreatedBy(SecurityUtil.getCurrentUsername());
coupon.setModified(LocalDateTime.now());
coupon.setModifiedBy(SecurityUtil.getCurrentUsername());
this.baseMapper.insert(coupon);
return R.OK(couponLogVO);
}
//
@Override
public R<CouponLogVO> updateById(String id, CouponLogVO couponVO) {
SysCouponLog coupon = getById(id);
if (null == coupon) {
return R.NG("优惠券不存在");
}
BeanUtil.copyProperties(couponVO, coupon);
baseMapper.updateById(coupon);
return R.OK(couponVO);
}
}

View File

@ -0,0 +1,174 @@
package com.hb0730.boot.admin.modules.api.buiness.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.mapper.SysBoxMapper;
import com.hb0730.boot.admin.modules.api.buiness.mapper.SysCouponLogMapper;
import com.hb0730.boot.admin.modules.api.buiness.mapper.SysCouponMapper;
import com.hb0730.boot.admin.modules.api.buiness.mapper.SysShopMapper;
import com.hb0730.boot.admin.modules.api.buiness.model.SysBox;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCoupon;
import com.hb0730.boot.admin.modules.api.buiness.model.SysCouponLog;
import com.hb0730.boot.admin.modules.api.buiness.model.SysShop;
import com.hb0730.boot.admin.modules.api.buiness.model.query.BoxQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.query.CouponQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.BoxVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.CouponVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.GetCouponLogVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.ShopVO;
import com.hb0730.boot.admin.modules.api.buiness.service.SysBoxService;
import com.hb0730.boot.admin.modules.api.buiness.service.SysCouponLogService;
import com.hb0730.boot.admin.modules.api.buiness.service.SysCouponService;
import com.hb0730.boot.admin.modules.sys.system.mapper.SysUserMapper;
import com.hb0730.boot.admin.modules.sys.system.model.entity.SysUser;
import com.hb0730.boot.admin.security.util.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.Formatter;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
@Slf4j
public class SysCouponServiceImpl extends ServiceImpl<SysCouponMapper, SysCoupon> implements SysCouponService {
@Autowired
private SysUserMapper sysUserMapper;
@Autowired
private SysCouponLogMapper sysCouponLogMapper;
@Override
public BasePage<CouponVO> queryPage(CouponQuery query) {
Page<CouponVO> page = new Page<>();
if ( query.getSize() == 0 || query.getCurrent() == 0) {
page = new Page<>(0, Integer.MAX_VALUE);
}else {
page = new Page<>(query.getCurrent(), query.getSize());
}
List<SysCoupon> coupons = baseMapper.queryPage(page, query);
List<CouponVO> collect = coupons.stream().map(coupon -> {
CouponVO couponVO = new CouponVO();
BeanUtils.copyProperties(coupon, couponVO);
return couponVO;
}).collect(Collectors.toList());
return new BasePage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
}
@Override
public R<CouponVO> detail(String id) {
LambdaQueryWrapper<SysCoupon> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysCoupon::getId, id);
SysCoupon box = this.baseMapper.selectOne(wrapper);
CouponVO couponVO = new CouponVO();
BeanUtil.copyProperties(box, couponVO);
return R.OK(couponVO);
}
@Override
public R<CouponVO> saveShop(CouponVO couponVO) {
SysCoupon coupon = new SysCoupon();
BeanUtils.copyProperties(couponVO,coupon);
coupon.setCreated(LocalDateTime.now());
coupon.setCreatedBy(SecurityUtil.getCurrentUsername());
coupon.setModified(LocalDateTime.now());
coupon.setModifiedBy(SecurityUtil.getCurrentUsername());
this.baseMapper.insert(coupon);
return R.OK(couponVO);
}
//
@Override
public R<CouponVO> updateById(String id, CouponVO couponVO) {
SysCoupon coupon = getById(id);
if (null == coupon) {
return R.NG("优惠券不存在");
}
BeanUtil.copyProperties(couponVO, coupon);
baseMapper.updateById(coupon);
return R.OK(couponVO);
}
@Override
public R<GetCouponLogVO> getCoupon(String id,String openid) {
LambdaQueryWrapper<SysCouponLog> logs = new LambdaQueryWrapper<>();
SysCoupon coupon = this.baseMapper.selectById(id);
LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
SysUser user = sysUserMapper.selectOne(wrapper.eq(SysUser::getOpenId, openid));
long l = System.currentTimeMillis();
String s = Long.toString(l, 36);
SysCouponLog sysCouponLog = new SysCouponLog();
if(Objects.nonNull(user)){
sysCouponLog.setUserId(user.getId());
if (StringUtils.isNotEmpty(user.getUsername())) {
sysCouponLog.setUserName(user.getUsername());
}
sysCouponLog.setOpenId(user.getOpenId());
}
sysCouponLog.setCouponId(coupon.getId());
sysCouponLog.setTitle(coupon.getTitle());
sysCouponLog.setGiftName(coupon.getGiftName());
sysCouponLog.setCreated(LocalDateTime.now());
sysCouponLog.setCheckCode(s);
sysCouponLogMapper.insert(sysCouponLog);
baseMapper.updateNums(id);
GetCouponLogVO getCouponLogVO = new GetCouponLogVO();
BeanUtils.copyProperties(sysCouponLog,getCouponLogVO);
return R.OK(getCouponLogVO);
}
@Override
public R<String> verification(String id, String checkCode) {
LambdaQueryWrapper<SysCouponLog> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysCouponLog::getCheckCode, checkCode);
wrapper.eq(SysCouponLog::getId, id);
SysCouponLog sysCouponLog = sysCouponLogMapper.selectOne(wrapper);
if(Objects.nonNull(sysCouponLog)){
UpdateWrapper<SysCouponLog> updateWrapper = new UpdateWrapper();
updateWrapper.set("modified", LocalDateTime.now());
updateWrapper.eq("id", id);
sysCouponLogMapper.update(sysCouponLog,updateWrapper);
return R.OK("验证通过!!!");
}else {
return R.error(201,"验证失败!!!!");
}
}
}

View File

@ -0,0 +1,111 @@
package com.hb0730.boot.admin.modules.api.buiness.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.api.buiness.mapper.SysShopMapper;
import com.hb0730.boot.admin.modules.api.buiness.model.SysShop;
import com.hb0730.boot.admin.modules.api.buiness.model.query.ShopQuery;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.HourVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.SeasonVO;
import com.hb0730.boot.admin.modules.api.buiness.model.vo.ShopVO;
import com.hb0730.boot.admin.modules.api.buiness.service.SysShopService;
import com.hb0730.boot.admin.security.util.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
public class SysShopServiceImpl extends ServiceImpl<SysShopMapper, SysShop> implements SysShopService {
@Autowired
private SysShopMapper sysShopMapper;
@Override
public BasePage<ShopVO> queryPage(ShopQuery query) {
Page<ShopVO> page = new Page<>();
if ( query.getSize() == 0 || query.getCurrent() == 0) {
page = new Page<>(0, Integer.MAX_VALUE);
}else {
page = new Page<>(query.getCurrent(), query.getSize());
}
List<SysShop> shops = this.sysShopMapper.queryPage(page, query);
List<ShopVO> collect = shops.stream().map(shop -> {
ShopVO shopVO = new ShopVO();
BeanUtils.copyProperties(shop, shopVO);
return shopVO;
}).collect(Collectors.toList());
System.out.println(collect);
return new BasePage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
}
@Override
public R<ShopVO> detail(String id)
{
SysShop shop = this.baseMapper.selectById(id);
ShopVO shopVO = new ShopVO();
BeanUtil.copyProperties(shop, shopVO);
return R.OK(shopVO);
}
@Override
public R<ShopVO> updateById(String id, ShopVO vo) {
SysShop shop = getById(id);
if (null == shop) {
return R.NG("店铺不存在");
}
BeanUtil.copyProperties(vo, shop);
baseMapper.updateById(shop);
return R.OK(vo);
}
@Override
public R<ShopVO> saveShop(ShopVO shopVO) {
SysShop sysShop = new SysShop();
BeanUtils.copyProperties(shopVO,sysShop);
sysShop.setCreated(LocalDateTime.now());
sysShop.setCreatedBy(SecurityUtil.getCurrentUsername());
sysShop.setModified(LocalDateTime.now());
sysShop.setModifiedBy(SecurityUtil.getCurrentUsername());
// sysShop.setPictureUrl(shopVO.getPictureUrl().toString());
this.baseMapper.insert(sysShop);
return R.OK(shopVO);
}
@Override
public List<SeasonVO> getSeason() {
List<SeasonVO> season = this.baseMapper.getSeason();
return season;
}
@Override
public List<HourVO> getHour() {
List<HourVO> hour = this.baseMapper.getHour();
return hour;
}
}

View File

@ -0,0 +1,98 @@
package com.hb0730.boot.admin.modules.sys.auth.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.SecureUtil;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.base.util.JwtUtil;
import com.hb0730.boot.admin.base.util.RsaUtil;
import com.hb0730.boot.admin.modules.sys.auth.event.LogoutEvent;
import com.hb0730.boot.admin.modules.sys.auth.model.LoginRequest;
import com.hb0730.boot.admin.modules.sys.auth.model.LoginResponse;
import com.hb0730.boot.admin.security.config.LoginProperties;
import com.hb0730.boot.admin.security.model.UserInfo;
import com.hb0730.boot.admin.security.token.TokenProvider;
import com.hb0730.boot.admin.security.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* token
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/12
*/
@RestController
@RequestMapping("/auth")
@Tag(name = "系统: 授权接口")
@RequiredArgsConstructor
public class AuthorizationController {
private final AuthenticationManager authenticationManager;
private final TokenProvider jwtTokenRedisCacheProvider;
private final LoginProperties loginProperties;
private final ApplicationContext applicationContext;
@Operation(summary = "登录授权")
@PostMapping("/login")
public R<LoginResponse> login(HttpServletRequest request, @RequestBody @Valid LoginRequest login) throws Exception {
SecureUtil.disableBouncyCastle();
String password = login.getPassword();
// 解密
password = RsaUtil.decryptByPrivateKey(login.getPassword(), loginProperties.getRsaPrivateKey());
//
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(login.getUsername(), password);
Authentication authenticate = null;
try {
// 会调用UserDetailsService#loadUserByUsername(String username)
authenticate = authenticationManager.authenticate(authenticationToken);
} catch (AuthenticationException e) {
if (e instanceof UsernameNotFoundException) {
return R.NG("用户名不存在");
} else {
return R.NG(e.getMessage());
}
}
assert authenticate != null;
UserInfo userInfo = (UserInfo) authenticate.getPrincipal();
String jwtToken = jwtTokenRedisCacheProvider.createToken(userInfo, request);
LoginResponse response = BeanUtil.toBean(userInfo, LoginResponse.class);
response.setToken(jwtToken);
return R.OK(response);
}
@Operation(summary = "用户信息")
@GetMapping("/info")
public R<Object> getUserInfo() {
return null;
}
@Operation(summary = "退出登录")
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request) {
String _jwtToken = JwtUtil.getTokenByRequest(request);
try {
// 如果超时,则获取失败
UserInfo userInfo = SecurityUtil.getCurrentUser();
applicationContext.publishEvent(new LogoutEvent(this, _jwtToken, userInfo.getUsername(), userInfo.getUserid()));
} catch (Exception ignored) {
}
jwtTokenRedisCacheProvider.removeToken(_jwtToken);
return R.OK("成功");
}
}

View File

@ -0,0 +1,73 @@
package com.hb0730.boot.admin.modules.sys.auth.controller;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class WeChatJSSDKSignature {
public static void main(String[] args) {
// 替换成你的公众号AppID和AppSecret
String appId = "wxbad2e8a91c62a734";
String appSecret = "e1b7fc425ca9cca05dd83609a6dc9c00";
// 替换成当前页面的URL
String url = "CURRENT_PAGE_URL";
String nonceStr = createNonceStr();
String timestamp = createTimestamp();
String jsapiTicket = getJsApiTicket(appId, appSecret);
String signature = generateSignature(jsapiTicket, nonceStr, timestamp, url);
System.out.println("nonceStr: " + nonceStr);
System.out.println("timestamp: " + timestamp);
System.out.println("signature: " + signature);
}
private static String createNonceStr() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
private static String createTimestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
private static String getJsApiTicket(String appId, String appSecret) {
// 调用微信API获取jsapi_ticket的逻辑这里省略实现
// 返回有效的jsapi_ticket
return "YOUR_JSAPI_TICKET";
}
private static String generateSignature(String jsapiTicket, String nonceStr, String timestamp, String url) {
Map<String, String> paramMap = new HashMap<>();
paramMap.put("noncestr", nonceStr);
paramMap.put("jsapi_ticket", jsapiTicket);
paramMap.put("timestamp", timestamp);
paramMap.put("url", url);
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
sb.deleteCharAt(sb.length() - 1);
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(sb.toString().getBytes("UTF-8"));
byte[] digest = crypt.digest();
Formatter formatter = new Formatter();
for (byte b : digest) {
formatter.format("%02x", b);
}
String signature = formatter.toString();
formatter.close();
return signature;
} catch (NoSuchAlgorithmException | java.io.UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,197 @@
package com.hb0730.boot.admin.modules.sys.auth.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.mrzin.tool.http.HttpTool;
import cn.mrzin.tool.lang.StringUtils;
import cn.mrzin.wx.login.WxCommonUtil;
import cn.mrzin.wx.login.WxH5LoginUtil;
import cn.mrzin.wx.login.enums.AccessTokenGrantType;
import cn.mrzin.wx.login.model.WxSecretInfo;
import cn.mrzin.wx.login.response.AccessTokenInfo;
import cn.mrzin.wx.login.response.WxH5LoginResponse;
import cn.mrzin.wx.login.response.WxLoginResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.modules.sys.auth.model.*;
import com.hb0730.boot.admin.modules.sys.auth.model.dto.LoginDto;
import com.hb0730.boot.admin.modules.sys.system.model.entity.SysUser;
import com.hb0730.boot.admin.modules.sys.system.service.SysUserService;
import com.hb0730.boot.admin.security.model.UserInfo;
import com.hb0730.boot.admin.security.token.TokenProvider;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
/**
* token
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/12
*/
@RestController
@RequestMapping("/wx")
@Tag(name = "系统: h5授权接口")
@RequiredArgsConstructor
public class WxLoginController {
private static final RestTemplate REST_TEMPLATE = new RestTemplate();
@Autowired
private SysUserService sysUserService;
/**
* AppID:wx292995002b9476f3
* AppSecret:896202811f43b146123f8d3f9ad3c153
*/
/**
* AppID
*/
private final static String AppID = "wxbad2e8a91c62a734";
/**
* AppSecret
*/
private final static String AppSecret = "e1b7fc425ca9cca05dd83609a6dc9c00";
@Operation(summary = "微信登录")
@GetMapping("/wxlogin")
public R getWechatLoginInfo(@RequestParam String code) {
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxbad2e8a91c62a734&secret=e1b7fc425ca9cca05dd83609a6dc9c00&code=" + code + "&grant_type=authorization_code";
String H5 = HttpTool.get(url, String.class);
Gson gson = new Gson();
H5LoginResponse h5LoginResponse = gson.fromJson(H5, H5LoginResponse.class);
System.out.println("h5LoginResponse = " + h5LoginResponse);
String useUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + h5LoginResponse.getAccessToken() + "&openid=" + h5LoginResponse.getOpenId() + "&lang=zh_CN";
String user = HttpTool.get(useUrl, String.class);
System.out.println("user = " + user);
UserResponse userResponse = gson.fromJson(user, UserResponse.class);
String opeId = userResponse.getOpenId();
SysUser sysUser = sysUserService.getByOpenId(opeId);
if(sysUser == null){
sysUser = new SysUser();
sysUser.setUsername(userResponse.getNicName());
sysUser.setOpenId(userResponse.getOpenId());
sysUser.setUnionId(userResponse.getOpenId());
sysUser.setPassword("123456");
sysUserService.save(sysUser);
}
JSH5LoginResponse jsh5LoginResponse = new JSH5LoginResponse();
BeanUtils.copyProperties(h5LoginResponse, jsh5LoginResponse);
jsh5LoginResponse.setUser(user);
return R.OK(jsh5LoginResponse);
}
@Operation(summary = "获取签名")
@GetMapping("/access")
public R access(String url){
Gson gson = new Gson();
Map<String,Object> map = new HashMap<>();
map.put("appid","wxbad2e8a91c62a734");
map.put("secret", "e1b7fc425ca9cca05dd83609a6dc9c00");
map.put("grant_type","client_credential");
String tokenUrl = "https://api.weixin.qq.com/cgi-bin/stable_token";
String access = REST_TEMPLATE.postForObject(tokenUrl, map, String.class);
// String access = HttpTool.pos(tokenUrl, map, String.class);
System.out.println("access = " + access);
AccessTokenResponse accessTokenResponse = gson.fromJson(access, AccessTokenResponse.class);
String jsUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessTokenResponse.getAccessToken()+"&type=jsapi";
String js = HttpTool.get(jsUrl, String.class);
JsResponse jsResponse = gson.fromJson(js, JsResponse.class);
System.out.println(js);
SignatureResponse signatureResponse = new SignatureResponse();
// 替换成你的公众号AppID和AppSecret
String appId = "wxbad2e8a91c62a734";
String appSecret = "e1b7fc425ca9cca05dd83609a6dc9c00";
String nonceStr = createNonceStr();
String timestamp = createTimestamp();
String jsapiTicket = jsResponse.getTicket();
String signature = generateSignature(jsapiTicket, nonceStr, timestamp, url);
signatureResponse.setSignature(signature);
signatureResponse.setTimestamp(timestamp);
signatureResponse.setJsapiTicket(jsapiTicket);
signatureResponse.setNonceStr(nonceStr);
System.out.println("signature = " + signature);
System.out.println(url);
return R.OK(signatureResponse);
}
private static String createNonceStr() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
private static String createTimestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
private static String getJsApiTicket(String appId, String appSecret) {
// 调用微信API获取jsapi_ticket的逻辑这里省略实现
// 返回有效的jsapi_ticket
return "YOUR_JSAPI_TICKET";
}
private static String generateSignature(String jsapiTicket, String nonceStr, String timestamp, String url) {
String sb = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + url;
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(sb.toString().getBytes("UTF-8"));
byte[] digest = crypt.digest();
Formatter formatter = new Formatter();
for (byte b : digest) {
formatter.format("%02x", b);
}
String signature = formatter.toString();
formatter.close();
return signature;
} catch (NoSuchAlgorithmException | java.io.UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
String json = "{\"openid\":\"o2r-U6sN-BMZEQlzEZIuVbRzeqPk\",\"nickname\":\"王文龙\",\"sex\":0,\"language\":\"\",\"city\":\"\",\"province\":\"\",\"country\":\"\",\"headimgurl\":\"https:\\/\\/thirdwx.qlogo.cn\\/mmopen\\/vi_32\\/PiajxSqBRaEJyptEMOSZmJ1480uG0gH5SpgxxXYtqIf6XKUn0fm9X6lxkT8aMRpX0sVBkTia5C9KtqsD70w8Q6VA\\/132\",\"privilege\":[]}";
Gson gson = new Gson();
UserResponse user = gson.fromJson(json, UserResponse.class);
System.out.println(user.getNicName());
System.out.println(user.getPrivilege());
}
}

View File

@ -0,0 +1,43 @@
package com.hb0730.boot.admin.modules.sys.auth.event;
import org.springframework.context.ApplicationEvent;
/**
* logout event
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/5
*/
public class LogoutEvent extends ApplicationEvent {
/**
* 访token
*/
private final String token;
/**
*
*/
private final String username;
/**
* ID
*/
private final String userid;
public LogoutEvent(Object source, String token, String username, String userid) {
super(source);
this.token = token;
this.username = username;
this.userid = userid;
}
public String getToken() {
return token;
}
public String getUsername() {
return username;
}
public String getUserid() {
return userid;
}
}

View File

@ -0,0 +1,32 @@
package com.hb0730.boot.admin.modules.sys.auth.event;
import com.hb0730.boot.admin.modules.sys.system.cache.RouteCache;
import com.hb0730.boot.admin.security.token.UserCacheProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/5
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class LogoutListener implements ApplicationListener<LogoutEvent> {
private final UserCacheProvider userCacheProvider;
private final RouteCache routeCache;
@Override
public void onApplicationEvent(LogoutEvent event) {
log.info("【用户注销事件】用户注销清理缓存信息>>>>>>>>>>>开始");
String username = event.getUsername();
userCacheProvider.clearUser(username);
log.info("【用户注销事件】成功清理缓存登录用户信息");
routeCache.removeCache(event.getUserid());
log.info("【用户注销事件】成功清理缓存用户路由信息");
}
}

View File

@ -0,0 +1,33 @@
package com.hb0730.boot.admin.modules.sys.auth.model;
import com.google.gson.annotations.SerializedName;
public class AccessTokenResponse {
@SerializedName("access_token")
private String accessToken;
@SerializedName("expires_in")
private Long expires_in;
public AccessTokenResponse() {
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public Long getExpires_in() {
return expires_in;
}
public void setExpires_in(Long expires_in) {
this.expires_in = expires_in;
}
}

View File

@ -0,0 +1,99 @@
package com.hb0730.boot.admin.modules.sys.auth.model;
import com.google.gson.annotations.SerializedName;
public class H5LoginResponse {
@SerializedName("access_token")
private String accessToken;
@SerializedName("refresh_token")
private String refreshToken;
@SerializedName("expiresIn")
private Long expires_in;
@SerializedName("unionid")
private String unionId;
@SerializedName("is_snapshotuser")
private Integer isSnapshotUser;
@SerializedName("openid")
private String openId;
@SerializedName("scope")
private String scope;
@SerializedName("errcode")
private Long errCode = 0L;
@SerializedName("errmsg")
private String errMsg;
public H5LoginResponse() {
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public Long getExpires_in() {
return expires_in;
}
public void setExpires_in(Long expires_in) {
this.expires_in = expires_in;
}
public String getUnionId() {
return unionId;
}
public void setUnionId(String unionId) {
this.unionId = unionId;
}
public Integer getIsSnapshotUser() {
return isSnapshotUser;
}
public void setIsSnapshotUser(Integer isSnapshotUser) {
this.isSnapshotUser = isSnapshotUser;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public Long getErrCode() {
return errCode;
}
public void setErrCode(Long errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
}

View File

@ -0,0 +1,121 @@
package com.hb0730.boot.admin.modules.sys.auth.model;
import com.google.gson.annotations.SerializedName;
public class JSH5LoginResponse {
@SerializedName("access_token")
private String accessToken;
@SerializedName("refresh_token")
private String refreshToken;
@SerializedName("expiresIn")
private Long expires_in;
@SerializedName("unionid")
private String unionId;
@SerializedName("is_snapshotuser")
private Integer isSnapshotUser;
@SerializedName("openid")
private String openId;
@SerializedName("scope")
private String scope;
@SerializedName("errcode")
private Long errCode = 0L;
@SerializedName("errmsg")
private String errMsg;
@SerializedName("ticket")
private String ticket;
private String user;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public JSH5LoginResponse() {
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public Long getExpires_in() {
return expires_in;
}
public void setExpires_in(Long expires_in) {
this.expires_in = expires_in;
}
public String getUnionId() {
return unionId;
}
public void setUnionId(String unionId) {
this.unionId = unionId;
}
public Integer getIsSnapshotUser() {
return isSnapshotUser;
}
public void setIsSnapshotUser(Integer isSnapshotUser) {
this.isSnapshotUser = isSnapshotUser;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public Long getErrCode() {
return errCode;
}
public void setErrCode(Long errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
}

View File

@ -0,0 +1,49 @@
package com.hb0730.boot.admin.modules.sys.auth.model;
import com.google.gson.annotations.SerializedName;
public class JsResponse {
@SerializedName("ticket")
private String ticket;
@SerializedName("expiresIn")
private Long expires_in;
@SerializedName("errcode")
private Long errCode = 0L;
@SerializedName("errmsg")
private String errMsg;
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public Long getExpires_in() {
return expires_in;
}
public void setExpires_in(Long expires_in) {
this.expires_in = expires_in;
}
public Long getErrCode() {
return errCode;
}
public void setErrCode(Long errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
}

View File

@ -0,0 +1,27 @@
package com.hb0730.boot.admin.modules.sys.auth.model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Serializable;
/**
* login request body
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/1/30
*/
@Data
@EqualsAndHashCode
@ToString
public class LoginRequest implements Serializable {
@Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "用户名为空")
private String username;
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "密码为空")
private String password;
}

View File

@ -0,0 +1,27 @@
package com.hb0730.boot.admin.modules.sys.auth.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Serializable;
import java.util.List;
/**
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/2/5
*/
@Data
@EqualsAndHashCode
@ToString
public class LoginResponse implements Serializable {
@Schema(description = "用户名")
private String username;
@Schema(description = "用户昵称")
private String nickname;
@Schema(description = "权限")
private List<String> permissions;
@Schema(description = "访问token")
private String token;
}

View File

@ -0,0 +1,15 @@
package com.hb0730.boot.admin.modules.sys.auth.model;
import lombok.Data;
@Data
public class SignatureResponse {
private String signature;
private String timestamp;
private String nonceStr;
private String jsapiTicket;
}

View File

@ -0,0 +1,105 @@
package com.hb0730.boot.admin.modules.sys.auth.model;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class UserResponse {
@SerializedName("openid")
private String openId;
@SerializedName("unionid")
private String unionId;
@SerializedName("nickname")
private String nicName;
@SerializedName("sex")
private String sex;
@SerializedName("province")
private String province;
@SerializedName("city")
private String city;
@SerializedName("headimgurl")
private String headImgurl;
@SerializedName("privilege")
private List<String> privilege;
@SerializedName("country")
private String country;
public List<String> getPrivilege() {
return privilege;
}
public void setPrivilege(List<String> privilege) {
this.privilege = privilege;
}
public UserResponse() {
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getUnionId() {
return unionId;
}
public void setUnionId(String unionId) {
this.unionId = unionId;
}
public String getNicName() {
return nicName;
}
public void setNicName(String nicName) {
this.nicName = nicName;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getHeadImgurl() {
return headImgurl;
}
public void setHeadImgurl(String headImgurl) {
this.headImgurl = headImgurl;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}

View File

@ -0,0 +1,14 @@
package com.hb0730.boot.admin.modules.sys.auth.model.dto;
import lombok.Data;
@Data
public class LoginDto {
private String code;
/**
*
*/
public Object extendParam;
}

View File

@ -0,0 +1,92 @@
package com.hb0730.boot.admin.modules.sys.monitor.controller;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.base.util.JsonUtil;
import com.hb0730.boot.admin.config.cache.BootAdminCache;
import com.hb0730.boot.admin.config.cache.DefaultKeyValue;
import com.hb0730.boot.admin.modules.sys.monitor.model.vo.CacheVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
/**
*
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/14
*/
@RestController
@RequestMapping("/monitor/cache")
@Tag(name = "系统:系统缓存", description = "业务缓存与系统缓存")
@RequiredArgsConstructor
public class CacheController {
private final BootAdminCache bootAdminCache;
@GetMapping
@Operation(summary = "缓存列表")
@PreAuthorize("hasAuthority('cache:list')")
public R<List<CacheVO>> queryList(HttpServletRequest request) {
List<CacheVO> res = Arrays.stream(DefaultKeyValue.values()).map(e -> {
CacheVO cacheVo = new CacheVO();
cacheVo.setPrefix(e.getPrefix());
cacheVo.setName(e.getName());
cacheVo.setDesc(e.getDesc());
return cacheVo;
}).toList();
return R.OK(res);
}
@GetMapping("/query")
@Operation(summary = "查询缓存")
@PreAuthorize("hasAuthority('cache:query')")
public R<CacheVO> query(HttpServletRequest request, CacheVO vo) {
// 完整缓存KEY值
String cacheKey = (vo.getPrefix() == null ? "" : vo.getPrefix() + ":") + vo.getKey();
boolean exist = bootAdminCache.hasKey(cacheKey);
if (!exist) {
return R.NG(String.format("缓存KEY:[%s]不存在", cacheKey));
}
// 缓存方式: 默认使用String方式
String cacheType = StringUtils.isNotBlank(vo.getType()) ? vo.getType() : "String";
switch (DefaultKeyValue.CacheType.valueOf(cacheType.toUpperCase())) {
case STRING, OBJECT ->
// <1> String 缓存
vo.setValue(bootAdminCache.getStr(cacheKey).orElse(""));
case HASHMAP ->
// <3> Map 缓存
bootAdminCache.hmget(cacheKey).ifPresent(e -> vo.setValue(JsonUtil.DEFAULT.toJson(e)));
case SET ->
// <4> Set 缓存
bootAdminCache.sGet(cacheKey).ifPresent(e -> vo.setValue(JsonUtil.DEFAULT.toJson(e)));
case LIST ->
// <5> List 缓存
bootAdminCache.lGet(cacheKey, 0, -1).ifPresent(e -> vo.setValue(JsonUtil.DEFAULT.toJson(e)));
default -> {
}
}
return R.OK(vo);
}
@DeleteMapping("/remove")
@Operation(summary = "删除缓存")
@PreAuthorize("hasAuthority('cache:remove')")
public R<String> remove(HttpServletRequest request, @RequestBody @Valid CacheVO vo) {
String cacheKey = (vo.getPrefix() == null ? "" : vo.getPrefix() + ":") + vo.getKey();
if (bootAdminCache.hasKey(cacheKey)) {
bootAdminCache.del(cacheKey);
}
return R.OK("");
}
}

View File

@ -0,0 +1,180 @@
package com.hb0730.boot.admin.modules.sys.monitor.controller;
import cn.hutool.core.bean.BeanUtil;
import com.hb0730.boot.admin.base.R;
import com.hb0730.boot.admin.data.domain.BasePage;
import com.hb0730.boot.admin.modules.sys.monitor.model.vo.QuartzJobVO;
import com.hb0730.boot.admin.modules.sys.monitor.model.entity.QuartzJob;
import com.hb0730.boot.admin.modules.sys.monitor.model.query.QuartzJobQuery;
import com.hb0730.boot.admin.modules.sys.monitor.service.QuartzJobService;
import com.hb0730.boot.admin.security.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.CronExpression;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.List;
/**
* QuartzController
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/12
*/
@RestController
@RequestMapping("/monitor/quartz/job")
@Tag(name = "定时任务")
@RequiredArgsConstructor
@Slf4j
public class QuartzJobController {
private final QuartzJobService quartzJobService;
/**
*
*
* @param request .
* @param cron .
* @return .
*/
@GetMapping("/check/cron")
@Operation(summary = "表达式是否正确")
public R<Boolean> checkCron(HttpServletRequest request, String cron) {
boolean success = CronExpression.isValidExpression(cron);
return success ? R.OK() : R.NG(200,"表达式错误");
}
@GetMapping("/query/page")
@Operation(summary = "分页查询")
@PreAuthorize("hasAuthority('sys:quartz:job:query')")
public R<BasePage<QuartzJobVO>> queryPage(HttpServletRequest request, @ParameterObject QuartzJobQuery query) {
return R.OK(quartzJobService.queryPage(query));
}
@GetMapping("/query/list")
@Operation(summary = "列表查询")
public R<List<QuartzJobVO>> queryList(HttpServletRequest request, @ParameterObject QuartzJobQuery query) {
return R.OK(quartzJobService.queryList(query));
}
@PostMapping("/save")
@Operation(summary = "保存")
@PreAuthorize("hasAuthority('sys:quartz:job:save')")
public R<QuartzJobVO> save(HttpServletRequest request, @RequestBody QuartzJobVO vo) {
String cronExpression = vo.getCronExpression();
boolean success = CronExpression.isValidExpression(cronExpression);
if (!success) {
return R.NG("表达式错误");
}
String username = SecurityUtil.getCurrentUsername();
QuartzJob quartzJob = BeanUtil.toBean(vo, QuartzJob.class);
quartzJob.setCreated(LocalDateTime.now());
quartzJob.setCreatedBy(username);
quartzJobService.saveAndScheduleJob(quartzJob);
vo = BeanUtil.toBean(quartzJob, QuartzJobVO.class);
return R.OK(vo);
}
@PutMapping("/update/{id}")
@Operation(summary = "更新")
@PreAuthorize("hasAuthority('sys:quartz:job:update')")
public R<QuartzJobVO> updateById(HttpServletRequest request, @PathVariable String id, @RequestBody QuartzJobVO vo) {
try {
QuartzJob job = quartzJobService.getById(id);
if (null == job) {
return R.NG("任务不存在");
}
String cronExpression = vo.getCronExpression();
boolean success = CronExpression.isValidExpression(cronExpression);
if (!success) {
return R.NG("表达式错误");
}
String username = SecurityUtil.getCurrentUsername();
QuartzJob quartzJob = BeanUtil.toBean(vo, QuartzJob.class);
quartzJob.setModified(LocalDateTime.now());
quartzJob.setModifiedBy(username);
quartzJobService.editAndScheduleJob(quartzJob);
vo = BeanUtil.toBean(quartzJob, QuartzJobVO.class);
return R.OK(vo);
} catch (Exception e) {
log.warn("更新定时任务失败", e);
return R.NG("更新定时任务失败");
}
}
@PutMapping("/pause/{id}")
@PreAuthorize("hasAuthority('sys:quartz:job:pause')")
@Operation(summary = "暂停")
public R<String> pause(HttpServletRequest request, @PathVariable String id) {
QuartzJob quartzJob = quartzJobService.getById(id);
if (null == quartzJob) {
return R.NG("任务不存在");
}
try {
quartzJobService.pauseJob(quartzJob);
return R.OK();
} catch (Exception e) {
log.warn("暂停定时任务失败", e);
return R.NG("暂停定时任务失败");
}
}
@PutMapping("/resume/{id}")
@PreAuthorize("hasAuthority('sys:quartz:job:resume')")
@Operation(summary = "恢复")
public R<String> resume(HttpServletRequest request, @PathVariable String id) {
QuartzJob quartzJob = quartzJobService.getById(id);
if (null == quartzJob) {
return R.NG("任务不存在");
}
try {
quartzJobService.resumeJob(quartzJob);
return R.OK();
} catch (Exception e) {
log.warn("恢复定时任务失败", e);
return R.NG("恢复定时任务失败");
}
}
@PutMapping("/execute/{id}")
@PreAuthorize("hasAuthority('sys:quartz:job:execute')")
@Operation(summary = "执行")
public R<String> execute(HttpServletRequest request, @PathVariable String id) {
QuartzJob quartzJob = quartzJobService.getById(id);
if (null == quartzJob) {
return R.NG("任务不存在");
}
try {
quartzJobService.executeJob(quartzJob);
return R.OK();
} catch (Exception e) {
log.warn("执行定时任务失败", e);
return R.NG("执行定时任务失败");
}
}
@DeleteMapping("/delete")
@Operation(summary = "删除")
@PreAuthorize("hasAuthority('sys:quartz:job:delete')")
public R<String> delete(HttpServletRequest request, @RequestParam String id) {
QuartzJob quartzJob = quartzJobService.getById(id);
if (null == quartzJob) {
return R.NG("任务不存在");
}
quartzJobService.deleteAndStopJob(quartzJob);
return R.OK();
}
}

View File

@ -0,0 +1,38 @@
package com.hb0730.boot.admin.modules.sys.monitor.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb0730.boot.admin.modules.sys.monitor.model.entity.QuartzJob;
import com.hb0730.boot.admin.modules.sys.monitor.model.vo.QuartzJobVO;
import com.hb0730.boot.admin.modules.sys.monitor.model.query.QuartzJobQuery;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 线 MAPPER
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/12
*/
public interface QuartzJobMapper extends BaseMapper<QuartzJob> {
/**
*
*
* @param jobClassName
* @return
*/
@Select("select * from sys_quartz_job where job_class_name = #{jobClassName}")
List<QuartzJob> findByJobClassName(@Param("jobClassName") String jobClassName);
/**
*
*
* @param page .
* @param query .
* @return .
*/
List<QuartzJobVO> queryPage(Page<QuartzJobVO> page, @Param("query") QuartzJobQuery query);
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hb0730.boot.admin.modules.sys.monitor.mapper.QuartzJobMapper">
<select id="queryPage" resultType="com.hb0730.boot.admin.modules.sys.monitor.model.vo.QuartzJobVO">
SELECT *
FROM `sys_quartz_job`
WHERE 1 = 1
<if test="query.jobClassName != null and query.jobClassName != '' ">
and job_class_name = #{query.jobClassName}
</if>
<if test="query.status != null ">
and status = #{query.status}
</if>
ORDER BY created DESC
</select>
</mapper>

View File

@ -0,0 +1,41 @@
package com.hb0730.boot.admin.modules.sys.monitor.model.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.hb0730.boot.admin.data.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* 线
*
* @author <a href="mailto:huangbing0730@gmail">hb0730</a>
* @date 2023/6/12
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString
@TableName("sys_quartz_job")
public class QuartzJob extends BaseEntity {
/**
*
*/
private java.lang.String jobClassName;
/**
*
*/
private java.lang.String parameter;
/**
* cron
*/
private java.lang.String cronExpression;
/**
* 1 0
*/
private java.lang.Integer status;
/**
*
*/
private java.lang.String description;
}

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