diff --git a/pom.xml b/pom.xml
index 216c74b..69366c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,15 +31,48 @@
+ com.alibaba
+ fastjson
+ 1.2.83
+
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.14
+
+
+ cn.hutool
+ hutool-all
+ 5.8.24
+
+
org.springframework.boot
spring-boot-starter-web
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
org.mybatis.spring.boot
mybatis-spring-boot-starter
3.0.4
-
+
+ com.alibaba
+ easyexcel
+ 3.1.3
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
org.springframework.boot
spring-boot-devtools
@@ -79,6 +112,7 @@
org.springframework.boot
spring-boot-starter-security
+ 3.3.6
org.springframework.boot
@@ -89,6 +123,16 @@
pagehelper-spring-boot-starter
1.4.6
+
+ jakarta.validation
+ jakarta.validation-api
+ 3.0.2
+
+
+ org.hibernate.validator
+ hibernate-validator
+ 8.0.0.Final
+
diff --git a/src/main/java/com/example/demo/Export/ExportService.java b/src/main/java/com/example/demo/Export/ExportService.java
new file mode 100644
index 0000000..f8a35ad
--- /dev/null
+++ b/src/main/java/com/example/demo/Export/ExportService.java
@@ -0,0 +1,25 @@
+package com.example.demo.Export;
+
+import com.example.demo.domain.DTO.ConsumeDTO;
+import com.example.demo.domain.DTO.GoldDetailDTO;
+import com.example.demo.domain.DTO.RechargeDTO;
+import com.example.demo.domain.DTO.RefundDTO;
+import com.example.demo.domain.vo.Result;
+
+/**
+ * @program: GOLD
+ * @ClassName ExportService
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−07-01 16:06
+ * @Version 1.0
+ **/
+public interface ExportService {
+ //充值导出
+ Result addExportRecharge(RechargeDTO dto);
+ //退款导出
+ Result addExportRefund(RefundDTO dto);
+ //消费导出
+ Result addExportConsume(ConsumeDTO dto);
+
+}
diff --git a/src/main/java/com/example/demo/Export/ExportServiceImpl.java b/src/main/java/com/example/demo/Export/ExportServiceImpl.java
new file mode 100644
index 0000000..2c52080
--- /dev/null
+++ b/src/main/java/com/example/demo/Export/ExportServiceImpl.java
@@ -0,0 +1,177 @@
+package com.example.demo.Export;
+
+import com.example.demo.domain.DTO.ConsumeDTO;
+import com.example.demo.domain.DTO.RechargeDTO;
+import com.example.demo.domain.DTO.RefundDTO;
+import com.example.demo.domain.vo.Result;
+import com.example.demo.exception.SystemException;
+import com.example.demo.mapper.GoldDetailMapper;
+import com.example.demo.Util.RedisUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @program: GOLD
+ * @ClassName ExportServiceImpl
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−07-01 16:11
+ * @Version 1.0
+ **/
+@Service
+public class ExportServiceImpl implements ExportService{
+ @Autowired
+ private GoldDetailMapper goldDetailMapper;
+ @Autowired
+ private RedisUtil redisUtil;
+
+ @Override
+ public Result addExportRecharge(RechargeDTO dto) {
+ // 生成文件名
+ String fileName = String.format("%s_%s_%s.xlsx",
+ "充值明细",
+ "操作人",
+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
+ System.out.println(fileName);
+ dto.setAccount(123456);
+ dto.setUrl("");
+ dto.setFileName(fileName);
+ dto.setDataNum(0);
+ try{
+ // 调用方式
+ GoldDetailMapper.ExportRecordIdHolder idHolder = new GoldDetailMapper.ExportRecordIdHolder();
+ goldDetailMapper.insertExportRecord(
+ idHolder, // 用于接收主键
+ dto.getAccount(),
+ dto.getType(),
+ dto.getState(),
+ dto.getUrl(),
+ dto.getFileName(),
+ dto.getDataNum()
+ );
+ // 获取主键
+ Long recordId = idHolder.getId();
+ // 2. 构造完整的 JSON 数据(包含所有请求参数)
+ Map exportData = new HashMap<>();
+ exportData.put("recordId", recordId);
+
+ // 手动构造请求数据(避免 toString() 只返回部分字段)
+ Map requestData = new HashMap<>();
+ requestData.put("text", dto.getText());
+ requestData.put("sort", dto.getSort());
+ requestData.put("field", dto.getField());
+ requestData.put("deptId", dto.getDeptid());
+ exportData.put("requestData", requestData);
+
+ // 3. 发送到 Redis 消息队列
+ String jsonData = new ObjectMapper().writeValueAsString(exportData);
+ redisUtil.sendMessage("recharge:queue:export_queue", jsonData);
+ }catch (Exception e){
+ e.printStackTrace();
+ throw new SystemException("导出数据异常,请稍后重试", e);
+ }
+ return Result.success();
+ }
+
+ @Override
+ public Result addExportRefund(RefundDTO dto) {
+ // 生成文件名
+ String fileName = String.format("%s_%s_%s.xlsx",
+ "退款明细",
+ "操作人",
+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
+ System.out.println(fileName);
+ dto.setAccount(123456);
+ dto.setUrl("");
+ dto.setFileName(fileName);
+ dto.setDataNum(0);
+ try{
+ // 调用方式
+ GoldDetailMapper.ExportRecordIdHolder idHolder = new GoldDetailMapper.ExportRecordIdHolder();
+ goldDetailMapper.insertExportRecord(
+ idHolder, // 用于接收主键
+ dto.getAccount(),
+ dto.getType(),
+ dto.getState(),
+ dto.getUrl(),
+ dto.getFileName(),
+ dto.getDataNum()
+ );
+ // 获取主键
+ Long recordId = idHolder.getId();
+ // 2. 构造完整的 JSON 数据(包含所有请求参数)
+ Map exportData = new HashMap<>();
+ exportData.put("recordId", recordId);
+
+ // 手动构造请求数据(避免 toString() 只返回部分字段)
+ Map requestData = new HashMap<>();
+ requestData.put("text", dto.getText());
+ requestData.put("sort", dto.getSort());
+ requestData.put("field", dto.getField());
+ requestData.put("deptId", dto.getDeptid());
+ exportData.put("requestData", requestData);
+
+ // 3. 发送到 Redis 消息队列
+ String jsonData = new ObjectMapper().writeValueAsString(exportData);
+ redisUtil.sendMessage("refund:queue:export_queue", jsonData);
+ }catch (Exception e){
+ e.printStackTrace();
+ throw new SystemException("导出数据异常,请稍后重试", e);
+ }
+ return Result.success();
+ }
+
+ @Override
+ public Result addExportConsume(ConsumeDTO dto) {
+ // 生成文件名
+ String fileName = String.format("%s_%s_%s.xlsx",
+ "消费明细",
+ "操作人",
+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
+ System.out.println(fileName);
+ dto.setAccount(123456);
+ dto.setUrl("");
+ dto.setFileName(fileName);
+ dto.setDataNum(0);
+ try{
+ // 调用方式
+ GoldDetailMapper.ExportRecordIdHolder idHolder = new GoldDetailMapper.ExportRecordIdHolder();
+ goldDetailMapper.insertExportRecord(
+ idHolder, // 用于接收主键
+ dto.getAccount(),
+ dto.getType(),
+ dto.getState(),
+ dto.getUrl(),
+ dto.getFileName(),
+ dto.getDataNum()
+ );
+ // 获取主键
+ Long recordId = idHolder.getId();
+ // 2. 构造完整的 JSON 数据(包含所有请求参数)
+ Map exportData = new HashMap<>();
+ exportData.put("recordId", recordId);
+
+ // 手动构造请求数据(避免 toString() 只返回部分字段)
+ Map requestData = new HashMap<>();
+ requestData.put("text", dto.getText());
+ requestData.put("sort", dto.getSort());
+ requestData.put("field", dto.getField());
+ requestData.put("deptId", dto.getDeptid());
+ exportData.put("requestData", requestData);
+
+ // 3. 发送到 Redis 消息队列
+ String jsonData = new ObjectMapper().writeValueAsString(exportData);
+ redisUtil.sendMessage("refund:queue:export_queue", jsonData);
+ }catch (Exception e){
+ e.printStackTrace();
+ throw new SystemException("导出数据异常,请稍后重试", e);
+ }
+ return Result.success();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/demo/Util/ExcelUploadUtil.java b/src/main/java/com/example/demo/Util/ExcelUploadUtil.java
new file mode 100644
index 0000000..77bf58f
--- /dev/null
+++ b/src/main/java/com/example/demo/Util/ExcelUploadUtil.java
@@ -0,0 +1,200 @@
+package com.example.demo.Util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.http.*;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Excel文件上传工具类
+ */
+public class ExcelUploadUtil {
+ private static final Logger logger = LoggerFactory.getLogger(ExcelUploadUtil.class);
+
+ // 默认配置
+ private static final int DEFAULT_CONNECT_TIMEOUT = 30000; // 30秒
+ private static final int DEFAULT_READ_TIMEOUT = 60000; // 60秒
+
+ private final RestTemplate restTemplate;
+ private final String uploadUrl;
+ private final Map defaultHeaders;
+ private final Map defaultParams;
+
+ /**
+ * 构造方法
+ *
+ * @param uploadUrl 上传接口URL
+ */
+ public ExcelUploadUtil(String uploadUrl) {
+ this(uploadUrl, new HashMap<>(), new HashMap<>());
+ }
+
+ /**
+ * 构造方法
+ *
+ * @param uploadUrl 上传接口URL
+ * @param defaultHeaders 默认请求头
+ * @param defaultParams 默认请求参数
+ */
+ public ExcelUploadUtil(String uploadUrl, Map defaultHeaders, Map defaultParams) {
+ this.uploadUrl = uploadUrl;
+ this.defaultHeaders = new HashMap<>(defaultHeaders);
+ this.defaultParams = new HashMap<>(defaultParams);
+ this.restTemplate = createRestTemplate(DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT);
+ }
+
+ /**
+ * 创建RestTemplate (Spring Boot 1.x 兼容版本)
+ */
+ private RestTemplate createRestTemplate(int connectTimeout, int readTimeout) {
+ RestTemplate restTemplate = new RestTemplate();
+
+ // 添加字符串消息转换器 (Spring 1.x 使用Charset而不是StandardCharsets)
+ restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
+
+ // 设置超时 (Spring 1.x 方式)
+ SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
+ factory.setConnectTimeout(connectTimeout);
+ factory.setReadTimeout(readTimeout);
+ restTemplate.setRequestFactory(factory);
+
+ return restTemplate;
+ }
+
+ /**
+ * 上传Excel文件
+ *
+ * @param excelFile Excel文件
+ * @param targetDir 目标目录
+ * @return 上传结果
+ * @throws IOException 文件操作异常
+ * @throws UploadException 上传异常
+ */
+ public String uploadExcel(File excelFile, String targetDir) throws IOException, UploadException {
+ return uploadExcel(excelFile, targetDir, new HashMap<>(), new HashMap<>());
+ }
+
+ /**
+ * 上传Excel文件(带自定义参数)
+ *
+ * @param excelFile Excel文件
+ * @param targetDir 目标目录
+ * @param customHeaders 自定义请求头
+ * @param customParams 自定义请求参数
+ * @return 上传结果
+ * @throws IOException 文件操作异常
+ * @throws UploadException 上传异常
+ */
+ public String uploadExcel(File excelFile, String targetDir,
+ Map customHeaders,
+ Map customParams) throws IOException, UploadException {
+ // 验证文件
+ validateFile(excelFile);
+
+ try {
+ // 准备请求
+ HttpEntity> requestEntity = prepareRequest(excelFile, targetDir, customHeaders, customParams);
+
+ // 执行上传
+ ResponseEntity response = restTemplate.exchange(
+ uploadUrl,
+ HttpMethod.POST,
+ requestEntity,
+ String.class
+ );
+
+ // 处理响应
+ return handleResponse(response, excelFile.getName());
+ } catch (Exception e) {
+ logger.error("Excel文件上传失败: {}", excelFile.getAbsolutePath(), e);
+ throw new UploadException("文件上传失败: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * 验证文件
+ */
+ private void validateFile(File file) throws IOException {
+ if (file == null) {
+ throw new IOException("文件不能为null");
+ }
+ if (!file.exists()) {
+ throw new IOException("文件不存在: " + file.getAbsolutePath());
+ }
+ if (!file.isFile()) {
+ throw new IOException("不是有效的文件: " + file.getAbsolutePath());
+ }
+ if (file.length() == 0) {
+ throw new IOException("文件内容为空: " + file.getAbsolutePath());
+ }
+ if (!file.getName().toLowerCase().endsWith(".xlsx") &&
+ !file.getName().toLowerCase().endsWith(".xls")) {
+ throw new IOException("仅支持Excel文件(.xlsx, .xls)");
+ }
+ }
+
+ /**
+ * 准备请求
+ */
+ private HttpEntity> prepareRequest(File file, String targetDir,
+ Map customHeaders,
+ Map customParams) {
+ // 设置请求头
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+
+ // 添加默认和自定义请求头
+ defaultHeaders.forEach(headers::set);
+ customHeaders.forEach(headers::set);
+
+ // 准备请求体
+ MultiValueMap body = new LinkedMultiValueMap<>();
+ body.add("file", new FileSystemResource(file));
+ body.add("dir", targetDir);
+
+ // 添加默认和自定义参数
+ defaultParams.forEach(body::add);
+ customParams.forEach(body::add);
+
+ return new HttpEntity<>(body, headers);
+ }
+
+ /**
+ * 处理响应
+ */
+ private String handleResponse(ResponseEntity response, String filename) throws UploadException {
+ if (response.getStatusCode() == HttpStatus.OK) {
+ logger.info("文件上传成功: {}", filename);
+ return response.getBody();
+ } else {
+ String errorMsg = String.format("上传接口返回错误状态码: %d, 响应: %s",
+ response.getStatusCodeValue(), response.getBody());
+ logger.error(errorMsg);
+ throw new UploadException(errorMsg);
+ }
+ }
+
+ /**
+ * 自定义上传异常
+ */
+ public static class UploadException extends Exception {
+ public UploadException(String message) {
+ super(message);
+ }
+
+ public UploadException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/demo/Util/ExecutionContextUtil.java b/src/main/java/com/example/demo/Util/ExecutionContextUtil.java
new file mode 100644
index 0000000..10bafa4
--- /dev/null
+++ b/src/main/java/com/example/demo/Util/ExecutionContextUtil.java
@@ -0,0 +1,227 @@
+package com.example.demo.Util;
+
+
+import com.example.demo.domain.vo.ExecutionContext;
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class ExecutionContextUtil {
+
+ /**
+ * 获取当前执行环境信息
+ * @param request 如果是Web请求,传入HttpServletRequest
+ * @return 执行环境信息对象
+ */
+ /**
+ * 从Spring上下文获取当前HttpServletRequest
+ */
+ public static ExecutionContext getExecutionContext() {
+ ExecutionContext context = new ExecutionContext();
+ context.setExecutionTime(new Date());
+
+ HttpServletRequest request = getCurrentHttpRequest();
+
+ if (isWebEnvironment(request)) {
+ // Web API 环境
+ context.setExecutionType("API");
+ context.setApiUrl(getRealRequestUrl(request));
+ context.setRequestParams(getRequestParams(request));
+ context.setToken(getRequestToken(request));
+ context.setMethod(request.getMethod());
+ } else {
+ // 脚本环境
+ context.setExecutionType("SCRIPT");
+ context.setScriptFile(getMainClassFile());
+ }
+
+ return context;
+ }
+
+ private static HttpServletRequest getCurrentHttpRequest() {
+ try {
+ return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
+ } catch (IllegalStateException e) {
+ // 不在Web请求上下文中
+ return null;
+ }
+ }
+
+ private static boolean isWebEnvironment(HttpServletRequest request) {
+ return request != null;
+ }
+
+ private static String getRealRequestUrl(HttpServletRequest request) {
+ // 1. 获取协议(优先从代理头获取)
+ String protocol = getHeaderWithFallback(request,
+ Arrays.asList("X-Forwarded-Proto", "X-Forwarded-Protocol"),
+ request.getScheme()
+ );
+
+ // 2. 获取真实域名(优先从代理头获取原始域名)
+ String domain = getHeaderWithFallback(request,
+ Arrays.asList(
+ "X-Original-Host", // 一些代理服务器设置的原始终端
+ "X-Real-Host", // 另一个可能的原始主机头
+ "X-Forwarded-Host", // 转发的主机头
+ "Host" // 最后回退到常规主机头
+ ),
+ request.getServerName()
+ );
+
+ // 3. 获取端口(智能处理默认端口)
+ Integer port = getRealPort(request, protocol);
+
+ // 4. 获取原始路径(包括QueryString)
+ String path = getOriginalUri(request);
+
+ // 组装完整URL
+ return String.format("%s://%s:%s%s",
+ protocol,
+ domain,
+ port,
+ path
+ );
+ }
+
+ // 辅助方法:带fallback的header获取
+ // 方法1:保持强类型(推荐)
+ private static String getHeaderWithFallback(
+ HttpServletRequest request,
+ List headerNames, // 明确要求String列表
+ String defaultValue
+ ) {
+ return headerNames.stream()
+ .map(request::getHeader)
+ .filter(Objects::nonNull)
+ .findFirst()
+ .orElse(defaultValue);
+ }
+
+ // 获取真实端口(处理代理情况)
+ private static int getRealPort(HttpServletRequest request, String protocol) {
+ // 优先从代理头获取
+ String forwardedPort = request.getHeader("X-Forwarded-Port");
+ if (forwardedPort != null) {
+ return Integer.parseInt(forwardedPort);
+ }
+
+ // 其次从请求获取
+ int port = request.getServerPort();
+
+ // 处理反向代理场景
+ if (port == 80 && "https".equals(protocol)) {
+ return 443;
+ }
+ if (port == 443 && "http".equals(protocol)) {
+ return 80;
+ }
+ return port;
+ }
+
+ // 获取原始URI(包含QueryString)
+ private static String getOriginalUri(HttpServletRequest request) {
+ // 优先从代理头获取原始URI
+ String originalUri = request.getHeader("X-Original-URI");
+ if (originalUri != null) {
+ return originalUri;
+ }
+
+ // 默认从request获取
+ String queryString = request.getQueryString();
+ return request.getRequestURI() +
+ (queryString != null ? "?" + queryString : "");
+ }
+
+ private static String getRequestParams(HttpServletRequest request) {
+ try {
+ // 1. 优先读取Query String(无需缓存)
+ String queryString = request.getQueryString();
+ if (queryString != null) return queryString;
+
+ // 2. 检查表单参数(GET/POST都适用)
+ Map params = request.getParameterMap();
+ if (!params.isEmpty()) return formatParams(params);
+
+ // 3. 只有明确是JSON请求时才尝试读取body
+ if (isJsonRequest(request)) {
+ return readJsonBodyOnDemand(request);
+ }
+
+ return "{}";
+ } catch (Exception e) {
+ return "{\"error\":\"failed to read params\"}";
+ }
+ }
+
+ private static String readJsonBodyOnDemand(HttpServletRequest request) throws IOException {
+ // 关键点:直接读取原始InputStream(不缓存)
+ try (BufferedReader reader = request.getReader()) {
+ String body = reader.lines().collect(Collectors.joining());
+ return body.isEmpty() ? "{}" : body;
+ }
+ }
+
+
+ private static boolean isJsonRequest(HttpServletRequest request) {
+ String contentType = request.getContentType();
+ return contentType != null && contentType.contains("application/json");
+ }
+
+
+ private static String formatParams(Map params) {
+ // 优化后的参数格式化方法
+ return params.entrySet().stream()
+ .map(entry -> {
+ String key = escapeJson(entry.getKey());
+ String[] values = entry.getValue();
+ if (values.length == 1) {
+ return "\"" + key + "\":\"" + escapeJson(values[0]) + "\"";
+ }
+ return "\"" + key + "\":[" +
+ Arrays.stream(values)
+ .map(v -> "\"" + escapeJson(v) + "\"")
+ .collect(Collectors.joining(",")) +
+ "]";
+ })
+ .collect(Collectors.joining(",", "{", "}"));
+ }
+
+ private static String escapeJson(String raw) {
+ return raw.replace("\\", "\\\\")
+ .replace("\"", "\\\"")
+ .replace("\n", "\\n");
+ }
+
+ private static String getRequestToken(HttpServletRequest request) {
+ String token = request.getHeader("Authorization");
+ if (token == null) {
+ token = request.getHeader("token");
+ }
+ return token;
+ }
+
+ private static String getMainClassFile() {
+ try {
+ // 获取主类名
+ String mainClass = ManagementFactory.getRuntimeMXBean().getSystemProperties().get("sun.java.command");
+ if (mainClass != null) {
+ // 简单处理,提取主类名
+ String className = mainClass.split(" ")[0];
+ // 转换为文件路径
+ return className.replace('.', File.separatorChar) + ".java";
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return "UnknownScript";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/demo/Util/FeiShuAlertUtil.java b/src/main/java/com/example/demo/Util/FeiShuAlertUtil.java
new file mode 100644
index 0000000..cf2a00e
--- /dev/null
+++ b/src/main/java/com/example/demo/Util/FeiShuAlertUtil.java
@@ -0,0 +1,173 @@
+package com.example.demo.Util;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.example.demo.domain.vo.ExecutionContext;
+import com.example.demo.config.EnvConfig;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 飞书报警信息发送工具类
+ */
+@Component
+public class FeiShuAlertUtil {
+
+ private static final String FEISHU_WEBHOOK_URL_PROD = "https://open.feishu.cn/open-apis/bot/v2/hook/1a515b19-b64f-46b7-9486-35842b9539fe";
+ private static final String FEISHU_WEBHOOK_URL_TEST = "https://open.feishu.cn/open-apis/bot/v2/hook/384c78aa-8df1-498b-9c47-04e890ed9877";
+ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ static {
+ DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+ }
+
+ /**
+ * 发送报警信息到飞书群(紧凑单行格式)
+ *
+ * @param context 请求接口
+ * @param errorFile 错误文件
+ * @param errorLine 错误行数
+ * @param errorMsg 错误信息
+ * @param params 脚本执行时需要手动传参,如果时API请求则无需传,自动获取参数
+ * @return 是否发送成功
+ */
+ public static boolean sendAlertMessage(ExecutionContext context,
+ String errorFile, int errorLine,
+ String errorMsg, String params) {
+ JSONObject message = new JSONObject();
+ message.put("msg_type", "post");
+
+ JSONObject content = new JSONObject();
+ JSONObject post = new JSONObject();
+ JSONObject zhCn = new JSONObject();
+ String title = "⚠️ 系统异常报警 ⚠️";
+ zhCn.put("title", title);
+
+ List> contentList = new ArrayList<>();
+ List elements = new ArrayList<>();
+
+ StringBuilder contentBuilder = new StringBuilder();
+ contentBuilder.append("------------------------------\n\n");
+
+ if ("API".equals(context.getExecutionType())) {
+ contentBuilder.append("**执行类型**: API请求\n\n");
+ contentBuilder.append("**请求接口**: ").append(context.getApiUrl()).append("\n\n");
+ contentBuilder.append("**请求参数**: ").append(params).append("\n\n");
+ contentBuilder.append("**请求方法**: ").append(context.getMethod()).append("\n\n");
+ if (context.getToken() != null) {
+ contentBuilder.append("**请求Token**: ")
+ .append(context.getToken().length() > 10 ?
+ context.getToken().substring(0, 10) + "..." :
+ context.getToken())
+ .append("\n\n");
+ }
+ } else {
+ contentBuilder.append("**执行类型**: 脚本执行\n\n");
+ contentBuilder.append("**脚本文件**: ").append(context.getScriptFile()).append("\n\n");
+ contentBuilder.append("**请求参数**: ").append(params).append("\n\n");
+ }
+
+ contentBuilder.append("**错误位置**: ").append(errorFile).append(":").append(errorLine).append("\n\n");
+ contentBuilder.append("**错误信息**: ").append(errorMsg).append("\n\n");
+ contentBuilder.append("**执行时间**: ").append(formatDate(context.getExecutionTime())).append("\n\n");
+ contentBuilder.append("**报警时间**: ").append(formatDate(new Date())).append("\n\n");
+ contentBuilder.append("------------------------------");
+
+ addContentElement(elements, "text", contentBuilder.toString());
+
+ contentList.add(elements);
+ zhCn.put("content", contentList);
+ post.put("zh_cn", zhCn);
+ content.put("post", post);
+ message.put("content", content);
+
+ return sendMessage(message);
+ }
+
+ private static String formatDate(Date date) {
+ // 实现日期格式化方法
+ return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
+ }
+
+ private static void addContentElement(List elements, String tag, String text) {
+ JSONObject element = new JSONObject();
+ element.put("tag", tag);
+ element.put("text", text);
+ elements.add(element);
+ }
+
+ private static boolean sendMessage(JSONObject message) {
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+ String FEISHU_WEBHOOK_URL;
+ String environment = EnvConfig.ENV;
+ System.out.println("当前环境变量:" + environment);
+ if (Objects.equals(environment, "unknown") || environment.equals("dev")) {
+ FEISHU_WEBHOOK_URL = FEISHU_WEBHOOK_URL_TEST;
+ } else {
+ FEISHU_WEBHOOK_URL = FEISHU_WEBHOOK_URL_PROD;
+ }
+ HttpPost httpPost = new HttpPost(FEISHU_WEBHOOK_URL);
+ httpPost.addHeader("Content-Type", "application/json; charset=utf-8");
+
+ StringEntity entity = new StringEntity(message.toJSONString(), "UTF-8");
+ httpPost.setEntity(entity);
+
+ HttpResponse response = httpClient.execute(httpPost);
+ if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+ String result = EntityUtils.toString(response.getEntity());
+ JSONObject obj = JSON.parseObject(result);
+ return obj.getInteger("code") == 0;
+ }
+ } catch (IOException e) {
+ System.out.println("发送飞书异常" + e.getMessage());
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ /**
+ * 发送普通信息到飞书群
+ *
+ * @param title 消息标题
+ * @param content 消息内容
+ * @return 是否发送成功
+ */
+ public static boolean sendNormalMessage(String title, String content) {
+ JSONObject message = new JSONObject();
+ message.put("msg_type", "post");
+
+ JSONObject messageContent = new JSONObject();
+ JSONObject post = new JSONObject();
+ JSONObject zhCn = new JSONObject();
+ zhCn.put("title", title);
+
+ List> contentList = new ArrayList<>();
+ List elements = new ArrayList<>();
+
+ StringBuilder contentBuilder = new StringBuilder();
+ contentBuilder.append("------------------------------\n\n");
+ contentBuilder.append(content).append("\n\n");
+ contentBuilder.append("**发送时间**: ").append(formatDate(new Date())).append("\n\n");
+ contentBuilder.append("------------------------------");
+
+ addContentElement(elements, "text", contentBuilder.toString());
+
+ contentList.add(elements);
+ zhCn.put("content", contentList);
+ post.put("zh_cn", zhCn);
+ messageContent.put("post", post);
+ message.put("content", messageContent);
+
+ return sendMessage(message);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/demo/Util/RedisLockUtil.java b/src/main/java/com/example/demo/Util/RedisLockUtil.java
new file mode 100644
index 0000000..5ae5858
--- /dev/null
+++ b/src/main/java/com/example/demo/Util/RedisLockUtil.java
@@ -0,0 +1,37 @@
+package com.example.demo.Util;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class RedisLockUtil {
+
+ @Autowired
+ private StringRedisTemplate redisTemplate;
+
+ /**
+ * 尝试获取分布式锁
+ * @param lockKey 锁的 Key
+ * @param requestId 请求 ID(可用 UUID)
+ * @param expireTime 锁的过期时间(毫秒)
+ * @return 是否获取成功
+ */
+ public boolean tryLock(String lockKey, String requestId, long expireTime) {
+ return redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * 释放分布式锁
+ * @param lockKey 锁的 Key
+ * @param requestId 请求 ID
+ */
+ public void unlock(String lockKey, String requestId) {
+ String currentValue = redisTemplate.opsForValue().get(lockKey);
+ if (requestId.equals(currentValue)) {
+ redisTemplate.delete(lockKey);
+ }
+ }
+}
diff --git a/src/main/java/com/example/demo/Util/RedisUtil.java b/src/main/java/com/example/demo/Util/RedisUtil.java
index 5431742..47e9e23 100644
--- a/src/main/java/com/example/demo/Util/RedisUtil.java
+++ b/src/main/java/com/example/demo/Util/RedisUtil.java
@@ -1,4 +1,3 @@
-/*
package com.example.demo.Util;
import jakarta.annotation.PostConstruct;
@@ -35,24 +34,24 @@ public class RedisUtil {
delayMessageExecutor = Executors.newFixedThreadPool(DELAY_THREAD_POOL_SIZE);
}
- */
+
/**
* 发送消息到队列
* @param queueName 队列名称
* @param message 消息内容
- *//*
+ */
public void sendMessage(String queueName, Object message) {
redisTemplate.opsForList().rightPush(queueName, message);
}
- */
+
/**
* 阻塞获取消息(优化版,增加重试机制)
* @param queueName 队列名称
* @param timeout 超时时间(秒)
* @return 消息内容
- *//*
+ */
public Object blockingGetMessage(String queueName, long timeout) {
// 分段获取,避免长时间阻塞
@@ -66,35 +65,35 @@ public class RedisUtil {
return null;
}
- */
+
/**
* 非阻塞获取消息
* @param queueName 队列名称
* @return 消息内容
- *//*
+ */
public Object getMessage(String queueName) {
return redisTemplate.opsForList().leftPop(queueName);
}
- */
+
/**
* 获取队列长度
* @param queueName 队列名称
* @return 队列长度
- *//*
+ */
public Long getQueueSize(String queueName) {
return redisTemplate.opsForList().size(queueName);
}
- */
+
/**
* 发送延迟消息(优化版)
* @param queueName 队列名称
* @param message 消息内容
* @param delay 延迟时间(秒)
- *//*
+ */
public void sendDelayMessage(String queueName, Object message, long delay) {
String delayQueueKey = getDelayQueueKey(queueName);
@@ -116,10 +115,10 @@ public class RedisUtil {
});
}
- */
+
/**
* 启动延迟消息处理任务
- *//*
+ */
@Scheduled(fixedRate = DELAY_QUEUE_POLL_INTERVAL)
public void processDelayMessages() {
@@ -134,10 +133,10 @@ public class RedisUtil {
}
}
- */
+
/**
* 处理单个延迟队列
- *//*
+ */
private void processSingleDelayQueue(String queueName) {
String delayQueueKey = getDelayQueueKey(queueName);
@@ -187,4 +186,4 @@ public class RedisUtil {
}
return serialized;
}
-}*/
+}
diff --git a/src/main/java/com/example/demo/config/EnvConfig.java b/src/main/java/com/example/demo/config/EnvConfig.java
new file mode 100644
index 0000000..1e7df48
--- /dev/null
+++ b/src/main/java/com/example/demo/config/EnvConfig.java
@@ -0,0 +1,18 @@
+package com.example.demo.config;
+
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @program: GOLD
+ * @ClassName EnvConfig
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−06-29 13:55
+ * @Version 1.0
+ **/
+@Configuration
+public class EnvConfig {
+ public static final String ENV = "dev";
+ public static final String ENV_PROD = "prod";
+ public static final String ENV_TEST = "test";
+}
diff --git a/src/main/java/com/example/demo/config/RedisConfig.java b/src/main/java/com/example/demo/config/RedisConfig.java
index dfd5115..3cae685 100644
--- a/src/main/java/com/example/demo/config/RedisConfig.java
+++ b/src/main/java/com/example/demo/config/RedisConfig.java
@@ -1,4 +1,4 @@
-/*
+
package com.example.demo.config;
import org.springframework.beans.factory.annotation.Autowired;
@@ -45,4 +45,4 @@ public class RedisConfig {
}
-*/
+
diff --git a/src/main/java/com/example/demo/controller/AdminController.java b/src/main/java/com/example/demo/controller/AdminController.java
new file mode 100644
index 0000000..c117b3e
--- /dev/null
+++ b/src/main/java/com/example/demo/controller/AdminController.java
@@ -0,0 +1,43 @@
+package com.example.demo.controller;
+
+import com.example.demo.Util.JWTUtil;
+import com.example.demo.domain.entity.Admin;
+import com.example.demo.domain.vo.Result;
+import com.example.demo.service.AdminService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @program: GOLD
+ * @ClassName AdminController
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−07-01 10:39
+ * @Version 1.0
+ **/
+@RestController
+@RequestMapping("/admin")
+@RequiredArgsConstructor
+@Slf4j
+@CrossOrigin
+public class AdminController {
+ @Autowired
+ private AdminService adminService;
+ @PostMapping("/login")
+ public Result login(@RequestBody Admin admin){
+
+ try {
+ admin = adminService.login(admin);
+ admin.setPassword(null);
+ System.out.println("达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达");
+ return Result.success(admin);
+ } catch (Exception e) {
+ e.printStackTrace();
+ log.error(e.getMessage());
+ return Result.error(e.getMessage());
+ }
+
+ }
+}
diff --git a/src/main/java/com/example/demo/controller/AuditController.java b/src/main/java/com/example/demo/controller/AuditController.java
index 7c58292..349df97 100644
--- a/src/main/java/com/example/demo/controller/AuditController.java
+++ b/src/main/java/com/example/demo/controller/AuditController.java
@@ -1,11 +1,14 @@
package com.example.demo.controller;
+import com.example.demo.domain.vo.*;
+import com.example.demo.service.AuditService;
+import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
/**
* @program: gold-java
@@ -23,4 +26,50 @@ import org.springframework.web.bind.annotation.RestController;
@Transactional
@CrossOrigin
public class AuditController {
+
+ @Autowired
+ private AuditService auditService;
+
+ //审核订单
+ @PostMapping("audit")
+ public ResponseEntity auditOrder(
+ @RequestBody AuditRequest request) {
+ boolean result = auditService.auditOrder(request.getToken(),request.getOrderCode(), request.getAuditId(), request.getAction(),request.getRejectReason());
+ return ResponseEntity.ok(result);
+}
+ //多条件查询充值审核订单列表
+ @PostMapping("selectRecharge")
+ public PageInfo searchRechargeAudit(
+ @RequestBody Page page) {
+ Integer pageNum = page.getPageNum();
+ Integer pageSize = page.getPageSize();
+ RechargeAudit rechargeAudit = page.getRechargeAudit();
+
+ return auditService.selectRechargeBy(pageNum, pageSize, rechargeAudit);
+} //多条件查询退款审核订单列表
+ @PostMapping("selectRefund")
+ public PageInfo searchRefundAudit(
+ @RequestBody Page page) {
+ Integer pageNum = page.getPageNum();
+ Integer pageSize = page.getPageSize();
+ RefundAudit refundAudit = page.getRefundAudit();
+
+ return auditService.selectRefundBy(pageNum, pageSize, refundAudit);
+}
+ //充值审核合计数
+ @PostMapping("sumRechargeGold")
+ public Gold sumRechargeGold(@RequestBody Page page) {
+ Integer pageNum = page.getPageNum();
+ Integer pageSize = page.getPageSize();
+ RechargeAudit rechargeAudit = page.getRechargeAudit();
+ return auditService.sumRechargeGold(pageNum, pageSize, rechargeAudit);
+ }
+ //退款审核合计数
+ @PostMapping("sumRefundGold")
+ public Gold sumRefundGold(@RequestBody Page page) {
+ Integer pageNum = page.getPageNum();
+ Integer pageSize = page.getPageSize();
+ RefundAudit refundAudit = page.getRefundAudit();
+ return auditService.sumRefundGold(pageNum, pageSize, refundAudit);
+ }
}
diff --git a/src/main/java/com/example/demo/controller/ConsumeController.java b/src/main/java/com/example/demo/controller/ConsumeController.java
index ba399bb..9ddf11b 100644
--- a/src/main/java/com/example/demo/controller/ConsumeController.java
+++ b/src/main/java/com/example/demo/controller/ConsumeController.java
@@ -6,6 +6,7 @@ import com.example.demo.domain.vo.Gold;
import com.example.demo.domain.vo.Page;
import com.example.demo.domain.vo.Result;
import com.example.demo.service.ConsumeService;
+import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -41,7 +42,7 @@ public class ConsumeController {
if (ObjectUtils.isEmpty(page.getPageSize())) {
return Result.error("页大小为空!");
} else {
- return Result.success(consumeService.selectAll(page.getPageNum(), page.getPageSize()));
+ return Result.success(consumeService.selectAll(page.getPageNum(), page.getPageSize(),page.getConsumeUser()));
}
} catch (Exception e) {
return Result.error("接口调用失败");
@@ -50,6 +51,7 @@ public class ConsumeController {
}
+
//消耗明细筛选
@PostMapping("/selectBy")
public Result selcetBy(@RequestBody Page page) {
@@ -70,9 +72,9 @@ public class ConsumeController {
//消耗金币统计
@PostMapping("/statsGold")
- public Result statsGold() {
+ public Result statsGold(@RequestBody ConsumeUser consumeUser) {
try {
- Gold gold = consumeService.statsGold();
+ Gold gold = consumeService.statsGold(consumeUser);
return Result.success(gold);
} catch (Exception e) {
return Result.error("接口调用失败");
@@ -84,6 +86,13 @@ public class ConsumeController {
public Result add(@RequestBody ConsumeUser consumeUser) {
try {
return consumeService.add(consumeUser);
+// if(consumeUser.getJwcode().equals(94226013))
+// {
+// return consumeService.add(consumeUser);
+// }else {
+// return Result.error("不是测试的精网号,无法添加消费");
+// }
+//
} catch (Exception e) {
return Result.error("接口调用失败");
}
diff --git a/src/main/java/com/example/demo/controller/ExportController.java b/src/main/java/com/example/demo/controller/ExportController.java
new file mode 100644
index 0000000..2269657
--- /dev/null
+++ b/src/main/java/com/example/demo/controller/ExportController.java
@@ -0,0 +1,99 @@
+package com.example.demo.controller;
+
+import com.example.demo.Util.BusinessException;
+import com.example.demo.Util.RedisLockUtil;
+import com.example.demo.domain.DTO.ConsumeDTO;
+import com.example.demo.domain.DTO.RechargeDTO;
+import com.example.demo.domain.DTO.RefundDTO;
+import com.example.demo.domain.entity.Export;
+import com.example.demo.domain.vo.Result;
+import com.example.demo.service.ExportExcelService;
+import com.example.demo.service.GoldDetailService;
+import com.example.demo.Export.ExportService;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @program: GOLD
+ * @ClassName ExportController
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−06-28 15:22
+ * @Version 1.0
+ **/
+@RestController
+@RequestMapping("/export")
+@RequiredArgsConstructor
+@Slf4j
+@CrossOrigin
+public class ExportController {
+ @Autowired
+ private ExportExcelService exportExcelService;
+ @Autowired
+ private RedisLockUtil redisLockUtil;
+ @Autowired
+ private GoldDetailService goldDetailService;
+ @Autowired
+ private ExportService exportService;
+ @PostMapping("/export")
+ public Result export(@RequestBody Export Export){
+ return Result.success(exportExcelService.getExcel(Export));
+ }
+ @PostMapping("/exportRecharge")
+ public Result export(@Valid @RequestBody RechargeDTO dto) {
+ String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分)
+ String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁)
+ long expireTime = 5000; // 锁过期时间(5秒)s
+ try {
+ // 尝试获取锁
+ if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) {
+ throw new BusinessException("操作太频繁,请稍后重试");
+ }
+ // 执行业务逻辑
+ return exportService.addExportRecharge(dto);
+ } finally {
+ // 释放锁
+ redisLockUtil.unlock(lockKey, requestId);
+ }
+ }
+ @PostMapping("/exportRefund")
+ public Result export(@Valid @RequestBody RefundDTO dto) {
+ String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分)
+ String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁)
+ long expireTime = 5000; // 锁过期时间(5秒)s
+ try {
+ // 尝试获取锁
+ if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) {
+ throw new BusinessException("操作太频繁,请稍后重试");
+ }
+ // 执行业务逻辑
+ return exportService.addExportRefund(dto);
+ } finally {
+ // 释放锁
+ redisLockUtil.unlock(lockKey, requestId);
+ }
+ }
+ @PostMapping("/exportConsume")
+ public Result export(@Valid @RequestBody ConsumeDTO dto) {
+ String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分)
+ String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁)
+ long expireTime = 5000; // 锁过期时间(5秒)s
+ try {
+ // 尝试获取锁
+ if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) {
+ throw new BusinessException("操作太频繁,请稍后重试");
+ }
+ // 执行业务逻辑
+ return exportService.addExportConsume(dto);
+ } finally {
+ // 释放锁
+ redisLockUtil.unlock(lockKey, requestId);
+ }
+ }
+}
diff --git a/src/main/java/com/example/demo/controller/GeneralController.java b/src/main/java/com/example/demo/controller/GeneralController.java
index f22a320..be01a78 100644
--- a/src/main/java/com/example/demo/controller/GeneralController.java
+++ b/src/main/java/com/example/demo/controller/GeneralController.java
@@ -47,4 +47,10 @@ public class GeneralController {
List list = generalService.getGoods();
return Result.success(list);
}
+ @PostMapping("/activity")
+ public Result getActivity()
+ {
+ List list = generalService.getActivity();
+ return Result.success(list);
+ }
}
diff --git a/src/main/java/com/example/demo/controller/GoldDetailController.java b/src/main/java/com/example/demo/controller/GoldDetailController.java
index 71e86a3..dde8d2d 100644
--- a/src/main/java/com/example/demo/controller/GoldDetailController.java
+++ b/src/main/java/com/example/demo/controller/GoldDetailController.java
@@ -1,15 +1,24 @@
package com.example.demo.controller;
+import com.example.demo.Util.BusinessException;
+import com.example.demo.Util.RedisLockUtil;
+import com.example.demo.domain.DTO.GoldDetailDTO;
+import com.example.demo.domain.DTO.GoldUserDTO;
import com.example.demo.domain.entity.User;
import com.example.demo.domain.vo.GoldDetail;
import com.example.demo.domain.vo.Page;
import com.example.demo.domain.vo.Result;
import com.example.demo.service.GoldDetailService;
+import com.example.demo.serviceImpl.AiEmotionServiceImpl;
+import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
+import java.util.UUID;
+
/**
* @program: GOLD
* @ClassName GoldDetailController
@@ -26,6 +35,12 @@ import org.springframework.web.bind.annotation.*;
@CrossOrigin
public class GoldDetailController {
private final GoldDetailService goldDetailService;
+
+ @Autowired
+ private RedisLockUtil redisLockUtil;
+ @Autowired
+ private AiEmotionServiceImpl aiEmotionServiceImpl;
+
@PostMapping("/getGoldDetail")
public Result getGoldDetail(@RequestBody Page page){
@@ -58,4 +73,39 @@ public class GoldDetailController {
}
return Result.success(goldDetailService.getGold(page.getPageNum(), page.getPageSize(), page.getUser()));
}
+ @PostMapping("/export")
+ public Result export(@Valid @RequestBody GoldDetailDTO dto) {
+ String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分)
+ String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁)
+ long expireTime = 5000; // 锁过期时间(5秒)s
+ try {
+ // 尝试获取锁
+ if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) {
+ throw new BusinessException("操作太频繁,请稍后重试");
+ }
+ // 执行业务逻辑
+ return goldDetailService.addExportRecord(dto);
+ } finally {
+ // 释放锁
+ redisLockUtil.unlock(lockKey, requestId);
+ }
+ }
+ @PostMapping("/exportGold")
+ public Result export(@Valid @RequestBody GoldUserDTO dto) {
+ String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分)
+ String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁)
+ long expireTime = 5000; // 锁过期时间(5秒)s
+ try {
+ // 尝试获取锁
+ if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) {
+ throw new BusinessException("操作太频繁,请稍后重试");
+ }
+ // 执行业务逻辑
+ return goldDetailService.addExportRecordGold(dto);
+ } finally {
+ // 释放锁
+ redisLockUtil.unlock(lockKey, requestId);
+ }
+ }
+
}
diff --git a/src/main/java/com/example/demo/controller/PermissionController.java b/src/main/java/com/example/demo/controller/PermissionController.java
index 964c986..9e043d4 100644
--- a/src/main/java/com/example/demo/controller/PermissionController.java
+++ b/src/main/java/com/example/demo/controller/PermissionController.java
@@ -62,5 +62,9 @@ public class PermissionController {
public Result updateAdminRole(@RequestBody AdminRole adminrole){
return Result.success(permissionService.updateAdminRole(adminrole));
}
+ @PostMapping("/upadatePermission")
+ public Result upadatePermission(@RequestBody Admin admin) throws Exception {
+ return Result.success(permissionService.upadatePermission(admin));
+ }
}
diff --git a/src/main/java/com/example/demo/controller/RateController.java b/src/main/java/com/example/demo/controller/RateController.java
new file mode 100644
index 0000000..1d34ac1
--- /dev/null
+++ b/src/main/java/com/example/demo/controller/RateController.java
@@ -0,0 +1,69 @@
+package com.example.demo.controller;
+
+
+import com.example.demo.domain.entity.Rate;
+import com.example.demo.domain.vo.Page;
+import com.example.demo.domain.vo.Result;
+import com.example.demo.mapper.RateMapper;
+import com.example.demo.service.RateService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.ObjectUtils;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+
+@RestController
+@RequestMapping("/rate")
+@RequiredArgsConstructor
+@Slf4j
+@CrossOrigin
+public class RateController {
+
+ @Autowired
+ private RateService rateService;
+
+ //货币汇率列表
+ @PostMapping("/selectAll")
+ public Result selectAll(@RequestBody Page page){
+ if (ObjectUtils.isEmpty(page.getPageNum())) {
+ return Result.error("页码数为空!");
+ }
+ if (ObjectUtils.isEmpty(page.getPageSize())) {
+ return Result.error("页大小为空!");
+ } else {
+ return Result.success(rateService.selectAll(page.getPageNum(), page.getPageSize()));
+ }
+ }
+
+ //查询货币
+ @PostMapping("/selectById")
+ public Result selectById(@RequestBody Map requestBody) {
+ Integer id = (Integer) requestBody.get("id");
+ if (ObjectUtils.isEmpty(id)) {
+ return Result.error("id 为空!");
+ }
+ Rate rate = rateService.selectById(id);
+ return Result.success(rate);
+ }
+
+ // 编辑
+ @PostMapping("/update")
+ public Result update(@RequestBody Rate rate) {
+ if (ObjectUtils.isEmpty(rate.getId())) {
+ return Result.error("id不能为空");
+ }
+ if (ObjectUtils.isEmpty(rate.getRateName())) {
+ return Result.error("汇率名称不能为空");
+ }
+ if (rate.getNum() == null) {
+ return Result.error("汇率数值不能为空");
+ }
+ rateService.update(rate);
+ return Result.success("编辑成功");
+ }
+
+}
diff --git a/src/main/java/com/example/demo/controller/RechargeController.java b/src/main/java/com/example/demo/controller/RechargeController.java
new file mode 100644
index 0000000..005e08a
--- /dev/null
+++ b/src/main/java/com/example/demo/controller/RechargeController.java
@@ -0,0 +1,93 @@
+package com.example.demo.controller;
+
+import com.example.demo.domain.vo.*;
+import com.example.demo.service.ConsumeService;
+import com.example.demo.service.RechargeService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @program: gold-java
+ * @ClassName RechargeController
+ * @description:
+ * @author: Double
+ * @create: 2025−06-29 13:01
+ * @Version 1.0
+ **/
+
+@RestController
+@RequestMapping("/recharge")
+@RequiredArgsConstructor
+@Slf4j
+@CrossOrigin
+public class RechargeController {
+
+
+ @Autowired
+ private RechargeService rechargeService;
+
+ //消耗明细
+ @PostMapping("/selectAll")
+ public Result selcetAll(@RequestBody Page page) {
+ try {
+ if (ObjectUtils.isEmpty(page.getPageNum())) {
+ return Result.error("页码数为空!");
+ }
+ if (ObjectUtils.isEmpty(page.getPageSize())) {
+ return Result.error("页大小为空!");
+ } else {
+ return Result.success(rechargeService.selectAll(page.getPageNum(), page.getPageSize(),page.getRechargeUser()));
+ }
+ } catch (Exception e) {
+ return Result.error("接口调用失败");
+
+ }
+
+ }
+
+
+ //消耗明细筛选
+ @PostMapping("/selectBy")
+ public Result selcetBy(@RequestBody Page page) {
+ try {
+ if (ObjectUtils.isEmpty(page.getPageNum())) {
+ return Result.error("页码数为空!");
+ }
+ if (ObjectUtils.isEmpty(page.getPageSize())) {
+ return Result.error("页大小为空!");
+ } else {
+ return Result.success(rechargeService.selectBy(page.getPageNum(), page.getPageSize(), page.getRechargeUser()));
+ }
+ } catch (Exception e) {
+ return Result.error("接口调用失败");
+ }
+
+ }
+
+ //消耗金币统计
+ @PostMapping("/statsGold")
+ public Result statsGold(@RequestBody RechargeUser rechargeUser) {
+ try {
+ Gold gold = rechargeService.statsGold(rechargeUser);
+ return Result.success(gold);
+ } catch (Exception e) {
+ return Result.error("接口调用失败");
+ }
+ }
+
+ //充值金币增加
+ @PostMapping("/add")
+ public Result add(@RequestBody RechargeUser rechargeUser) {
+ try {
+ return rechargeService.add(rechargeUser);
+ } catch (Exception e) {
+ return Result.error("接口调用失败");
+ }
+ }
+
+
+
+}
diff --git a/src/main/java/com/example/demo/controller/RefundController.java b/src/main/java/com/example/demo/controller/RefundController.java
index 51f92f7..edd707b 100644
--- a/src/main/java/com/example/demo/controller/RefundController.java
+++ b/src/main/java/com/example/demo/controller/RefundController.java
@@ -1,8 +1,6 @@
package com.example.demo.controller;
-import com.example.demo.domain.vo.Gold;
-import com.example.demo.domain.vo.Page;
-import com.example.demo.domain.vo.Result;
+import com.example.demo.domain.vo.*;
import com.example.demo.service.ConsumeService;
import com.example.demo.service.RefundService;
import lombok.RequiredArgsConstructor;
@@ -11,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
+import java.util.List;
+
/**
* @program: gold-java
* @ClassName RefundMapper.xml
@@ -40,7 +40,7 @@ public class RefundController {
if (ObjectUtils.isEmpty(page.getPageSize())) {
return Result.error("页大小为空!");
} else {
- return Result.success(refundService.selectAll(page.getPageNum(), page.getPageSize()));
+ return Result.success(refundService.selectAll(page.getPageNum(), page.getPageSize(), page.getRefundUser()));
}
} catch (Exception e) {
return Result.error("接口调用失败");
@@ -66,13 +66,36 @@ public class RefundController {
}
@PostMapping("/statsGold")
- public Result statsGold() {
+ public Result statsGold(@RequestBody RefundUser refundUser) {
try {
- Gold gold = refundService.statsGold();
+ Gold gold = refundService.statsGold(refundUser);
return Result.success(gold);
} catch (Exception e) {
return Result.error("接口调用失败");
}
}
+ @PostMapping("/refundType")
+ public Result getRefundType()
+ {
+ List list = refundService.getRefundType();
+ return Result.success(list);
+ }
+
+ @PostMapping("/selectGoods")
+ public Result getSelectGoods(@RequestBody RefundUser refundUser)
+ {
+ List list = refundService.selectGoods(refundUser.getJwcode());
+ return Result.success(list);
+ }
+
+ //消耗金币增加
+ @PostMapping("/add")
+ public Result add(@RequestBody RefundUser refundUser) {
+ try {
+ return refundService.add(refundUser);
+ } catch (Exception e) {
+ return Result.error("接口调用失败");
+ }
+ }
}
diff --git a/src/main/java/com/example/demo/controller/StatisticsController.java b/src/main/java/com/example/demo/controller/StatisticsController.java
index d18fee3..c1a9726 100644
--- a/src/main/java/com/example/demo/controller/StatisticsController.java
+++ b/src/main/java/com/example/demo/controller/StatisticsController.java
@@ -44,6 +44,11 @@ public class StatisticsController {
public void HourlyTask2() {
statisticsService.runHourlyTaskPart2();
}
+ //测试一周内定时任务part2
+ @PostMapping("/Daily2")
+ public void DailyTask2() {
+ statisticsService.runDailyTaskPart2();
+ }
diff --git a/src/main/java/com/example/demo/controller/WorkbenchController.java b/src/main/java/com/example/demo/controller/WorkbenchController.java
index 3e73097..f6fcf8c 100644
--- a/src/main/java/com/example/demo/controller/WorkbenchController.java
+++ b/src/main/java/com/example/demo/controller/WorkbenchController.java
@@ -43,7 +43,7 @@ public class WorkbenchController {
*/
@PostMapping("getCard")
public ResponseEntity card1(@RequestBody WorkbenchCard workbench){
- WorkbenchCard result =workbenchService.getCard(workbench.getToken(),workbench.getMarkets());
+ WorkbenchCard result =workbenchService.getCard(workbench.getToken());
return ResponseEntity.ok(result);
}
/*
diff --git a/src/main/java/com/example/demo/domain/DTO/ConsumeDTO.java b/src/main/java/com/example/demo/domain/DTO/ConsumeDTO.java
new file mode 100644
index 0000000..d8a7b01
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/DTO/ConsumeDTO.java
@@ -0,0 +1,42 @@
+package com.example.demo.domain.DTO;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @program: GOLD
+ * @ClassName ConsumeDTO
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−07-01 16:17
+ * @Version 1.0
+ **/
+@Data
+@NoArgsConstructor
+public class ConsumeDTO {
+ private String token;
+ private String url = "";
+ private String fileName = "";
+ private Integer sort = 0;
+ private String field = "";
+ private Integer account;
+ private Integer type = 4; //类型
+ private Integer state = 0; //状态
+ private String text = ""; //关键词搜索
+ private Integer dataNum = 0;
+ private String deptid = "";
+
+ @NotNull(message = "page不能为空")
+ private Integer page = 1;
+ @NotNull(message = "pageSize不能为空")
+ private Integer pageSize = 20;
+
+ @Override
+ public String toString() {
+ return String.format(
+ "AiEmotionExport(account=%d, type=%d, state=%d, dataNum=%d)",
+ account, type, state, dataNum
+ );
+ }
+}
diff --git a/src/main/java/com/example/demo/domain/DTO/GoldDetailDTO.java b/src/main/java/com/example/demo/domain/DTO/GoldDetailDTO.java
new file mode 100644
index 0000000..b03acca
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/DTO/GoldDetailDTO.java
@@ -0,0 +1,44 @@
+package com.example.demo.domain.DTO;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @program: GOLD
+ * @ClassName AiEmotionExportDTO
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−06-30 15:06
+ * @Version 1.0
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class GoldDetailDTO {
+ private String token;
+ private String url = "";
+ private String fileName = "";
+ private Integer sort = 0;
+ private String field = "";
+ private Integer account;
+ private Integer type = 0; //类型
+ private Integer state = 0; //状态
+ private String text = ""; //关键词搜索
+ private Integer dataNum = 0;
+ private String deptid = "";
+
+ @NotNull(message = "page不能为空")
+ private Integer page = 1;
+ @NotNull(message = "pageSize不能为空")
+ private Integer pageSize = 20;
+
+ @Override
+ public String toString() {
+ return String.format(
+ "AiEmotionExport(account=%d, type=%d, state=%d, dataNum=%d)",
+ account, type, state, dataNum
+ );
+ }
+}
diff --git a/src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java b/src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java
new file mode 100644
index 0000000..0087f6f
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java
@@ -0,0 +1,42 @@
+package com.example.demo.domain.DTO;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @program: GOLD
+ * @ClassName GoldDTO
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−06-30 23:40
+ * @Version 1.0
+ **/
+@Data
+@NoArgsConstructor
+public class GoldUserDTO {
+ private String token;
+ private String url = "";
+ private String fileName = "";
+ private Integer sort = 0;
+ private String field = "";
+ private Integer account;
+ private Integer type = 1; //类型
+ private Integer state = 0; //状态
+ private String text = ""; //关键词搜索
+ private Integer dataNum = 0;
+ private String deptid = "";
+
+ @NotNull(message = "page不能为空")
+ private Integer page = 1;
+ @NotNull(message = "pageSize不能为空")
+ private Integer pageSize = 20;
+
+ @Override
+ public String toString() {
+ return String.format(
+ "AiEmotionExport(account=%d, type=%d, state=%d, dataNum=%d)",
+ account, type, state, dataNum
+ );
+ }
+}
diff --git a/src/main/java/com/example/demo/domain/DTO/RechargeDTO.java b/src/main/java/com/example/demo/domain/DTO/RechargeDTO.java
new file mode 100644
index 0000000..d9608c4
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/DTO/RechargeDTO.java
@@ -0,0 +1,43 @@
+package com.example.demo.domain.DTO;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @program: GOLD
+ * @ClassName RechargeDTO
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−07-01 16:15
+ * @Version 1.0
+ **/
+
+@Data
+@NoArgsConstructor
+public class RechargeDTO {
+ private String token;
+ private String url = "";
+ private String fileName = "";
+ private Integer sort = 0;
+ private String field = "";
+ private Integer account;
+ private Integer type = 2; //类型
+ private Integer state = 0; //状态
+ private String text = ""; //关键词搜索
+ private Integer dataNum = 0;
+ private String deptid = "";
+
+ @NotNull(message = "page不能为空")
+ private Integer page = 1;
+ @NotNull(message = "pageSize不能为空")
+ private Integer pageSize = 20;
+
+ @Override
+ public String toString() {
+ return String.format(
+ "AiEmotionExport(account=%d, type=%d, state=%d, dataNum=%d)",
+ account, type, state, dataNum
+ );
+ }
+}
diff --git a/src/main/java/com/example/demo/domain/DTO/RefundDTO.java b/src/main/java/com/example/demo/domain/DTO/RefundDTO.java
new file mode 100644
index 0000000..dcd232d
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/DTO/RefundDTO.java
@@ -0,0 +1,42 @@
+package com.example.demo.domain.DTO;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @program: GOLD
+ * @ClassName RefundDTO
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−07-01 16:16
+ * @Version 1.0
+ **/
+@Data
+@NoArgsConstructor
+public class RefundDTO {
+ private String token;
+ private String url = "";
+ private String fileName = "";
+ private Integer sort = 0;
+ private String field = "";
+ private Integer account;
+ private Integer type = 3; //类型
+ private Integer state = 0; //状态
+ private String text = ""; //关键词搜索
+ private Integer dataNum = 0;
+ private String deptid = "";
+
+ @NotNull(message = "page不能为空")
+ private Integer page = 1;
+ @NotNull(message = "pageSize不能为空")
+ private Integer pageSize = 20;
+
+ @Override
+ public String toString() {
+ return String.format(
+ "AiEmotionExport(account=%d, type=%d, state=%d, dataNum=%d)",
+ account, type, state, dataNum
+ );
+ }
+}
diff --git a/src/main/java/com/example/demo/domain/entity/Admin.java b/src/main/java/com/example/demo/domain/entity/Admin.java
index 666c30a..86dbb80 100644
--- a/src/main/java/com/example/demo/domain/entity/Admin.java
+++ b/src/main/java/com/example/demo/domain/entity/Admin.java
@@ -1,17 +1,19 @@
package com.example.demo.domain.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.NoArgsConstructor;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
-import java.util.Date;
+import java.util.*;
@Data
@NoArgsConstructor
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Admin implements Serializable {
+public class Admin implements UserDetails, Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 主键ID
@@ -30,4 +32,60 @@ public class Admin implements Serializable {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date updateTime; // 更新时间
private Integer roleId;
+
+
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ Set authorities = new HashSet<>();
+ Optional.ofNullable(postiton)
+ .map(Integer::valueOf)
+ .ifPresent(permValue -> {
+ switch (permValue) {
+ case 1:
+ authorities.add(new SimpleGrantedAuthority("ROLE_SUPER_ADMIN"));
+ break;
+ case 2:
+ authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
+ break;
+ case 3:
+ authorities.add(new SimpleGrantedAuthority("ROLE_AUDITORS"));
+ break;
+ case 5:
+ authorities.add(new SimpleGrantedAuthority("Branch_Manager"));
+ break;
+ default:
+ // 可以添加默认角色或处理未知权限
+ break;
+ }
+ });
+ return authorities;
+ }
+ @Override
+ public String getUsername() {
+ return account;
+ }
+
+ @Override
+ @JsonIgnore
+ public boolean isAccountNonExpired() {
+ return true; // 默认账户未过期
+ }
+
+ @Override
+ @JsonIgnore
+ public boolean isAccountNonLocked() {
+ return true; // 默认账户未锁定
+ }
+
+ @Override
+ @JsonIgnore
+ public boolean isCredentialsNonExpired() {
+ return true; // 默认凭证未过期
+ }
+
+ @Override
+ @JsonIgnore
+ public boolean isEnabled() {
+ return adminStatus != null && adminStatus == 1;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/example/demo/domain/export/Goldmingxi.java b/src/main/java/com/example/demo/domain/export/Goldmingxi.java
new file mode 100644
index 0000000..a5c0b08
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/export/Goldmingxi.java
@@ -0,0 +1,28 @@
+package com.example.demo.domain.export;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @program: GOLD
+ * @ClassName goldmingxi
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−06-29 17:37
+ * @Version 1.0
+ **/
+@Data
+@NoArgsConstructor
+public class Goldmingxi {
+ private String name; // 名称
+ private Integer jwcode; // 精网号
+ private String market; // 所属地区
+ private String payPlatform; // 支付平台
+ private Integer type; // 类型
+ private Integer sumGold; // 总金币
+ private Integer permentGold; //永久金币
+ private Integer freeJune; // 免费金币六月到期
+ private Integer freeDecember; // 免费金币七月到期
+ private Integer taskGold; // 任务金币
+ private String adminName; //提交人
+}
diff --git a/src/main/java/com/example/demo/domain/vo/AiEmotionExportRecordVO.java b/src/main/java/com/example/demo/domain/vo/AiEmotionExportRecordVO.java
new file mode 100644
index 0000000..8f4a5e8
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/vo/AiEmotionExportRecordVO.java
@@ -0,0 +1,28 @@
+package com.example.demo.domain.vo;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @program: GOLD
+ * @ClassName AiEmotionExportRecordVO
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−06-29 14:59
+ * @Version 1.0
+ **/
+@Data
+@NoArgsConstructor
+public class AiEmotionExportRecordVO {
+ private static final long serialVersionUID = 1L;
+ private String token;
+ private Long id;
+ private Long jwcode;
+ private String fileName;
+ private String url;
+ private Integer state;
+ private Date createTime;
+ private Date updateTime;
+}
diff --git a/src/main/java/com/example/demo/domain/vo/AuditRequest.java b/src/main/java/com/example/demo/domain/vo/AuditRequest.java
new file mode 100644
index 0000000..3be612a
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/vo/AuditRequest.java
@@ -0,0 +1,18 @@
+package com.example.demo.domain.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AuditRequest {
+ private String token;
+ private String orderCode; //订单号
+ private Integer auditId; //审核人id
+ private Integer action; //操作
+ private String rejectReason; //驳回理由
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/demo/domain/vo/ConsumeUser.java b/src/main/java/com/example/demo/domain/vo/ConsumeUser.java
index f1617c7..d2370ce 100644
--- a/src/main/java/com/example/demo/domain/vo/ConsumeUser.java
+++ b/src/main/java/com/example/demo/domain/vo/ConsumeUser.java
@@ -1,6 +1,7 @@
package com.example.demo.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
+import jakarta.validation.constraints.PositiveOrZero;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -43,4 +44,7 @@ public class ConsumeUser implements Serializable {
private Date startTime; // 开始时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date endTime; // 结束时间
+
+ private String sortField; //排序字段
+ private String sortOrder; //排序顺序
}
diff --git a/src/main/java/com/example/demo/domain/vo/ExecutionContext.java b/src/main/java/com/example/demo/domain/vo/ExecutionContext.java
new file mode 100644
index 0000000..76d3213
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/vo/ExecutionContext.java
@@ -0,0 +1,25 @@
+package com.example.demo.domain.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@AllArgsConstructor
+public class ExecutionContext {
+ // getters 和 setters
+ private String executionType; // "API" 或 "SCRIPT"
+ private String apiUrl;
+ private String requestParams;
+ private String token;
+ private String scriptFile;
+ private Date executionTime;
+ private String method;
+
+ // 构造方法
+ public ExecutionContext() {
+ this.executionTime = new Date();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/demo/domain/vo/ExportVo.java b/src/main/java/com/example/demo/domain/vo/ExportVo.java
new file mode 100644
index 0000000..3042db9
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/vo/ExportVo.java
@@ -0,0 +1,26 @@
+package com.example.demo.domain.vo;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @program: GOLD
+ * @ClassName ExportVo
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−06-29 17:24
+ * @Version 1.0
+ **/
+@Data
+@NoArgsConstructor
+
+public class ExportVo {
+ private String token;
+ private Long id;
+ private String fileName;
+ private String url;
+ private Integer state;
+
+}
diff --git a/src/main/java/com/example/demo/domain/vo/Gold.java b/src/main/java/com/example/demo/domain/vo/Gold.java
index a38a574..94119e2 100644
--- a/src/main/java/com/example/demo/domain/vo/Gold.java
+++ b/src/main/java/com/example/demo/domain/vo/Gold.java
@@ -20,6 +20,7 @@ import java.io.Serializable;
@AllArgsConstructor
public class Gold implements Serializable {
private static final long serialVersionUID = 1L;
+ private Integer totalNum; //总条数
private Integer permanentGolds; // 永久金币总数
private Integer freeGolds; // 免费金币总数
private Integer taskGolds; // 任务金币总数
diff --git a/src/main/java/com/example/demo/domain/vo/Page.java b/src/main/java/com/example/demo/domain/vo/Page.java
index 978d398..72b26bf 100644
--- a/src/main/java/com/example/demo/domain/vo/Page.java
+++ b/src/main/java/com/example/demo/domain/vo/Page.java
@@ -24,4 +24,7 @@ public class Page {
private User user;
private RefundUser refundUser;
private Permission permission;
+ private RechargeAudit rechargeAudit;
+ private RefundAudit refundAudit;
+ private RechargeUser rechargeUser;
}
diff --git a/src/main/java/com/example/demo/domain/vo/RateDetail.java b/src/main/java/com/example/demo/domain/vo/RateDetail.java
new file mode 100644
index 0000000..37a240b
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/vo/RateDetail.java
@@ -0,0 +1,30 @@
+package com.example.demo.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+ @Data
+ @NoArgsConstructor
+ public class RateDetail {
+ private static final long serialVersionUID = 1L;
+
+
+ private Integer id;
+ private String rateName;
+ private BigDecimal num = BigDecimal.ZERO;
+ private Integer adminId;//提交人
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date createTime; // 创建时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date updateTime; // 更新时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date lastTime; // 最晚时间
+
+
+ }
+
+
diff --git a/src/main/java/com/example/demo/domain/vo/RechargeAudit.java b/src/main/java/com/example/demo/domain/vo/RechargeAudit.java
new file mode 100644
index 0000000..4438ea6
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/vo/RechargeAudit.java
@@ -0,0 +1,57 @@
+package com.example.demo.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @program: gold-java
+ * @ClassName RechargeAudit
+ * @description: 充值审核
+ * @author: Ethan
+ * @create: 2025−06-30 10:29
+ * @Version 1.0
+ **/
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class RechargeAudit {
+ private static final long serialVersionUID = 1L;
+
+ private String name; // 客户姓名
+ private Integer jwcode; // 精网号
+ private String orderCode; // 订单号
+ private String activity; // 活动名称
+ private String market; // 所属地区
+ private Byte refundType; // 退款类型
+ private Integer sumGold; //充值金额
+ private Integer permanentGold; // 永久金币
+ private Integer freeGold; // 免费金币
+ private Integer freeJune; // 6月免费金币
+ private Integer freeDecember; // 12月免费金币
+ private String remark; // 备注
+ private String payModel; //支付方式
+ private String voucher; //支付凭证
+ private Integer adminId; //提交人Id
+ private String adminName; //提交人姓名
+ private String auditStatus; //审核状态
+ private Integer auditId; //审核人Id
+ private String auditName; //审核人姓名
+ private Byte type; //类型
+ private String rejectReason; //驳回理由
+
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private String payTime; //支付时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date createTime; // 创建时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date startTime; // 开始时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date endTime; // 结束时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date auditTime; // 审核时间
+}
diff --git a/src/main/java/com/example/demo/domain/vo/RechargeUser.java b/src/main/java/com/example/demo/domain/vo/RechargeUser.java
new file mode 100644
index 0000000..1ae120c
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/vo/RechargeUser.java
@@ -0,0 +1,51 @@
+package com.example.demo.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @program: gold-java
+ * @ClassName Recharge
+ * @description:
+ * @author: Double
+ * @create: 2025−06-29 13:18
+ * @Version 1.0
+ **/
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class RechargeUser {
+
+ private static final long serialVersionUID = 1L;
+
+ private String name; // 客户姓名
+ private Integer jwcode; // 精网号
+ private String market; // 所属地区
+ private String activity; // 活动名称
+ private Integer rateId; // 汇率ID
+ private String rateName; // 汇率名称
+ private Integer money; // 金额[分]
+ private Integer permanentGold; // 永久金币
+ private Integer freeGold; // 免费金币
+ private String payModel; // 支付方式
+ private String payPlatform; // 支付平台
+ private String voucher; // 支付凭证
+ private String remark; // 备注
+ private Integer adminId; //提交人Id
+ private String adminName; //提交人姓名
+
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date payTime; // 创建时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date startTime; // 开始时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date endTime; // 结束时间
+
+ private String sortField; //排序字段
+ private String sortOrder; //排序顺序
+}
diff --git a/src/main/java/com/example/demo/domain/vo/RefundAudit.java b/src/main/java/com/example/demo/domain/vo/RefundAudit.java
new file mode 100644
index 0000000..3c18eb6
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/vo/RefundAudit.java
@@ -0,0 +1,54 @@
+package com.example.demo.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @program: gold-java
+ * @ClassName RechargeAudit
+ * @description: 退款审核
+ * @author: Ethan
+ * @create: 2025−06-30 13:29
+ * @Version 1.0
+ **/
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class RefundAudit {
+ private static final long serialVersionUID = 1L;
+ private String name; // 客户姓名
+ private Integer jwcode; // 精网号
+ private String orderCode; // 订单号
+ private String market; // 所属地区
+ private Integer refundModel; // 退款方式-全额 部分
+ private String goodsName; // 商品名称
+ private Integer sumGold; // 退款金额
+ private Integer permanentGold; // 永久金币
+ private Integer freeGold; // 免费金币
+ private Integer freeJune; // 6月免费金币
+ private Integer freeDecember; // 12月免费金币
+ private Integer taskGold; // 任务金币
+ private String remark; // 备注
+ private Integer adminId; //提交人Id
+ private String adminName; //提交人姓名
+ private String auditStatus; //审核状态
+ private Integer auditId; //审核人Id
+ private String auditName; //审核人姓名
+ private String rejectReason; //驳回理由
+ private Byte type; //类型
+
+
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date createTime; // 创建时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date startTime; // 开始时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date endTime; // 结束时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
+ private Date auditTime; // 审核时间
+}
diff --git a/src/main/java/com/example/demo/domain/vo/RefundUser.java b/src/main/java/com/example/demo/domain/vo/RefundUser.java
index 0d4d3d4..e0e42f6 100644
--- a/src/main/java/com/example/demo/domain/vo/RefundUser.java
+++ b/src/main/java/com/example/demo/domain/vo/RefundUser.java
@@ -23,6 +23,7 @@ public class RefundUser {
private static final long serialVersionUID = 1L;
+ private String orderCode; // 订单号
private String name; // 客户姓名
private Integer jwcode; // 精网号
private String market; // 所属地区
@@ -43,4 +44,7 @@ public class RefundUser {
private Date startTime; // 开始时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date endTime; // 结束时间
+
+ private String sortField; //排序字段
+ private String sortOrder; //排序顺序
}
diff --git a/src/main/java/com/example/demo/domain/vo/WorkbenchMarketCard.java b/src/main/java/com/example/demo/domain/vo/WorkbenchMarketCard.java
index 747c0bc..36db07f 100644
--- a/src/main/java/com/example/demo/domain/vo/WorkbenchMarketCard.java
+++ b/src/main/java/com/example/demo/domain/vo/WorkbenchMarketCard.java
@@ -45,7 +45,7 @@ public class WorkbenchMarketCard implements Serializable {
private Integer refundFreeJune; // 当日新增退款(六月免费)
private Integer refundFreeDecember; // 当日新增退款(十二月免费)
private Integer refundTask; // 当日新增退款(任务)
- private Integer dailyConsume; // 当日总消耗 = consumePermanent + consumeFreeJune + consumeFreeDecember + consumeTask - (refundPermanent + refundFreeJune + refundFreeDecember + refundTask)
+ private Integer dailyReduce; // 当日总消耗 = consumePermanent + consumeFreeJune + consumeFreeDecember + consumeTask - (refundPermanent + refundFreeJune + refundFreeDecember + refundTask)
private Integer yearlyConsume; // 全年累计消费
private Integer yearlyRefund; // 全年累计退款金币数
private Integer yearlyReduce; // 全年累计消耗金币数 = yearlyConsume - yearlyRefund
diff --git a/src/main/java/com/example/demo/exception/SystemException.java b/src/main/java/com/example/demo/exception/SystemException.java
new file mode 100644
index 0000000..5a049f1
--- /dev/null
+++ b/src/main/java/com/example/demo/exception/SystemException.java
@@ -0,0 +1,13 @@
+package com.example.demo.exception;
+
+public class SystemException extends RuntimeException {
+ public SystemException(String message) {
+ super(message);
+ }
+
+
+ public SystemException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/src/main/java/com/example/demo/mapper/AiEmotionMapper.java b/src/main/java/com/example/demo/mapper/AiEmotionMapper.java
new file mode 100644
index 0000000..52cd24b
--- /dev/null
+++ b/src/main/java/com/example/demo/mapper/AiEmotionMapper.java
@@ -0,0 +1,25 @@
+package com.example.demo.mapper;
+
+import com.example.demo.domain.vo.AiEmotionExportRecordVO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * @program: GOLD
+ * @ClassName AiEmotionMapper
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−06-29 16:48
+ * @Version 1.0
+ **/
+@Mapper
+public interface AiEmotionMapper {
+ void updateStatus(
+ @Param("recordId") Long recordId,
+ @Param("state") Integer state,
+ @Param("url") String url,
+ @Param("reason") String reason,
+ @Param("dataNum") Integer dataNum
+ );
+ AiEmotionExportRecordVO getRecordById(Long recordId);
+}
diff --git a/src/main/java/com/example/demo/mapper/AuditMapper.java b/src/main/java/com/example/demo/mapper/AuditMapper.java
index 63dc767..23041e2 100644
--- a/src/main/java/com/example/demo/mapper/AuditMapper.java
+++ b/src/main/java/com/example/demo/mapper/AuditMapper.java
@@ -1,6 +1,14 @@
package com.example.demo.mapper;
+import com.example.demo.domain.entity.User;
+import com.example.demo.domain.entity.UserGoldRecord;
+import com.example.demo.domain.vo.RechargeAudit;
+import com.example.demo.domain.vo.RefundAudit;
+import com.github.pagehelper.PageInfo;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
/**
* @program: gold-java
@@ -13,6 +21,21 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AuditMapper {
-
+ //根据订单号查订单
+ UserGoldRecord selectOrderByOrderCode(String orderCode);
+ //修改订单审核人与审核状态
+ int updateOrder (UserGoldRecord userGoldRecord);
+ //修改用户余额
+ int updateUserGold(User user);
+ //修改消费订单为以退款
+ int updateOrderRefund(String orderCode ,Byte isRefund);
+ //多条件查询充值审核订单
+ List selectRechargeBy(@Param("pageNum") Integer pageNum,
+ @Param("pageSize") Integer pageSize,
+ @Param("rechargeAudit") RechargeAudit rechargeAudit);
+ //多条件查询消费审核订单
+ List selectRefundBy(@Param("pageNum") Integer pageNum,
+ @Param("pageSize") Integer pageSize,
+ @Param("refundAudit") RefundAudit refundAudit);
}
diff --git a/src/main/java/com/example/demo/mapper/ConsumeMapper.java b/src/main/java/com/example/demo/mapper/ConsumeMapper.java
index 31d0355..fd6bf53 100644
--- a/src/main/java/com/example/demo/mapper/ConsumeMapper.java
+++ b/src/main/java/com/example/demo/mapper/ConsumeMapper.java
@@ -18,9 +18,11 @@ import java.util.List;
@Mapper
public interface ConsumeMapper {
- List selectAll();
+ List selectAll(ConsumeUser consumeUser);
List selectBy(ConsumeUser consumeUser);
void add(UserGoldRecord userGoldRecord);
+
+ void updateIsRefund(String orderCode);
}
diff --git a/src/main/java/com/example/demo/mapper/ExportMapper.java b/src/main/java/com/example/demo/mapper/ExportMapper.java
new file mode 100644
index 0000000..4bb7cd6
--- /dev/null
+++ b/src/main/java/com/example/demo/mapper/ExportMapper.java
@@ -0,0 +1,23 @@
+package com.example.demo.mapper;
+
+import com.example.demo.domain.entity.Export;
+import com.example.demo.domain.vo.ExportVo;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * @program: GOLD
+ * @ClassName ExportMapper
+ * @description:
+ * @author: huangqizhen
+ * @create: 2025−06-29 17:28
+ * @Version 1.0
+ **/
+@Mapper
+public interface ExportMapper {
+ ExportVo getExportData(Integer id);
+ int updateExportData(Long recordId, Integer state, String url, String reason, Integer dataNum);
+ List getExportRecord(Integer account);
+
+}
diff --git a/src/main/java/com/example/demo/mapper/GeneralMapper.java b/src/main/java/com/example/demo/mapper/GeneralMapper.java
index 8913458..de73b8a 100644
--- a/src/main/java/com/example/demo/mapper/GeneralMapper.java
+++ b/src/main/java/com/example/demo/mapper/GeneralMapper.java
@@ -17,4 +17,5 @@ public interface GeneralMapper {
List getMarket();
List getPlatform();
List getGoods();
+ List getActivity();
}
diff --git a/src/main/java/com/example/demo/mapper/GoldDetailMapper.java b/src/main/java/com/example/demo/mapper/GoldDetailMapper.java
index a6343f2..7494332 100644
--- a/src/main/java/com/example/demo/mapper/GoldDetailMapper.java
+++ b/src/main/java/com/example/demo/mapper/GoldDetailMapper.java
@@ -3,7 +3,9 @@ package com.example.demo.mapper;
import com.example.demo.domain.entity.User;
import com.example.demo.domain.vo.GoldDetail;
import com.example.demo.domain.vo.Total;
+import lombok.Data;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -19,7 +21,19 @@ import java.util.List;
public interface GoldDetailMapper {
List getGoldDetail(GoldDetail goldDetail);
Total getTotal(GoldDetail goldDetail);
-
List getGold(User user);
Total GoldTotal(User user);
+ @Data
+ public static class ExportRecordIdHolder{
+ private Long id;
+ }
+ void insertExportRecord(
+ @Param("recordId") ExportRecordIdHolder recordId, // 用于接收主键
+ @Param("account") Integer account,
+ @Param("type") Integer type,
+ @Param("state") Integer state,
+ @Param("url") String url,
+ @Param("fileName") String fileName,
+ @Param("dataNum") Integer dataNum
+ );
}
diff --git a/src/main/java/com/example/demo/mapper/RateMapper.java b/src/main/java/com/example/demo/mapper/RateMapper.java
new file mode 100644
index 0000000..05602f3
--- /dev/null
+++ b/src/main/java/com/example/demo/mapper/RateMapper.java
@@ -0,0 +1,18 @@
+package com.example.demo.mapper;
+
+import com.example.demo.domain.entity.Rate;
+import com.example.demo.domain.vo.RateDetail;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+@Mapper
+public interface RateMapper {
+
+ List selectAll();
+
+ Rate selectById(Integer id);
+
+ void update(Rate rate);
+
+ void add(Rate rate);
+}
diff --git a/src/main/java/com/example/demo/mapper/RechargeMapper.java b/src/main/java/com/example/demo/mapper/RechargeMapper.java
new file mode 100644
index 0000000..e600ced
--- /dev/null
+++ b/src/main/java/com/example/demo/mapper/RechargeMapper.java
@@ -0,0 +1,27 @@
+package com.example.demo.mapper;
+
+
+import com.example.demo.domain.entity.UserGoldRecord;
+import com.example.demo.domain.vo.RechargeUser;
+import com.example.demo.domain.vo.RefundUser;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * @program: gold-java
+ * @ClassName RechargeMapper
+ * @description:
+ * @author: Double
+ * @create: 2025−06-29 13:41
+ * @Version 1.0
+ **/
+
+@Mapper
+public interface RechargeMapper {
+ List selectAll(RechargeUser rechargeUser);
+
+ List selectBy(RechargeUser rechargeUser);
+
+ void add(UserGoldRecord userGoldRecord);
+}
diff --git a/src/main/java/com/example/demo/mapper/RefundMapper.java b/src/main/java/com/example/demo/mapper/RefundMapper.java
index 3067263..3f8f14c 100644
--- a/src/main/java/com/example/demo/mapper/RefundMapper.java
+++ b/src/main/java/com/example/demo/mapper/RefundMapper.java
@@ -19,9 +19,14 @@ import java.util.List;
@Mapper
public interface RefundMapper {
- List selectAll();
+ List selectAll(RefundUser refundUser);
List selectBy(RefundUser refundUser);
void add(UserGoldRecord userGoldRecord);
+
+ List getRefundType();
+
+ List selectGoods(Integer jwcode);
+
}
diff --git a/src/main/java/com/example/demo/security/SecurityConfig.java b/src/main/java/com/example/demo/security/SecurityConfig.java
index 4843f2a..42fa25d 100644
--- a/src/main/java/com/example/demo/security/SecurityConfig.java
+++ b/src/main/java/com/example/demo/security/SecurityConfig.java
@@ -36,8 +36,8 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
public class SecurityConfig {
- @Autowired
- TokenFilter tokenFilter;
+// @Autowired
+// TokenFilter tokenFilter;
// 核心配置 配置一个过滤器链
@@ -60,7 +60,7 @@ public class SecurityConfig {
request
.requestMatchers( HttpMethod.POST,
// 用户不登录就可以访问的路径
- "/admin/login","/upload/**","/detailY/ERP","/home/java/haiwaiyanfa/gold1/**","/home/java/haiwaiyanfa/**","/**").permitAll()
+ "/admin/login","/upload/**","/detailY/ERP","/home/java/haiwaiyanfa/gold1/**","/home/java/haiwaiyanfa/**").permitAll()
.requestMatchers(
"/error","alipay/**","/upload/**","/home/java/haiwaiyanfa/gold1/**","/home/java/haiwaiyanfa/**"
).permitAll()
@@ -70,7 +70,7 @@ public class SecurityConfig {
- http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class); // 然后是TokenFilter
+// http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class); // 然后是TokenFilter
return http.build();
}
diff --git a/src/main/java/com/example/demo/security/TokenFilter.java b/src/main/java/com/example/demo/security/TokenFilter.java
index 7652567..35f929c 100644
--- a/src/main/java/com/example/demo/security/TokenFilter.java
+++ b/src/main/java/com/example/demo/security/TokenFilter.java
@@ -1,205 +1,8 @@
-//package com.example.demo.security;
-//
-//
-//import com.example.demo.Util.JWTUtil;
-//import com.example.demo.Util.RequestWrapper;
-//import com.example.demo.domain.entity.Admin;
-//import jakarta.servlet.FilterChain;
-//import jakarta.servlet.ServletException;
-//import jakarta.servlet.http.HttpServletRequest;
-//import jakarta.servlet.http.HttpServletResponse;
-//import org.springframework.core.annotation.Order;
-//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-//import org.springframework.security.core.context.SecurityContextHolder;
-//import org.springframework.security.core.userdetails.UserDetails;
-//import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-//import org.springframework.stereotype.Component;
-//import org.springframework.util.ObjectUtils;
-//import org.springframework.util.StringUtils;
-//import org.springframework.web.filter.OncePerRequestFilter;
-//import java.io.IOException;
-//
-//
-//@Component
-//public class TokenFilter extends OncePerRequestFilter {
-// @Override
-// protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
-// // 取Token 生成登录信息
-// String token = request.getHeader("token");
-//
-//
-// System.out.println(token+"123132132");
-//
-// // token不为空
-// if (StringUtils.hasText(token)){
-// try {
-// UserDetails userDetails = JWTUtil.getUserDetailsList(token, Admin.class);
-// if ( ! ObjectUtils.isEmpty(userDetails)) {
-// // 将这个用户注册到Security中
-// UsernamePasswordAuthenticationToken authenticationToken
-// = new UsernamePasswordAuthenticationToken(
-// userDetails, null,
-// userDetails.getAuthorities());
-// authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-// SecurityContextHolder.getContext().setAuthentication(authenticationToken);
-// }
-// } catch (Exception e) {
-// e.printStackTrace();
-// // Token无效,
-// }
-// }
-// // 过滤器放行
-// filterChain.doFilter(request, response);
-// }
-//}
-//package com.example.demo.security;
-//
-//import com.example.demo.Util.JWTUtil;
-//import com.example.demo.Util.RequestWrapper;
-//import com.example.demo.Util.TokenPayload;
-//import com.example.demo.domain.entity.Admin;
-//import com.fasterxml.jackson.databind.ObjectMapper;
-//import jakarta.servlet.FilterChain;
-//import jakarta.servlet.ServletException;
-//import jakarta.servlet.http.HttpServletRequest;
-//import jakarta.servlet.http.HttpServletResponse;
-//import org.springframework.core.annotation.Order;
-//import org.springframework.security.access.prepost.PreFilter;
-//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-//import org.springframework.security.core.context.SecurityContextHolder;
-//import org.springframework.security.core.userdetails.UserDetails;
-//import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-//import org.springframework.stereotype.Component;
-//import org.springframework.util.ObjectUtils;
-//import org.springframework.util.StringUtils;
-//import org.springframework.web.filter.OncePerRequestFilter;
-//import java.io.IOException;
-//import java.io.InputStream;
-//
-//
-//@Component
-//public class TokenFilter extends OncePerRequestFilter {
-//
-// @Override
-// protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-// throws ServletException, IOException {
-// // 使用RequestWrapper包装原始的HttpServletRequest,使其输入流可以被重复读取
-// RequestWrapper requestWrapper = new RequestWrapper(request);
-// // 确保请求体只被读取一次
-// boolean hasRequestBody = "POST".equals(requestWrapper.getMethod());
-// System.out.println("/*-/*-/*"+requestWrapper.getBodyString());
-// if (hasRequestBody) {
-// // 获取输入流
-// InputStream inputStream = requestWrapper.getInputStream();
-// // 使用Jackson ObjectMapper解析JSON
-// ObjectMapper objectMapper = new ObjectMapper();
-// TokenPayload tokenPayload = objectMapper.readValue(inputStream, TokenPayload.class);
-//
-// // 检查tokenPayload中是否存在token属性,并且这个属性不为空
-// String token = tokenPayload.getToken();
-// if (StringUtils.hasText(token)) {
-// try {
-// UserDetails userDetails = JWTUtil.getUserDetailsList(token, Admin.class);
-// if (!ObjectUtils.isEmpty(userDetails)) {
-// // 将这个用户注册到Security中
-// UsernamePasswordAuthenticationToken authenticationToken
-// = new UsernamePasswordAuthenticationToken(
-// userDetails, null,
-// userDetails.getAuthorities());
-// authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(requestWrapper));
-// SecurityContextHolder.getContext().setAuthentication(authenticationToken);
-// }
-// } catch (Exception e) {
-// e.printStackTrace();
-// // Token无效,可以在这里添加相应的处理逻辑,例如返回401状态码等
-// }
-// }
-// }
-// filterChain.doFilter(requestWrapper, response); // 注意这里使用requestWrapper
-// }
-//}
-//package com.example.demo.security;
-//
-//import com.example.demo.Util.JWTUtil;
-//import com.example.demo.Util.RequestWrapper;
-//import com.example.demo.Util.TokenPayload;
-//import com.example.demo.domain.entity.Admin;
-//import com.fasterxml.jackson.databind.ObjectMapper;
-//import jakarta.servlet.FilterChain;
-//import jakarta.servlet.ServletException;
-//import jakarta.servlet.http.HttpServletRequest;
-//import jakarta.servlet.http.HttpServletResponse;
-//import org.springframework.core.annotation.Order;
-//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-//import org.springframework.security.core.context.SecurityContextHolder;
-//import org.springframework.security.core.userdetails.UserDetails;
-//import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-//import org.springframework.stereotype.Component;
-//import org.springframework.util.ObjectUtils;
-//import org.springframework.util.StringUtils;
-//import org.springframework.web.filter.OncePerRequestFilter;
-//import java.io.IOException;
-//import java.io.InputStream;
-//
-//@Component
-//public class TokenFilter extends OncePerRequestFilter {
-//
-// @Override
-// protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-// throws ServletException, IOException {
-// // 检查是否是上传请求
-// boolean isUploadRequest = request.getRequestURI().startsWith("/upload");
-// System.out.println(request.getRequestURI());
-// System.out.println(isUploadRequest);
-// if (isUploadRequest) {
-// // 如果是上传请求,直接将请求传递给下一个过滤器或目标资源
-// filterChain.doFilter(request, response);
-// return;
-// } else {
-// // 使用RequestWrapper包装原始的HttpServletRequest,使其输入流可以被重复读取
-// RequestWrapper requestWrapper = new RequestWrapper(request);
-// System.out.println(request);
-// // 确保请求体只被读取一次
-// boolean hasRequestBody = "POST".equals(requestWrapper.getMethod());
-// if (hasRequestBody) {
-// // 获取输入流
-// InputStream inputStream = requestWrapper.getInputStream();
-// // 使用Jackson ObjectMapper解析JSON
-// ObjectMapper objectMapper = new ObjectMapper();
-// TokenPayload tokenPayload = objectMapper.readValue(inputStream, TokenPayload.class);
-//
-// // 检查tokenPayload中是否存在token属性,并且这个属性不为空
-// String token = tokenPayload.getToken();
-// if (StringUtils.hasText(token)) {
-// try {
-// UserDetails userDetails = JWTUtil.getUserDetailsList(token, Admin.class);
-// if (!ObjectUtils.isEmpty(userDetails)) {
-// // 将这个用户注册到Security中
-// UsernamePasswordAuthenticationToken authenticationToken
-// = new UsernamePasswordAuthenticationToken(
-// userDetails, null,
-// userDetails.getAuthorities());
-// authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(requestWrapper));
-// SecurityContextHolder.getContext().setAuthentication(authenticationToken);
-// }
-// } catch (Exception e) {
-// e.printStackTrace();
-// // Token无效,可以在这里添加相应的处理逻辑,例如返回401状态码等
-// }
-// }
-// }
-// // 非上传请求,继续执行过滤器链
-// filterChain.doFilter(requestWrapper, response);
-// }
-// }
-//}
package com.example.demo.security;
import com.example.demo.Util.JWTUtil;
-import com.example.demo.Util.RequestWrapper;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import com.example.demo.domain.entity.Admin;
+import com.example.demo.domain.entity.User;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
@@ -214,65 +17,23 @@ import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
@Component
public class TokenFilter extends OncePerRequestFilter {
-
- private final ObjectMapper objectMapper = new ObjectMapper();
-
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
- // 检查是否是上传请求
- boolean isErpRequest = request.getRequestURI().startsWith("/ERP") || request.getRequestURI().contains("ERP");
- boolean isUploadRequest = request.getRequestURI().startsWith("/upload");
-// System.out.println(request.getRequestURI());
-// System.out.println(isUploadRequest);
- if (isUploadRequest ) {
- // 如果是上传请求,直接将请求传递给下一个过滤器或目标资源
+ // 忽略登录接口的token处理,防止无限递归
+ if (request.getRequestURI().startsWith("/admin/login")) {
filterChain.doFilter(request, response);
return;
- } else {
- // 使用RequestWrapper包装原始的HttpServletRequest,使其输入流可以被重复读取
- RequestWrapper requestWrapper = new RequestWrapper(request);
-// System.out.println(request);
-
- // 确保请求体只被读取一次
- boolean hasRequestBody = "POST".equals(requestWrapper.getMethod());
- if (hasRequestBody) {
- // 获取输入流
- InputStream inputStream = requestWrapper.getInputStream();
-
- try {
- // 尝试将输入流转换为Map
- Map jsonMap = objectMapper.readValue(inputStream, new TypeReference