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));
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/config/cache/BootAdminProperties.java b/src/main/java/com/hb0730/boot/admin/config/cache/BootAdminProperties.java
new file mode 100644
index 0000000..0a06ad7
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/config/cache/BootAdminProperties.java
@@ -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 hb0730
+ * @date 2023/1/11
+ */
+@Configuration
+@ConfigurationProperties(prefix = "boot.admin")
+@Data
+public class BootAdminProperties {
+ /**
+ * 缓存
+ */
+ private CacheProperties cache = new CacheProperties();
+ /**
+ * 是否刷新路由,默认不刷新
+ *
+ * 一般用于用户权限发生变化时,刷新路由,如果用户量过多,不建议启用
+ *
+ */
+ public Boolean refreshRoutes = false;
+
+ @Data
+ public static class CacheProperties {
+ /**
+ * 前缀
+ */
+ private String prefix = "boot:admin:cache";
+
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/config/cache/CacheUtil.java b/src/main/java/com/hb0730/boot/admin/config/cache/CacheUtil.java
new file mode 100644
index 0000000..80400e7
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/config/cache/CacheUtil.java
@@ -0,0 +1,37 @@
+package com.hb0730.boot.admin.config.cache;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/**
+ * @author hb0730
+ * @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));
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/config/cache/DefaultKeyValue.java b/src/main/java/com/hb0730/boot/admin/config/cache/DefaultKeyValue.java
new file mode 100644
index 0000000..3ab7f51
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/config/cache/DefaultKeyValue.java
@@ -0,0 +1,96 @@
+package com.hb0730.boot.admin.config.cache;
+
+/**
+ * 非系统级别的缓存定义
+ *
+ * @author hb0730
+ * @date 2023/6/6
+ */
+public enum DefaultKeyValue implements KeyValue {
+
+ /**
+ * 【系统配置项】
+ * --------------------------------------------------------------------------------
+ * 系统配置表【sys_config】缓存
+ * --------------------------------------------------------------------------------
+ */
+ 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缓存的 get、set 方法使用}
+ */
+ 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缓存的数据类型
+ * 涉及如何 set、get
+ */
+ public enum CacheType {
+ STRING, OBJECT, HASHMAP, SET, LIST
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/config/cache/KeyValue.java b/src/main/java/com/hb0730/boot/admin/config/cache/KeyValue.java
new file mode 100644
index 0000000..b621ce1
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/config/cache/KeyValue.java
@@ -0,0 +1,65 @@
+package com.hb0730.boot.admin.config.cache;
+
+/**
+ * 缓存定义
+ *
+ * @author hb0730
+ * @date 2023/1/30
+ */
+public interface KeyValue {
+
+ /**
+ * 缓存key的失效时间
+ * 不设置失效时间 == 永久有效 ;
+ * XXX: setObject方法设为-1时,经封装后代表永久有效
+ *
单位:秒
+ */
+ 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 "";
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/config/cors/CorsConfiguration.java b/src/main/java/com/hb0730/boot/admin/config/cors/CorsConfiguration.java
new file mode 100644
index 0000000..6d05117
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/config/cors/CorsConfiguration.java
@@ -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 hb0730
+ * @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);
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/config/handler/JsonHandler.java b/src/main/java/com/hb0730/boot/admin/config/handler/JsonHandler.java
new file mode 100644
index 0000000..02634eb
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/config/handler/JsonHandler.java
@@ -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
+ */
+ @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);
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/job/SampleJob.java b/src/main/java/com/hb0730/boot/admin/job/SampleJob.java
new file mode 100644
index 0000000..c01467b
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/job/SampleJob.java
@@ -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 hb0730
+ * @date 2023/6/12
+ */
+@Slf4j
+public class SampleJob implements Job {
+ @Override
+ public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+ log.info("普通定时任务 SampleJob ! 时间: {}", DateUtil.now());
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/job/SampleParamJob.java b/src/main/java/com/hb0730/boot/admin/job/SampleParamJob.java
new file mode 100644
index 0000000..8c85ab0
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/job/SampleParamJob.java
@@ -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 hb0730
+ * @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());
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/OssController.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/OssController.java
new file mode 100644
index 0000000..4753064
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/OssController.java
@@ -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);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysBoxController.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysBoxController.java
new file mode 100644
index 0000000..660f9eb
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysBoxController.java
@@ -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 hb0730
+ * @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> queryPage(HttpServletRequest request, @ParameterObject BoxQuery query) {
+ BasePage res = this.sysBoxService.queryPage(query);
+ return R.OK(res);
+ }
+
+// @GetMapping("/query/list")
+// @Operation(summary = "列表查询")
+// public R> queryList(HttpServletRequest request, @ParameterObject UserQuery query) {
+// List res = this.sysShopService.queryList(query);
+// return R.OK(res);
+// }
+//
+// @GetMapping("/check/username")
+// @Operation(summary = "检查用户名是否存在")
+// public R checkUsername(HttpServletRequest request, @RequestParam String username) {
+// return this.sysBoxService.hashUsername(username);
+// }
+////
+ @GetMapping("/")
+ @Operation(summary = "详情")
+ public R detail(HttpServletRequest request, @Parameter(name = "id", description = "包厢ID",
+ required = true) @RequestParam String id) {
+ return this.sysBoxService.detail(id);
+ }
+
+ @PostMapping("/save")
+ @Operation(summary = "保存")
+ public R save(HttpServletRequest request, @Validated @RequestBody BoxVO boxVO) {
+
+ return this.sysBoxService.saveShop(boxVO);
+ }
+
+
+ @PutMapping("/update/{id}")
+ @Operation(summary = "修改")
+ public R 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 wrapper = new QueryWrapper<>();
+ wrapper.eq(
+ "id",id
+ );
+ return R.OK(this.sysBoxService.remove(wrapper));
+ }
+
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysCouponController.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysCouponController.java
new file mode 100644
index 0000000..321a84b
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysCouponController.java
@@ -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 hb0730
+ * @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> queryPage(HttpServletRequest request, @ParameterObject CouponQuery query) {
+ BasePage res = this.sysCouponService.queryPage(query);
+ return R.OK(res);
+ }
+
+ @GetMapping()
+ @Operation(summary = "详情")
+ public R detail(HttpServletRequest request, @Parameter(name = "id", description = "优惠券ID",
+ required = true) @RequestParam String id) {
+ return this.sysCouponService.detail(id);
+ }
+
+ @PostMapping("/save")
+ @Operation(summary = "保存")
+ public R save(HttpServletRequest request, @Validated @RequestBody CouponVO couponVO) {
+
+ return this.sysCouponService.saveShop(couponVO);
+ }
+
+
+ @PutMapping("/update/{id}")
+ @Operation(summary = "修改")
+ public R 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 wrapper = new QueryWrapper<>();
+ wrapper.eq(
+ "id",id
+ );
+ return R.OK(this.sysCouponService.remove(wrapper));
+ }
+
+
+ @GetMapping("/getCoupon")
+ @Operation(summary = "领取取优惠券")
+ public R getCoupon(HttpServletRequest request , @RequestParam("id") String id , @RequestParam String openId) {
+ return this.sysCouponService.getCoupon(id,openId);
+ }
+
+ @GetMapping("/verification")
+ @Operation(summary = "核销优惠券")
+ public R 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);
+ }
+
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysCouponLogController.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysCouponLogController.java
new file mode 100644
index 0000000..e0ac3f3
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysCouponLogController.java
@@ -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 hb0730
+ * @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> queryPage(HttpServletRequest request, @ParameterObject CouponQuery query) {
+ BasePage res = this.sysCouponLogService.queryPage(query);
+ return R.OK(res);
+ }
+
+ @GetMapping()
+ @Operation(summary = "详情")
+ public R detail(HttpServletRequest request, @Parameter(name = "id", description = "优惠券ID",
+ required = true) @RequestParam String id) {
+ return this.sysCouponLogService.detail(id);
+ }
+
+ @PostMapping("/save")
+ @Operation(summary = "保存")
+ public R save(HttpServletRequest request, @Validated @RequestBody CouponLogVO couponlogVO) {
+
+ return this.sysCouponLogService.saveShop(couponlogVO);
+ }
+
+
+ @PutMapping("/update/{id}")
+ @Operation(summary = "修改")
+ public R 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 wrapper = new QueryWrapper<>();
+ wrapper.eq(
+ "id",id
+ );
+ return R.OK(this.sysCouponLogService.remove(wrapper));
+ }
+
+
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysShopController.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysShopController.java
new file mode 100644
index 0000000..a514d99
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/controller/SysShopController.java
@@ -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 hb0730
+ * @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> queryPage(HttpServletRequest request, @ParameterObject ShopQuery query) {
+
+ BasePage res = this.sysShopService.queryPage(query);
+
+ return R.OK(res);
+ }
+
+ @GetMapping
+ @Operation(summary = "详情")
+ public R detail(HttpServletRequest request, @Parameter(name = "id", description = "店铺ID",
+ required = true) @RequestParam String id) {
+ return this.sysShopService.detail(id);
+ }
+
+ @PostMapping("/save")
+ @Operation(summary = "保存")
+ public R save(HttpServletRequest request, @Validated @RequestBody ShopVO shopVO) {
+
+ return this.sysShopService.saveShop(shopVO);
+ }
+//
+//
+ @PutMapping("/update/{id}")
+ @Operation(summary = "修改")
+ public R 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 wrapper = new QueryWrapper<>();
+ wrapper.eq(
+ "id",id
+ );
+ return R.OK(this.sysShopService.remove(wrapper));
+ }
+
+
+ @GetMapping("/getSeason")
+ @Operation(summary = "获取季节菜品")
+ public R> getSeason(HttpServletRequest request) {
+ return R.OK(this.sysShopService.getSeason());
+ }
+
+ @GetMapping("/getHour")
+ @Operation(summary = "获取小时菜品")
+ public R> getHour(HttpServletRequest request) {
+ return R.OK(this.sysShopService.getHour());
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysBoxMapper.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysBoxMapper.java
new file mode 100644
index 0000000..a92fca4
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysBoxMapper.java
@@ -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 {
+ List queryPage(Page page, @Param("query") BoxQuery query);
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysCouponLogMapper.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysCouponLogMapper.java
new file mode 100644
index 0000000..6b445d1
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysCouponLogMapper.java
@@ -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 {
+ List queryPage(Page page, @Param("query") CouponQuery query);
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysCouponMapper.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysCouponMapper.java
new file mode 100644
index 0000000..bfad284
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysCouponMapper.java
@@ -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 {
+ List queryPage(Page page, @Param("query") CouponQuery query);
+
+ void updateNums(@Param("id")String id);
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysShopMapper.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysShopMapper.java
new file mode 100644
index 0000000..ae431c5
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/SysShopMapper.java
@@ -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 {
+ List queryPage(Page page, @Param("query") ShopQuery query);
+
+ List getSeason();
+
+ List getHour();
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysBoxMapper.xml b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysBoxMapper.xml
new file mode 100644
index 0000000..0c271ca
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysBoxMapper.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+ 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
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysCouponLogMapper.xml b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysCouponLogMapper.xml
new file mode 100644
index 0000000..d329973
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysCouponLogMapper.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+ 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
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysCouponMapper.xml b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysCouponMapper.xml
new file mode 100644
index 0000000..df84b81
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysCouponMapper.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+ 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
+
+
+
+
+
+
+
+ UPDATE sys_coupon SET nums = nums - 1 WHERE id = #{id};
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysShopMapper.xml b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysShopMapper.xml
new file mode 100644
index 0000000..0e344c3
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/mapper/xml/SysShopMapper.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+ 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
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/PictureEntity.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/PictureEntity.java
new file mode 100644
index 0000000..c000b65
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/PictureEntity.java
@@ -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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysBox.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysBox.java
new file mode 100644
index 0000000..1ea3fcb
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysBox.java
@@ -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 hb0730
+ * @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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysCoupon.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysCoupon.java
new file mode 100644
index 0000000..300633a
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysCoupon.java
@@ -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 hb0730
+ * @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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysCouponLog.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysCouponLog.java
new file mode 100644
index 0000000..f1e1ec9
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysCouponLog.java
@@ -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 hb0730
+ * @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;
+
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysShop.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysShop.java
new file mode 100644
index 0000000..d1704fb
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/SysShop.java
@@ -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 hb0730
+ * @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;
+ /**
+ * 是否启用,true:启用,false:禁用
+ */
+ @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;
+
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/query/BoxQuery.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/query/BoxQuery.java
new file mode 100644
index 0000000..6675772
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/query/BoxQuery.java
@@ -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 hb0730
+ * @date 2023/6/8
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString
+public class BoxQuery extends BasePageQuery {
+
+ /**
+ * 店铺id
+ */
+ @Parameter(description = "店铺id")
+ private String shopId;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/query/CouponQuery.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/query/CouponQuery.java
new file mode 100644
index 0000000..93ecdc6
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/query/CouponQuery.java
@@ -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 hb0730
+ * @date 2023/6/8
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString
+public class CouponQuery extends BasePageQuery {
+
+
+ private String id;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/query/ShopQuery.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/query/ShopQuery.java
new file mode 100644
index 0000000..f8753a6
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/query/ShopQuery.java
@@ -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 hb0730
+ * @date 2023/6/8
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString
+public class ShopQuery extends BasePageQuery {
+
+ /**
+ * 店铺名称
+ */
+ @Parameter(description = "店铺名称")
+ private String name;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/BoxVO.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/BoxVO.java
new file mode 100644
index 0000000..b55f746
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/BoxVO.java
@@ -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 hb0730
+ * @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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/CouponLogVO.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/CouponLogVO.java
new file mode 100644
index 0000000..9970034
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/CouponLogVO.java
@@ -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 hb0730
+ * @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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/CouponVO.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/CouponVO.java
new file mode 100644
index 0000000..43fb5fe
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/CouponVO.java
@@ -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 hb0730
+ * @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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/GetCouponLogVO.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/GetCouponLogVO.java
new file mode 100644
index 0000000..dc1374b
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/GetCouponLogVO.java
@@ -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 hb0730
+ * @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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/HourVO.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/HourVO.java
new file mode 100644
index 0000000..54b88d8
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/HourVO.java
@@ -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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/SeasonVO.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/SeasonVO.java
new file mode 100644
index 0000000..8f18330
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/SeasonVO.java
@@ -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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/ShopVO.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/ShopVO.java
new file mode 100644
index 0000000..dfe1738
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/model/vo/ShopVO.java
@@ -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 hb0730
+ * @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;
+
+ /**
+ * 是否启用,true:启用,false:禁用
+ */
+ @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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/OssService.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/OssService.java
new file mode 100644
index 0000000..c6c8f05
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/OssService.java
@@ -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);
+}
\ No newline at end of file
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysBoxService.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysBoxService.java
new file mode 100644
index 0000000..820c9bd
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysBoxService.java
@@ -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 {
+ BasePage queryPage(BoxQuery query);
+
+ Rdetail(String id);
+
+ R saveShop(BoxVO boxVO);
+
+ R updateById(String id, BoxVO boxVO);
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysCouponLogService.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysCouponLogService.java
new file mode 100644
index 0000000..93d9e9e
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysCouponLogService.java
@@ -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 {
+
+ BasePage queryPage(CouponQuery query);
+
+ R detail(String id);
+
+ R saveShop(CouponLogVO couponlogVO);
+
+ R updateById(String id, CouponLogVO couponVO);
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysCouponService.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysCouponService.java
new file mode 100644
index 0000000..6ad90d0
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysCouponService.java
@@ -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 {
+ BasePage queryPage(CouponQuery query);
+
+ Rdetail(String id);
+
+ R saveShop(CouponVO couponVO);
+//
+ R updateById(String id, CouponVO couponVO);
+
+ R getCoupon(String id , String openId);
+
+ R verification(String id, String checkCode);
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysShopService.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysShopService.java
new file mode 100644
index 0000000..5a73b5b
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/SysShopService.java
@@ -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 {
+ BasePage queryPage(ShopQuery query);
+
+
+ R detail(String id);
+
+
+ R updateById(String id, ShopVO vo);
+
+ R saveShop(ShopVO shopVO);
+
+ List getSeason();
+
+ List getHour();
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/OssServiceImpl.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/OssServiceImpl.java
new file mode 100644
index 0000000..e06ebd2
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/OssServiceImpl.java
@@ -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("删除成功");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysBoxServiceImpl.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysBoxServiceImpl.java
new file mode 100644
index 0000000..99b09cc
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysBoxServiceImpl.java
@@ -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 implements SysBoxService {
+
+ @Autowired
+ private SysShopMapper sysShopMapper;
+ @Override
+ public BasePage queryPage(BoxQuery query) {
+
+
+ Page 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 boxes = baseMapper.queryPage(page, query);
+
+ List 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 detail(String id) {
+ LambdaQueryWrapper 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 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 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);
+ }
+}
+
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysCouponLogServiceImpl.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysCouponLogServiceImpl.java
new file mode 100644
index 0000000..9b14eab
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysCouponLogServiceImpl.java
@@ -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 implements SysCouponLogService {
+
+ @Autowired
+ private SysCouponLogMapper sysCouponLogMapper;
+
+ @Autowired
+ private SysUserMapper sysUserMapper;
+ @Override
+ public BasePage queryPage(CouponQuery query) {
+ Page 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 coupons = sysCouponLogMapper.queryPage(page, query);
+
+ List 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 detail(String id) {
+ LambdaQueryWrapper 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 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 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);
+}
+
+}
+
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysCouponServiceImpl.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysCouponServiceImpl.java
new file mode 100644
index 0000000..f92d1ef
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysCouponServiceImpl.java
@@ -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 implements SysCouponService {
+
+
+ @Autowired
+ private SysUserMapper sysUserMapper;
+
+ @Autowired
+ private SysCouponLogMapper sysCouponLogMapper;
+ @Override
+ public BasePage queryPage(CouponQuery query) {
+ Page 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 coupons = baseMapper.queryPage(page, query);
+
+ List 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 detail(String id) {
+ LambdaQueryWrapper 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 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 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 getCoupon(String id,String openid) {
+
+ LambdaQueryWrapper logs = new LambdaQueryWrapper<>();
+
+ SysCoupon coupon = this.baseMapper.selectById(id);
+
+ LambdaQueryWrapper 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 verification(String id, String checkCode) {
+
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(SysCouponLog::getCheckCode, checkCode);
+ wrapper.eq(SysCouponLog::getId, id);
+ SysCouponLog sysCouponLog = sysCouponLogMapper.selectOne(wrapper);
+ if(Objects.nonNull(sysCouponLog)){
+ UpdateWrapper updateWrapper = new UpdateWrapper();
+ updateWrapper.set("modified", LocalDateTime.now());
+ updateWrapper.eq("id", id);
+ sysCouponLogMapper.update(sysCouponLog,updateWrapper);
+ return R.OK("验证通过!!!");
+ }else {
+ return R.error(201,"验证失败!!!!");
+ }
+
+ }
+
+}
+
diff --git a/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysShopServiceImpl.java b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysShopServiceImpl.java
new file mode 100644
index 0000000..29bab1f
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/api/buiness/service/impl/SysShopServiceImpl.java
@@ -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 implements SysShopService {
+
+ @Autowired
+ private SysShopMapper sysShopMapper;
+ @Override
+ public BasePage queryPage(ShopQuery query) {
+ Page 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 shops = this.sysShopMapper.queryPage(page, query);
+
+ List 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 detail(String id)
+ {
+ SysShop shop = this.baseMapper.selectById(id);
+ ShopVO shopVO = new ShopVO();
+ BeanUtil.copyProperties(shop, shopVO);
+ return R.OK(shopVO);
+ }
+
+ @Override
+ public R 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 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 getSeason() {
+ List season = this.baseMapper.getSeason();
+
+ return season;
+ }
+
+ @Override
+ public List getHour() {
+ List hour = this.baseMapper.getHour();
+ return hour;
+ }
+
+
+}
+
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/controller/AuthorizationController.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/controller/AuthorizationController.java
new file mode 100644
index 0000000..8cbf2eb
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/controller/AuthorizationController.java
@@ -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 hb0730
+ * @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 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 getUserInfo() {
+ return null;
+ }
+
+ @Operation(summary = "退出登录")
+ @PostMapping("/logout")
+ public R 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("成功");
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/controller/WeChatJSSDKSignature.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/controller/WeChatJSSDKSignature.java
new file mode 100644
index 0000000..38a96a8
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/controller/WeChatJSSDKSignature.java
@@ -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 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 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/controller/WxLoginController.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/controller/WxLoginController.java
new file mode 100644
index 0000000..77edbe3
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/controller/WxLoginController.java
@@ -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 hb0730
+ * @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 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 + "×tamp=" + 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());
+
+ }
+
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/event/LogoutEvent.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/event/LogoutEvent.java
new file mode 100644
index 0000000..e52a9ec
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/event/LogoutEvent.java
@@ -0,0 +1,43 @@
+package com.hb0730.boot.admin.modules.sys.auth.event;
+
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * logout event
+ *
+ * @author hb0730
+ * @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;
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/event/LogoutListener.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/event/LogoutListener.java
new file mode 100644
index 0000000..066591c
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/event/LogoutListener.java
@@ -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 hb0730
+ * @date 2023/2/5
+ */
+@Component
+@RequiredArgsConstructor
+@Slf4j
+public class LogoutListener implements ApplicationListener {
+ 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("【用户注销事件】成功清理缓存用户路由信息");
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/AccessTokenResponse.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/AccessTokenResponse.java
new file mode 100644
index 0000000..60fdf18
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/AccessTokenResponse.java
@@ -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;
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/H5LoginResponse.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/H5LoginResponse.java
new file mode 100644
index 0000000..94e1988
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/H5LoginResponse.java
@@ -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;
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/JSH5LoginResponse.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/JSH5LoginResponse.java
new file mode 100644
index 0000000..8526e17
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/JSH5LoginResponse.java
@@ -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;
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/JsResponse.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/JsResponse.java
new file mode 100644
index 0000000..4854955
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/JsResponse.java
@@ -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;
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/LoginRequest.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/LoginRequest.java
new file mode 100644
index 0000000..0d9e4be
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/LoginRequest.java
@@ -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 hb0730
+ * @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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/LoginResponse.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/LoginResponse.java
new file mode 100644
index 0000000..9eaac4e
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/LoginResponse.java
@@ -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 hb0730
+ * @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 permissions;
+ @Schema(description = "访问token")
+ private String token;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/SignatureResponse.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/SignatureResponse.java
new file mode 100644
index 0000000..525dea4
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/SignatureResponse.java
@@ -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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/UserResponse.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/UserResponse.java
new file mode 100644
index 0000000..a6108e5
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/UserResponse.java
@@ -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 privilege;
+ @SerializedName("country")
+ private String country;
+
+ public List getPrivilege() {
+ return privilege;
+ }
+
+ public void setPrivilege(List 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;
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/dto/LoginDto.java b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/dto/LoginDto.java
new file mode 100644
index 0000000..ac180d1
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/auth/model/dto/LoginDto.java
@@ -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;
+}
\ No newline at end of file
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/controller/CacheController.java b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/controller/CacheController.java
new file mode 100644
index 0000000..19df5f3
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/controller/CacheController.java
@@ -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 hb0730
+ * @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> queryList(HttpServletRequest request) {
+ List 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 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 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("");
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/controller/QuartzJobController.java b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/controller/QuartzJobController.java
new file mode 100644
index 0000000..cf7e276
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/controller/QuartzJobController.java
@@ -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;
+
+/**
+ * Quartz定时任务Controller
+ *
+ * @author hb0730
+ * @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 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> queryPage(HttpServletRequest request, @ParameterObject QuartzJobQuery query) {
+ return R.OK(quartzJobService.queryPage(query));
+ }
+
+ @GetMapping("/query/list")
+ @Operation(summary = "列表查询")
+ public R> queryList(HttpServletRequest request, @ParameterObject QuartzJobQuery query) {
+ return R.OK(quartzJobService.queryList(query));
+ }
+
+ @PostMapping("/save")
+ @Operation(summary = "保存")
+ @PreAuthorize("hasAuthority('sys:quartz:job:save')")
+ public R 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 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 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 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 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 delete(HttpServletRequest request, @RequestParam String id) {
+ QuartzJob quartzJob = quartzJobService.getById(id);
+ if (null == quartzJob) {
+ return R.NG("任务不存在");
+ }
+ quartzJobService.deleteAndStopJob(quartzJob);
+ return R.OK();
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/mapper/QuartzJobMapper.java b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/mapper/QuartzJobMapper.java
new file mode 100644
index 0000000..9c2bc54
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/mapper/QuartzJobMapper.java
@@ -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 hb0730
+ * @date 2023/6/12
+ */
+public interface QuartzJobMapper extends BaseMapper {
+
+ /**
+ * 根据任务实现类全名取得匹配的任务
+ *
+ * @param jobClassName 任务实现类全名
+ * @return 匹配的任务
+ */
+ @Select("select * from sys_quartz_job where job_class_name = #{jobClassName}")
+ List findByJobClassName(@Param("jobClassName") String jobClassName);
+
+ /**
+ * 分页查询
+ *
+ * @param page .
+ * @param query .
+ * @return .
+ */
+ List queryPage(Page page, @Param("query") QuartzJobQuery query);
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/mapper/xml/QuratzJobMapper.xml b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/mapper/xml/QuratzJobMapper.xml
new file mode 100644
index 0000000..9c8b981
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/mapper/xml/QuratzJobMapper.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/entity/QuartzJob.java b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/entity/QuartzJob.java
new file mode 100644
index 0000000..747a111
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/entity/QuartzJob.java
@@ -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 hb0730
+ * @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;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/query/QuartzJobQuery.java b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/query/QuartzJobQuery.java
new file mode 100644
index 0000000..b003548
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/query/QuartzJobQuery.java
@@ -0,0 +1,23 @@
+package com.hb0730.boot.admin.modules.sys.monitor.model.query;
+
+import com.hb0730.boot.admin.data.domain.BasePageQuery;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+/**
+ * 定时任务在线管理查询条件
+ *
+ * @author hb0730
+ * @date 2023/6/13
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString
+public class QuartzJobQuery extends BasePageQuery {
+ @Schema(description = "任务类名")
+ private String jobClassName;
+ @Schema(description = "任务状态")
+ private Integer status;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/vo/CacheVO.java b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/vo/CacheVO.java
new file mode 100644
index 0000000..ba37a77
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/vo/CacheVO.java
@@ -0,0 +1,57 @@
+package com.hb0730.boot.admin.modules.sys.monitor.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.io.Serializable;
+
+/**
+ * 系统缓存
+ *
+ * @author hb0730
+ * @date 2023/6/14
+ */
+@Data
+@EqualsAndHashCode
+@ToString
+public class CacheVO implements Serializable {
+ /**
+ * 缓存分类:前缀
+ */
+ @Schema(description = "缓存分类:前缀")
+ private String prefix;
+
+ /**
+ * 配置KEY
+ */
+ @Schema(description = "配置KEY")
+ @NotNull(message = "配置KEY不能为空")
+ private String key;
+
+ /**
+ * 缓存实体JSON字符串
+ */
+ @Schema(description = "缓存实体JSON字符串")
+ private String value;
+
+ /**
+ * 缓存名称
+ */
+ @Schema(description = "缓存名称")
+ private String name;
+
+ /**
+ * 缓存描述
+ */
+ @Schema(description = "缓存描述")
+ private String desc;
+
+ /**
+ * 缓存方式
+ */
+ @Schema(description = "缓存方式")
+ private String type;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/vo/QuartzJobVO.java b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/vo/QuartzJobVO.java
new file mode 100644
index 0000000..9d167c6
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/model/vo/QuartzJobVO.java
@@ -0,0 +1,75 @@
+package com.hb0730.boot.admin.modules.sys.monitor.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.time.LocalDateTime;
+
+/**
+ * 定时任务在线管理
+ *
+ * @author hb0730
+ * @date 2023/6/13
+ */
+@Data
+@EqualsAndHashCode
+@ToString
+public class QuartzJobVO implements java.io.Serializable {
+ @Schema(description = "主键")
+ private String id;
+
+ /**
+ * 任务类名
+ */
+ @Schema(description = "任务类名")
+ @NotBlank(message = "任务类名不能为空")
+ private java.lang.String jobClassName;
+ /**
+ * 参数
+ */
+ @Schema(description = "参数")
+ private java.lang.String parameter;
+ /**
+ * cron表达式
+ */
+ @Schema(description = "cron表达式")
+ @NotBlank(message = "cron表达式不能为空")
+ private java.lang.String cronExpression;
+
+ /**
+ * 状态 1正常 0停止
+ */
+ @Schema(description = "状态 1正常 0停止")
+ private java.lang.Integer status;
+ /**
+ * 描述
+ */
+ @Schema(description = "描述")
+ private java.lang.String description;
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人")
+ protected String createdBy;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ protected LocalDateTime created;
+
+ /**
+ * 更新人
+ */
+ @Schema(description = "更新人")
+ protected String modifiedBy;
+
+ /**
+ * 更新时间
+ */
+ @Schema(description = "更新时间")
+ protected LocalDateTime modified;
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/service/QuartzJobService.java b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/service/QuartzJobService.java
new file mode 100644
index 0000000..6e55d3d
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/monitor/service/QuartzJobService.java
@@ -0,0 +1,267 @@
+package com.hb0730.boot.admin.modules.sys.monitor.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hb0730.boot.admin.base.exception.BootAdminException;
+import com.hb0730.boot.admin.core.service.BaseServiceImpl;
+import com.hb0730.boot.admin.data.domain.BasePage;
+import com.hb0730.boot.admin.data.enums.EnabledEnums;
+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.mapper.QuartzJobMapper;
+import com.hb0730.boot.admin.modules.sys.monitor.model.query.QuartzJobQuery;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.CronScheduleBuilder;
+import org.quartz.CronTrigger;
+import org.quartz.Job;
+import org.quartz.JobBuilder;
+import org.quartz.JobDetail;
+import org.quartz.JobKey;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.Trigger;
+import org.quartz.TriggerBuilder;
+import org.quartz.TriggerKey;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author hb0730
+ * @date 2023/6/12
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class QuartzJobService extends BaseServiceImpl {
+ private final Scheduler scheduler;
+
+ /**
+ * 列表查询
+ *
+ * @param query .
+ * @return .
+ */
+ public BasePage queryPage(QuartzJobQuery query) {
+ Page page = new Page<>(query.getCurrent(), query.getSize());
+ List list = this.baseMapper.queryPage(page, query);
+ return new BasePage<>(page.getCurrent(), page.getSize(), page.getTotal(), list);
+ }
+
+ /**
+ * 列表查询
+ *
+ * @param query .
+ * @return .
+ */
+ public List queryList(QuartzJobQuery query) {
+ return this.baseMapper.queryPage(null, query);
+ }
+
+ /**
+ * 根据任务实现类全名取得匹配的任务
+ *
+ * @param jobClassName 任务实现类全名
+ * @return 匹配的任务
+ */
+ public List findByJobClassName(String jobClassName) {
+ return this.baseMapper.findByJobClassName(jobClassName);
+ }
+
+ /**
+ * 保存&启动定时任务
+ *
+ * @param job 任务
+ * @return 处理结果
+ */
+ public boolean saveAndScheduleJob(QuartzJob job) {
+ if (EnabledEnums.enabled.getValue().equals(job.getStatus())) {
+ // 定时器添加
+ this.schedulerAdd(
+ job.getJobClassName().trim(),
+ job.getCronExpression().trim(),
+ job.getParameter());
+ }
+ return this.save(job);
+ }
+
+ /**
+ * 编辑&启停定时任务
+ *
+ * @param job 任务
+ * @return 处理结果
+ * @throws SchedulerException .
+ */
+ public boolean editAndScheduleJob(QuartzJob job) throws SchedulerException {
+ if (EnabledEnums.enabled.getValue().equals(job.getStatus())) {
+ schedulerDelete(job.getJobClassName().trim());
+
+ schedulerAdd(
+ job.getJobClassName().trim(),
+ job.getCronExpression().trim(),
+ job.getParameter());
+ } else {
+ scheduler.pauseJob(JobKey.jobKey(job.getJobClassName().trim()));
+ }
+
+ return this.updateById(job);
+ }
+
+ /**
+ * 删除&停止删除定时任务
+ *
+ * @param job 任务
+ * @return 处理结果
+ */
+ public boolean deleteAndStopJob(QuartzJob job) {
+ schedulerDelete(job.getJobClassName().trim());
+
+ return this.removeById(job.getId());
+ }
+
+ /**
+ * 暂停定时任务
+ *
+ * @param job 任务
+ * @return 处理结果
+ */
+ public boolean pauseJob(QuartzJob job) throws SchedulerException {
+ scheduler.pauseJob(JobKey.jobKey(job.getJobClassName().trim()));
+
+ job.setStatus(EnabledEnums.un_enabled.getValue());
+ return this.updateById(job);
+ }
+
+ /**
+ * 恢复定时任务
+ *
+ * @param job 任务
+ * @return 处理结果
+ */
+ public boolean resumeJob(QuartzJob job) {
+ schedulerDelete(job.getJobClassName().trim());
+
+ schedulerAdd(
+ job.getJobClassName().trim(),
+ job.getCronExpression().trim(),
+ job.getParameter());
+
+ job.setStatus(EnabledEnums.enabled.getValue());
+ return this.updateById(job);
+ }
+
+ /**
+ * 立即执行定时任务
+ *
+ * @param job 任务
+ */
+ public void executeJob(QuartzJob job) {
+
+ schedulerDelete(job.getJobClassName().trim());
+
+ //没有cronExpression表达式,只执行一次
+ schedulerAdd(
+ job.getJobClassName().trim(),
+ job.getParameter());
+ }
+
+ /**
+ * 删除定时任务
+ *
+ * @param jobClassName 任务实现类全名
+ */
+ private void schedulerDelete(String jobClassName) {
+ try {
+ scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
+ scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
+ scheduler.deleteJob(JobKey.jobKey(jobClassName));
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ throw new BootAdminException("删除定时任务失败");
+ }
+ }
+
+ /**
+ * 添加定时任务
+ *
+ * @param jobClassName 任务实现类全名
+ * @param cronExpression cron表达式
+ * @param parameter 任务参数
+ */
+ private void schedulerAdd(String jobClassName, String cronExpression, String parameter) {
+ try {
+ // 启动调度器
+ scheduler.start();
+
+ // 构建job信息
+ JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
+ .withIdentity(jobClassName)
+ .usingJobData("parameter", parameter)
+ .build();
+
+ // 表达式调度构建器(即任务执行的时间)
+ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
+
+ // 按新的cronExpression表达式构建一个新的trigger
+ CronTrigger trigger = TriggerBuilder.newTrigger()
+ .withIdentity(jobClassName)
+ .withSchedule(scheduleBuilder)
+ .build();
+
+ scheduler.scheduleJob(jobDetail, trigger);
+ } catch (SchedulerException e) {
+ throw new BootAdminException("创建定时任务失败", e);
+ } catch (RuntimeException e) {
+ throw new BootAdminException(e.getMessage(), e);
+ } catch (Exception e) {
+ throw new BootAdminException("后台找不到该类名:" + jobClassName, e);
+ }
+ }
+
+ /**
+ * 添加定时任务,不带cron表达式,执行一次
+ *
+ * @param jobClassName 任务实现类全名
+ * @param parameter 任务参数
+ */
+ private void schedulerAdd(String jobClassName, String parameter) {
+ try {
+ // 启动调度器
+ scheduler.start();
+
+ // 构建job信息
+ JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
+ .withIdentity(jobClassName)
+ .usingJobData("parameter", parameter)
+ .build();
+
+ // 没有cronExpression表达式构建一个新的trigger
+ Trigger trigger = TriggerBuilder.newTrigger()
+ .withIdentity(jobClassName)
+ .build();
+
+ scheduler.scheduleJob(jobDetail, trigger);
+
+ } catch (SchedulerException e) {
+ throw new BootAdminException("创建定时任务失败", e);
+ } catch (RuntimeException e) {
+ throw new BootAdminException(e.getMessage(), e);
+ } catch (Exception e) {
+ throw new BootAdminException("后台找不到该类名:" + jobClassName, e);
+ }
+ }
+
+ /**
+ * 实例化指定任务实现类
+ *
+ * @param jobClassName 任务实现类全名
+ * @return 任务实现类实例
+ * @throws Exception .
+ */
+ @SuppressWarnings("unchecked")
+ private static Job getClass(String jobClassName) throws Exception {
+ Class clazz = (Class) Class.forName(jobClassName);
+ return clazz.getConstructor().newInstance();
+ }
+
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/system/cache/ConfigCache.java b/src/main/java/com/hb0730/boot/admin/modules/sys/system/cache/ConfigCache.java
new file mode 100644
index 0000000..ec2e42e
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/system/cache/ConfigCache.java
@@ -0,0 +1,53 @@
+package com.hb0730.boot.admin.modules.sys.system.cache;
+
+import com.hb0730.boot.admin.config.cache.BootAdminCache;
+import com.hb0730.boot.admin.config.cache.CacheUtil;
+import com.hb0730.boot.admin.config.cache.DefaultKeyValue;
+import com.hb0730.boot.admin.modules.sys.system.model.entity.SysConfig;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+/**
+ * @author hb0730
+ * @date 2023/6/12
+ */
+@Component
+@RequiredArgsConstructor
+public class ConfigCache implements CacheUtil {
+ private final BootAdminCache cache;
+
+ /**
+ * 设置缓存
+ *
+ * @param config .
+ * @return .
+ */
+ public boolean putCache(SysConfig config) {
+ String key = getCacheKey(DefaultKeyValue.SYS_CONFIG, config.getCode());
+ return cache.set(key, config.getValue());
+ }
+
+ /**
+ * 移除缓存
+ *
+ * @param code .
+ * @return .
+ */
+ public boolean delCache(String code) {
+ String key = getCacheKey(DefaultKeyValue.SYS_CONFIG, code);
+ return cache.del(key);
+ }
+
+ /**
+ * 获取缓存
+ *
+ * @param code .
+ * @return .
+ */
+ public Optional getCache(String code) {
+ String key = getCacheKey(DefaultKeyValue.SYS_CONFIG, code);
+ return cache.getStr(key);
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/system/cache/RouteCache.java b/src/main/java/com/hb0730/boot/admin/modules/sys/system/cache/RouteCache.java
new file mode 100644
index 0000000..b1650db
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/system/cache/RouteCache.java
@@ -0,0 +1,89 @@
+package com.hb0730.boot.admin.modules.sys.system.cache;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.hb0730.boot.admin.base.util.JsonUtil;
+import com.hb0730.boot.admin.config.cache.BootAdminCache;
+import com.hb0730.boot.admin.config.cache.CacheUtil;
+import com.hb0730.boot.admin.config.cache.KeyValue;
+import com.hb0730.boot.admin.modules.sys.system.model.vo.VueMenuRouteVO;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 缓存当前用户路由信息
+ *
+ * @author hb0730
+ * @date 2023/2/6
+ */
+@Component
+@RequiredArgsConstructor
+@Slf4j
+public class RouteCache implements CacheUtil {
+ private final BootAdminCache cache;
+
+ /**
+ * 缓存用户路由
+ *
+ * @param userid 用户路由
+ * @param routes 路由
+ */
+ public void putCache(String userid, List routes) {
+ log.info("【用户路由】缓存用户: {} 路由信息, 缓存时间: 2小时", userid);
+ String cacheKey = getCacheKey(RouteCacheKey.default_key, userid);
+ String json = JsonUtil.DEFAULT.toJson(routes);
+ cache.set(cacheKey, json, 60 * 60 * 2);
+ }
+
+ /**
+ * 获取用户路由
+ *
+ * @param userid 用户ID
+ * @return 用户路由
+ */
+ public Optional> getCache(String userid) {
+ log.info("【用户路由】获取用户: {} 缓存的路由信息", userid);
+ String cacheKey = getCacheKey(RouteCacheKey.default_key, userid);
+ Optional jsonOptional = cache.getStr(cacheKey);
+ return jsonOptional.flatMap(e ->
+ Optional.ofNullable(JsonUtil.DEFAULT.fromJson(e, new TypeReference>() {
+ }))
+ );
+ }
+
+ /**
+ * 清理用户路由
+ *
+ * @param userid .
+ */
+ public void removeCache(String userid) {
+ log.info("【用户路由】清理用户: {} 缓存的路由信息", userid);
+ String cacheKey = getCacheKey(RouteCacheKey.default_key, userid);
+ cache.del(cacheKey);
+ }
+
+
+ public enum RouteCacheKey implements KeyValue {
+ default_key("route", "当前用户路由");
+ private final String prefix;
+ private final String desc;
+
+ RouteCacheKey(String prefix, String desc) {
+ this.prefix = prefix;
+ this.desc = desc;
+ }
+
+ @Override
+ public String getPrefix() {
+ return this.prefix;
+ }
+
+ @Override
+ public String getDesc() {
+ return this.desc;
+ }
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysCacheController.java b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysCacheController.java
new file mode 100644
index 0000000..4b037a0
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysCacheController.java
@@ -0,0 +1,11 @@
+package com.hb0730.boot.admin.modules.sys.system.controller;
+
+/**
+ * 系统缓存管理
+ *
+ * @author hb0730
+ * @date 2023/6/6
+ * @see com.hb0730.boot.admin.config.cache.DefaultKeyValue
+ */
+public class SysCacheController {
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysConfigController.java b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysConfigController.java
new file mode 100644
index 0000000..8fd63c2
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysConfigController.java
@@ -0,0 +1,101 @@
+package com.hb0730.boot.admin.modules.sys.system.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.system.model.entity.SysConfig;
+import com.hb0730.boot.admin.modules.sys.system.model.query.ConfigQuery;
+import com.hb0730.boot.admin.modules.sys.system.model.vo.ConfigVO;
+import com.hb0730.boot.admin.modules.sys.system.service.SysConfigService;
+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 org.springdoc.core.annotations.ParameterObject;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+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.RestController;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 系统配置
+ *
+ * @author hb0730
+ * @date 2023/6/12
+ */
+@RestController
+@RequestMapping("/sys/config")
+@Tag(name = "系统:系统配置")
+@RequiredArgsConstructor
+@Validated
+public class SysConfigController {
+ private final SysConfigService configService;
+
+ @GetMapping("/query/page")
+ @PreAuthorize("hasAuthority('sys:config:query')")
+ @Operation(summary = "分页查询")
+ public R> queryPage(HttpServletRequest request, @ParameterObject ConfigQuery query) {
+ return configService.queryPage(query);
+ }
+
+ @GetMapping("/query/list")
+ @Operation(summary = "列表查询")
+ public R> queryList(HttpServletRequest request, @ParameterObject ConfigQuery query) {
+ return configService.queryList(query);
+ }
+
+ @PostMapping("/save")
+ @Operation(summary = "保存")
+ @PreAuthorize("hasAuthority('sys:config:save')")
+ public R save(HttpServletRequest request, @RequestBody ConfigVO vo) {
+ String username = SecurityUtil.getCurrentUsername();
+ SysConfig config = BeanUtil.toBean(vo, SysConfig.class);
+ config.setCreated(LocalDateTime.now());
+ config.setCreatedBy(username);
+ configService.save(config);
+ ConfigVO bean = BeanUtil.toBean(config, ConfigVO.class);
+ return R.OK(bean);
+ }
+
+ @PutMapping("/update/{id}")
+ @Operation(summary = "修改")
+ @PreAuthorize("hasAuthority('sys:config:update')")
+ public R updateById(HttpServletRequest request, @PathVariable String id, @RequestBody ConfigVO vo) {
+ String username = SecurityUtil.getCurrentUsername();
+ SysConfig config = configService.getById(id);
+ if (null == config) {
+ return R.NG("数据不存在");
+ }
+ BeanUtil.copyProperties(vo, config);
+ config.setModified(LocalDateTime.now());
+ config.setModifiedBy(username);
+ configService.updateById(config);
+ ConfigVO bean = BeanUtil.toBean(config, ConfigVO.class);
+ return R.OK(bean);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除")
+ @PreAuthorize("hasAuthority('sys:config:del')")
+ public R delBatch(HttpServletRequest request, @RequestBody List ids) {
+ configService.removeByIds(ids);
+ return R.OK();
+ }
+
+ @PutMapping("/refresh/{id}")
+ @Operation(summary = "刷新缓存")
+ @PreAuthorize("hasAuthority('sys:config:refresh')")
+ public R refreshCache(HttpServletRequest request, @PathVariable String id) {
+ return configService.refreshCache(id);
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysEnumsController.java b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysEnumsController.java
new file mode 100644
index 0000000..1153509
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysEnumsController.java
@@ -0,0 +1,71 @@
+package com.hb0730.boot.admin.modules.sys.system.controller;
+
+import com.hb0730.boot.admin.base.R;
+import com.hb0730.boot.admin.data.enums.ConfigTypeEnums;
+import com.hb0730.boot.admin.data.enums.EnabledEnums;
+import com.hb0730.boot.admin.data.enums.GenderEnums;
+import com.hb0730.boot.admin.modules.sys.system.vo.SelectOptionVO;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author hb0730
+ * @date 2023/1/11
+ */
+@RestController
+@RequestMapping("/sys/enums")
+@RequiredArgsConstructor
+@Tag(name = "系统:常量")
+public class SysEnumsController {
+
+
+ /**
+ * 状态 options
+ *
+ * @return .
+ */
+ @GetMapping("/enabled")
+ @Operation(summary = "状态列表")
+ public R> enabledOptions() {
+ List res = Stream.of(EnabledEnums.values())
+ .map(v -> SelectOptionVO.builder().value(v.getValue() + "").name(v.getName()).build())
+ .collect(Collectors.toList());
+ return R.OK(res);
+ }
+
+ /**
+ * 性别
+ *
+ * @return .
+ */
+ @GetMapping("/gender")
+ @Operation(summary = "性别")
+ public R> genderOptions() {
+ List res = Stream.of(GenderEnums.values())
+ .map(v -> SelectOptionVO.builder().name(v.getName()).value(v.getValue() + "").build())
+ .collect(Collectors.toList());
+ return R.OK(res);
+ }
+
+ /**
+ * 配置类型
+ *
+ * @return .
+ */
+ @Operation(summary = "配置类型")
+ @GetMapping("/config_type")
+ public R> configTypeOptions() {
+ List res = Stream.of(ConfigTypeEnums.values())
+ .map(v -> SelectOptionVO.builder().name(v.getName()).value(v.getValue() + "").build())
+ .collect(Collectors.toList());
+ return R.OK(res);
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysOrgController.java b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysOrgController.java
new file mode 100644
index 0000000..0d7bbd0
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysOrgController.java
@@ -0,0 +1,97 @@
+package com.hb0730.boot.admin.modules.sys.system.controller;
+
+import cn.hutool.core.util.StrUtil;
+import com.hb0730.boot.admin.base.R;
+import com.hb0730.boot.admin.data.domain.BasePage;
+import com.hb0730.boot.admin.modules.sys.system.model.query.OrganizationQuery;
+import com.hb0730.boot.admin.modules.sys.system.model.vo.OrganizationTree;
+import com.hb0730.boot.admin.modules.sys.system.model.vo.OrganizationVO;
+import com.hb0730.boot.admin.modules.sys.system.service.SysOrgService;
+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 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.RestController;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 机构Controller
+ *
+ * @author hb0730
+ * @date 2023/6/3
+ */
+@RestController
+@RequestMapping("/sys/org")
+@Tag(name = "系统:机构")
+@RequiredArgsConstructor
+public class SysOrgController {
+ private final SysOrgService sysOrgService;
+
+ @GetMapping("/query/page")
+ @Operation(summary = "分页查询")
+ @PreAuthorize("hasAuthority('org:query')")
+ public R> getListPage(HttpServletRequest request,@ParameterObject OrganizationQuery query) {
+ BasePage page = sysOrgService.queryPage(query);
+ return R.OK(page);
+ }
+
+ @GetMapping("/query/tree")
+ @Operation(summary = "树形结构")
+ @PreAuthorize("hasAuthority('org:query:tree')")
+ public R> getTree(HttpServletRequest request,@ParameterObject OrganizationQuery query) {
+ List res = sysOrgService.queryTree(query);
+ return R.OK(res);
+ }
+
+ @GetMapping("/query/list")
+ @Operation(summary = "列表")
+ public R> getList(HttpServletRequest request,@ParameterObject OrganizationQuery query) {
+ List res = sysOrgService.queryList(query);
+ return R.OK(res);
+ }
+
+ @PostMapping("/save")
+ @Operation(summary = "保存机构")
+ @PreAuthorize("hasAuthority('org:save')")
+ public R save(HttpServletRequest request, @RequestBody OrganizationVO vo) {
+ String parentId = vo.getParentId();
+ if (StrUtil.isBlank(parentId)) {
+ return R.NG("不允许添加根节点");
+ }
+ vo.setCreatedBy(SecurityUtil.getCurrentUsername());
+ vo.setCreated(LocalDateTime.now());
+ vo.setIsSystem(0);
+ return sysOrgService.save(vo);
+ }
+
+ @PutMapping("/update/{id}")
+ @Operation(summary = "更新机构")
+ @PreAuthorize("hasAuthority('org:update')")
+ public R update(HttpServletRequest request, @PathVariable("id") String id,
+ @RequestBody OrganizationVO vo) {
+ vo.setModifiedBy(SecurityUtil.getCurrentUsername());
+ vo.setModified(LocalDateTime.now());
+ return sysOrgService.updateById(id, vo);
+ }
+
+ @DeleteMapping("/del")
+ @Operation(summary = "删除机构")
+ @PreAuthorize("hasAuthority('org:del')")
+ public R del(HttpServletRequest request, @RequestBody List ids) {
+ return sysOrgService.batchDel(ids);
+ }
+
+
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysPermissionController.java b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysPermissionController.java
new file mode 100644
index 0000000..b5328b9
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysPermissionController.java
@@ -0,0 +1,193 @@
+package com.hb0730.boot.admin.modules.sys.system.controller;
+
+import cn.hutool.core.util.StrUtil;
+import com.hb0730.boot.admin.base.R;
+import com.hb0730.boot.admin.data.enums.MenuTypeEnums;
+import com.hb0730.boot.admin.data.enums.ValueEnum;
+import com.hb0730.boot.admin.modules.sys.system.cache.RouteCache;
+import com.hb0730.boot.admin.modules.sys.system.model.dto.PermissionTree;
+import com.hb0730.boot.admin.modules.sys.system.model.entity.SysPermission;
+import com.hb0730.boot.admin.modules.sys.system.model.query.PermissionTreeQuery;
+import com.hb0730.boot.admin.modules.sys.system.model.vo.PermissionVO;
+import com.hb0730.boot.admin.modules.sys.system.model.vo.VueMenuRouteVO;
+import com.hb0730.boot.admin.modules.sys.system.service.SysPermissionService;
+import com.hb0730.boot.admin.security.model.UserInfo;
+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 jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+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.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author hb0730
+ * @date 2023/2/6
+ */
+
+@RestController
+@RequestMapping("/sys/permission")
+@Tag(name = "系统:菜单与权限")
+@RequiredArgsConstructor
+public class SysPermissionController {
+ private final SysPermissionService sysPermissionService;
+ private final RouteCache routeCache;
+
+ /**
+ * 获取当前用户路由
+ *
+ * @param request .
+ * @return .
+ */
+ @GetMapping("/routes")
+ @Operation(summary = "获取当前用户路由")
+ public R> getCurrentRoute(HttpServletRequest request) {
+ UserInfo user = SecurityUtil.getCurrentUser();
+ Optional> routeCacheOptional = routeCache.getCache(user.getUserid());
+ if (routeCacheOptional.isPresent()) {
+ return R.OK(routeCacheOptional.get());
+ }
+ List menuRoute = null;
+ if (user.isManger()) {
+ Set permissionIds = sysPermissionService.allPermissionIds();
+ menuRoute = sysPermissionService.queryRouteByIds(List.copyOf(permissionIds));
+ } else {
+ menuRoute = sysPermissionService.queryRouteByUserid(user.getUserid());
+ }
+ routeCache.putCache(user.getUserid(), menuRoute);
+ return R.OK(menuRoute);
+ }
+
+ /**
+ * 获取菜单与权限
+ *
+ * @return .
+ */
+ @GetMapping("/tree")
+ @Operation(summary = "获取菜单与权限树形列表")
+ @PreAuthorize("@permission.hashPermission('menu:query','role:query')")
+ public R> treesPermission(@ParameterObject PermissionTreeQuery query) {
+ Optional> permissionOpt = sysPermissionService.listPermission(query);
+ Optional> treeOpt = permissionOpt
+ .flatMap(e -> Optional.ofNullable(sysPermissionService.buildTree(e)));
+ List tree = treeOpt.orElse(Collections.emptyList());
+ return R.OK(tree);
+ }
+
+ @GetMapping("/tree/menu")
+ @Operation(summary = "获取菜单树形列表")
+ public R> tressMenus(@ParameterObject PermissionTreeQuery query) {
+ Optional> permissionOpt = sysPermissionService.listMenu(query);
+ Optional> treeOpt = permissionOpt
+ .flatMap(e -> Optional.ofNullable(sysPermissionService.buildTree(e)));
+ List tree = treeOpt.orElse(Collections.emptyList());
+ return R.OK(tree);
+ }
+
+ @PostMapping("/save")
+ @Operation(summary = "保存菜单与权限")
+ @PreAuthorize("@permission.hashPermission('menu:save')")
+ public R save(@RequestBody PermissionVO vo) {
+ MenuTypeEnums menuType = ValueEnum.valueToEnum(MenuTypeEnums.class, vo.getMenuType());
+ R res = null;
+ if (MenuTypeEnums.dir == menuType) {
+ res = checkDirMenuType(vo);
+ } else if (MenuTypeEnums.menu == menuType) {
+ res = checkMenuType(vo);
+ } else {
+ res = checkPermissionType(vo);
+ }
+ if (null != res) {
+ return res;
+ }
+ String username = SecurityUtil.getCurrentUsername();
+ vo.setCreated(LocalDateTime.now());
+ vo.setCreatedBy(username);
+ Optional optional = sysPermissionService.save(vo);
+ return optional.map(R::OK).orElseGet(() -> R.NG("保存失败"));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新菜单与权限")
+ @PreAuthorize("@permission.hashPermission('menu:update')")
+ public R update(@Parameter(name = "id", description = "当前ID", required = true) @RequestParam("id") String id,
+ @Valid @RequestBody PermissionVO vo) {
+ MenuTypeEnums menuType = ValueEnum.valueToEnum(MenuTypeEnums.class, vo.getMenuType());
+ R res = null;
+ if (MenuTypeEnums.dir == menuType) {
+ res = checkDirMenuType(vo);
+ } else if (MenuTypeEnums.menu == menuType) {
+ res = checkMenuType(vo);
+ } else {
+ res = checkPermissionType(vo);
+ }
+ if (null != res) {
+ return res;
+ }
+ String username = SecurityUtil.getCurrentUsername();
+ vo.setModified(LocalDateTime.now());
+ vo.setModifiedBy(username);
+ Optional optional = sysPermissionService.updateById(vo, id
+ );
+ return optional.map(R::OK).orElseGet(() -> R.NG("更新失败"));
+ }
+
+ private R checkDirMenuType(PermissionVO vo) {
+ String title = vo.getTitle();
+ if (StrUtil.isBlank(title)) {
+ return R.NG("菜单名称为空");
+ }
+ String path = vo.getPath();
+ if (StrUtil.isBlank(path)) {
+ return R.NG("路由地址为空");
+ }
+ Integer rank = vo.getRank();
+ if (null == rank) {
+ return R.NG("显示顺序为空");
+ }
+ return null;
+ }
+
+ private R checkMenuType(PermissionVO vo) {
+ String title = vo.getTitle();
+ if (StrUtil.isBlank(title)) {
+ return R.NG("菜单名称为空");
+ }
+ String path = vo.getPath();
+ if (StrUtil.isBlank(path)) {
+ return R.NG("路由地址为空");
+ }
+ Integer rank = vo.getRank();
+ if (null == rank) {
+ return R.NG("显示顺序为空");
+ }
+ return null;
+ }
+
+ private R checkPermissionType(PermissionVO vo) {
+ String title = vo.getTitle();
+ if (StrUtil.isBlank(title)) {
+ return R.NG("权限名称为空");
+ }
+ String perms = vo.getPerms();
+ if (StrUtil.isBlank(perms)) {
+ return R.NG("权限标识为空");
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysRoleController.java b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysRoleController.java
new file mode 100644
index 0000000..f47acc7
--- /dev/null
+++ b/src/main/java/com/hb0730/boot/admin/modules/sys/system/controller/SysRoleController.java
@@ -0,0 +1,132 @@
+package com.hb0730.boot.admin.modules.sys.system.controller;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.hb0730.boot.admin.base.R;
+import com.hb0730.boot.admin.data.domain.BasePage;
+import com.hb0730.boot.admin.modules.sys.system.model.entity.SysRole;
+import com.hb0730.boot.admin.modules.sys.system.model.entity.SysRolePermission;
+import com.hb0730.boot.admin.modules.sys.system.model.query.RoleQuery;
+import com.hb0730.boot.admin.modules.sys.system.service.SysRolePermissionService;
+import com.hb0730.boot.admin.modules.sys.system.service.SysRoleService;
+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 jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+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.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.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * 系统角色
+ *
+ * @author hb0730
+ * @date 2023/2/28
+ */
+@RestController
+@RequestMapping("/sys/role")
+@Tag(name = "系统:系统角色")
+@RequiredArgsConstructor
+public class SysRoleController {
+ private final SysRoleService sysRoleService;
+ private final SysRolePermissionService sysRolePermissionService;
+
+ @GetMapping("/query/page")
+ @PreAuthorize("@permission.hashPermission('role:query')")
+ @Operation(summary = "分页查询")
+ public R> queryPage(@ParameterObject RoleQuery query) {
+ BasePage page = sysRoleService.queryPage(query);
+ return R.OK(page);
+ }
+
+ @GetMapping("/query/list")
+ @Operation(summary = "列表查询")
+ public R> queryList(@ParameterObject RoleQuery query) {
+ List roles = sysRoleService.queryList(query);
+ return R.OK(roles);
+ }
+
+ @GetMapping("/check/code")
+ @Operation(summary = "校验code是否重复", parameters = {
+ @Parameter(name = "id", required = false, description = "id"),
+ @Parameter(name = "code", required = true, description = "角色编码")
+ })
+ public R checkRole(@RequestParam(value = "id", required = false) String id,
+ @RequestParam(value = "code") String code) {
+ boolean checkCode = sysRoleService.checkCode(code, id);
+ return R.OK(checkCode);
+ }
+
+ @PostMapping("/save")
+ @PreAuthorize("@permission.hashPermission('role:save')")
+ @Operation(summary = "新增")
+ public R