diff --git a/xinnengyuan/fonts/simhei.ttf b/xinnengyuan/fonts/simhei.ttf
new file mode 100644
index 00000000..5bd4687e
Binary files /dev/null and b/xinnengyuan/fonts/simhei.ttf differ
diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/application-prod.yml b/xinnengyuan/ruoyi-admin/src/main/resources/application-prod.yml
index 847eb1be..26006274 100644
--- a/xinnengyuan/ruoyi-admin/src/main/resources/application-prod.yml
+++ b/xinnengyuan/ruoyi-admin/src/main/resources/application-prod.yml
@@ -273,7 +273,7 @@ weather:
api-host: n35rk53njv.re.qweatherapi.com
# dxf转 geojson 执行文件名
dxf2GeoJson:
- file-name: main
+ file-name: main.exe
ys7:
app-key: 3acf9f1a43dc4209841e0893003db0a2
app-secret: 4bbf3e9394f55d3af6e3af27b2d3db36
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml
index 3208faaa..2a9fd2d1 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml
@@ -17,6 +17,16 @@
+
+
+
+
+ technology.tabula
+ tabula
+ 1.0.4
+
+
+
com.alibaba
@@ -73,18 +83,24 @@
-
com.itextpdf
- itext-asian
- 5.2.0
-
-
-
- com.itextpdf
- itextpdf
- 5.5.13.3
+ layout
+ 7.2.5
+
+
+
+
+
+
+
+
+
+
+
+
+
com.google.zxing
@@ -221,6 +237,12 @@
5.3.0
compile
+
+ org.javassist
+ javassist
+ 3.25.0-GA
+ compile
+
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bidding/controller/BusBiddingLimitListController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bidding/controller/BusBiddingLimitListController.java
index 7ac0e34f..80f55675 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bidding/controller/BusBiddingLimitListController.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/bidding/controller/BusBiddingLimitListController.java
@@ -3,7 +3,9 @@ package org.dromara.bidding.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
+import org.apache.pdfbox.pdmodel.PDDocument;
import lombok.RequiredArgsConstructor;
+import org.apache.pdfbox.pdmodel.PDDocument;
import org.dromara.bidding.domain.bo.BusBiddingLimitListBo;
import org.dromara.bidding.domain.bo.BiddingAllVersionNumbersReq;
import org.dromara.bidding.domain.vo.BusBiddingLimitListVo;
@@ -22,6 +24,8 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
+import java.io.File;
+import java.io.IOException;
import java.util.List;
/**
@@ -38,6 +42,8 @@ public class BusBiddingLimitListController extends BaseController {
private final IBusBiddingLimitListService busBiddingLimitListService;
+
+
/**
* 查询成本-投标列表
*/
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/PdfBoxQrCodeGenerator.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/PdfBoxQrCodeGenerator.java
index 6baf8f22..6d208f7c 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/PdfBoxQrCodeGenerator.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/PdfBoxQrCodeGenerator.java
@@ -6,33 +6,27 @@ import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
-import com.itextpdf.text.DocumentException;
-import com.itextpdf.text.Image;
-import com.itextpdf.text.pdf.PdfContentByte;
-import com.itextpdf.text.pdf.PdfReader;
-import com.itextpdf.text.pdf.PdfStamper;
-import org.dromara.system.domain.vo.SysOssVo;
+import com.itextpdf.io.image.ImageData;
+import com.itextpdf.io.image.ImageDataFactory;
+import com.itextpdf.kernel.geom.Rectangle;
+import com.itextpdf.kernel.pdf.*;
+import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
+import com.itextpdf.layout.Canvas;
+import com.itextpdf.layout.element.Image;
import java.awt.image.BufferedImage;
import java.io.*;
-import java.net.FileNameMap;
-import java.net.URLConnection;
-import java.util.concurrent.CompletableFuture;
+import java.net.HttpURLConnection;
+import java.net.URL;
/**
* @author lilemy
- * @date 2025/7/7 9:56
+ * @date 2025/7/7
*/
public class PdfBoxQrCodeGenerator {
/**
* 生成二维码图片并返回路径
- *
- * @param text 二维码文本
- * @param width 二维码宽度
- * @param height 二维码高度
- * @param outputPath 二维码图片保存路径
- * @return 二维码图片保存路径
*/
public static String generateQRCodeImage(String text, int width, int height, String outputPath) throws Exception {
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height);
@@ -42,11 +36,6 @@ public class PdfBoxQrCodeGenerator {
/**
* 获取二维码图片字节数组
- *
- * @param text 二维码文本
- * @param width 二维码宽度
- * @param height 二维码高度
- * @return 二维码图片字节数组
*/
public static byte[] generateQRCodeBytes(String text, int width, int height) {
BufferedImage image = QrCodeUtil.generate(text, width, height);
@@ -56,212 +45,164 @@ public class PdfBoxQrCodeGenerator {
}
/**
- * 获取二维码图片字节数组
- *
- * @param text 二维码文本
- * @return 二维码图片字节数组
+ * 获取二维码图片字节数组(默认200x200)
*/
public static byte[] generateQRCodeBytes(String text) {
return generateQRCodeBytes(text, 200, 200);
}
/**
- * 在PDF指定位置添加二维码
- *
- * @param srcPdf 原PDF文件路径
- * @param destPdf 新PDF文件路径
- * @param qrImagePath 二维码图片路径
- * @param pageNum 页码
- * @param x 坐标
- * @param y 坐标
+ * 在PDF指定位置添加二维码(基于图片路径)
*/
- public static void addQRCodeToPDF(String srcPdf, String destPdf, String qrImagePath, int pageNum, float x, float y) throws IOException, DocumentException {
- PdfReader reader = new PdfReader(srcPdf);
- PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPdf));
- PdfContentByte content = stamper.getOverContent(pageNum);
- Image image = Image.getInstance(qrImagePath);
- image.setAbsolutePosition(x, y); // 坐标:左下角为原点
- image.scaleAbsolute(100, 100); // 设置二维码大小
-
- content.addImage(image);
- stamper.close();
- reader.close();
+ public static void addQRCodeToPDF(String srcPdf, String destPdf, String qrImagePath, int pageNum, float x, float y)
+ throws IOException {
+ byte[] qrBytes = java.nio.file.Files.readAllBytes(new File(qrImagePath).toPath());
+ addQRCodeToPDF(srcPdf, destPdf, qrBytes, pageNum, x, y);
}
/**
- * 在PDF指定位置添加二维码
- *
- * @param srcPdf 原PDF文件路径
- * @param destPdf 新PDF文件路径
- * @param qrCodeBytes 二维码图片字节数组
- * @param pageNum 页码
- * @param x 坐标
- * @param y 坐标
+ * 在PDF指定位置添加二维码(基于字节数组)
*/
- public static void addQRCodeToPDF(String srcPdf, String destPdf, byte[] qrCodeBytes, int pageNum, float x, float y) throws IOException, DocumentException {
+ public static void addQRCodeToPDF(String srcPdf, String destPdf, byte[] qrCodeBytes, int pageNum, float x, float y)
+ throws IOException {
PdfReader reader = new PdfReader(srcPdf);
- PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPdf));
- PdfContentByte content = stamper.getOverContent(pageNum);
+ PdfWriter writer = new PdfWriter(destPdf);
+ PdfDocument pdfDoc = new PdfDocument(reader, writer);
- Image image = Image.getInstance(qrCodeBytes);
- image.setAbsolutePosition(x, y); // 坐标:左下角为原点
- image.scaleAbsolute(100, 100); // 设置二维码大小
+ PdfPage page = pdfDoc.getPage(pageNum);
- content.addImage(image);
- stamper.close();
- reader.close();
+ PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDoc);
+ try (Canvas canvas = new Canvas(pdfCanvas, page.getPageSize())) {
+ ImageData imageData = ImageDataFactory.create(qrCodeBytes);
+ Image image = new Image(imageData)
+ .scaleAbsolute(100, 100)
+ .setFixedPosition(x, y);
+ canvas.add(image);
+ }
+
+ pdfDoc.close();
}
/**
* 在PDF指定位置添加二维码并返回数据流
- *
- * @param srcPdf 原PDF文件路径
- * @param qrCodeBytes 二维码图片字节数组
- * @param pageNum 页码
- * @param x 坐标
- * @param y 坐标
- * @return 插入二维码后的PDF文件流
*/
-// public static ByteArrayOutputStream addQRCodeToPDF(String srcPdf, byte[] qrCodeBytes, int pageNum, float x, float y) throws IOException, DocumentException {
-//
-// PdfReader reader = new PdfReader(srcPdf);
-// ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
-// PdfStamper stamper = new PdfStamper(reader, pdfOut);
-//
-// PdfContentByte content = stamper.getOverContent(pageNum);
-// Image image = Image.getInstance(qrCodeBytes);
-// image.setAbsolutePosition(x, y); // 坐标:左下角为原点
-// image.scaleAbsolute(100, 100); // 设置二维码大小
-//
-// content.addImage(image);
-// stamper.close();
-// reader.close();
-//
-// return pdfOut;
-// }
- /**
- * 在PDF每一页的指定位置添加二维码并返回数据流(根据页面方向自动调整位置)
- *
- * @param srcPdf 原PDF文件路径(可以是本地路径或网络地址)
- * @param qrCodeBytes 二维码图片字节数组
- * @return 插入二维码后的PDF文件流
- */
- public static ByteArrayOutputStream addQRCodeToPDFOnAllPages(String srcPdf, byte[] qrCodeBytes, boolean isChangeFile)
- throws IOException, DocumentException {
-
- PdfReader reader = null;
- PdfStamper stamper = null;
+ public static ByteArrayOutputStream addQRCodeToPDF(String srcPdf, byte[] qrCodeBytes, int pageNum, float x, float y)
+ throws IOException {
+ PdfReader reader = new PdfReader(srcPdf);
ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
+ PdfWriter writer = new PdfWriter(pdfOut);
+ PdfDocument pdfDoc = new PdfDocument(reader, writer);
- try {
- // 判断是网络地址还是本地文件路径
- if (srcPdf.startsWith("http://") || srcPdf.startsWith("https://")) {
- // 网络地址:从URL读取PDF
- java.net.URL url = new java.net.URL(srcPdf);
- java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
- connection.setConnectTimeout(10000); // 连接超时10秒
- connection.setReadTimeout(30000); // 读取超时30秒
- connection.setRequestMethod("GET");
+ PdfPage page = pdfDoc.getPage(pageNum);
- int responseCode = connection.getResponseCode();
- if (responseCode != java.net.HttpURLConnection.HTTP_OK) {
- throw new IOException("无法从URL获取PDF文件,HTTP响应码: " + responseCode + ", URL: " + srcPdf);
- }
-
- java.io.InputStream inputStream = connection.getInputStream();
- reader = new PdfReader(inputStream);
- } else {
- // 本地文件路径:检查文件是否存在
- File srcFile = new File(srcPdf);
- if (!srcFile.exists()) {
- throw new IOException("源PDF文件不存在: " + srcPdf);
- }
- reader = new PdfReader(srcPdf);
- }
-
- stamper = new PdfStamper(reader, pdfOut);
-
- int numberOfPages = reader.getNumberOfPages();
-
- // 遍历每一页并添加二维码
- for (int pageNum = 1; pageNum <= numberOfPages; pageNum++) {
- // 获取页面尺寸
- com.itextpdf.text.Rectangle pageSize = reader.getPageSize(pageNum);
- float pageWidth = pageSize.getWidth();
- float pageHeight = pageSize.getHeight();
-
- // 根据页面方向确定二维码位置
- float qrX, qrY;
-
- float newWidth, newHeight;
-
- // 如果是变更文件且为第一页,使用特殊位置处理
- if (isChangeFile && pageNum == 1) {
- // 变更文件第一页使用传入的坐标参数
- qrX = (pageWidth - 143);
- qrY = pageHeight - 213;
- newWidth = 67;
- newHeight = 80;
- } else {
- // 判断页面方向:宽度大于高度为横版,否则为竖版
- if (pageWidth > pageHeight) {
- // 横版页面:二维码放在右下角
- qrX = (pageWidth - 90); // 距离右边90点
- qrY = 24; // 距离底部24点
- newWidth = 67;
- newHeight = 79;
- } else {
- // 竖版页面:二维码放在左上角
- qrX = 226; // 距离左边226点
- qrY = pageHeight - 185; // 距离顶部185点
- newWidth = 69;
- newHeight = 80;
- }
- }
-
-
- PdfContentByte content = stamper.getOverContent(pageNum);
- Image image = Image.getInstance(qrCodeBytes);
- image.setAbsolutePosition(qrX, qrY); // 坐标:左下角为原点
- image.scaleAbsolute(newWidth, newHeight); // 设置二维码大小
- content.addImage(image);
- }
-
- } finally {
- if (stamper != null) {
- try {
- stamper.close();
- } catch (Exception e) {
- // 忽略关闭异常
- }
- }
- if (reader != null) {
- try {
- reader.close();
- } catch (Exception e) {
- // 忽略关闭异常
- }
- }
+ PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDoc);
+ try (Canvas canvas = new Canvas(pdfCanvas, page.getPageSize())) {
+ ImageData imageData = ImageDataFactory.create(qrCodeBytes);
+ Image image = new Image(imageData)
+ .scaleAbsolute(100, 100)
+ .setFixedPosition(x, y);
+ canvas.add(image);
}
+ pdfDoc.close();
return pdfOut;
}
+ /**
+ * 在PDF每一页的指定位置添加二维码并返回数据流(根据页面方向自动调整位置)
+ */
+ public static ByteArrayOutputStream addQRCodeToPDFOnAllPages(String srcPdf, byte[] qrCodeBytes, boolean isChangeFile)
+ throws IOException {
+
+ PdfReader reader;
+ if (srcPdf.startsWith("http://") || srcPdf.startsWith("https://")) {
+ // 网络地址 PDF
+ URL url = new URL(srcPdf);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setConnectTimeout(10000);
+ connection.setReadTimeout(30000);
+ connection.setRequestMethod("GET");
+
+ int responseCode = connection.getResponseCode();
+ if (responseCode != HttpURLConnection.HTTP_OK) {
+ throw new IOException("无法获取 PDF 文件,HTTP响应码: " + responseCode);
+ }
+ InputStream inputStream = connection.getInputStream();
+ reader = new PdfReader(inputStream);
+ } else {
+ // 本地文件 PDF
+ File srcFile = new File(srcPdf);
+ if (!srcFile.exists()) {
+ throw new IOException("源PDF文件不存在: " + srcPdf);
+ }
+ reader = new PdfReader(srcPdf);
+ }
+
+ ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
+ PdfWriter writer = new PdfWriter(pdfOut);
+ PdfDocument pdfDoc = new PdfDocument(reader, writer);
+
+ int numberOfPages = pdfDoc.getNumberOfPages();
+
+ for (int pageNum = 1; pageNum <= numberOfPages; pageNum++) {
+ PdfPage page = pdfDoc.getPage(pageNum);
+ Rectangle pageSize = page.getPageSize();
+
+ float pageWidth = pageSize.getWidth();
+ float pageHeight = pageSize.getHeight();
+
+ float qrX, qrY;
+ float newWidth, newHeight;
+
+ if (isChangeFile && pageNum == 1) {
+ qrX = pageWidth - 143;
+ qrY = pageHeight - 213;
+ newWidth = 67;
+ newHeight = 80;
+ } else {
+ if (pageWidth > pageHeight) {
+ // 横版
+ qrX = pageWidth - 90;
+ qrY = 24;
+ newWidth = 67;
+ newHeight = 79;
+ } else {
+ // 竖版
+ qrX = 226;
+ qrY = pageHeight - 185;
+ newWidth = 69;
+ newHeight = 80;
+ }
+ }
+
+ PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDoc);
+ try (Canvas canvas = new Canvas(pdfCanvas, page.getPageSize())) {
+ ImageData imageData = ImageDataFactory.create(qrCodeBytes);
+ Image image = new Image(imageData)
+ .scaleAbsolute(newWidth, newHeight)
+ .setFixedPosition(qrX, qrY);
+ canvas.add(image);
+ }
+ }
+
+ pdfDoc.close();
+ return pdfOut;
+ }
public static void main(String[] args) {
String path = "C:\\Users\\YuanJie\\Desktop\\test.pdf";
String outputPath = "C:\\Users\\YuanJie\\Desktop\\test1.pdf";
- String params = "http://192.168.110.151:7788/codeDetail?id="+"1957649652924448769";
+ String params = "http://192.168.110.151:7788/codeDetail?id=" + "1957649652924448769";
byte[] bytes = PdfBoxQrCodeGenerator.generateQRCodeBytes(params);
try {
System.out.println("二维码字节大小: " + bytes.length + " 字节");
// 在每一页添加二维码
- ByteArrayOutputStream byteArrayOutputStream = PdfBoxQrCodeGenerator.addQRCodeToPDFOnAllPages(path, bytes,false);
+ ByteArrayOutputStream byteArrayOutputStream =
+ PdfBoxQrCodeGenerator.addQRCodeToPDFOnAllPages(path, bytes, false);
- // 将输出流写入到指定文件
try (FileOutputStream fileOut = new FileOutputStream(outputPath)) {
byteArrayOutputStream.writeTo(fileOut);
}
@@ -271,7 +212,296 @@ public class PdfBoxQrCodeGenerator {
} catch (Exception e) {
e.printStackTrace();
- System.out.println("图纸管理 => 审核结束,向文件添加二维码失败, 错误");
+ System.out.println("图纸管理 => 审核结束,向文件添加二维码失败");
}
}
}
+
+
+
+
+
+
+
+
+
+
+
+
+//package org.dromara.common.utils;
+//
+//import cn.hutool.core.img.ImgUtil;
+//import cn.hutool.extra.qrcode.QrCodeUtil;
+//import com.google.zxing.BarcodeFormat;
+//import com.google.zxing.MultiFormatWriter;
+//import com.google.zxing.client.j2se.MatrixToImageWriter;
+//import com.google.zxing.common.BitMatrix;
+//import com.itextpdf.text.DocumentException;
+//import com.itextpdf.text.Image;
+//import com.itextpdf.text.pdf.PdfContentByte;
+//import com.itextpdf.text.pdf.PdfReader;
+//import com.itextpdf.text.pdf.PdfStamper;
+//import org.dromara.system.domain.vo.SysOssVo;
+//
+//import java.awt.image.BufferedImage;
+//import java.io.*;
+//import java.net.FileNameMap;
+//import java.net.URLConnection;
+//import java.util.concurrent.CompletableFuture;
+//
+///**
+// * @author lilemy
+// * @date 2025/7/7 9:56
+// */
+//public class PdfBoxQrCodeGenerator {
+//
+// /**
+// * 生成二维码图片并返回路径
+// *
+// * @param text 二维码文本
+// * @param width 二维码宽度
+// * @param height 二维码高度
+// * @param outputPath 二维码图片保存路径
+// * @return 二维码图片保存路径
+// */
+// public static String generateQRCodeImage(String text, int width, int height, String outputPath) throws Exception {
+// BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height);
+// MatrixToImageWriter.writeToPath(bitMatrix, "PNG", new File(outputPath).toPath());
+// return outputPath;
+// }
+//
+// /**
+// * 获取二维码图片字节数组
+// *
+// * @param text 二维码文本
+// * @param width 二维码宽度
+// * @param height 二维码高度
+// * @return 二维码图片字节数组
+// */
+// public static byte[] generateQRCodeBytes(String text, int width, int height) {
+// BufferedImage image = QrCodeUtil.generate(text, width, height);
+// ByteArrayOutputStream out = new ByteArrayOutputStream();
+// ImgUtil.write(image, ImgUtil.IMAGE_TYPE_PNG, out);
+// return out.toByteArray();
+// }
+//
+// /**
+// * 获取二维码图片字节数组
+// *
+// * @param text 二维码文本
+// * @return 二维码图片字节数组
+// */
+// public static byte[] generateQRCodeBytes(String text) {
+// return generateQRCodeBytes(text, 200, 200);
+// }
+//
+// /**
+// * 在PDF指定位置添加二维码
+// *
+// * @param srcPdf 原PDF文件路径
+// * @param destPdf 新PDF文件路径
+// * @param qrImagePath 二维码图片路径
+// * @param pageNum 页码
+// * @param x 坐标
+// * @param y 坐标
+// */
+// public static void addQRCodeToPDF(String srcPdf, String destPdf, String qrImagePath, int pageNum, float x, float y) throws IOException, DocumentException {
+// PdfReader reader = new PdfReader(srcPdf);
+// PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPdf));
+// PdfContentByte content = stamper.getOverContent(pageNum);
+// Image image = Image.getInstance(qrImagePath);
+// image.setAbsolutePosition(x, y); // 坐标:左下角为原点
+// image.scaleAbsolute(100, 100); // 设置二维码大小
+//
+// content.addImage(image);
+// stamper.close();
+// reader.close();
+// }
+//
+// /**
+// * 在PDF指定位置添加二维码
+// *
+// * @param srcPdf 原PDF文件路径
+// * @param destPdf 新PDF文件路径
+// * @param qrCodeBytes 二维码图片字节数组
+// * @param pageNum 页码
+// * @param x 坐标
+// * @param y 坐标
+// */
+// public static void addQRCodeToPDF(String srcPdf, String destPdf, byte[] qrCodeBytes, int pageNum, float x, float y) throws IOException, DocumentException {
+// PdfReader reader = new PdfReader(srcPdf);
+// PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPdf));
+// PdfContentByte content = stamper.getOverContent(pageNum);
+//
+// Image image = Image.getInstance(qrCodeBytes);
+// image.setAbsolutePosition(x, y); // 坐标:左下角为原点
+// image.scaleAbsolute(100, 100); // 设置二维码大小
+//
+// content.addImage(image);
+// stamper.close();
+// reader.close();
+// }
+//
+// /**
+// * 在PDF指定位置添加二维码并返回数据流
+// *
+// * @param srcPdf 原PDF文件路径
+// * @param qrCodeBytes 二维码图片字节数组
+// * @param pageNum 页码
+// * @param x 坐标
+// * @param y 坐标
+// * @return 插入二维码后的PDF文件流
+// */
+//// public static ByteArrayOutputStream addQRCodeToPDF(String srcPdf, byte[] qrCodeBytes, int pageNum, float x, float y) throws IOException, DocumentException {
+////
+//// PdfReader reader = new PdfReader(srcPdf);
+//// ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
+//// PdfStamper stamper = new PdfStamper(reader, pdfOut);
+////
+//// PdfContentByte content = stamper.getOverContent(pageNum);
+//// Image image = Image.getInstance(qrCodeBytes);
+//// image.setAbsolutePosition(x, y); // 坐标:左下角为原点
+//// image.scaleAbsolute(100, 100); // 设置二维码大小
+////
+//// content.addImage(image);
+//// stamper.close();
+//// reader.close();
+////
+//// return pdfOut;
+//// }
+// /**
+// * 在PDF每一页的指定位置添加二维码并返回数据流(根据页面方向自动调整位置)
+// *
+// * @param srcPdf 原PDF文件路径(可以是本地路径或网络地址)
+// * @param qrCodeBytes 二维码图片字节数组
+// * @return 插入二维码后的PDF文件流
+// */
+// public static ByteArrayOutputStream addQRCodeToPDFOnAllPages(String srcPdf, byte[] qrCodeBytes, boolean isChangeFile)
+// throws IOException, DocumentException {
+//
+// PdfReader reader = null;
+// PdfStamper stamper = null;
+// ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
+//
+// try {
+// // 判断是网络地址还是本地文件路径
+// if (srcPdf.startsWith("http://") || srcPdf.startsWith("https://")) {
+// // 网络地址:从URL读取PDF
+// java.net.URL url = new java.net.URL(srcPdf);
+// java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
+// connection.setConnectTimeout(10000); // 连接超时10秒
+// connection.setReadTimeout(30000); // 读取超时30秒
+// connection.setRequestMethod("GET");
+//
+// int responseCode = connection.getResponseCode();
+// if (responseCode != java.net.HttpURLConnection.HTTP_OK) {
+// throw new IOException("无法从URL获取PDF文件,HTTP响应码: " + responseCode + ", URL: " + srcPdf);
+// }
+//
+// java.io.InputStream inputStream = connection.getInputStream();
+// reader = new PdfReader(inputStream);
+// } else {
+// // 本地文件路径:检查文件是否存在
+// File srcFile = new File(srcPdf);
+// if (!srcFile.exists()) {
+// throw new IOException("源PDF文件不存在: " + srcPdf);
+// }
+// reader = new PdfReader(srcPdf);
+// }
+//
+// stamper = new PdfStamper(reader, pdfOut);
+//
+// int numberOfPages = reader.getNumberOfPages();
+//
+// // 遍历每一页并添加二维码
+// for (int pageNum = 1; pageNum <= numberOfPages; pageNum++) {
+// // 获取页面尺寸
+// com.itextpdf.text.Rectangle pageSize = reader.getPageSize(pageNum);
+// float pageWidth = pageSize.getWidth();
+// float pageHeight = pageSize.getHeight();
+//
+// // 根据页面方向确定二维码位置
+// float qrX, qrY;
+//
+// float newWidth, newHeight;
+//
+// // 如果是变更文件且为第一页,使用特殊位置处理
+// if (isChangeFile && pageNum == 1) {
+// // 变更文件第一页使用传入的坐标参数
+// qrX = (pageWidth - 143);
+// qrY = pageHeight - 213;
+// newWidth = 67;
+// newHeight = 80;
+// } else {
+// // 判断页面方向:宽度大于高度为横版,否则为竖版
+// if (pageWidth > pageHeight) {
+// // 横版页面:二维码放在右下角
+// qrX = (pageWidth - 90); // 距离右边90点
+// qrY = 24; // 距离底部24点
+// newWidth = 67;
+// newHeight = 79;
+// } else {
+// // 竖版页面:二维码放在左上角
+// qrX = 226; // 距离左边226点
+// qrY = pageHeight - 185; // 距离顶部185点
+// newWidth = 69;
+// newHeight = 80;
+// }
+// }
+//
+//
+// PdfContentByte content = stamper.getOverContent(pageNum);
+// Image image = Image.getInstance(qrCodeBytes);
+// image.setAbsolutePosition(qrX, qrY); // 坐标:左下角为原点
+// image.scaleAbsolute(newWidth, newHeight); // 设置二维码大小
+// content.addImage(image);
+// }
+//
+// } finally {
+// if (stamper != null) {
+// try {
+// stamper.close();
+// } catch (Exception e) {
+// // 忽略关闭异常
+// }
+// }
+// if (reader != null) {
+// try {
+// reader.close();
+// } catch (Exception e) {
+// // 忽略关闭异常
+// }
+// }
+// }
+//
+// return pdfOut;
+// }
+//
+//
+// public static void main(String[] args) {
+// String path = "C:\\Users\\YuanJie\\Desktop\\test.pdf";
+// String outputPath = "C:\\Users\\YuanJie\\Desktop\\test1.pdf";
+//
+// String params = "http://192.168.110.151:7788/codeDetail?id="+"1957649652924448769";
+// byte[] bytes = PdfBoxQrCodeGenerator.generateQRCodeBytes(params);
+//
+// try {
+// System.out.println("二维码字节大小: " + bytes.length + " 字节");
+//
+// // 在每一页添加二维码
+// ByteArrayOutputStream byteArrayOutputStream = PdfBoxQrCodeGenerator.addQRCodeToPDFOnAllPages(path, bytes,false);
+//
+// // 将输出流写入到指定文件
+// try (FileOutputStream fileOut = new FileOutputStream(outputPath)) {
+// byteArrayOutputStream.writeTo(fileOut);
+// }
+//
+// System.out.println("PDF文件已成功生成到: " + outputPath);
+// System.out.println("生成的PDF大小: " + new File(outputPath).length() + " 字节");
+//
+// } catch (Exception e) {
+// e.printStackTrace();
+// System.out.println("图纸管理 => 审核结束,向文件添加二维码失败, 错误");
+// }
+// }
+//}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/controller/DesVolumeCatalogController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/controller/DesVolumeCatalogController.java
index dd856efe..ecc45bd1 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/controller/DesVolumeCatalogController.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/controller/DesVolumeCatalogController.java
@@ -286,25 +286,49 @@ public class DesVolumeCatalogController extends BaseController {
}
private static LocalDate getLocalDateValue(Cell cell) {
- if (cell != null) {
- CellType cellType = cell.getCellType();
- if (cellType == CellType.FORMULA) {
- cellType = cell.getCachedFormulaResultType();
- }
+ if (cell == null) {
+ return null;
+ }
- if (DateUtil.isCellDateFormatted(cell)) {
- Date date = cell.getDateCellValue();
- return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+ CellType cellType = cell.getCellType();
+ if (cellType == CellType.FORMULA) {
+ cellType = cell.getCachedFormulaResultType();
+ }
+
+ try {
+ if (cellType == CellType.NUMERIC) {
+ if (DateUtil.isCellDateFormatted(cell)) {
+ Date date = cell.getDateCellValue();
+ return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+ } else {
+ // 如果是数字但不是日期,就尝试转为 LocalDate (例如 20250730)
+ double numericValue = cell.getNumericCellValue();
+ String text = String.valueOf((long) numericValue);
+ return LocalDate.parse(text);
+ }
} else if (cellType == CellType.STRING) {
- // 处理字符串格式的日期
- try {
- return LocalDate.parse(cell.getStringCellValue());
- } catch (Exception e) {
- // 日期格式不正确时返回null
+ String text = cell.getStringCellValue().trim();
+ if (text.isEmpty()) {
return null;
}
+ // 尝试解析不同格式
+ try {
+ return LocalDate.parse(text); // 默认 ISO 格式 yyyy-MM-dd
+ } catch (Exception e) {
+ // 如果 Excel 是 yyyy/MM/dd 或 yyyy.MM.dd,可以额外处理
+ try {
+ return LocalDate.parse(text, java.time.format.DateTimeFormatter.ofPattern("yyyy/MM/dd"));
+ } catch (Exception ignored) {}
+ try {
+ return LocalDate.parse(text, java.time.format.DateTimeFormatter.ofPattern("yyyy.MM.dd"));
+ } catch (Exception ignored) {}
+ return null; // 不识别的格式就返回 null
+ }
}
+ } catch (Exception e) {
+ return null;
}
return null;
}
+
}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesDrawingServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesDrawingServiceImpl.java
index ccb4437e..36bb2af6 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesDrawingServiceImpl.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesDrawingServiceImpl.java
@@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.itextpdf.text.DocumentException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.HttpStatus;
@@ -426,7 +425,7 @@ public class DesDrawingServiceImpl extends ServiceImpl 审核结束,向文件添加二维码失败", e);
return CompletableFuture.completedFuture(false);
}
@@ -452,7 +451,7 @@ public class DesDrawingServiceImpl extends ServiceImpl 审核结束,向文件添加二维码失败", e);
return CompletableFuture.completedFuture(false);
}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/formalities/service/impl/BusListOfFormalitiesServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/formalities/service/impl/BusListOfFormalitiesServiceImpl.java
index 6282e7a0..fb636269 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/formalities/service/impl/BusListOfFormalitiesServiceImpl.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/formalities/service/impl/BusListOfFormalitiesServiceImpl.java
@@ -110,7 +110,7 @@ public class BusListOfFormalitiesServiceImpl extends ServiceImpl buildQueryWrapper(BusListOfFormalitiesBo bo) {
Map params = bo.getParams();
LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
- lqw.orderByDesc(BusListOfFormalities::getId);
+ lqw.orderByAsc(BusListOfFormalities::getCreateTime);
lqw.eq(bo.getPid() != null, BusListOfFormalities::getPid, bo.getPid());
lqw.like(StringUtils.isNotBlank(bo.getName()), BusListOfFormalities::getName, bo.getName());
return lqw;
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/land/service/impl/BusEnterRoadServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/land/service/impl/BusEnterRoadServiceImpl.java
index f483f919..5c3c39a3 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/land/service/impl/BusEnterRoadServiceImpl.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/land/service/impl/BusEnterRoadServiceImpl.java
@@ -45,11 +45,13 @@ public class BusEnterRoadServiceImpl extends ServiceImpl records = result.getRecords();
List ids = records.stream().map(BusEnterRoadVo::getLandBlockId).toList();
- if(CollectionUtil.isNotEmpty(ids)){
- List list = iBusLandBlockService.queryListByIds(ids,true);
+ if (CollectionUtil.isNotEmpty(ids)) {
+ List list = iBusLandBlockService.queryListByIds(ids, true);
records.forEach(vo -> {
BusLandBlockVo landBlock = list.stream().filter(item -> item.getId().equals(vo.getLandBlockId())).findFirst().orElse(null);
- if(landBlock != null){
+ if (landBlock != null) {
vo.setLandName(landBlock.getLandName());
vo.setUnit(landBlock.getUnit());
}
@@ -141,7 +143,7 @@ public class BusEnterRoadServiceImpl extends ServiceImpl ids, Boolean isValid) {
- if(isValid){
+ if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueServiceImpl.java
index 9149d06a..4928c2c1 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueServiceImpl.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/materials/service/impl/MatMaterialIssueServiceImpl.java
@@ -448,6 +448,7 @@ public class MatMaterialIssueServiceImpl extends ServiceImpl list;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/req/WgzQuestionReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/req/WgzQuestionReq.java
new file mode 100644
index 00000000..228e2be6
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/req/WgzQuestionReq.java
@@ -0,0 +1,49 @@
+package org.dromara.safety.bo.req;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 题库新增对象
+ */
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class WgzQuestionReq implements Serializable {
+
+
+ /**
+ * 题目类别(外键关联到类别表)
+ */
+ private Long categoryId;
+
+
+ /**
+ * 题目类型(1单选、2多选、3判断)
+ */
+ private String questionType;
+
+
+ /**
+ * 题目内容
+ */
+ private String questionText;
+
+
+
+ /**
+ * 选项(对单选、多选、判断这种固定答案有效,以JSON数组形式存储)
+ */
+ private String options;
+
+
+ /**
+ * 正确答案
+ */
+ private String correctAnswer;
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/res/WgzAppSubmitATestPaperRes.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/res/WgzAppSubmitATestPaperRes.java
new file mode 100644
index 00000000..320a00a7
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/res/WgzAppSubmitATestPaperRes.java
@@ -0,0 +1,52 @@
+package org.dromara.safety.bo.res;
+
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 务工者APP-提交考试信息返回对象
+ */
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class WgzAppSubmitATestPaperRes implements Serializable {
+ /**
+ * 总考试时间(分钟)
+ */
+ private Integer answerTime;
+
+ /**
+ * 用时时间(时间戳/秒)
+ */
+ private Long takeTime;
+
+ /**
+ * 满分
+ */
+ private Double fullMark;
+
+ /**
+ * 及格分
+ */
+ private Double passingScore;
+
+ /**
+ * 当前分
+ */
+ private Double score;
+
+ /**
+ * 答对题数
+ */
+ private Integer number;
+
+ /**
+ * 试卷
+ */
+ private String pdfStr;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/res/WgzAppUserScoreQuery.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/res/WgzAppUserScoreQuery.java
new file mode 100644
index 00000000..df87c7a0
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/res/WgzAppUserScoreQuery.java
@@ -0,0 +1,42 @@
+package org.dromara.safety.bo.res;
+
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 岗前培训·分数查询返回对象
+ */
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class WgzAppUserScoreQuery implements Serializable {
+ /**
+ * 是否及格(1、及格 2、不及格 3、暂无记录)
+ */
+ private String isPass;
+
+ /**
+ * 试卷满分
+ */
+ private float fullMark;
+
+ /**
+ * 及格线
+ */
+ private float passingScore;
+
+ /**
+ * 当前分
+ */
+ private float CurrentMinute;
+
+ /**
+ * 试卷
+ */
+ private String pdfStr;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/ExaminationPaper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/ExaminationPaper.java
new file mode 100644
index 00000000..f18c7aee
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/ExaminationPaper.java
@@ -0,0 +1,33 @@
+package org.dromara.safety.bo.rests;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 考试试卷实体类
+ */
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class ExaminationPaper implements Serializable {
+ private String userName;
+
+ private String pass;
+
+ private String sumScore;
+
+ private ExaminationPaperOne single;
+
+ private ExaminationPaperOne multiple;
+
+ private ExaminationPaperOne estimate;
+
+ private String sign;
+
+ private String userId;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/ExaminationPaperOne.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/ExaminationPaperOne.java
new file mode 100644
index 00000000..6b46a76a
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/ExaminationPaperOne.java
@@ -0,0 +1,24 @@
+package org.dromara.safety.bo.rests;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ExaminationPaperOne implements Serializable {
+ /**
+ * 题目+分数
+ */
+ private String topic;
+
+ /**
+ * 二级题目列表
+ */
+ private List list;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/ExaminationPaperTwo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/ExaminationPaperTwo.java
new file mode 100644
index 00000000..98bd1045
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/ExaminationPaperTwo.java
@@ -0,0 +1,44 @@
+package org.dromara.safety.bo.rests;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class ExaminationPaperTwo implements Serializable {
+ /**
+ * 题目内容
+ */
+ private String questionText;
+
+ /**
+ * 题目选项
+ */
+ private String options;
+
+ /**
+ * 用户填写的答案
+ */
+ private String answer;
+
+ /**
+ * 题目的正确答案
+ */
+ private String correctAnswer;
+
+ /**
+ * 答题是否正确,1 表示正确,2 表示错误
+ */
+ private String correct;
+
+ /**
+ * 当前题目的得分
+ */
+ private double score;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/GetsTheMembersUnderTheCurrentProject.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/GetsTheMembersUnderTheCurrentProject.java
new file mode 100644
index 00000000..56a8ceeb
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/GetsTheMembersUnderTheCurrentProject.java
@@ -0,0 +1,6 @@
+package org.dromara.safety.bo.rests;
+
+import java.io.Serializable;
+
+public class GetsTheMembersUnderTheCurrentProject implements Serializable {
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/PdfEntity.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/PdfEntity.java
new file mode 100644
index 00000000..671f364c
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/PdfEntity.java
@@ -0,0 +1,35 @@
+package org.dromara.safety.bo.rests;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class PdfEntity implements Serializable {
+ // 类型
+ private String questionType;
+ // 内容
+ private String questionText;
+ // 选择
+ private String options;
+ // 用户答案
+ private String answer;
+ // 正确答案
+ private String correctAnswer;
+ // 答案是否正确(1正 2错)
+ private String correct;
+ // 用户当前题得分
+ private double score;
+ // 用户姓名
+ private String userName;
+ // 及格线及总分
+ private String pass;
+ // 用户试卷总得分
+ private double sumScore;
+ // 签名路径
+ private String sign;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/WgzAppGetTestPaperThree.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/WgzAppGetTestPaperThree.java
new file mode 100644
index 00000000..b65c8991
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/WgzAppGetTestPaperThree.java
@@ -0,0 +1,37 @@
+package org.dromara.safety.bo.rests;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class WgzAppGetTestPaperThree implements Serializable {
+ /**
+ * 题库id
+ */
+ private long id;
+
+ /**
+ * 题类型
+ */
+ private String questionType;
+
+ /**
+ * 题内容
+ */
+ private String questionText;
+
+ /**
+ * 题选项
+ */
+ private String options;
+
+ /**
+ * 题分数
+ */
+ private double score;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/WgzAppGetTestPaperTwo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/WgzAppGetTestPaperTwo.java
new file mode 100644
index 00000000..df4f11c0
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/WgzAppGetTestPaperTwo.java
@@ -0,0 +1,23 @@
+package org.dromara.safety.bo.rests;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class WgzAppGetTestPaperTwo implements Serializable {
+
+ /**
+ * 题目+分数
+ */
+ private String topic;
+ /**
+ * 题目选项
+ */
+ private List list;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/WgzAppSubmitATestPaperTwo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/WgzAppSubmitATestPaperTwo.java
new file mode 100644
index 00000000..d3940fe1
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/bo/rests/WgzAppSubmitATestPaperTwo.java
@@ -0,0 +1,29 @@
+package org.dromara.safety.bo.rests;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class WgzAppSubmitATestPaperTwo implements Serializable {
+
+ /**
+ * 题库ID
+ */
+ private long bankId;
+
+ /**
+ * 答案
+ */
+ private String answer;
+
+ /**
+ * 当前题分数
+ */
+ private double score;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionBankController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionBankController.java
new file mode 100644
index 00000000..27e34edc
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionBankController.java
@@ -0,0 +1,90 @@
+package org.dromara.safety.controller;
+
+import java.util.Arrays;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.safety.bo.req.WgzQuestionReq;
+import org.dromara.safety.domain.WgzQuestionBank;
+import org.dromara.safety.domain.bo.WgzQuestionBankBo;
+import org.dromara.safety.domain.vo.WgzQuestionBankVo;
+import org.dromara.safety.service.IWgzQuestionBankService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+
+
+/**
+ * 题库Controller
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/safety/wgzQuestionBank")
+public class WgzQuestionBankController extends BaseController {
+
+ private final IWgzQuestionBankService iWgzQuestionBankService;
+
+ /**
+ * 查询题库列表
+ */
+ @SaCheckPermission("safety:wgzQuestionBank:list")
+ @GetMapping("/list")
+ public TableDataInfo list(@Validated WgzQuestionBankBo bo, PageQuery pageQuery) {
+ return iWgzQuestionBankService.queryPageList(bo, pageQuery);
+ }
+
+ /**
+ * 获取题库详细信息
+ */
+ @SaCheckPermission("safety:wgzQuestionBank:query")
+ @GetMapping("/{id}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable("id") Long id) {
+ return R.ok(iWgzQuestionBankService.queryById(id));
+ }
+
+ /**
+ * 新增题库
+ */
+ @SaCheckPermission("safety:wgzQuestionBank:add")
+ @Log(title = "题库", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated @RequestBody WgzQuestionReq bo) {
+ return toAjax(iWgzQuestionBankService.insert(bo) ? 1 : 0);
+ }
+
+ /**
+ * 修改题库
+ */
+ @SaCheckPermission("safety:wgzQuestionBank:edit")
+ @Log(title = "题库", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated @RequestBody WgzQuestionBank bo) {
+ return toAjax(iWgzQuestionBankService.update(bo) ? 1 : 0);
+ }
+
+ /**
+ * 删除题库
+ */
+ @SaCheckPermission("safety:wgzQuestionBank:remove")
+ @Log(title = "题库", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{ids}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] ids) {
+ return toAjax(iWgzQuestionBankService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionCategoryController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionCategoryController.java
new file mode 100644
index 00000000..ed1c011e
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionCategoryController.java
@@ -0,0 +1,88 @@
+package org.dromara.safety.controller;
+
+import java.util.Arrays;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.safety.domain.WgzQuestionCategory;
+import org.dromara.safety.domain.bo.WgzQuestionCategoryBo;
+import org.dromara.safety.domain.vo.WgzQuestionCategoryVo;
+import org.dromara.safety.service.IWgzQuestionCategoryService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * 题库_题库类别
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/safety/wzgQuestionCategory")
+public class WgzQuestionCategoryController extends BaseController {
+
+ private final IWgzQuestionCategoryService iWgzQuestionCategoryService;
+
+ /**
+ * 查询题库_题库类别列表
+ */
+ @SaCheckPermission("safety:wzgQuestionCategory:list")
+ @GetMapping("/list")
+ public TableDataInfo list(@Validated WgzQuestionCategoryBo bo, PageQuery pageQuery) {
+ return iWgzQuestionCategoryService.queryPageList(bo, pageQuery);
+ }
+
+ /**
+ * 获取题库_题库类别详细信息
+ */
+ @SaCheckPermission("safety:wzgQuestionCategory:query")
+ @GetMapping("/{id}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable("id") Long id) {
+ return R.ok(iWgzQuestionCategoryService.queryById(id));
+ }
+
+ /**
+ * 新增题库_题库类别
+ */
+ @SaCheckPermission("safety:wzgQuestionCategory:add")
+ @Log(title = "题库_题库类别", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated @RequestBody WgzQuestionCategory bo) {
+ return toAjax(iWgzQuestionCategoryService.insert(bo) ? 1 : 0);
+ }
+
+ /**
+ * 修改题库_题库类别
+ */
+ @SaCheckPermission("safety:wzgQuestionCategory:edit")
+ @Log(title = "题库_题库类别", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated @RequestBody WgzQuestionCategory bo) {
+ return toAjax(iWgzQuestionCategoryService.update(bo) ? 1 : 0);
+ }
+
+ /**
+ * 删除题库_题库类别
+ */
+ @SaCheckPermission("safety:wzgQuestionCategory:remove")
+ @Log(title = "题库_题库类别", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{ids}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] ids) {
+ return toAjax(iWgzQuestionCategoryService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionSaveController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionSaveController.java
new file mode 100644
index 00000000..01ecd070
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionSaveController.java
@@ -0,0 +1,89 @@
+package org.dromara.safety.controller;
+
+import java.util.Arrays;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.safety.domain.WgzQuestionSave;
+import org.dromara.safety.domain.bo.WgzQuestionSaveBo;
+import org.dromara.safety.domain.vo.WgzQuestionSaveVo;
+import org.dromara.safety.service.IWgzQuestionSaveService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+/**
+ * 用户试卷存储Controller
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/safety/wgzQuestionSave")
+public class WgzQuestionSaveController extends BaseController {
+
+ private final IWgzQuestionSaveService iWgzQuestionSaveService;
+
+ /**
+ * 查询用户试卷存储列表
+ */
+ @SaCheckPermission("safety:wgzQuestionSave:list")
+ @GetMapping("/list")
+ public TableDataInfo list(@Validated WgzQuestionSaveBo bo, PageQuery pageQuery) {
+ return iWgzQuestionSaveService.queryPageList(bo,pageQuery);
+ }
+
+
+
+ /**
+ * 获取用户试卷存储详细信息
+ */
+ @SaCheckPermission("safety:wgzQuestionSave:query")
+ @GetMapping("/{id}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable("id") Long id) {
+ return R.ok(iWgzQuestionSaveService.queryById(id));
+ }
+
+ /**
+ * 新增用户试卷存储
+ */
+ @SaCheckPermission("safety:wgzQuestionSave:add")
+ @Log(title = "用户试卷存储", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated @RequestBody WgzQuestionSave bo) {
+ return toAjax(iWgzQuestionSaveService.insert(bo) ? 1 : 0);
+ }
+
+ /**
+ * 修改用户试卷存储
+ */
+ @SaCheckPermission("safety:wgzQuestionSave:edit")
+ @Log(title = "用户试卷存储", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated @RequestBody WgzQuestionSave bo) {
+ return toAjax(iWgzQuestionSaveService.update(bo) ? 1 : 0);
+ }
+
+ /**
+ * 删除用户试卷存储
+ */
+ @SaCheckPermission("safety:wgzQuestionSave:remove")
+ @Log(title = "用户试卷存储", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{ids}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] ids) {
+ return toAjax(iWgzQuestionSaveService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionsConfigurationController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionsConfigurationController.java
new file mode 100644
index 00000000..21ec5e63
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/WgzQuestionsConfigurationController.java
@@ -0,0 +1,90 @@
+package org.dromara.safety.controller;
+
+import java.util.Arrays;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.safety.domain.WgzQuestionsConfiguration;
+import org.dromara.safety.domain.bo.WgzQuestionsConfigurationBo;
+import org.dromara.safety.domain.vo.WgzQuestionsConfigurationVo;
+import org.dromara.safety.service.IWgzQuestionsConfigurationService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * 题库配置Controller
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/safety/wzgQuestionsConfiguration")
+public class WgzQuestionsConfigurationController extends BaseController {
+
+ private final IWgzQuestionsConfigurationService iWgzQuestionsConfigurationService;
+
+ /**
+ * 查询题库配置列表
+ */
+ @SaCheckPermission("safety:wzgQuestionsConfiguration:list")
+ @GetMapping("/list")
+ public TableDataInfo list(@Validated WgzQuestionsConfigurationBo bo, PageQuery pageQuery) {
+ return iWgzQuestionsConfigurationService.queryPageList(bo, pageQuery);
+ }
+
+
+
+ /**
+ * 获取题库配置详细信息
+ */
+ @SaCheckPermission("safety:wzgQuestionsConfiguration:query")
+ @GetMapping("/{id}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable("id") Long id) {
+ return R.ok(iWgzQuestionsConfigurationService.queryById(id));
+ }
+
+ /**
+ * 新增题库配置
+ */
+ @SaCheckPermission("safety:wzgQuestionsConfiguration:add")
+ @Log(title = "题库配置", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated @RequestBody WgzQuestionsConfiguration bo) {
+ return toAjax(iWgzQuestionsConfigurationService.insert(bo) ? 1 : 0);
+ }
+
+ /**
+ * 修改题库配置
+ */
+ @SaCheckPermission("safety:wzgQuestionsConfiguration:edit")
+ @Log(title = "题库配置", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated @RequestBody WgzQuestionsConfiguration bo) {
+ return toAjax(iWgzQuestionsConfigurationService.update(bo) ? 1 : 0);
+ }
+
+ /**
+ * 删除题库配置
+ */
+ @SaCheckPermission("safety:wzgQuestionsConfiguration:remove")
+ @Log(title = "题库配置", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{ids}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] ids) {
+ return toAjax(iWgzQuestionsConfigurationService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionBank.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionBank.java
new file mode 100644
index 00000000..d1e305eb
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionBank.java
@@ -0,0 +1,57 @@
+package org.dromara.safety.domain;
+
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.math.BigDecimal;
+
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.LocalDate;
+
+/**
+ * 题库对象 wgz_question_bank
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("wgz_question_bank")
+public class WgzQuestionBank extends BaseEntity {
+
+ private static final long serialVersionUID=1L;
+
+ /** 主键ID */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /** 题目类别(外键关联到类别表) */
+ private Long categoryId;
+
+ /** 题目类型(1单选、2多选、3判断、4填空、5问答) */
+ private String questionType;
+
+ /** 题目内容 */
+ private String questionText;
+
+ /** 选项(对单选、多选、判断这种固定答案有效,以JSON数组形式存储) */
+ private String options;
+
+ /** 正确答案 */
+ private String correctAnswer;
+
+ /** 得分 */
+ private Long score;
+
+ /** 备注 */
+ private String remark;
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionCategory.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionCategory.java
new file mode 100644
index 00000000..edcb40fe
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionCategory.java
@@ -0,0 +1,38 @@
+package org.dromara.safety.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.math.BigDecimal;
+
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.LocalDate;
+
+/**
+ * 题库_题库类别对象 wgz_question_category
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("wgz_question_category")
+public class WgzQuestionCategory extends BaseEntity {
+
+ private static final long serialVersionUID=1L;
+
+ /** 主键ID */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /** 题库类别 */
+ private String categoryName;
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionSave.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionSave.java
new file mode 100644
index 00000000..e597771b
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionSave.java
@@ -0,0 +1,65 @@
+package org.dromara.safety.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.math.BigDecimal;
+
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.LocalDate;
+
+/**
+ * 用户试卷存储对象 wgz_question_save
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("wgz_question_save")
+public class WgzQuestionSave extends BaseEntity {
+
+ private static final long serialVersionUID=1L;
+
+ /** 主键ID */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /** 务工者唯一标识 */
+ private Long userId;
+
+ /** 题库ID */
+ private Long bankId;
+
+ /** 答案 */
+ private String answer;
+
+ /** 答题是否正确(1正确 2错误) */
+ private String correct;
+
+ /** 得分(当前题) */
+ private Double score;
+
+ /** 签名路径 */
+ private String sign;
+
+ /** 用时时间(时间戳/秒) */
+ private Long takeTime;
+
+ /** 最大超时时间(单位/分钟) */
+ private Integer timeOut;
+
+ /** 及格线/总分(格式:60,100) */
+ private String pass;
+
+ /** 备注 */
+ private String remark;
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionSavePdf.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionSavePdf.java
new file mode 100644
index 00000000..8f18ad76
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionSavePdf.java
@@ -0,0 +1,56 @@
+package org.dromara.safety.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.math.BigDecimal;
+
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.LocalDate;
+
+/**
+ * 用户试卷存储pdf对象 wgz_question_save_pdf
+ *
+ * @author ruoyi
+ * @date 2025-03-26
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("wgz_question_save_pdf")
+public class WgzQuestionSavePdf extends BaseEntity {
+
+ private static final long serialVersionUID=1L;
+
+ /** 主键iD */
+ @TableId(value = "id")
+ private Long id;
+
+ /** 1线上 2线下 */
+ private String type;
+
+ /** 用户主键ID */
+ private Long userId;
+
+ /** pdf路径 */
+ private String path;
+
+ /** 及格线/总分(格式:60,100) */
+ private String pass;
+
+ /** 最大超时时间(单位/分钟) */
+ private int timeOut;
+
+ /** 用时时间(时间戳/秒) */
+ private Long takeTime;
+
+ /** 总得分 */
+ private Double sumScore;
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionsConfiguration.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionsConfiguration.java
new file mode 100644
index 00000000..b707ff8c
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/WgzQuestionsConfiguration.java
@@ -0,0 +1,61 @@
+package org.dromara.safety.domain;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.math.BigDecimal;
+
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.LocalDate;
+
+/**
+ * 题库配置对象 wgz_questions_configuration
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("wgz_questions_configuration")
+public class WgzQuestionsConfiguration extends BaseEntity {
+
+ private static final long serialVersionUID=1L;
+
+ /** 主键ID */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /** 单选题(单位/道) */
+ private Integer singleChoice;
+
+ /** 单选分数 */
+ private Float singleScore;
+
+ /** 多选题(单位/道) */
+ private Integer multipleChoice;
+
+ /** 多选分数 */
+ private Float multipleScore;
+
+ /** 判断题(单位/道) */
+ private Integer estimate;
+
+ /** 判断分数 */
+ private Float estimateScore;
+
+ /** 满分 */
+ private Double fullMark;
+
+ /** 及格线 */
+ private Double passingScore;
+
+ /** 答题最大时间(单位/分钟) */
+ private int answerTime;
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionBankBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionBankBo.java
new file mode 100644
index 00000000..09f7ab67
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionBankBo.java
@@ -0,0 +1,65 @@
+package org.dromara.safety.domain.bo;
+
+import org.dromara.safety.domain.WgzQuestionBank;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 题库业务对象 wgz_question_bank
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = WgzQuestionBank.class, reverseConvertGenerate = false)
+public class WgzQuestionBankBo extends BaseEntity {
+
+ /**
+ * 主键ID
+ */
+ @NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
+ private Long id;
+
+ /**
+ * 题目类别(外键关联到类别表)
+ */
+ private Long categoryId;
+
+ /**
+ * 题目类型(1单选、2多选、3判断、4填空、5问答)
+ */
+ private String questionType;
+
+ /**
+ * 题目内容
+ */
+ private String questionText;
+
+ /**
+ * 选项(对单选、多选、判断这种固定答案有效,以JSON数组形式存储)
+ */
+ private String options;
+
+ /**
+ * 正确答案
+ */
+ private String correctAnswer;
+
+ /**
+ * 得分
+ */
+ private Long score;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionCategoryBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionCategoryBo.java
new file mode 100644
index 00000000..95979782
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionCategoryBo.java
@@ -0,0 +1,35 @@
+package org.dromara.safety.domain.bo;
+
+import org.dromara.safety.domain.WgzQuestionCategory;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 题库_题库类别业务对象 wgz_question_category
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = WgzQuestionCategory.class, reverseConvertGenerate = false)
+public class WgzQuestionCategoryBo extends BaseEntity {
+
+ /**
+ * 主键ID
+ */
+ @NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
+ private Long id;
+
+ /**
+ * 题库类别
+ */
+ private String categoryName;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionSaveBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionSaveBo.java
new file mode 100644
index 00000000..0398f4b0
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionSaveBo.java
@@ -0,0 +1,81 @@
+package org.dromara.safety.domain.bo;
+
+import org.dromara.safety.domain.WgzQuestionSave;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 用户试卷存储业务对象 wgz_question_save
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = WgzQuestionSave.class, reverseConvertGenerate = false)
+public class WgzQuestionSaveBo extends BaseEntity {
+
+ /**
+ * 主键ID
+ */
+ @NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
+ private Long id;
+
+ /**
+ * 务工者唯一标识
+ */
+ @NotNull(message = "务工者唯一标识不能为空", groups = { AddGroup.class, EditGroup.class })
+ private Long userId;
+
+ /**
+ * 题库ID
+ */
+ private Long bankId;
+
+ /**
+ * 答案
+ */
+ private String answer;
+
+ /**
+ * 答题是否正确(1正确 2错误)
+ */
+ private String correct;
+
+ /**
+ * 得分(当前题)
+ */
+ private Long score;
+
+ /**
+ * 签名路径
+ */
+ private String sign;
+
+ /**
+ * 用时时间(时间戳/秒)
+ */
+ private Long takeTime;
+
+ /**
+ * 最大超时时间(单位/分钟)
+ */
+ private Long timeOut;
+
+ /**
+ * 及格线/总分(格式:60,100)
+ */
+ private String pass;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionSavePdfBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionSavePdfBo.java
new file mode 100644
index 00000000..75b0320e
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionSavePdfBo.java
@@ -0,0 +1,66 @@
+package org.dromara.safety.domain.bo;
+
+import org.dromara.safety.domain.WgzQuestionSavePdf;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 用户试卷存储pdf业务对象 wgz_question_save_pdf
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = WgzQuestionSavePdf.class, reverseConvertGenerate = false)
+public class WgzQuestionSavePdfBo extends BaseEntity {
+
+ /**
+ * 主键iD
+ */
+ @NotNull(message = "主键iD不能为空", groups = { EditGroup.class })
+ private Long id;
+
+ /**
+ * 1线上 2线下
+ */
+ @NotBlank(message = "1线上 2线下不能为空", groups = { EditGroup.class })
+ private String type;
+
+ /**
+ * 用户主键ID
+ */
+ private Long userId;
+
+ /**
+ * pdf路径
+ */
+ private String path;
+
+ /**
+ * 及格线/总分(格式:60,100)
+ */
+ private String pass;
+
+ /**
+ * 最大超时时间(单位/分钟)
+ */
+ private Long timeOut;
+
+ /**
+ * 用时时间(时间戳/秒)
+ */
+ private Long takeTime;
+
+ /**
+ * 总得分
+ */
+ private Long sumScore;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionsConfigurationBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionsConfigurationBo.java
new file mode 100644
index 00000000..a99612bb
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/bo/WgzQuestionsConfigurationBo.java
@@ -0,0 +1,84 @@
+package org.dromara.safety.domain.bo;
+
+import org.dromara.safety.domain.WgzQuestionsConfiguration;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 题库配置业务对象 wgz_questions_configuration
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = WgzQuestionsConfiguration.class, reverseConvertGenerate = false)
+public class WgzQuestionsConfigurationBo extends BaseEntity {
+
+ /**
+ * 主键ID
+ */
+ @NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
+ private Long id;
+
+ /**
+ * 单选题(单位/道)
+ */
+ @NotNull(message = "单选题(单位/道)不能为空", groups = { AddGroup.class, EditGroup.class })
+ private Long singleChoice;
+
+ /**
+ * 单选分数
+ */
+ @NotNull(message = "单选分数不能为空", groups = { AddGroup.class, EditGroup.class })
+ private Long singleScore;
+
+ /**
+ * 多选题(单位/道)
+ */
+ @NotNull(message = "多选题(单位/道)不能为空", groups = { AddGroup.class, EditGroup.class })
+ private Long multipleChoice;
+
+ /**
+ * 多选分数
+ */
+ @NotNull(message = "多选分数不能为空", groups = { AddGroup.class, EditGroup.class })
+ private Long multipleScore;
+
+ /**
+ * 判断题(单位/道)
+ */
+ @NotNull(message = "判断题(单位/道)不能为空", groups = { AddGroup.class, EditGroup.class })
+ private Long estimate;
+
+ /**
+ * 判断分数
+ */
+ @NotNull(message = "判断分数不能为空", groups = { AddGroup.class, EditGroup.class })
+ private Long estimateScore;
+
+ /**
+ * 满分
+ */
+ @NotNull(message = "满分不能为空", groups = { AddGroup.class, EditGroup.class })
+ private Long fullMark;
+
+ /**
+ * 及格线
+ */
+ @NotNull(message = "及格线不能为空", groups = { AddGroup.class, EditGroup.class })
+ private Long passingScore;
+
+ /**
+ * 答题最大时间(单位/分钟)
+ */
+ @NotNull(message = "答题最大时间(单位/分钟)不能为空", groups = { AddGroup.class, EditGroup.class })
+ private Long answerTime;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BgtQuestionResult.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BgtQuestionResult.java
new file mode 100644
index 00000000..40d7776d
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/BgtQuestionResult.java
@@ -0,0 +1,45 @@
+package org.dromara.safety.domain.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 务工者岗前培训结果视图对象
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class BgtQuestionResult {
+
+ /**
+ * 分数
+ */
+ private Double score;
+
+ /**
+ * 答对题数
+ */
+ private Integer successNum;
+
+ /**
+ * 答错题数
+ */
+ private Integer errorNum;
+
+ /**
+ * 耗时
+ */
+ private Long time;
+
+ /**
+ * 头像
+ */
+ private String avatarName;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionBankVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionBankVo.java
new file mode 100644
index 00000000..71ead65d
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionBankVo.java
@@ -0,0 +1,83 @@
+package org.dromara.safety.domain.vo;
+
+import org.dromara.safety.domain.WgzQuestionBank;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 题库视图对象 wgz_question_bank
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = WgzQuestionBank.class)
+public class WgzQuestionBankVo implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键ID
+ */
+ @ExcelProperty(value = "主键ID")
+ private Long id;
+
+ /**
+ * 题目类别(外键关联到类别表)
+ */
+ @ExcelProperty(value = "题目类别", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "外=键关联到类别表")
+ private Long categoryId;
+
+ /**
+ * 题目类型(1单选、2多选、3判断、4填空、5问答)
+ */
+ @ExcelProperty(value = "题目类型", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "1=单选、2多选、3判断、4填空、5问答")
+ private String questionType;
+
+ /**
+ * 题目内容
+ */
+ @ExcelProperty(value = "题目内容")
+ private String questionText;
+
+ /**
+ * 选项(对单选、多选、判断这种固定答案有效,以JSON数组形式存储)
+ */
+ @ExcelProperty(value = "选项", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "对=单选、多选、判断这种固定答案有效,以JSON数组形式存储")
+ private String options;
+
+ /**
+ * 正确答案
+ */
+ @ExcelProperty(value = "正确答案")
+ private String correctAnswer;
+
+ /**
+ * 得分
+ */
+ @ExcelProperty(value = "得分")
+ private Long score;
+
+ /**
+ * 备注
+ */
+ @ExcelProperty(value = "备注")
+ private String remark;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionCategoryVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionCategoryVo.java
new file mode 100644
index 00000000..3a31e581
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionCategoryVo.java
@@ -0,0 +1,44 @@
+package org.dromara.safety.domain.vo;
+
+import org.dromara.safety.domain.WgzQuestionCategory;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 题库_题库类别视图对象 wgz_question_category
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = WgzQuestionCategory.class)
+public class WgzQuestionCategoryVo implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键ID
+ */
+ @ExcelProperty(value = "主键ID")
+ private Long id;
+
+ /**
+ * 题库类别
+ */
+ @ExcelProperty(value = "题库类别")
+ private String categoryName;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionSavePdfVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionSavePdfVo.java
new file mode 100644
index 00000000..58ef688f
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionSavePdfVo.java
@@ -0,0 +1,83 @@
+package org.dromara.safety.domain.vo;
+
+import org.dromara.safety.domain.WgzQuestionSavePdf;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 用户试卷存储pdf视图对象 wgz_question_save_pdf
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = WgzQuestionSavePdf.class)
+public class WgzQuestionSavePdfVo implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键iD
+ */
+ @ExcelProperty(value = "主键iD")
+ private Long id;
+
+ /**
+ * 1线上 2线下
+ */
+ @ExcelProperty(value = "1线上 2线下")
+ private String type;
+
+ /**
+ * 用户主键ID
+ */
+ @ExcelProperty(value = "用户主键ID")
+ private Long userId;
+
+ /**
+ * pdf路径
+ */
+ @ExcelProperty(value = "pdf路径")
+ private String path;
+
+ /**
+ * 及格线/总分(格式:60,100)
+ */
+ @ExcelProperty(value = "及格线/总分", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "格=式:60,100")
+ private String pass;
+
+ /**
+ * 最大超时时间(单位/分钟)
+ */
+ @ExcelProperty(value = "最大超时时间", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "单=位/分钟")
+ private Long timeOut;
+
+ /**
+ * 用时时间(时间戳/秒)
+ */
+ @ExcelProperty(value = "用时时间", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "时=间戳/秒")
+ private Long takeTime;
+
+ /**
+ * 总得分
+ */
+ @ExcelProperty(value = "总得分")
+ private Long sumScore;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionSaveVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionSaveVo.java
new file mode 100644
index 00000000..fb30360b
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionSaveVo.java
@@ -0,0 +1,103 @@
+package org.dromara.safety.domain.vo;
+
+import org.dromara.safety.domain.WgzQuestionSave;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 用户试卷存储视图对象 wgz_question_save
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = WgzQuestionSave.class)
+public class WgzQuestionSaveVo implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键ID
+ */
+ @ExcelProperty(value = "主键ID")
+ private Long id;
+
+ /**
+ * 务工者唯一标识
+ */
+ @ExcelProperty(value = "务工者唯一标识")
+ private Long userId;
+
+ /**
+ * 题库ID
+ */
+ @ExcelProperty(value = "题库ID")
+ private Long bankId;
+
+ /**
+ * 答案
+ */
+ @ExcelProperty(value = "答案")
+ private String answer;
+
+ /**
+ * 答题是否正确(1正确 2错误)
+ */
+ @ExcelProperty(value = "答题是否正确", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "1=正确,2=错误")
+ private String correct;
+
+ /**
+ * 得分(当前题)
+ */
+ @ExcelProperty(value = "得分", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "当=前题")
+ private Long score;
+
+ /**
+ * 签名路径
+ */
+ @ExcelProperty(value = "签名路径")
+ private String sign;
+
+ /**
+ * 用时时间(时间戳/秒)
+ */
+ @ExcelProperty(value = "用时时间", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "时=间戳/秒")
+ private Long takeTime;
+
+ /**
+ * 最大超时时间(单位/分钟)
+ */
+ @ExcelProperty(value = "最大超时时间", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "单=位/分钟")
+ private Long timeOut;
+
+ /**
+ * 及格线/总分(格式:60,100)
+ */
+ @ExcelProperty(value = "及格线/总分", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "格=式:60,100")
+ private String pass;
+
+ /**
+ * 备注
+ */
+ @ExcelProperty(value = "备注")
+ private String remark;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionsConfigurationVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionsConfigurationVo.java
new file mode 100644
index 00000000..152518e1
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/WgzQuestionsConfigurationVo.java
@@ -0,0 +1,96 @@
+package org.dromara.safety.domain.vo;
+
+import org.dromara.safety.domain.WgzQuestionsConfiguration;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 题库配置视图对象 wgz_questions_configuration
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = WgzQuestionsConfiguration.class)
+public class WgzQuestionsConfigurationVo implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键ID
+ */
+ @ExcelProperty(value = "主键ID")
+ private Long id;
+
+ /**
+ * 单选题(单位/道)
+ */
+ @ExcelProperty(value = "单选题", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "单=位/道")
+ private Long singleChoice;
+
+ /**
+ * 单选分数
+ */
+ @ExcelProperty(value = "单选分数")
+ private Long singleScore;
+
+ /**
+ * 多选题(单位/道)
+ */
+ @ExcelProperty(value = "多选题", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "单=位/道")
+ private Long multipleChoice;
+
+ /**
+ * 多选分数
+ */
+ @ExcelProperty(value = "多选分数")
+ private Long multipleScore;
+
+ /**
+ * 判断题(单位/道)
+ */
+ @ExcelProperty(value = "判断题", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "单=位/道")
+ private Long estimate;
+
+ /**
+ * 判断分数
+ */
+ @ExcelProperty(value = "判断分数")
+ private Long estimateScore;
+
+ /**
+ * 满分
+ */
+ @ExcelProperty(value = "满分")
+ private Long fullMark;
+
+ /**
+ * 及格线
+ */
+ @ExcelProperty(value = "及格线")
+ private Long passingScore;
+
+ /**
+ * 答题最大时间(单位/分钟)
+ */
+ @ExcelProperty(value = "答题最大时间", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "单=位/分钟")
+ private Long answerTime;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionBankMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionBankMapper.java
new file mode 100644
index 00000000..a38190ff
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionBankMapper.java
@@ -0,0 +1,18 @@
+package org.dromara.safety.mapper;
+
+
+import org.apache.ibatis.annotations.CacheNamespace;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.safety.domain.WgzQuestionBank;
+import org.dromara.safety.domain.vo.WgzQuestionBankVo;
+
+
+/**
+ * 题库Mapper接口
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+public interface WgzQuestionBankMapper extends BaseMapperPlus {
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionCategoryMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionCategoryMapper.java
new file mode 100644
index 00000000..0cc71d04
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionCategoryMapper.java
@@ -0,0 +1,18 @@
+package org.dromara.safety.mapper;
+
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.safety.domain.WgzQuestionCategory;
+import org.dromara.safety.domain.vo.WgzQuestionCategoryVo;
+
+
+/**
+ * 题库_题库类别Mapper接口
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+public interface WgzQuestionCategoryMapper extends BaseMapperPlus {
+
+}
+
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionSaveMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionSaveMapper.java
new file mode 100644
index 00000000..fec6c77f
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionSaveMapper.java
@@ -0,0 +1,53 @@
+package org.dromara.safety.mapper;
+
+
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.safety.bo.rests.PdfEntity;
+import org.dromara.safety.domain.WgzQuestionSave;
+import org.dromara.safety.domain.vo.WgzQuestionSaveVo;
+
+import java.util.List;
+import java.util.Map;
+
+///**
+// * 用户试卷存储Mapper接口
+// *
+// * @author ruoyi
+// * @date 2025-02-17
+// */
+//// 如使需切换数据源 请勿使用缓存 会造成数据不一致现象
+//@CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
+//public interface WgzQuestionSaveMapper extends BaseMapperPlus {
+//
+//
+//}
+
+
+/**
+ * 用户试卷存储Mapper接口
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+public interface WgzQuestionSaveMapper extends BaseMapperPlus {
+ @Select("SELECT SUM(score) AS sumScore, " +
+ "(SELECT pass FROM wgz_question_save WHERE user_id = #{userId} AND del_flag = '0' ORDER BY id ASC LIMIT 1) AS pass, " +
+ "(SELECT sign FROM wgz_question_save WHERE user_id = #{userId} AND del_flag = '0' ORDER BY id ASC LIMIT 1) AS sign " +
+ "FROM wgz_question_save " +
+ "WHERE correct = 1 AND user_id = #{userId}")
+ Map getSumScoreAndPassAndSign(@Param("userId") Long userId);
+
+ //查询指定用户所有答对的题目分数
+ @Select("SELECT SUM(score) AS sumScore FROM wgz_question_save WHERE user_id = #{userId} AND correct = 1")
+ float getSumScore(@Param("userId") Long userId);
+
+ //获取生成pdf所需要的数据
+ @Select("SELECT SUM(score) FROM wgz_question_save WHERE user_id=#{userId} AND correct=1")
+ String pdfSumScore (@Param("userId") Long userId);
+
+ //
+ @Select("SELECT c.question_type,c.question_text,c.OPTIONS,a.answer,c.correct_answer,a.correct,a.score,a.sign,a.id,a.pass,b.username as userName FROM wgz_question_save AS a LEFT JOIN wgz_user AS b ON b.user_id=a.user_id LEFT JOIN wgz_question_bank AS c ON a.bank_id=c.id WHERE a.user_id=#{userId}")
+ List pdfSc (@Param("userId") Long userId);
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionSavePdfMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionSavePdfMapper.java
new file mode 100644
index 00000000..6412073d
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionSavePdfMapper.java
@@ -0,0 +1,17 @@
+package org.dromara.safety.mapper;
+
+
+import org.apache.ibatis.annotations.CacheNamespace;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.safety.domain.WgzQuestionSavePdf;
+import org.dromara.safety.domain.vo.WgzQuestionSavePdfVo;
+
+/**
+ * 用户试卷存储pdfMapper接口
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+public interface WgzQuestionSavePdfMapper extends BaseMapperPlus {
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionsConfigurationMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionsConfigurationMapper.java
new file mode 100644
index 00000000..710fef6e
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/WgzQuestionsConfigurationMapper.java
@@ -0,0 +1,16 @@
+package org.dromara.safety.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.safety.domain.WgzQuestionsConfiguration;
+import org.dromara.safety.domain.vo.WgzQuestionsConfigurationVo;
+
+
+/**
+ * 题库配置Mapper接口
+ *
+ * @author Lion Li
+ * @date 2025-09-03
+ */
+public interface WgzQuestionsConfigurationMapper extends BaseMapperPlus {
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionBankService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionBankService.java
new file mode 100644
index 00000000..901c6a8a
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionBankService.java
@@ -0,0 +1,81 @@
+package org.dromara.safety.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.safety.bo.req.WgzQuestionReq;
+import org.dromara.safety.bo.rests.WgzAppGetTestPaperThree;
+import org.dromara.safety.domain.WgzQuestionBank;
+import org.dromara.safety.domain.bo.WgzQuestionBankBo;
+import org.dromara.safety.domain.vo.WgzQuestionBankVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 题库Service接口
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+public interface IWgzQuestionBankService extends IService {
+ /**
+ * 查询单个
+ * @return
+ */
+ WgzQuestionBank queryById(Long id);
+
+ /**
+ * 查询列表
+ */
+ TableDataInfo queryPageList(WgzQuestionBankBo bo, PageQuery pageQuery);
+
+ /**
+ * 查询列表
+ */
+ List queryList(WgzQuestionBankBo bo);
+
+ /**
+ * 根据新增业务对象插入题库
+ * @param bo 题库新增业务对象
+ * @return
+ */
+ Boolean insert(WgzQuestionReq bo);
+
+ /**
+ * 根据编辑业务对象修改题库
+ * @param bo 题库编辑业务对象
+ * @return
+ */
+ Boolean update(WgzQuestionBank bo);
+
+ /**
+ * 校验并删除数据
+ * @param ids 主键集合
+ * @param isValid 是否校验,true-删除前校验,false-不校验
+ * @return
+ */
+ Boolean deleteWithValidByIds(Collection ids, Boolean isValid);
+
+ /**
+ * 务工者APP相关
+ * =================================================================================================================
+ * =================================================================================================================
+ * =================================================================================================================
+ */
+
+ /**
+ * 随机获取指定个数类型的题
+ * @param type 类型
+ * 1:单选
+ * 2:多选
+ * 3:判断
+ * @param num 数量
+ */
+ List appQueryList(int type, int num);
+
+ /**
+ * 根据id查询得到具体题库的信息
+ */
+ WgzQuestionBank selectById(Long id);
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionCategoryService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionCategoryService.java
new file mode 100644
index 00000000..aedae62e
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionCategoryService.java
@@ -0,0 +1,60 @@
+package org.dromara.safety.service;
+
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.safety.domain.WgzQuestionCategory;
+import org.dromara.safety.domain.bo.WgzQuestionCategoryBo;
+import org.dromara.safety.domain.vo.WgzQuestionCategoryVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 题库_题库类别Service接口
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+public interface IWgzQuestionCategoryService extends IService{
+
+ /**
+ * 查询单个
+ * @return
+ */
+ WgzQuestionCategory queryById(Long id);
+
+ /**
+ * 查询列表
+ */
+ TableDataInfo queryPageList(WgzQuestionCategoryBo bo, PageQuery pageQuery);
+
+ /**
+ * 查询列表
+ */
+ List queryList(WgzQuestionCategoryBo bo);
+
+ /**
+ * 根据新增业务对象插入题库_题库类别
+ * @param bo 题库_题库类别新增业务对象
+ * @return
+ */
+ Boolean insert(WgzQuestionCategory bo);
+
+ /**
+ * 根据编辑业务对象修改题库_题库类别
+ * @param bo 题库_题库类别编辑业务对象
+ * @return
+ */
+ Boolean update(WgzQuestionCategory bo);
+
+ /**
+ * 校验并删除数据
+ * @param ids 主键集合
+ * @param isValid 是否校验,true-删除前校验,false-不校验
+ * @return
+ */
+ Boolean deleteWithValidByIds(Collection ids, Boolean isValid);
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionSavePdfService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionSavePdfService.java
new file mode 100644
index 00000000..f4bf4787
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionSavePdfService.java
@@ -0,0 +1,71 @@
+package org.dromara.safety.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.safety.domain.WgzQuestionSavePdf;
+import org.dromara.safety.domain.bo.WgzQuestionSavePdfBo;
+import org.dromara.safety.domain.vo.WgzQuestionSavePdfVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 用户试卷存储pdfService接口
+ *
+ * @author ruoyi
+ * @date 2025-03-26
+ */
+public interface IWgzQuestionSavePdfService extends IService {
+ /**
+ * 查询单个
+ * @return
+ */
+ WgzQuestionSavePdf queryById(Long id);
+
+ /**
+ * 查询列表
+ */
+ TableDataInfo queryPageList(WgzQuestionSavePdfBo bo, PageQuery pageQuery);
+
+ /**
+ * 查询列表
+ */
+ List queryList(WgzQuestionSavePdfBo bo);
+
+ /**
+ * 根据新增业务对象插入用户试卷存储pdf
+ * @param bo 用户试卷存储pdf新增业务对象
+ * @return
+ */
+ Boolean insert(WgzQuestionSavePdf bo);
+
+ /**
+ * 根据编辑业务对象修改用户试卷存储pdf
+ * @param bo 用户试卷存储pdf编辑业务对象
+ * @return
+ */
+ Boolean update(WgzQuestionSavePdf bo);
+
+ /**
+ * 校验并删除数据
+ * @param ids 主键集合
+ * @param isValid 是否校验,true-删除前校验,false-不校验
+ * @return
+ */
+ Boolean deleteWithValidByIds(Collection ids, Boolean isValid);
+
+ /**
+ * APP相关
+ * =================================================================================================================
+ * =================================================================================================================
+ * =================================================================================================================
+ */
+
+ //根据当前用户ID查询用户试卷存储pdf
+ WgzQuestionSavePdf queryByUserId(Long userId);
+
+ //根据当前用户ID删除用户试卷存储pdf
+ Boolean deleteByUserId(Long userId);
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionSaveService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionSaveService.java
new file mode 100644
index 00000000..21246d6a
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionSaveService.java
@@ -0,0 +1,80 @@
+package org.dromara.safety.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.safety.bo.req.WgzAppSubmitATestPaperReq;
+import org.dromara.safety.bo.res.WgzAppSubmitATestPaperRes;
+import org.dromara.safety.bo.res.WgzAppUserScoreQuery;
+import org.dromara.safety.domain.WgzQuestionSave;
+import org.dromara.safety.domain.bo.WgzQuestionSaveBo;
+import org.dromara.safety.domain.vo.WgzQuestionSaveVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 用户试卷存储Service接口
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+public interface IWgzQuestionSaveService extends IService {
+ /**
+ * 查询单个
+ * @return
+ */
+ WgzQuestionSave queryById(Long id);
+
+ /**
+ * 查询列表
+ */
+ TableDataInfo queryPageList(WgzQuestionSaveBo bo, PageQuery pageQuery);
+
+ /**
+ * 查询列表
+ */
+ List queryList(WgzQuestionSaveBo bo);
+
+ /**
+ * 根据新增业务对象插入用户试卷存储
+ * @param bo 用户试卷存储新增业务对象
+ * @return
+ */
+ Boolean insert(WgzQuestionSave bo);
+
+ /**
+ * 根据编辑业务对象修改用户试卷存储
+ * @param bo 用户试卷存储编辑业务对象
+ * @return
+ */
+ Boolean update(WgzQuestionSave bo);
+
+ /**
+ * 校验并删除数据
+ * @param ids 主键集合
+ * @param isValid 是否校验,true-删除前校验,false-不校验
+ * @return
+ */
+ Boolean deleteWithValidByIds(Collection ids, Boolean isValid);
+
+ /**
+ * APP相关
+ * =================================================================================================================
+ * =================================================================================================================
+ * =================================================================================================================
+ */
+
+ /**
+ * 安全教育试卷提交保存
+ */
+ WgzAppSubmitATestPaperRes userSubmitATestPaper(WgzAppSubmitATestPaperReq req);
+
+ /**
+ * 查詢指定用戶的试卷是否及格
+ */
+ WgzAppUserScoreQuery userScoreQuery(long userId);
+
+
+// BgtQuestionResult getResult(Long userId);
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionsConfigurationService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionsConfigurationService.java
new file mode 100644
index 00000000..ee5333c0
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IWgzQuestionsConfigurationService.java
@@ -0,0 +1,70 @@
+package org.dromara.safety.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.safety.domain.WgzQuestionsConfiguration;
+import org.dromara.safety.domain.bo.WgzQuestionsConfigurationBo;
+import org.dromara.safety.domain.vo.WgzQuestionsConfigurationVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 题库配置Service接口
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+public interface IWgzQuestionsConfigurationService extends IService {
+ /**
+ * 查询单个
+ * @return
+ */
+ WgzQuestionsConfiguration queryById(Long id);
+
+ /**
+ * 查询列表
+ */
+ TableDataInfo queryPageList(WgzQuestionsConfigurationBo bo, PageQuery pageQuery);
+
+ /**
+ * 查询列表
+ */
+ List queryList(WgzQuestionsConfigurationBo bo);
+
+ /**
+ * 根据新增业务对象插入题库配置
+ * @param bo 题库配置新增业务对象
+ * @return
+ */
+ Boolean insert(WgzQuestionsConfiguration bo);
+
+ /**
+ * 根据编辑业务对象修改题库配置
+ * @param bo 题库配置编辑业务对象
+ * @return
+ */
+ Boolean update(WgzQuestionsConfiguration bo);
+
+ /**
+ * 校验并删除数据
+ * @param ids 主键集合
+ * @param isValid 是否校验,true-删除前校验,false-不校验
+ * @return
+ */
+ Boolean deleteWithValidByIds(Collection ids, Boolean isValid);
+
+ /**
+ * 务工者APP相关
+ * =================================================================================================================
+ * =================================================================================================================
+ * =================================================================================================================
+ */
+
+
+ /**
+ * 根据id查询到具体信息
+ */
+ WgzQuestionsConfiguration appQueryLimitOne();
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionBankServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionBankServiceImpl.java
new file mode 100644
index 00000000..fae43ec7
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionBankServiceImpl.java
@@ -0,0 +1,121 @@
+package org.dromara.safety.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.safety.bo.req.WgzQuestionReq;
+import org.dromara.safety.bo.rests.WgzAppGetTestPaperThree;
+import org.dromara.safety.domain.WgzQuestionBank;
+import org.dromara.safety.domain.bo.WgzQuestionBankBo;
+import org.dromara.safety.domain.vo.WgzQuestionBankVo;
+import org.dromara.safety.mapper.WgzQuestionBankMapper;
+import org.dromara.safety.service.IWgzQuestionBankService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+
+import java.util.*;
+
+/**
+ * 题库Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@RequiredArgsConstructor
+@Service
+public class WgzQuestionBankServiceImpl extends ServiceImpl implements IWgzQuestionBankService {
+
+ @Override
+ public WgzQuestionBank queryById(Long id){
+ return getById(id);
+ }
+
+ @Override
+ public TableDataInfo queryPageList(WgzQuestionBankBo bo, PageQuery pageQuery) {
+ LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+ Page result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+ return TableDataInfo.build(result);
+
+
+ }
+
+ public List queryList(WgzQuestionBankBo bo) {
+ LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+ return baseMapper.selectVoList(lqw);
+ }
+
+ private LambdaQueryWrapper buildQueryWrapper(WgzQuestionBankBo bo) {
+ Map params = bo.getParams();
+ LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
+ lqw.orderByDesc(WgzQuestionBank::getId);
+ lqw.eq(bo.getCategoryId() != null, WgzQuestionBank::getCategoryId, bo.getCategoryId());
+ lqw.eq(StringUtils.isNotBlank(bo.getQuestionType()), WgzQuestionBank::getQuestionType, bo.getQuestionType());
+ lqw.eq(StringUtils.isNotBlank(bo.getQuestionText()), WgzQuestionBank::getQuestionText, bo.getQuestionText());
+ return lqw;
+ }
+
+
+ @Override
+ public Boolean insert(WgzQuestionReq bo) {
+ WgzQuestionBank add = BeanUtil.toBean(bo, WgzQuestionBank.class);
+ validEntityBeforeSave(add);
+ return save(add);
+ }
+
+ @Override
+ public Boolean update(WgzQuestionBank bo) {
+ WgzQuestionBank update = BeanUtil.toBean(bo, WgzQuestionBank.class);
+ validEntityBeforeSave(update);
+ return updateById(update);
+ }
+
+ /**
+ * 保存前的数据校验
+ *
+ * @param entity 实体类数据
+ */
+ private void validEntityBeforeSave(WgzQuestionBank entity){
+ //TODO 做一些数据校验,如唯一约束
+ }
+
+ @Override
+ public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) {
+ if(isValid){
+ //TODO 做一些业务上的校验,判断是否需要校验
+ }
+ return removeByIds(ids);
+ }
+
+ /**
+ * 务工者APP相关
+ * =================================================================================================================
+ * =================================================================================================================
+ * =================================================================================================================
+ */
+
+ @Override
+ public List appQueryList(int type, int num) {
+ LambdaQueryWrapper last = new LambdaQueryWrapper().
+ eq(WgzQuestionBank::getQuestionType, type).
+ last("order by rand() limit " + num);
+ List wgzQuestionBanks = baseMapper.selectList(last);
+ List wgzAppGetTestPaperThrees = new ArrayList<>();
+ for (WgzQuestionBank wai : wgzQuestionBanks) {
+ WgzAppGetTestPaperThree nei = new WgzAppGetTestPaperThree();
+ BeanUtils.copyProperties(wai, nei);
+ wgzAppGetTestPaperThrees.add(nei);
+ }
+ return wgzAppGetTestPaperThrees;
+ }
+
+ @Override
+ public WgzQuestionBank selectById(Long id) {
+ return baseMapper.selectById(id);
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionCategoryServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionCategoryServiceImpl.java
new file mode 100644
index 00000000..8a2a5ac0
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionCategoryServiceImpl.java
@@ -0,0 +1,88 @@
+package org.dromara.safety.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.safety.domain.WgzQuestionCategory;
+import org.dromara.safety.domain.bo.WgzQuestionCategoryBo;
+import org.dromara.safety.domain.vo.WgzQuestionCategoryVo;
+import org.dromara.safety.mapper.WgzQuestionCategoryMapper;
+import org.dromara.safety.service.IWgzQuestionCategoryService;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 题库_题库类别Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@Service
+public class WgzQuestionCategoryServiceImpl extends ServiceImpl implements IWgzQuestionCategoryService {
+
+ @Override
+ public WgzQuestionCategory queryById(Long id){
+ return getById(id);
+ }
+
+ @Override
+ public TableDataInfo queryPageList(WgzQuestionCategoryBo bo, PageQuery pageQuery) {
+ LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+ Page result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+ return TableDataInfo.build(result);
+ }
+
+ @Override
+ public List queryList(WgzQuestionCategoryBo bo) {
+ LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+ return baseMapper.selectVoList(lqw);
+ }
+
+ private LambdaQueryWrapper buildQueryWrapper(WgzQuestionCategoryBo bo) {
+ Map params = bo.getParams();
+ LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
+ lqw.orderByDesc(WgzQuestionCategory::getId);
+ lqw.like(StringUtils.isNotBlank(bo.getCategoryName()), WgzQuestionCategory::getCategoryName, bo.getCategoryName());
+ return lqw;
+ }
+ @Override
+ public Boolean insert(WgzQuestionCategory bo) {
+ WgzQuestionCategory add = BeanUtil.toBean(bo, WgzQuestionCategory.class);
+ validEntityBeforeSave(add);
+ return save(add);
+ }
+
+ @Override
+ public Boolean update(WgzQuestionCategory bo) {
+ WgzQuestionCategory update = BeanUtil.toBean(bo, WgzQuestionCategory.class);
+ validEntityBeforeSave(update);
+ return updateById(update);
+ }
+
+ /**
+ * 保存前的数据校验
+ *
+ * @param entity 实体类数据
+ */
+ private void validEntityBeforeSave(WgzQuestionCategory entity){
+ //TODO 做一些数据校验,如唯一约束
+ }
+
+ @Override
+ public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) {
+ if(isValid){
+ //TODO 做一些业务上的校验,判断是否需要校验
+ }
+ return removeByIds(ids);
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionSavePdfServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionSavePdfServiceImpl.java
new file mode 100644
index 00000000..1cd7f113
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionSavePdfServiceImpl.java
@@ -0,0 +1,120 @@
+package org.dromara.safety.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.safety.domain.WgzQuestionSavePdf;
+import org.dromara.safety.domain.bo.WgzQuestionSavePdfBo;
+import org.dromara.safety.domain.vo.WgzQuestionSavePdfVo;
+import org.dromara.safety.mapper.WgzQuestionSavePdfMapper;
+import org.dromara.safety.service.IWgzQuestionSavePdfService;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 用户试卷存储pdfService业务层处理
+ *
+ * @author ruoyi
+ * @date 2025-03-26
+ */
+@Service
+public class WgzQuestionSavePdfServiceImpl extends ServiceImpl implements IWgzQuestionSavePdfService {
+
+ @Override
+ public WgzQuestionSavePdf queryById(Long id){
+ return getById(id);
+ }
+
+ @Override
+ public TableDataInfo queryPageList(WgzQuestionSavePdfBo bo, PageQuery pageQuery) {
+ LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+ Page result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+ return TableDataInfo.build(result);
+ }
+
+
+ @Override
+ public List queryList(WgzQuestionSavePdfBo bo) {
+ LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+ return baseMapper.selectVoList(lqw);
+ }
+
+ private LambdaQueryWrapper buildQueryWrapper(WgzQuestionSavePdfBo bo) {
+ Map params = bo.getParams();
+ LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
+ lqw.orderByDesc(WgzQuestionSavePdf::getId);
+ lqw.orderByDesc(WgzQuestionSavePdf::getType);
+ lqw.eq(bo.getUserId() != null, WgzQuestionSavePdf::getUserId, bo.getUserId());
+ lqw.eq(StringUtils.isNotBlank(bo.getPath()), WgzQuestionSavePdf::getPath, bo.getPath());
+ lqw.eq(StringUtils.isNotBlank(bo.getPass()), WgzQuestionSavePdf::getPass, bo.getPass());
+ lqw.eq(bo.getTimeOut() != null, WgzQuestionSavePdf::getTimeOut, bo.getTimeOut());
+ lqw.eq(bo.getTakeTime() != null, WgzQuestionSavePdf::getTakeTime, bo.getTakeTime());
+ lqw.eq(bo.getSumScore() != null, WgzQuestionSavePdf::getSumScore, bo.getSumScore());
+ return lqw;
+ }
+
+ @Override
+ public Boolean insert(WgzQuestionSavePdf bo) {
+ WgzQuestionSavePdf add = BeanUtil.toBean(bo, WgzQuestionSavePdf.class);
+ validEntityBeforeSave(add);
+ return save(add);
+ }
+
+ @Override
+ public Boolean update(WgzQuestionSavePdf bo) {
+ WgzQuestionSavePdf update = BeanUtil.toBean(bo, WgzQuestionSavePdf.class);
+ validEntityBeforeSave(update);
+ return updateById(update);
+ }
+
+ /**
+ * 保存前的数据校验
+ *
+ * @param entity 实体类数据
+ */
+ private void validEntityBeforeSave(WgzQuestionSavePdf entity){
+ //TODO 做一些数据校验,如唯一约束
+ }
+
+ @Override
+ public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) {
+ if(isValid){
+ //TODO 做一些业务上的校验,判断是否需要校验
+ }
+ return removeByIds(ids);
+ }
+
+
+ @Override
+ public WgzQuestionSavePdf queryByUserId(Long userId) {
+ LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
+ lqw.eq(WgzQuestionSavePdf::getUserId, userId);
+ return baseMapper.selectOne(lqw);
+ }
+
+ @Override
+ public Boolean deleteByUserId(Long userId) {
+ //1、查询数据
+ WgzQuestionSavePdf wgzQuestionSavePdf = queryByUserId(userId);
+ //2、删除数据
+ LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
+ lqw.eq(WgzQuestionSavePdf::getUserId, userId);
+ int delete = baseMapper.delete(lqw);
+ //3、删除相对路径的pdf文件
+ if(delete > 0){
+ String path = wgzQuestionSavePdf.getPath();
+ StrUtil.removePrefix(path, "upload/");
+ StrUtil.removePrefix(path, "upload\\");
+ }
+ return true;
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionSaveServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionSaveServiceImpl.java
new file mode 100644
index 00000000..8e69935e
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionSaveServiceImpl.java
@@ -0,0 +1,551 @@
+package org.dromara.safety.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.itextpdf.io.font.PdfEncodings;
+import com.itextpdf.kernel.colors.ColorConstants;
+import com.itextpdf.kernel.font.PdfFont;
+import com.itextpdf.kernel.font.PdfFontFactory;
+import com.itextpdf.kernel.geom.PageSize;
+import com.itextpdf.kernel.pdf.PdfDocument;
+import com.itextpdf.kernel.pdf.PdfWriter;
+import com.itextpdf.layout.Document;
+import com.itextpdf.layout.element.Paragraph;
+import com.itextpdf.layout.properties.TextAlignment;
+import jakarta.annotation.Resource;
+import org.dromara.common.core.utils.DateUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.safety.bo.req.WgzAppSubmitATestPaperReq;
+import org.dromara.safety.bo.res.WgzAppSubmitATestPaperRes;
+import org.dromara.safety.bo.res.WgzAppUserScoreQuery;
+import org.dromara.safety.bo.rests.*;
+import org.dromara.safety.domain.WgzQuestionBank;
+import org.dromara.safety.domain.WgzQuestionSave;
+import org.dromara.safety.domain.WgzQuestionSavePdf;
+import org.dromara.safety.domain.WgzQuestionsConfiguration;
+import org.dromara.safety.domain.bo.WgzQuestionSaveBo;
+import org.dromara.safety.domain.vo.WgzQuestionSaveVo;
+import org.dromara.safety.mapper.WgzQuestionSaveMapper;
+import org.dromara.safety.service.IWgzQuestionBankService;
+import org.dromara.safety.service.IWgzQuestionSavePdfService;
+import org.dromara.safety.service.IWgzQuestionSaveService;
+import org.dromara.safety.service.IWgzQuestionsConfigurationService;
+import org.dromara.system.domain.vo.SysOssVo;
+import org.dromara.system.service.ISysOssService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * 用户试卷存储Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@Service
+public class WgzQuestionSaveServiceImpl extends ServiceImpl implements IWgzQuestionSaveService {
+ @Override
+ public WgzQuestionSave queryById(Long id) {
+ return null;
+ }
+
+ @Override
+ public TableDataInfo queryPageList(WgzQuestionSaveBo bo, PageQuery pageQuery) {
+ return null;
+ }
+
+ @Override
+ public List queryList(WgzQuestionSaveBo bo) {
+ return List.of();
+ }
+
+ @Override
+ public Boolean insert(WgzQuestionSave bo) {
+ return null;
+ }
+
+ @Override
+ public Boolean update(WgzQuestionSave bo) {
+ return null;
+ }
+
+ @Override
+ public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) {
+ return null;
+ }
+
+ @Override
+ public WgzAppSubmitATestPaperRes userSubmitATestPaper(WgzAppSubmitATestPaperReq req) {
+ return null;
+ }
+
+ @Override
+ public WgzAppUserScoreQuery userScoreQuery(long userId) {
+ return null;
+ }
+
+//
+// @Autowired
+// private IWgzQuestionsConfigurationService iWgzQuestionsConfigurationService;
+//
+// @Autowired
+// private IWgzQuestionBankService iWgzQuestionBankService;
+//
+// @Autowired
+// private IWgzQuestionSavePdfService wgzQuestionSavePdfService;
+//
+// @Resource
+// private ISysOssService ossService;
+//
+// @Override
+// public WgzQuestionSave queryById(Long id) {
+// return getById(id);
+// }
+//
+// @Override
+// public TableDataInfo queryPageList(WgzQuestionSaveBo bo, PageQuery pageQuery) {
+// LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+// Page result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+// return TableDataInfo.build(result);
+// }
+//
+// @Override
+// public List queryList(WgzQuestionSaveBo bo) {
+// LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+// return baseMapper.selectVoList(lqw);
+// }
+//
+// private LambdaQueryWrapper buildQueryWrapper(WgzQuestionSaveBo bo) {
+// Map params = bo.getParams();
+// LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
+// lqw.orderByDesc(WgzQuestionSave::getId);
+// lqw.eq(bo.getUserId() != null, WgzQuestionSave::getUserId, bo.getUserId());
+// lqw.eq(bo.getBankId() != null, WgzQuestionSave::getBankId, bo.getBankId());
+// lqw.eq(StringUtils.isNotBlank(bo.getAnswer()), WgzQuestionSave::getAnswer, bo.getAnswer());
+// lqw.eq(StringUtils.isNotBlank(bo.getCorrect()), WgzQuestionSave::getCorrect, bo.getCorrect());
+// lqw.eq(bo.getScore() != null, WgzQuestionSave::getScore, bo.getScore());
+// lqw.eq(StringUtils.isNotBlank(bo.getSign()), WgzQuestionSave::getSign, bo.getSign());
+// lqw.eq(bo.getTakeTime() != null, WgzQuestionSave::getTakeTime, bo.getTakeTime());
+// lqw.eq(bo.getTimeOut() != null, WgzQuestionSave::getTimeOut, bo.getTimeOut());
+// lqw.eq(StringUtils.isNotBlank(bo.getPass()), WgzQuestionSave::getPass, bo.getPass());
+// return lqw;
+// }
+//
+// @Override
+// public Boolean insert(WgzQuestionSave bo) {
+// WgzQuestionSave add = BeanUtil.toBean(bo, WgzQuestionSave.class);
+// validEntityBeforeSave(add);
+// return save(add);
+// }
+//
+// @Override
+// public Boolean update(WgzQuestionSave bo) {
+// WgzQuestionSave update = BeanUtil.toBean(bo, WgzQuestionSave.class);
+// validEntityBeforeSave(update);
+// return updateById(update);
+// }
+//
+// /**
+// * 保存前的数据校验
+// *
+// * @param entity 实体类数据
+// */
+// private void validEntityBeforeSave(WgzQuestionSave entity) {
+// //TODO 做一些数据校验,如唯一约束
+// }
+//
+// @Override
+// public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) {
+// if (isValid) {
+// //TODO 做一些业务上的校验,判断是否需要校验
+// }
+// return removeByIds(ids);
+// }
+//
+// /**
+// * APP相关
+// * =================================================================================================================
+// * =================================================================================================================
+// * =================================================================================================================
+// */
+//
+// @Override
+// @Transactional(rollbackFor = Exception.class)
+// public WgzAppSubmitATestPaperRes userSubmitATestPaper(WgzAppSubmitATestPaperReq req) {
+// String coryPass = "";
+// int coryTimeOut = 0;
+// Long coryTakeTime = 0L;
+// Double corySumScore = 0.00;
+// /**
+// * 第一部分:计算并保存最高分试卷
+// */
+// // 初始化第一次分数和当前考试的分数
+// double scoreOne = 0.00;
+// double scoreTwo = 0.00;
+// //1、获取上次考试的分数
+// Map spMap = baseMapper.getSumScoreAndPassAndSign(req.getUserId());
+// if (spMap != null) {
+// String pass = (String) spMap.get("pass");
+// if (pass != null && !pass.isEmpty()) {
+// String[] split = pass.split(",");
+// double float1 = Double.parseDouble(split[1]);
+// double sumScore = (double) spMap.get("sumScore");
+// scoreOne = 100.00 / float1 * sumScore;
+// }
+// }
+// //2、获取配置信息
+// WgzQuestionsConfiguration configuration = iWgzQuestionsConfigurationService.appQueryLimitOne();
+// //3、计算这次用户提交的试卷信息所得到的分数
+// List bqs = new ArrayList<>();
+// Double fenshu = 0.0;
+// Integer number = 0;
+// Integer index = 0;
+// List list = req.getList();
+// for (WgzAppSubmitATestPaperTwo data : list) {
+// String correct = "";
+// String pass = "";
+// // 获取题库的正确答案,然后和用户的答案作对比
+// WgzQuestionBank bqb = iWgzQuestionBankService.selectById(data.getBankId());
+// if (bqb == null) {
+// throw new RuntimeException("您的试卷被外星人卷走了!");
+// } else {
+// if (StringUtils.isEmpty(data.getAnswer())) {
+// throw new RuntimeException("您还有题未答完!");
+// }
+// if (bqb.getCorrectAnswer().toLowerCase().contains(data.getAnswer().toLowerCase())) {
+// correct = "1";
+// fenshu = fenshu + data.getScore();
+// number = number + 1;
+// } else {
+// correct = "2";
+// }
+// }
+// // 记录这次的及格线和总分
+// pass = configuration.getPassingScore().toString() + "," + configuration.getFullMark().toString();
+// WgzQuestionSave bqsTwo = new WgzQuestionSave();
+// bqsTwo.setUserId(req.getUserId());
+// bqsTwo.setBankId(data.getBankId());
+// bqsTwo.setAnswer(data.getAnswer());
+// bqsTwo.setCorrect(correct);
+// bqsTwo.setScore(data.getScore());
+// //这几条数据只在每张试卷的第一条数据中存储(重复的没必要每条都存储)
+// if (index == 0) {
+// bqsTwo.setTakeTime(req.getTakeTime());
+// bqsTwo.setTimeOut(configuration.getAnswerTime());
+// bqsTwo.setPass(pass);
+//
+// coryTakeTime = req.getTakeTime();
+// coryTimeOut = configuration.getAnswerTime();
+// coryPass = pass;
+// }
+// bqs.add(bqsTwo);
+// index = index + 1;
+// }
+// Double fullMark = configuration.getFullMark();
+// scoreTwo = 100.00 / fullMark * fenshu;
+// WgzAppSubmitATestPaperRes res = new WgzAppSubmitATestPaperRes();
+// res.setAnswerTime(configuration.getAnswerTime());
+// res.setTakeTime(req.getTakeTime());
+// res.setFullMark(fullMark);
+// res.setPassingScore(configuration.getPassingScore());
+// res.setScore(fenshu);
+// res.setNumber(number);
+// //4、两次卷子的分数对比,第一次的分数比第二次大那么第二次只返回结果;第二次的分数比第一次大那么删除第一次的数据再重新插入
+// if (scoreOne > scoreTwo) {
+// return res;
+// } else {
+// corySumScore = scoreTwo;
+// if (scoreOne == 0) {
+// // 插入新数据
+// super.saveBatch(bqs);
+// }
+// // 先查询当前用户是否有答题,有就把之前的删除(真删)
+// int deleteResult = baseMapper.delete(new LambdaQueryWrapper().eq(WgzQuestionSave::getUserId, req.getUserId()));
+// if (deleteResult > 0) {
+// // 删除pdf
+// wgzQuestionSavePdfService.deleteByUserId(req.getUserId());
+// // 插入新数据
+// super.saveBatch(bqs);
+// }
+// }
+// /**
+// * 第二部分:分离出试卷信息
+// */
+// ExaminationPaper examinationPaper = separateTestInformation(req.getUserId(), configuration);
+// /**
+// * 第三部分:生成pdf并存储到数据库中
+// */
+// try {
+// String xdPath = generateExamPaper(examinationPaper);
+// res.setPdfStr(xdPath);
+// WgzQuestionSavePdf wgzQuestionSavePdf = new WgzQuestionSavePdf()
+// .setType("1")
+// .setUserId(req.getUserId())
+// .setPath(xdPath)
+// .setPass(coryPass)
+// .setTimeOut(coryTimeOut)
+// .setTakeTime(coryTakeTime)
+// .setSumScore(corySumScore);
+// wgzQuestionSavePdfService.insert(wgzQuestionSavePdf);
+// } catch (Exception e1) {
+// throw new RuntimeException("生成PDF试卷出现了意外,请重新提交!");
+// }
+// return res;
+// }
+//
+// // 分离试卷信息
+// private ExaminationPaper separateTestInformation(Long userId, WgzQuestionsConfiguration configurationEntity) {
+// //1、组装数据
+// List we = baseMapper.pdfSc(userId);
+// if (!we.isEmpty()) {
+// String sumScore = baseMapper.pdfSumScore(userId);
+// Integer s = configurationEntity.getSingleChoice();
+// Integer m = configurationEntity.getMultipleChoice();
+// Integer e = configurationEntity.getEstimate();
+// ExaminationPaper rs = new ExaminationPaper()
+// .setPass(we.get(0).getPass())
+// .setSumScore(sumScore)
+// .setSign(we.get(0).getSign())
+// .setUserId(userId.toString())
+// .setUserName(we.get(0).getUserName());
+// ExaminationPaperOne one = new ExaminationPaperOne();
+// ExaminationPaperOne two = new ExaminationPaperOne();
+// ExaminationPaperOne three = new ExaminationPaperOne();
+// one.setTopic("一、单选题,共" + s + "道题,每小题" + configurationEntity.getSingleScore() + "分,共计" + configurationEntity.getSingleScore() * s + "分");
+// two.setTopic("二、多选题,共" + m + "道题,每小题" + configurationEntity.getMultipleScore() + "分,共计" + configurationEntity.getMultipleScore() * m + "分");
+// three.setTopic("三、判断题,共" + e + "道题,每小题" + configurationEntity.getEstimateScore() + "分,共计" + configurationEntity.getEstimateScore() * e + "分");
+// List sEntity = new ArrayList<>();
+// List mEntity = new ArrayList<>();
+// List eEntity = new ArrayList<>();
+// for (PdfEntity data : we) {
+// ExaminationPaperTwo sy = new ExaminationPaperTwo();
+// sy.setQuestionText(data.getQuestionText());
+// sy.setOptions(data.getOptions());
+// sy.setAnswer(data.getAnswer());
+// sy.setCorrectAnswer(data.getCorrectAnswer());
+// sy.setCorrect(data.getCorrect());
+// sy.setScore(data.getScore());
+// if (data.getQuestionType().equals("1")) {
+// sEntity.add(sy);
+// }
+// if (data.getQuestionType().equals("2")) {
+// mEntity.add(sy);
+// }
+// if (data.getQuestionType().equals("3")) {
+// eEntity.add(sy);
+// }
+// }
+// one.setList(sEntity);
+// two.setList(mEntity);
+// three.setList(eEntity);
+// rs.setSingle(one);
+// rs.setMultiple(two);
+// rs.setEstimate(three);
+// return rs;
+// }
+// throw new RuntimeException("未获取到试卷信息!");
+// }
+//
+// // pdf生成
+// private String generateExamPaper(ExaminationPaper rs) throws IOException {
+// String fileName = DateUtils.datePath() + File.separator + rs.getUserId() + IdUtil.fastUUID() + ".pdf";
+// File desc = new File("file" + File.separator + "exam" + File.separator + fileName);
+// // 创建PDF文档
+// PdfWriter writer = new PdfWriter(desc);
+// PdfDocument pdfDoc = new PdfDocument(writer);
+// Document document = new Document(pdfDoc, PageSize.A4);
+//
+// // 加载字体(确保 simhei.ttf 可用)
+// String fontPath = "fonts/simhei.ttf";
+// PdfFont simhei = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H);
+// PdfFont simheiBold = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H);
+//
+// // 标题
+// document.setFont(simheiBold).setFontSize(36);
+//
+// document.add(new Paragraph("《灵活用工岗前培训》")
+// .setTextAlignment(TextAlignment.CENTER));
+//
+// document.add(new Paragraph("\n"));
+//
+// // 考生信息
+// document.setFont(simhei).setFontSize(16);
+// document.add(new Paragraph("姓名: " + rs.getUserName()));
+// document.add(new Paragraph("及格线/总分: " + rs.getPass()));
+// document.add(new Paragraph("实际得分: " + rs.getSumScore()));
+// document.add(new Paragraph("\n"));
+//
+// // 处理单选、多选、判断题
+// for (int i = 1; i <= 3; i++) {
+// ExaminationPaperOne ep;
+// if (i == 1) {
+// ep = rs.getSingle();
+// } else if (i == 2) {
+// ep = rs.getMultiple();
+// } else {
+// ep = rs.getEstimate();
+// }
+//
+// document.setFont(simhei).setFontSize(20);
+// document.add(new Paragraph(ep.getTopic()));
+//
+// document.setFont(simhei).setFontSize(12);
+// List questionList = ep.getList();
+// for (int qIndex = 0; qIndex < questionList.size(); qIndex++) {
+// ExaminationPaperTwo data = questionList.get(qIndex);
+// String questionText = (i == 3) ?
+// (qIndex + 1) + "、" + data.getQuestionText() + "( " + data.getAnswer() + " )"
+// : (qIndex + 1) + "、" + replaceBrackets(data.getQuestionText(), data.getAnswer());
+//
+// document.add(new Paragraph(questionText));
+//
+// // 选项
+// String[] options = data.getOptions().split("@");
+// for (String option : options) {
+// document.add(new Paragraph(" " + option));
+// }
+//
+// // 标记错误答案
+// if ("2".equals(data.getCorrect())) {
+// document.add(new Paragraph("正确答案为:" + data.getCorrectAnswer())
+// .setFontColor(ColorConstants.RED));
+// }
+//
+// document.add(new Paragraph("\n"));
+// }
+// }
+//
+//// // 签名部分
+//// document.add(new Paragraph("\n\n\n"));
+//// document.setFont(simheiBold).setFontSize(16);
+//// document.add(new Paragraph("签字:").setTextAlignment(TextAlignment.RIGHT));
+//// // 嵌入签名图片
+//// if (rs.getSign() != null && !rs.getSign().isEmpty()) {
+//// String signPath = Paths.get(System.getProperty("user.dir"), rs.getSign()).toString();
+//// File signFile = new File(signPath);
+//// if (signFile.exists()) {
+//// ImageData imageData = ImageDataFactory.create(signPath);
+//// Image image = new Image(imageData).scaleToFit(100, 50);
+//// document.add(image.setRotationAngle(Math.PI / 2));
+//// }
+//// }
+//
+// document.close();
+// SysOssVo upload = ossService.upload(desc);
+// // 刪除本地文件
+// try {
+// boolean delete = desc.delete();
+// if (!delete) {
+// log.error("删除本地文件失败");
+// }
+// } catch (Exception e) {
+// log.error("删除本地文件失败", e);
+// }
+// return upload.getOssId().toString();
+// }
+//
+// // 括号填充
+// private String replaceBrackets(String text, String replacement) {
+// Pattern pattern = Pattern.compile("\\s*(\\s*)\\s*");
+// Matcher matcher = pattern.matcher(text);
+// return matcher.replaceAll("( " + replacement + " )");
+// }
+//
+// @Override
+// public WgzAppUserScoreQuery userScoreQuery(long userId) {
+// WgzAppUserScoreQuery res = new WgzAppUserScoreQuery();
+// //1、查询及格分和满分,为空表示暂无记录
+// LambdaQueryWrapper wra = new LambdaQueryWrapper()
+// .eq(WgzQuestionSave::getUserId, userId);
+// List savaList = baseMapper.selectList(wra);
+// if (savaList.isEmpty()) {
+// res.setIsPass("3");
+// return res;
+// }
+// //2、查询用户答对的分数
+// float sumScore = baseMapper.getSumScore(userId);
+// //3、计算上次分数是否及格
+// String pass = savaList.get(0).getPass();
+// if (pass != null && !pass.isEmpty()) {
+// String[] split = pass.split(",");
+// float fullMark = Float.parseFloat(split[1]);
+// float passingGrade = Float.parseFloat(split[0]);
+//// // 100分 / 满分 * 答对的分数 = 当前分数
+//// double score = 100.00 / fullMark * sumScore;
+//// // 使用 DecimalFormat 保证分数最多1位小数
+//// DecimalFormat df = new DecimalFormat("#.#");
+//// score = Double.parseDouble(df.format(score));
+// // 当前分数 >= 及格线 = 及格 否则 不及格
+// if (sumScore >= passingGrade) {
+// res.setIsPass("1");
+// } else {
+// res.setIsPass("2");
+// }
+// res.setFullMark(fullMark);
+// res.setPassingScore(passingGrade);
+// }
+// res.setCurrentMinute(sumScore);
+// //4、获取pdf试卷信息
+// WgzQuestionSavePdf wgzQuestionSavePdf = wgzQuestionSavePdfService.queryByUserId(userId);
+// if (wgzQuestionSavePdf != null) {
+// res.setPdfStr(wgzQuestionSavePdf.getPath());
+// }
+// return res;
+// }
+//
+//// @Override
+//// public BgtQuestionResult getResult(Long userId) {
+////
+//// BgtQuestionResult bgtQuestionResult = new BgtQuestionResult();
+////
+//// WgzUser byUserId = wgzUserService.findByUserId(userId);
+//// if(byUserId == null){
+//// throw new BaseException("用户不存在");
+//// }
+//// bgtQuestionResult.setAvatarName(byUserId.getAvatarName());
+////
+//// LambdaQueryWrapper wra = new LambdaQueryWrapper()
+//// .eq(WgzQuestionSave::getUserId, userId);
+//// List savaList = baseMapper.selectList(wra);
+////
+//// double score= 0d;
+//// int successNum = 0;
+//// int errorNum= 0;
+//// long time= 0L;
+////
+//// for (WgzQuestionSave wgzQuestionSave : savaList){
+//// if(wgzQuestionSave.getCorrect().equals("1")){
+//// score += wgzQuestionSave.getScore();
+//// successNum++;
+//// }else{
+//// errorNum++;
+//// }
+//// if(wgzQuestionSave.getTakeTime() != null){
+//// time += wgzQuestionSave.getTakeTime();
+//// }
+//// }
+////
+//// bgtQuestionResult.setScore(score);
+//// bgtQuestionResult.setSuccessNum(successNum);
+//// bgtQuestionResult.setErrorNum(errorNum);
+//// bgtQuestionResult.setTime(time);
+//// return bgtQuestionResult;
+//// }
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionsConfigurationServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionsConfigurationServiceImpl.java
new file mode 100644
index 00000000..c7a9dd68
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/WgzQuestionsConfigurationServiceImpl.java
@@ -0,0 +1,112 @@
+package org.dromara.safety.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.safety.domain.WgzQuestionsConfiguration;
+import org.dromara.safety.domain.bo.WgzQuestionsConfigurationBo;
+import org.dromara.safety.domain.vo.WgzQuestionsConfigurationVo;
+import org.dromara.safety.mapper.WgzQuestionsConfigurationMapper;
+import org.dromara.safety.service.IWgzQuestionsConfigurationService;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 题库配置Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2025-02-17
+ */
+@Service
+public class WgzQuestionsConfigurationServiceImpl extends ServiceImpl implements IWgzQuestionsConfigurationService {
+
+ @Override
+ public WgzQuestionsConfiguration queryById(Long id){
+ return getById(id);
+ }
+
+ @Override
+ public TableDataInfo queryPageList(WgzQuestionsConfigurationBo bo, PageQuery pageQuery) {
+ LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+ Page result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+ return TableDataInfo.build(result);
+ }
+
+ @Override
+ public List queryList(WgzQuestionsConfigurationBo bo) {
+ LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+ return baseMapper.selectVoList(lqw);
+ }
+
+ private LambdaQueryWrapper buildQueryWrapper(WgzQuestionsConfigurationBo bo) {
+ Map params = bo.getParams();
+ LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
+ lqw.orderByDesc(WgzQuestionsConfiguration::getId);
+ lqw.eq(bo.getSingleChoice() != null, WgzQuestionsConfiguration::getSingleChoice, bo.getSingleChoice());
+ lqw.eq(bo.getSingleScore() != null, WgzQuestionsConfiguration::getSingleScore, bo.getSingleScore());
+ lqw.eq(bo.getMultipleChoice() != null, WgzQuestionsConfiguration::getMultipleChoice, bo.getMultipleChoice());
+ lqw.eq(bo.getMultipleScore() != null, WgzQuestionsConfiguration::getMultipleScore, bo.getMultipleScore());
+ lqw.eq(bo.getEstimate() != null, WgzQuestionsConfiguration::getEstimate, bo.getEstimate());
+ lqw.eq(bo.getEstimateScore() != null, WgzQuestionsConfiguration::getEstimateScore, bo.getEstimateScore());
+ lqw.eq(bo.getFullMark() != null, WgzQuestionsConfiguration::getFullMark, bo.getFullMark());
+ lqw.eq(bo.getPassingScore() != null, WgzQuestionsConfiguration::getPassingScore, bo.getPassingScore());
+ lqw.eq(bo.getAnswerTime() != null, WgzQuestionsConfiguration::getAnswerTime, bo.getAnswerTime());
+ return lqw;
+ }
+
+ @Override
+ public Boolean insert(WgzQuestionsConfiguration bo) {
+ WgzQuestionsConfiguration add = BeanUtil.toBean(bo, WgzQuestionsConfiguration.class);
+ validEntityBeforeSave(add);
+ return save(add);
+ }
+
+ @Override
+ public Boolean update(WgzQuestionsConfiguration bo) {
+ WgzQuestionsConfiguration update = BeanUtil.toBean(bo, WgzQuestionsConfiguration.class);
+ validEntityBeforeSave(update);
+ return updateById(update);
+ }
+
+ /**
+ * 保存前的数据校验
+ *
+ * @param entity 实体类数据
+ */
+ private void validEntityBeforeSave(WgzQuestionsConfiguration entity){
+ //TODO 做一些数据校验,如唯一约束
+ }
+
+ @Override
+ public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) {
+ if(isValid){
+ //TODO 做一些业务上的校验,判断是否需要校验
+ }
+ return removeByIds(ids);
+ }
+
+ /**
+ * 务工者APP相关
+ * =================================================================================================================
+ * =================================================================================================================
+ * =================================================================================================================
+ */
+
+ @Override
+ public WgzQuestionsConfiguration appQueryLimitOne() {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.last("LIMIT 1");
+ WgzQuestionsConfiguration wgzQuestionsConfiguration = baseMapper.selectOne(queryWrapper);
+ if(wgzQuestionsConfiguration==null){
+ throw new RuntimeException("题库配置为空");
+ }
+ return wgzQuestionsConfiguration;
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionBankMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionBankMapper.xml
new file mode 100644
index 00000000..e420165c
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionBankMapper.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionCategoryMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionCategoryMapper.xml
new file mode 100644
index 00000000..704f61d1
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionCategoryMapper.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionSaveMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionSaveMapper.xml
new file mode 100644
index 00000000..36f44cfc
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionSaveMapper.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionSavePdfMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionSavePdfMapper.xml
new file mode 100644
index 00000000..6f1d584b
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionSavePdfMapper.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionsConfigurationMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionsConfigurationMapper.xml
new file mode 100644
index 00000000..3acbc137
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/WgzQuestionsConfigurationMapper.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+