变更jar,增加考试卷

This commit is contained in:
2025-09-04 10:56:54 +08:00
parent d19cda78b3
commit 17d4041ef3
62 changed files with 3913 additions and 225 deletions

Binary file not shown.

View File

@ -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

View File

@ -17,6 +17,16 @@
<dependencies>
<dependency>
<groupId>technology.tabula</groupId>
<artifactId>tabula</artifactId>
<version>1.0.4</version>
</dependency>
<!-- JSON解析FastJSON -->
<dependency>
<groupId>com.alibaba</groupId>
@ -73,18 +83,24 @@
</dependency>
<!-- 在pdf上生成二维码 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
<version>7.2.5</version>
</dependency>
<!-- 支持中文字体 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!-- iText -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.itextpdf</groupId>-->
<!-- <artifactId>itext-asian</artifactId>-->
<!-- <version>5.2.0</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; iText &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.itextpdf</groupId>-->
<!-- <artifactId>itextpdf</artifactId>-->
<!-- <version>5.5.13.3</version>-->
<!-- </dependency>-->
<!-- ZXing -->
<dependency>
<groupId>com.google.zxing</groupId>
@ -221,6 +237,12 @@
<version>5.3.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@ -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;
/**
* 查询成本-投标列表
*/

View File

@ -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,122 +45,92 @@ 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;
// }
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);
PdfPage page = pdfDoc.getPage(pageNum);
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每一页的指定位置添加二维码并返回数据流根据页面方向自动调整位置
*
* @param srcPdf 原PDF文件路径可以是本地路径或网络地址
* @param qrCodeBytes 二维码图片字节数组
* @return 插入二维码后的PDF文件流
*/
public static ByteArrayOutputStream addQRCodeToPDFOnAllPages(String srcPdf, byte[] qrCodeBytes, boolean isChangeFile)
throws IOException, DocumentException {
throws IOException {
PdfReader reader = null;
PdfStamper stamper = null;
ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
try {
// 判断是网络地址还是本地文件路径
PdfReader reader;
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秒
// 网络地址 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 != java.net.HttpURLConnection.HTTP_OK) {
throw new IOException("无法从URL获取PDF文件HTTP响应码: " + responseCode + ", URL: " + srcPdf);
if (responseCode != HttpURLConnection.HTTP_OK) {
throw new IOException("无法获取 PDF 文件HTTP响应码: " + responseCode);
}
java.io.InputStream inputStream = connection.getInputStream();
InputStream inputStream = connection.getInputStream();
reader = new PdfReader(inputStream);
} else {
// 本地文件路径:检查文件是否存在
// 本地文件 PDF
File srcFile = new File(srcPdf);
if (!srcFile.exists()) {
throw new IOException("源PDF文件不存在: " + srcPdf);
@ -179,89 +138,71 @@ public class PdfBoxQrCodeGenerator {
reader = new PdfReader(srcPdf);
}
stamper = new PdfStamper(reader, pdfOut);
ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(pdfOut);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
int numberOfPages = reader.getNumberOfPages();
int numberOfPages = pdfDoc.getNumberOfPages();
// 遍历每一页并添加二维码
for (int pageNum = 1; pageNum <= numberOfPages; pageNum++) {
// 获取页面尺寸
com.itextpdf.text.Rectangle pageSize = reader.getPageSize(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);
qrX = pageWidth - 143;
qrY = pageHeight - 213;
newWidth = 67;
newHeight = 80;
} else {
// 判断页面方向:宽度大于高度为横版,否则为竖版
if (pageWidth > pageHeight) {
// 横版页面:二维码放在右下角
qrX = (pageWidth - 90); // 距离右边90点
qrY = 24; // 距离底部24点
// 横版
qrX = pageWidth - 90;
qrY = 24;
newWidth = 67;
newHeight = 79;
} else {
// 竖版页面:二维码放在左上角
qrX = 226; // 距离左边226点
qrY = pageHeight - 185; // 距离顶部185点
// 竖版
qrX = 226;
qrY = pageHeight - 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(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("图纸管理 => 审核结束,向文件添加二维码失败, 错误");
// }
// }
//}

View File

@ -286,25 +286,49 @@ public class DesVolumeCatalogController extends BaseController {
}
private static LocalDate getLocalDateValue(Cell cell) {
if (cell != null) {
if (cell == null) {
return null;
}
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) {
// 处理字符串格式的日期
String text = cell.getStringCellValue().trim();
if (text.isEmpty()) {
return null;
}
// 尝试解析不同格式
try {
return LocalDate.parse(cell.getStringCellValue());
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) {
// 日期格式不正确时返回null
return null;
}
}
}
return null;
}
}

View File

@ -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<DesDrawingMapper, DesDraw
String contentType = fileNameMap.getContentTypeFor(originalName);
SysOssVo upload = ossService.upload(new ByteArrayInputStream(baos.toByteArray()), originalName, contentType, baos.size());
drawing.setFileUrl(upload.getOssId());
} catch (IOException | DocumentException e) {
} catch (IOException e) {
log.error("图纸管理 => 审核结束,向文件添加二维码失败", e);
return CompletableFuture.completedFuture(false);
}
@ -452,7 +451,7 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
String contentType = fileNameMap.getContentTypeFor(originalName);
SysOssVo upload = ossService.upload(new ByteArrayInputStream(baos.toByteArray()), originalName, contentType, baos.size());
byId.setFileId(upload.getOssId());
} catch (IOException | DocumentException e) {
} catch (IOException e) {
log.error("图纸管理 => 审核结束,向文件添加二维码失败", e);
return CompletableFuture.completedFuture(false);
}

View File

@ -110,7 +110,7 @@ public class BusListOfFormalitiesServiceImpl extends ServiceImpl<BusListOfFormal
private LambdaQueryWrapper<BusListOfFormalities> buildQueryWrapper(BusListOfFormalitiesBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BusListOfFormalities> 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;

View File

@ -45,11 +45,13 @@ public class BusEnterRoadServiceImpl extends ServiceImpl<BusEnterRoadMapper, Bus
* @return 进场道路信息
*/
@Override
public BusEnterRoadVo queryById(Long id){
public BusEnterRoadVo queryById(Long id) {
BusEnterRoadVo busEnterRoadVo = baseMapper.selectVoById(id);
BusLandBlockVo busLandBlockVo = iBusLandBlockService.queryById(busEnterRoadVo.getLandBlockId());
if (busLandBlockVo != null) {
busEnterRoadVo.setLandName(busLandBlockVo.getLandName());
busEnterRoadVo.setUnit(busLandBlockVo.getUnit());
}
return baseMapper.selectVoById(id);
}
@ -67,11 +69,11 @@ public class BusEnterRoadServiceImpl extends ServiceImpl<BusEnterRoadMapper, Bus
List<BusEnterRoadVo> records = result.getRecords();
List<Long> ids = records.stream().map(BusEnterRoadVo::getLandBlockId).toList();
if(CollectionUtil.isNotEmpty(ids)){
List<BusLandBlockVo> list = iBusLandBlockService.queryListByIds(ids,true);
if (CollectionUtil.isNotEmpty(ids)) {
List<BusLandBlockVo> 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<BusEnterRoadMapper, Bus
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(BusEnterRoad entity){
private void validEntityBeforeSave(BusEnterRoad entity) {
//TODO 做一些数据校验,如唯一约束
}
@ -154,7 +156,7 @@ public class BusEnterRoadServiceImpl extends ServiceImpl<BusEnterRoadMapper, Bus
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;

View File

@ -448,6 +448,7 @@ public class MatMaterialIssueServiceImpl extends ServiceImpl<MatMaterialIssueMap
lqw.like(StringUtils.isNotBlank(formCode), MatMaterialIssue::getFormCode, formCode);
lqw.eq(ObjectUtils.isNotEmpty(projectId), MatMaterialIssue::getProjectId, projectId);
lqw.eq(StringUtils.isNotBlank(materialSource), MatMaterialIssue::getMaterialSource, materialSource);
lqw.orderByDesc(MatMaterialIssue::getId);
return lqw;
}
@ -522,7 +523,7 @@ public class MatMaterialIssueServiceImpl extends ServiceImpl<MatMaterialIssueMap
}
if (StringUtils.isNotBlank(certCountFileId)) {
int size = Arrays.stream(certCountFileId.split(",")).map(Long::parseLong).toList().size();
materialIssue.setLicenseCount(size);
materialIssue.setCertCount(size);
}
}

View File

@ -0,0 +1,31 @@
package org.dromara.safety.bo.req;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.dromara.safety.bo.rests.WgzAppSubmitATestPaperTwo;
import java.io.Serializable;
import java.util.List;
@Data
@NoArgsConstructor
@Accessors(chain = true)
public class WgzAppSubmitATestPaperReq implements Serializable {
/**
* 务工者唯一标识
*/
private Long userId;
/**
* 用时时间(时间戳/秒)
*/
private Long takeTime;
/**
* list
*/
private List<WgzAppSubmitATestPaperTwo> list;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<ExaminationPaperTwo> list;
}

View File

@ -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;
}

View File

@ -0,0 +1,6 @@
package org.dromara.safety.bo.rests;
import java.io.Serializable;
public class GetsTheMembersUnderTheCurrentProject implements Serializable {
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<WgzAppGetTestPaperThree> list;
}

View File

@ -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;
}

View File

@ -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<WgzQuestionBankVo> list(@Validated WgzQuestionBankBo bo, PageQuery pageQuery) {
return iWgzQuestionBankService.queryPageList(bo, pageQuery);
}
/**
* 获取题库详细信息
*/
@SaCheckPermission("safety:wgzQuestionBank:query")
@GetMapping("/{id}")
public R<WgzQuestionBank> 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<Void> 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<Void> 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<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iWgzQuestionBankService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
}
}

View File

@ -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<WgzQuestionCategoryVo> list(@Validated WgzQuestionCategoryBo bo, PageQuery pageQuery) {
return iWgzQuestionCategoryService.queryPageList(bo, pageQuery);
}
/**
* 获取题库_题库类别详细信息
*/
@SaCheckPermission("safety:wzgQuestionCategory:query")
@GetMapping("/{id}")
public R<WgzQuestionCategory> 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<Void> 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<Void> 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<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iWgzQuestionCategoryService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
}
}

View File

@ -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<WgzQuestionSaveVo> list(@Validated WgzQuestionSaveBo bo, PageQuery pageQuery) {
return iWgzQuestionSaveService.queryPageList(bo,pageQuery);
}
/**
* 获取用户试卷存储详细信息
*/
@SaCheckPermission("safety:wgzQuestionSave:query")
@GetMapping("/{id}")
public R<WgzQuestionSave> 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<Void> 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<Void> 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<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iWgzQuestionSaveService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
}
}

View File

@ -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<WgzQuestionsConfigurationVo> list(@Validated WgzQuestionsConfigurationBo bo, PageQuery pageQuery) {
return iWgzQuestionsConfigurationService.queryPageList(bo, pageQuery);
}
/**
* 获取题库配置详细信息
*/
@SaCheckPermission("safety:wzgQuestionsConfiguration:query")
@GetMapping("/{id}")
public R<WgzQuestionsConfiguration> 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<Void> 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<Void> 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<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iWgzQuestionsConfigurationService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<WgzQuestionBank, WgzQuestionBankVo> {
}

View File

@ -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<WgzQuestionCategory, WgzQuestionCategoryVo> {
}

View File

@ -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<WgzQuestionSave> {
//
//
//}
/**
* 用户试卷存储Mapper接口
*
* @author Lion Li
* @date 2025-09-03
*/
public interface WgzQuestionSaveMapper extends BaseMapperPlus<WgzQuestionSave, WgzQuestionSaveVo> {
@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<String, Object> 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<PdfEntity> pdfSc (@Param("userId") Long userId);
}

View File

@ -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<WgzQuestionSavePdf, WgzQuestionSavePdfVo> {
}

View File

@ -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<WgzQuestionsConfiguration, WgzQuestionsConfigurationVo> {
}

View File

@ -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<WgzQuestionBank> {
/**
* 查询单个
* @return
*/
WgzQuestionBank queryById(Long id);
/**
* 查询列表
*/
TableDataInfo<WgzQuestionBankVo> queryPageList(WgzQuestionBankBo bo, PageQuery pageQuery);
/**
* 查询列表
*/
List<WgzQuestionBankVo> 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<Long> ids, Boolean isValid);
/**
* 务工者APP相关
* =================================================================================================================
* =================================================================================================================
* =================================================================================================================
*/
/**
* 随机获取指定个数类型的题
* @param type 类型
* 1单选
* 2多选
* 3判断
* @param num 数量
*/
List<WgzAppGetTestPaperThree> appQueryList(int type, int num);
/**
* 根据id查询得到具体题库的信息
*/
WgzQuestionBank selectById(Long id);
}

View File

@ -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<WgzQuestionCategory>{
/**
* 查询单个
* @return
*/
WgzQuestionCategory queryById(Long id);
/**
* 查询列表
*/
TableDataInfo<WgzQuestionCategoryVo> queryPageList(WgzQuestionCategoryBo bo, PageQuery pageQuery);
/**
* 查询列表
*/
List<WgzQuestionCategoryVo> 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<Long> ids, Boolean isValid);
}

View File

@ -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<WgzQuestionSavePdf> {
/**
* 查询单个
* @return
*/
WgzQuestionSavePdf queryById(Long id);
/**
* 查询列表
*/
TableDataInfo<WgzQuestionSavePdfVo> queryPageList(WgzQuestionSavePdfBo bo, PageQuery pageQuery);
/**
* 查询列表
*/
List<WgzQuestionSavePdfVo> 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<Long> ids, Boolean isValid);
/**
* APP相关
* =================================================================================================================
* =================================================================================================================
* =================================================================================================================
*/
//根据当前用户ID查询用户试卷存储pdf
WgzQuestionSavePdf queryByUserId(Long userId);
//根据当前用户ID删除用户试卷存储pdf
Boolean deleteByUserId(Long userId);
}

View File

@ -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<WgzQuestionSave> {
/**
* 查询单个
* @return
*/
WgzQuestionSave queryById(Long id);
/**
* 查询列表
*/
TableDataInfo<WgzQuestionSaveVo> queryPageList(WgzQuestionSaveBo bo, PageQuery pageQuery);
/**
* 查询列表
*/
List<WgzQuestionSaveVo> 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<Long> ids, Boolean isValid);
/**
* APP相关
* =================================================================================================================
* =================================================================================================================
* =================================================================================================================
*/
/**
* 安全教育试卷提交保存
*/
WgzAppSubmitATestPaperRes userSubmitATestPaper(WgzAppSubmitATestPaperReq req);
/**
* 查詢指定用戶的试卷是否及格
*/
WgzAppUserScoreQuery userScoreQuery(long userId);
// BgtQuestionResult getResult(Long userId);
}

View File

@ -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<WgzQuestionsConfiguration> {
/**
* 查询单个
* @return
*/
WgzQuestionsConfiguration queryById(Long id);
/**
* 查询列表
*/
TableDataInfo<WgzQuestionsConfigurationVo> queryPageList(WgzQuestionsConfigurationBo bo, PageQuery pageQuery);
/**
* 查询列表
*/
List<WgzQuestionsConfigurationVo> 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<Long> ids, Boolean isValid);
/**
* 务工者APP相关
* =================================================================================================================
* =================================================================================================================
* =================================================================================================================
*/
/**
* 根据id查询到具体信息
*/
WgzQuestionsConfiguration appQueryLimitOne();
}

View File

@ -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<WgzQuestionBankMapper, WgzQuestionBank> implements IWgzQuestionBankService {
@Override
public WgzQuestionBank queryById(Long id){
return getById(id);
}
@Override
public TableDataInfo<WgzQuestionBankVo> queryPageList(WgzQuestionBankBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<WgzQuestionBank> lqw = buildQueryWrapper(bo);
Page<WgzQuestionBankVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
public List<WgzQuestionBankVo> queryList(WgzQuestionBankBo bo) {
LambdaQueryWrapper<WgzQuestionBank> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<WgzQuestionBank> buildQueryWrapper(WgzQuestionBankBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<WgzQuestionBank> 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<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return removeByIds(ids);
}
/**
* 务工者APP相关
* =================================================================================================================
* =================================================================================================================
* =================================================================================================================
*/
@Override
public List<WgzAppGetTestPaperThree> appQueryList(int type, int num) {
LambdaQueryWrapper<WgzQuestionBank> last = new LambdaQueryWrapper<WgzQuestionBank>().
eq(WgzQuestionBank::getQuestionType, type).
last("order by rand() limit " + num);
List<WgzQuestionBank> wgzQuestionBanks = baseMapper.selectList(last);
List<WgzAppGetTestPaperThree> 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);
}
}

View File

@ -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<WgzQuestionCategoryMapper, WgzQuestionCategory> implements IWgzQuestionCategoryService {
@Override
public WgzQuestionCategory queryById(Long id){
return getById(id);
}
@Override
public TableDataInfo<WgzQuestionCategoryVo> queryPageList(WgzQuestionCategoryBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<WgzQuestionCategory> lqw = buildQueryWrapper(bo);
Page<WgzQuestionCategoryVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<WgzQuestionCategoryVo> queryList(WgzQuestionCategoryBo bo) {
LambdaQueryWrapper<WgzQuestionCategory> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<WgzQuestionCategory> buildQueryWrapper(WgzQuestionCategoryBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<WgzQuestionCategory> 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<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return removeByIds(ids);
}
}

View File

@ -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<WgzQuestionSavePdfMapper, WgzQuestionSavePdf> implements IWgzQuestionSavePdfService {
@Override
public WgzQuestionSavePdf queryById(Long id){
return getById(id);
}
@Override
public TableDataInfo<WgzQuestionSavePdfVo> queryPageList(WgzQuestionSavePdfBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<WgzQuestionSavePdf> lqw = buildQueryWrapper(bo);
Page<WgzQuestionSavePdfVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<WgzQuestionSavePdfVo> queryList(WgzQuestionSavePdfBo bo) {
LambdaQueryWrapper<WgzQuestionSavePdf> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<WgzQuestionSavePdf> buildQueryWrapper(WgzQuestionSavePdfBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<WgzQuestionSavePdf> 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<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return removeByIds(ids);
}
@Override
public WgzQuestionSavePdf queryByUserId(Long userId) {
LambdaQueryWrapper<WgzQuestionSavePdf> 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<WgzQuestionSavePdf> 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;
}
}

View File

@ -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<WgzQuestionSaveMapper, WgzQuestionSave> implements IWgzQuestionSaveService {
@Override
public WgzQuestionSave queryById(Long id) {
return null;
}
@Override
public TableDataInfo<WgzQuestionSaveVo> queryPageList(WgzQuestionSaveBo bo, PageQuery pageQuery) {
return null;
}
@Override
public List<WgzQuestionSaveVo> 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<Long> 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<WgzQuestionSaveVo> queryPageList(WgzQuestionSaveBo bo, PageQuery pageQuery) {
// LambdaQueryWrapper<WgzQuestionSave> lqw = buildQueryWrapper(bo);
// Page<WgzQuestionSaveVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
// return TableDataInfo.build(result);
// }
//
// @Override
// public List<WgzQuestionSaveVo> queryList(WgzQuestionSaveBo bo) {
// LambdaQueryWrapper<WgzQuestionSave> lqw = buildQueryWrapper(bo);
// return baseMapper.selectVoList(lqw);
// }
//
// private LambdaQueryWrapper<WgzQuestionSave> buildQueryWrapper(WgzQuestionSaveBo bo) {
// Map<String, Object> params = bo.getParams();
// LambdaQueryWrapper<WgzQuestionSave> 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<Long> 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<String, Object> 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<WgzQuestionSave> bqs = new ArrayList<>();
// Double fenshu = 0.0;
// Integer number = 0;
// Integer index = 0;
// List<WgzAppSubmitATestPaperTwo> 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<WgzQuestionSave>().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<PdfEntity> 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<ExaminationPaperTwo> sEntity = new ArrayList<>();
// List<ExaminationPaperTwo> mEntity = new ArrayList<>();
// List<ExaminationPaperTwo> 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<ExaminationPaperTwo> 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<WgzQuestionSave> wra = new LambdaQueryWrapper<WgzQuestionSave>()
// .eq(WgzQuestionSave::getUserId, userId);
// List<WgzQuestionSave> 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<WgzQuestionSave> wra = new LambdaQueryWrapper<WgzQuestionSave>()
//// .eq(WgzQuestionSave::getUserId, userId);
//// List<WgzQuestionSave> 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;
//// }
}

View File

@ -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<WgzQuestionsConfigurationMapper, WgzQuestionsConfiguration> implements IWgzQuestionsConfigurationService {
@Override
public WgzQuestionsConfiguration queryById(Long id){
return getById(id);
}
@Override
public TableDataInfo<WgzQuestionsConfigurationVo> queryPageList(WgzQuestionsConfigurationBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<WgzQuestionsConfiguration> lqw = buildQueryWrapper(bo);
Page<WgzQuestionsConfigurationVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<WgzQuestionsConfigurationVo> queryList(WgzQuestionsConfigurationBo bo) {
LambdaQueryWrapper<WgzQuestionsConfiguration> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<WgzQuestionsConfiguration> buildQueryWrapper(WgzQuestionsConfigurationBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<WgzQuestionsConfiguration> 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<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return removeByIds(ids);
}
/**
* 务工者APP相关
* =================================================================================================================
* =================================================================================================================
* =================================================================================================================
*/
@Override
public WgzQuestionsConfiguration appQueryLimitOne() {
QueryWrapper<WgzQuestionsConfiguration> queryWrapper = new QueryWrapper<>();
queryWrapper.last("LIMIT 1");
WgzQuestionsConfiguration wgzQuestionsConfiguration = baseMapper.selectOne(queryWrapper);
if(wgzQuestionsConfiguration==null){
throw new RuntimeException("题库配置为空");
}
return wgzQuestionsConfiguration;
}
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.safety.mapper.WgzQuestionBankMapper">
<resultMap type="org.dromara.safety.domain.WgzQuestionBank" id="WgzQuestionBankResult">
<result property="id" column="id"/>
<result property="categoryId" column="category_id"/>
<result property="questionType" column="question_type"/>
<result property="questionText" column="question_text"/>
<result property="options" column="options"/>
<result property="correctAnswer" column="correct_answer"/>
<result property="score" column="score"/>
<result property="delFlag" column="del_flag"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
</mapper>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.safety.mapper.WgzQuestionCategoryMapper">
<resultMap type="org.dromara.safety.domain.WgzQuestionCategory" id="WgzQuestionCategoryResult">
<result property="id" column="id"/>
<result property="categoryName" column="category_name"/>
</resultMap>
</mapper>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.safety.mapper.WgzQuestionSaveMapper">
<resultMap type="org.dromara.safety.domain.WgzQuestionSave" id="WgzQuestionSaveResult">
<result property="id" column="id"/>
<result property="userId" column="user_id"/>
<result property="bankId" column="bank_id"/>
<result property="answer" column="answer"/>
<result property="correct" column="correct"/>
<result property="score" column="score"/>
<result property="sign" column="sign"/>
<result property="takeTime" column="take_time"/>
<result property="timeOut" column="time_out"/>
<result property="pass" column="pass"/>
<result property="delFlag" column="del_flag"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
</mapper>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.safety.mapper.WgzQuestionSavePdfMapper">
<resultMap type="org.dromara.safety.domain.WgzQuestionSavePdf" id="WgzQuestionSavePdfResult">
<result property="id" column="id"/>
<result property="type" column="type"/>
<result property="userId" column="user_id"/>
<result property="path" column="path"/>
<result property="pass" column="pass"/>
<result property="timeOut" column="time_out"/>
<result property="takeTime" column="take_time"/>
<result property="sumScore" column="sum_score"/>
</resultMap>
</mapper>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.safety.mapper.WgzQuestionsConfigurationMapper">
<resultMap type="org.dromara.safety.domain.WgzQuestionsConfiguration" id="WgzQuestionsConfigurationResult">
<result property="id" column="id"/>
<result property="singleChoice" column="single_choice"/>
<result property="singleScore" column="single_score"/>
<result property="multipleChoice" column="multiple_choice"/>
<result property="multipleScore" column="multiple_score"/>
<result property="estimate" column="estimate"/>
<result property="estimateScore" column="estimate_score"/>
<result property="fullMark" column="full_mark"/>
<result property="passingScore" column="passing_score"/>
<result property="answerTime" column="answer_time"/>
</resultMap>
</mapper>