This commit is contained in:
2026-05-13 16:14:53 +08:00
commit e90729baae
2084 changed files with 203995 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
package com.hotwj.platform.common.controller;
import com.hotwj.platform.common.mapper.PublicMapper;
import com.hotwj.platform.common.vo.AddressVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequiredArgsConstructor
@RestController
@RequestMapping("/common/region")
@Tag(name = "区域管理", description = "区域树查询接口")
public class RegionController {
private final PublicMapper publicMapper;
/**
* 查询区域树列表
*/
@GetMapping("/tree")
@Operation(summary = "查询区域树列表")
public R<List<AddressVo>> tree() {
// 查询数据库,查询所有区域树
List<AddressVo> addressVoList = publicMapper.selectList();
// 组装成树
List<AddressVo> tree = AddressVo.buildTree(addressVoList);
return R.ok(tree);
}
}

View File

@@ -0,0 +1,80 @@
package com.hotwj.platform.common.helper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hotwj.platform.driverManagement.driver.domain.HotDriver;
import com.hotwj.platform.driverManagement.driver.mapper.HotDriverMapper;
import com.hotwj.platform.resourceManagement.company.domain.vo.SysUserLoginPortVo;
import com.hotwj.platform.resourceManagement.company.service.ISysUserLoginPortService;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import java.util.List;
/**
* 驾驶员登录上下文帮助类
*
* @author shihongwei
* @date 2026/02/22
*/
public final class DriverLoginContextHelper {
private DriverLoginContextHelper() {
}
public static boolean isDriverPort() {
LoginUser loginUser = LoginHelper.getLoginUser();
if (loginUser == null) {
return false;
}
return StringUtils.equals(loginUser.getLoginPort(), ISysUserLoginPortService.DRIVER_PORT);
}
public static HotDriver getCurrentDriver() {
if (!isDriverPort()) {
throw new ServiceException("当前登录端口不是驾驶员端");
}
LoginUser loginUser = LoginHelper.getLoginUser();
if (loginUser == null) {
throw new ServiceException("登录信息不存在");
}
String businessUserId = loginUser.getBusinessUserId();
if (StringUtils.isBlank(businessUserId)) {
Long userId = loginUser.getUserId();
if (userId == null) {
throw new ServiceException("用户ID不存在");
}
ISysUserLoginPortService userLoginPortService = SpringUtils.getBean(ISysUserLoginPortService.class);
List<SysUserLoginPortVo> ports = userLoginPortService.selectLoginPortListByPort(userId, ISysUserLoginPortService.DRIVER_PORT);
Long companyId = ports.stream()
.map(SysUserLoginPortVo::getCompanyId)
.filter(id -> id != null)
.findFirst()
.orElse(null);
if (companyId == null) {
throw new ServiceException("未找到驾驶员所属企业信息");
}
LambdaQueryWrapper<HotDriver> lqw = new LambdaQueryWrapper<>();
lqw.eq(HotDriver::getCompanyId, companyId);
lqw.eq(HotDriver::getId, userId);
lqw.eq(HotDriver::getStatus, 1L);
lqw.eq(HotDriver::getAuditStatus, 1);
lqw.orderByDesc(HotDriver::getCreateTime);
lqw.last("limit 1");
HotDriverMapper hotDriverMapper = SpringUtils.getBean(HotDriverMapper.class);
HotDriver driver = hotDriverMapper.selectOne(lqw);
if (driver == null) {
throw new ServiceException("未找到当前登录用户对应的驾驶员信息");
}
return driver;
}
HotDriverMapper hotDriverMapper = SpringUtils.getBean(HotDriverMapper.class);
HotDriver driver = hotDriverMapper.selectById(businessUserId);
if (driver == null) {
throw new ServiceException("驾驶员信息不存在");
}
return driver;
}
}

View File

@@ -0,0 +1,40 @@
package com.hotwj.platform.common.mapper;
import com.hotwj.platform.common.vo.AddressVo;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface PublicMapper {
/**
* 查询所有区域树,目前只查四川省的
*/
List<AddressVo> selectList();
/**
* 单SQL透视根据6位区划代码返回“省 市 区”全名
*/
String selectRegionFullNameByCode(String code);
/**
* 根据code查询
*/
AddressVo selectAddressByCode(String code);
/**
* 根据用户ID列表查询用户名称 (逗号分隔)
*/
String selectUserNamesByIds(@org.apache.ibatis.annotations.Param("userIds") List<Long> userIds);
/**
* 根据课程ID列表查询课程名称 (逗号分隔)
*/
String selectCourseNamesByIds(@org.apache.ibatis.annotations.Param("courseIds") List<Long> courseIds);
/**
* 根据ID列表查询参会人员姓名驾驶员 + 安全管理员),按中文顿号拼接
*/
String selectAttendeeNamesByIds(@org.apache.ibatis.annotations.Param("ids") List<String> ids);
}

View File

@@ -0,0 +1,44 @@
package com.hotwj.platform.common.photoEvidence.controller;
import com.hotwj.platform.common.photoEvidence.domain.bo.PhotoEvidenceCreateBo;
import com.hotwj.platform.common.photoEvidence.domain.vo.PhotoEvidenceVo;
import com.hotwj.platform.common.photoEvidence.service.IPhotoEvidenceService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser;
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.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Validated
@RestController
@RequestMapping("/common/photoEvidence")
public class PhotoEvidenceController extends BaseController {
@Resource
private IPhotoEvidenceService photoEvidenceService;
@RepeatSubmit
@Log(title = "照片取证水印生成", businessType = BusinessType.INSERT)
@PostMapping("/create")
@Operation(summary = "生成带时间地点水印的照片取证记录")
public R<PhotoEvidenceVo> create(@Valid @RequestBody PhotoEvidenceCreateBo bo) {
LoginUser loginUser = LoginHelper.getLoginUser();
Long companyId = loginUser.getCompanyId();
bo.setCompanyId(companyId);
bo.setOperatorId(loginUser.getBusinessUserId());
bo.setOperatorName(loginUser.getUsername());
PhotoEvidenceVo vo = photoEvidenceService.create(bo);
return R.ok(vo);
}
}

View File

@@ -0,0 +1,58 @@
package com.hotwj.platform.common.photoEvidence.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_photo_evidence")
public class HotPhotoEvidence extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id")
private Long id;
private Long originalOssId;
private Long watermarkedOssId;
private Date captureTimeClient;
private Date captureTimeServer;
private Double latitude;
private Double longitude;
private String addressTextServer;
private String addressTextClient;
private String addressSource;
private String bizType;
private String bizId;
private Long companyId;
private String operatorId;
private String operatorName;
/**
* 0=正常, 1=已删除
*/
@TableLogic
private Long isDeleted;
}

View File

@@ -0,0 +1,37 @@
package com.hotwj.platform.common.photoEvidence.domain.bo;
import com.baomidou.mybatisplus.annotation.TableLogic;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
public class PhotoEvidenceCreateBo {
@NotBlank(message = "originalOssId不能为空")
private String originalOssId;
@NotNull(message = "latitude不能为空")
private Double latitude;
@NotNull(message = "longitude不能为空")
private Double longitude;
private String addressTextClient;
@NotBlank(message = "bizType不能为空")
private String bizType;
private String bizId;
private Long companyId;
private String operatorId;
private String operatorName;
/**
* 0=正常, 1=已删除
*/
private Long isDeleted;
}

View File

@@ -0,0 +1,92 @@
package com.hotwj.platform.common.photoEvidence.domain.vo;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
/**
* 照片取证水印生成的返回视图对象
* 对应 hot_photo_evidence 表记录返回给前端的字段
*/
@Data
public class PhotoEvidenceVo {
/**
* 取证记录主键ID
*/
private String evidenceId;
/**
* 原始图片 OSS 记录主键ossId
*/
private String originalOssId;
/**
* 生成的水印图片 OSS 记录主键ossId
*/
private String watermarkedOssId;
/**
* 客户端拍摄时间字符串yyyy-MM-dd HH:mm:ss
*/
private String captureTimeClient;
/**
* 服务端生成取证记录时间字符串
*/
private String captureTimeServer;
/**
* 拍摄位置纬度
*/
private Double latitude;
/**
* 拍摄位置经度
*/
private Double longitude;
/**
* 服务端(高德逆地理)解析到的地址
*/
private String addressTextServer;
/**
* 客户端上传的地址文本
*/
private String addressTextClient;
/**
* 地址来源SERVER服务端解析/ CLIENT客户端上传
*/
private String addressSource;
/**
* 业务类型标识
*/
private String bizType;
/**
* 业务主键或业务单号
*/
private String bizId;
/**
* 公司ID
*/
private Long companyId;
/**
* 操作人ID
*/
private String operatorId;
/**
* 操作人姓名
*/
private String operatorName;
/**
* 0=正常, 1=已删除
*/
private Long isDeleted;
}

View File

@@ -0,0 +1,10 @@
package com.hotwj.platform.common.photoEvidence.mapper;
import com.hotwj.platform.common.photoEvidence.domain.HotPhotoEvidence;
import com.hotwj.platform.common.photoEvidence.domain.vo.PhotoEvidenceVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
@Mapper
public interface HotPhotoEvidenceMapper extends BaseMapperPlus<HotPhotoEvidence, PhotoEvidenceVo> {
}

View File

@@ -0,0 +1,10 @@
package com.hotwj.platform.common.photoEvidence.service;
import com.hotwj.platform.common.photoEvidence.domain.bo.PhotoEvidenceCreateBo;
import com.hotwj.platform.common.photoEvidence.domain.vo.PhotoEvidenceVo;
public interface IPhotoEvidenceService {
PhotoEvidenceVo create(PhotoEvidenceCreateBo bo);
}

View File

@@ -0,0 +1,335 @@
package com.hotwj.platform.common.photoEvidence.service.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.hotwj.platform.common.photoEvidence.domain.HotPhotoEvidence;
import com.hotwj.platform.common.photoEvidence.domain.bo.PhotoEvidenceCreateBo;
import com.hotwj.platform.common.photoEvidence.domain.vo.PhotoEvidenceVo;
import com.hotwj.platform.common.photoEvidence.mapper.HotPhotoEvidenceMapper;
import com.hotwj.platform.common.photoEvidence.service.IPhotoEvidenceService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.enums.FormatsType;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.oss.core.OssClient;
import org.dromara.common.oss.factory.OssFactory;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.service.ISysOssService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Slf4j
@Service
public class PhotoEvidenceServiceImpl implements IPhotoEvidenceService {
@Resource
private HotPhotoEvidenceMapper hotPhotoEvidenceMapper;
@Resource
private ISysOssService ossService;
@Value("${map.gd.key:}")
private String gdKey;
@Override
@Transactional(rollbackFor = Exception.class)
public PhotoEvidenceVo create(PhotoEvidenceCreateBo bo) {
Long originalOssId = parseOssId(bo.getOriginalOssId());
SysOssVo originalOss = ossService.getById(originalOssId);
if (originalOss == null) {
throw new ServiceException("原始图片不存在");
}
Date captureTimeClient = new Date();
Date captureTimeServer = captureTimeClient;
String addressServer = reverseGeocode(bo.getLatitude(), bo.getLongitude());
String addressSource;
String addressForWatermark;
if (StringUtils.isNotBlank(addressServer)) {
addressSource = "SERVER";
addressForWatermark = addressServer;
} else {
addressSource = "CLIENT";
addressForWatermark = bo.getAddressTextClient();
}
Long watermarkedOssId = generateAndUploadWatermarkedImage(
originalOss,
captureTimeClient,
addressForWatermark
);
String operatorName = bo.getOperatorName();
if (StringUtils.isBlank(operatorName)) {
operatorName = LoginHelper.getUsername();
}
HotPhotoEvidence entity = new HotPhotoEvidence();
entity.setOriginalOssId(originalOssId);
entity.setWatermarkedOssId(watermarkedOssId);
entity.setCaptureTimeClient(captureTimeClient);
entity.setCaptureTimeServer(captureTimeServer);
entity.setLatitude(bo.getLatitude());
entity.setLongitude(bo.getLongitude());
entity.setAddressTextServer(addressServer);
entity.setAddressTextClient(bo.getAddressTextClient());
entity.setAddressSource(addressSource);
entity.setBizType(bo.getBizType());
entity.setBizId(bo.getBizId());
entity.setCompanyId(bo.getCompanyId());
entity.setOperatorId(bo.getOperatorId());
entity.setOperatorName(operatorName);
hotPhotoEvidenceMapper.insert(entity);
PhotoEvidenceVo vo = new PhotoEvidenceVo();
vo.setEvidenceId(entity.getId() != null ? String.valueOf(entity.getId()) : null);
vo.setOriginalOssId(String.valueOf(originalOssId));
vo.setWatermarkedOssId(watermarkedOssId != null ? String.valueOf(watermarkedOssId) : null);
vo.setCaptureTimeClient(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, captureTimeClient));
vo.setCaptureTimeServer(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, captureTimeServer));
vo.setLatitude(bo.getLatitude());
vo.setLongitude(bo.getLongitude());
vo.setAddressTextServer(addressServer);
vo.setAddressTextClient(bo.getAddressTextClient());
vo.setAddressSource(addressSource);
vo.setBizType(bo.getBizType());
vo.setBizId(bo.getBizId());
vo.setCompanyId(bo.getCompanyId());
vo.setOperatorId(bo.getOperatorId());
vo.setOperatorName(operatorName);
return vo;
}
private Long parseOssId(String ossIdStr) {
try {
return Long.valueOf(ossIdStr);
} catch (NumberFormatException e) {
throw new ServiceException("originalOssId格式不正确");
}
}
private Long generateAndUploadWatermarkedImage(SysOssVo originalOss,
Date captureTimeClient,
String address) {
byte[] originalBytes = downloadOssFile(originalOss);
BufferedImage originalImage = readImage(originalBytes);
BufferedImage watermarked = addWatermark(originalImage, captureTimeClient, address);
File tempFile = null;
try {
String suffix = originalOss.getFileSuffix();
if (StringUtils.isBlank(suffix)) {
suffix = "jpg";
}
if (suffix.startsWith(".")) {
suffix = suffix.substring(1);
}
tempFile = File.createTempFile("photo_evidence_", "." + suffix);
try (OutputStream os = new FileOutputStream(tempFile)) {
ImageIO.write(watermarked, suffix, os);
}
return ossService.upload(tempFile).getOssId();
} catch (IOException e) {
throw new ServiceException("水印图片生成失败");
} finally {
if (tempFile != null && tempFile.exists()) {
if (!tempFile.delete()) {
log.warn("临时文件删除失败: {}", tempFile.getAbsolutePath());
}
}
}
}
private byte[] downloadOssFile(SysOssVo oss) {
OssClient storage = OssFactory.instance(oss.getService());
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
storage.download(oss.getFileName(), baos, null);
return baos.toByteArray();
} catch (Exception e) {
throw new ServiceException("原始图片下载失败");
}
}
private BufferedImage readImage(byte[] bytes) {
try (InputStream is = new ByteArrayInputStream(bytes)) {
BufferedImage image = ImageIO.read(is);
if (image == null) {
String hex = "";
if (bytes.length >= 4) {
hex = String.format("%02X%02X%02X%02X", bytes[0], bytes[1], bytes[2], bytes[3]);
}
log.error("ImageIO.read returned null. Header: {}", hex);
throw new ServiceException("原始图片格式不支持 (Header: " + hex + ")");
}
return image;
} catch (IOException e) {
log.error("图片解析失败", e);
throw new ServiceException("原始图片解析失败: " + e.getMessage());
}
}
private BufferedImage addWatermark(BufferedImage original,
Date captureTimeClient,
String address) {
int width = original.getWidth();
int height = original.getHeight();
// 强制最小画布宽度,防止文字区域过窄
int minWidth = 600;
if (width < minWidth) {
int newWidth = minWidth;
int newHeight = (int) Math.round((double) height * newWidth / width);
BufferedImage resized = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D gResize = resized.createGraphics();
gResize.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
gResize.drawImage(original, 0, 0, newWidth, newHeight, null);
gResize.dispose();
original = resized;
width = newWidth;
height = newHeight;
}
// 字体大小随宽度自适应(设置最小值)
int fontSize = Math.max(20, width / 30);
int padding = Math.max(fontSize, 16);
String timeText = DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, captureTimeClient);
String addressText = "地址:" + (address != null ? address : "");
// 构建字体并测量
Font font;
try (InputStream is = getClass().getResourceAsStream("/fonts/simsun.ttc")) {
if (is == null) {
font = new Font("SansSerif", Font.PLAIN, fontSize);
} else {
font = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(Font.PLAIN, fontSize);
}
} catch (Exception e) {
log.warn("Failed to load simsun font, fallback to SansSerif", e);
font = new Font("SansSerif", Font.PLAIN, fontSize);
}
// 使用临时图形上下文计算文字宽度与行高
BufferedImage tmp = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D gMeasure = tmp.createGraphics();
gMeasure.setFont(font);
FontMetrics fm = gMeasure.getFontMetrics();
int contentWidth = Math.max(1, width - padding * 2);
// 构造文本行:第一行时间,后续为地址按宽度换行
List<String> lines = new ArrayList<>();
lines.add(timeText);
if (fm.stringWidth(addressText) <= contentWidth) {
lines.add(addressText);
} else {
StringBuilder current = new StringBuilder();
for (char c : addressText.toCharArray()) {
if (fm.stringWidth(current.toString() + c) > contentWidth) {
lines.add(current.toString());
current = new StringBuilder();
}
current.append(c);
}
if (current.length() > 0) {
lines.add(current.toString());
}
}
int lineHeight = fm.getHeight() + fontSize / 4;
gMeasure.dispose();
// 计算白条高度,确保所有行完整显示
int barHeight = Math.max(lineHeight + padding * 2, lines.size() * lineHeight + padding * 2);
// 输出结果图
BufferedImage result = new BufferedImage(width, height + barHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = result.createGraphics();
try {
// 绘制原图
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(original, 0, 0, null);
// 绘制底部白条
g.setColor(Color.WHITE);
g.fillRect(0, height, width, barHeight);
// 绘制文本
g.setFont(font);
g.setColor(new Color(51, 51, 51));
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
int y = height + padding + fm.getAscent();
for (String line : lines) {
g.drawString(line, padding, y);
y += lineHeight;
}
return result;
} finally {
g.dispose();
}
}
private String reverseGeocode(Double latitude, Double longitude) {
if (latitude == null || longitude == null) {
return null;
}
if (StringUtils.isBlank(gdKey)) {
return null;
}
String location = longitude + "," + latitude;
String url = "https://restapi.amap.com/v3/geocode/regeo?output=JSON&location="
+ location + "&key=" + gdKey + "&radius=1000&extensions=base";
HttpURLConnection connection = null;
try {
URL u = new URL(url);
connection = (HttpURLConnection) u.openConnection();
connection.setConnectTimeout(3000);
connection.setReadTimeout(3000);
connection.setRequestMethod("GET");
int code = connection.getResponseCode();
if (code != HttpURLConnection.HTTP_OK) {
return null;
}
try (InputStream is = connection.getInputStream()) {
String body = new String(is.readAllBytes(), StandardCharsets.UTF_8);
JsonNode root = JsonUtils.getObjectMapper().readTree(body);
if (root == null) {
return null;
}
if (!"1".equals(root.path("status").asText())) {
return null;
}
JsonNode regeocode = root.path("regeocode");
String formatted = regeocode.path("formatted_address").asText();
if (StringUtils.isNotBlank(formatted)) {
return formatted;
}
return null;
}
} catch (Exception e) {
log.warn("高德逆地理解析失败: {},{}", latitude, longitude);
return null;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}

View File

@@ -0,0 +1,29 @@
package com.hotwj.platform.common.service;
import java.util.Map;
/**
* 通用模板填充服务
*
* @author shihongwei
*/
public interface ITemplateService {
/**
* 根据模板内容和数据映射,填充模板变量
*
* @param templateContent 包含 {变量名} 的模板字符串
* @param dataMap 变量名到实际数据的映射
* @return 填充后的字符串
*/
String fillTemplate(String templateContent, Map<String, Object> dataMap);
/**
* 为指定的签订文件明细记录准备模板所需的数据映射
*
* @param detailId 签订文件明细ID (hot_sign_file_detail.id)
* @return 包含所有可替换变量的Map
*/
Map<String, Object> prepareDataMapForSignDetail(Long detailId);
}

View File

@@ -0,0 +1,141 @@
package com.hotwj.platform.common.service.impl;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.hotwj.platform.common.service.ITemplateService;
import com.hotwj.platform.driverManagement.driver.domain.HotDriver;
import com.hotwj.platform.driverManagement.driver.mapper.HotDriverMapper;
import com.hotwj.platform.noticeManagerment.signFileDetail.domain.vo.HotSignFileDetailVo;
import com.hotwj.platform.noticeManagerment.signFileDetail.mapper.HotSignFileDetailMapper;
import com.hotwj.platform.resourceManagement.company.domain.vo.SysCompanyVo;
import com.hotwj.platform.resourceManagement.company.service.ISysCompanyService;
import com.hotwj.platform.resourceManagement.companySafetyManager.domain.HotCompanySafetyManager;
import com.hotwj.platform.resourceManagement.companySafetyManager.mapper.HotCompanySafetyManagerMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.text.StringSubstitutor;
import org.dromara.common.core.service.OssService;
import org.dromara.common.core.utils.StringUtils;
import org.springframework.stereotype.Service;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class TemplateServiceImpl implements ITemplateService {
private static final DateTimeFormatter SIGN_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
private final HotSignFileDetailMapper signFileDetailMapper;
private final ISysCompanyService companyService;
private final HotCompanySafetyManagerMapper safetyManagerMapper;
private final HotDriverMapper driverMapper;
private final OssService ossService;
@Override
public String fillTemplate(String templateContent, Map<String, Object> dataMap) {
if (StrUtil.isBlank(templateContent)) {
return "";
}
Map<String, Object> renderMap = dataMap == null ? new HashMap<>() : dataMap;
StringSubstitutor substitutor = new StringSubstitutor(renderMap, "{", "}");
substitutor.setEnableUndefinedVariableException(false);
String rendered = substitutor.replace(templateContent);
return rendered.replaceAll("\\{[^{}]+\\}", "");
}
@Override
public Map<String, Object> prepareDataMapForSignDetail(Long detailId) {
Map<String, Object> dataMap = new HashMap<>();
HotSignFileDetailVo detail = signFileDetailMapper.selectVoById(detailId);
if (detail == null) {
return dataMap;
}
String signOssId = detail.getSignOssId();
if (detail.getCompanyId() != null) {
SysCompanyVo company = companyService.queryById(detail.getCompanyId());
if (company != null) {
dataMap.put("企业名字", StringUtils.defaultString(company.getCompanyName()));
dataMap.put("信用代码", StringUtils.defaultString(company.getCreditCode()));
String sealUrl = resolveOssUrl(company.getSealUrl());
if (StrUtil.isNotBlank(sealUrl)) {
dataMap.put("电子公章", buildSealImgTag(sealUrl));
}
}
}
if (StrUtil.isNotBlank(detail.getStaffId()) && NumberUtil.isLong(detail.getStaffId())) {
HotCompanySafetyManager manager;
try {
manager = safetyManagerMapper.selectById(Long.valueOf(detail.getStaffId()));
} catch (Exception e) {
manager = null;
}
if (manager != null && manager.getId() != null) {
dataMap.put("管理员姓名", StringUtils.defaultString(manager.getName()));
dataMap.put("管理员身份证号码", StringUtils.defaultString(manager.getIdCardNo()));
dataMap.put("管理员手机号码", StringUtils.defaultString(manager.getPhone()));
dataMap.put("管理员岗位", StringUtils.defaultString(manager.getJobName()));
if (StrUtil.isNotBlank(signOssId)) {
String signImg = resolveOssUrl(signOssId);
dataMap.put("管理员签名", buildSignImgTag(signImg));
if (detail.getSignTime() != null) {
String signDate = detail.getSignTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(SIGN_DATE_FORMATTER);
dataMap.put("管理员签字日期", signDate);
}
}
}
} else if (StrUtil.isNotBlank(detail.getStaffId()) && !NumberUtil.isLong(detail.getStaffId())) {
HotDriver driver = driverMapper.selectById(detail.getStaffId());
if (driver != null && driver.getId() != null) {
dataMap.put("驾驶员姓名", StringUtils.defaultString(driver.getName()));
dataMap.put("驾驶员身份证号码", StringUtils.defaultString(driver.getIdCardNo()));
dataMap.put("驾驶员手机号码", StringUtils.defaultString(driver.getPhone()));
dataMap.put("驾驶员从业资格证号码", StringUtils.defaultString(driver.getQualificationNo()));
dataMap.put("驾驶员驾驶车牌号", StringUtils.defaultString(driver.getPlateNumber()));
if (StrUtil.isNotBlank(signOssId)) {
String signImg = resolveOssUrl(signOssId);
dataMap.put("驾驶员签名", buildSignImgTag(signImg));
if (detail.getSignTime() != null) {
String signDate = detail.getSignTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(SIGN_DATE_FORMATTER);
dataMap.put("驾驶员签字日期", signDate);
}
}
}
}
return dataMap;
}
private String resolveOssUrl(String source) {
if (StrUtil.isBlank(source)) {
return null;
}
if (source.startsWith("http://") || source.startsWith("https://")) {
return source;
}
String urls = ossService.selectUrlByIds(source);
if (StrUtil.isBlank(urls)) {
return source;
}
if (urls.contains(",")) {
for (String part : urls.split(",")) {
if (StrUtil.isNotBlank(part)) {
return part.trim();
}
}
}
return urls;
}
private String buildSignImgTag(String url) {
return "<img src=\"" + url + "\" style=\"display:inline-block !important; max-height: 66px; max-width: 160px; vertical-align: middle; margin: 0 2px;\" />";
}
private String buildSealImgTag(String url) {
return "<span style=\"display:inline-block; position:relative; width:0; height:0; line-height:0; vertical-align:middle; overflow:visible;\"><img src=\"" + url + "\" style=\"position:absolute; left:-35px; top:-60px; max-height:120px; max-width:220px; z-index:9; pointer-events:none;\" /></span>";
}
}

View File

@@ -0,0 +1,89 @@
package com.hotwj.platform.common.utils;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hssf.extractor.ExcelExtractor;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.sl.extractor.SlideShowExtractor;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
@Slf4j
public class FileTextExtractor {
public static String extractText(InputStream is, String fileExtension) {
if (is == null || StrUtil.isBlank(fileExtension)) {
return "";
}
String ext = fileExtension.toLowerCase();
// Remove dot if present
if (ext.startsWith(".")) {
ext = ext.substring(1);
}
try {
switch (ext) {
case "txt":
return IoUtil.read(is, StandardCharsets.UTF_8);
case "pdf":
try (PDDocument document = PDDocument.load(is)) {
PDFTextStripper stripper = new PDFTextStripper();
return stripper.getText(document);
}
case "doc":
try (HWPFDocument doc = new HWPFDocument(is);
WordExtractor extractor = new WordExtractor(doc)) {
return extractor.getText();
}
case "docx":
try (XWPFDocument doc = new XWPFDocument(is);
XWPFWordExtractor extractor = new XWPFWordExtractor(doc)) {
return extractor.getText();
}
case "xls":
try (HSSFWorkbook wb = new HSSFWorkbook(is);
ExcelExtractor extractor = new ExcelExtractor(wb)) {
extractor.setFormulasNotResults(false);
extractor.setIncludeSheetNames(false);
return extractor.getText();
}
case "xlsx":
try (XSSFWorkbook wb = new XSSFWorkbook(is);
XSSFExcelExtractor extractor = new XSSFExcelExtractor(wb)) {
extractor.setFormulasNotResults(false);
extractor.setIncludeSheetNames(false);
return extractor.getText();
}
case "ppt":
try (HSLFSlideShow ppt = new HSLFSlideShow(is);
SlideShowExtractor extractor = new SlideShowExtractor(ppt)) {
return extractor.getText();
}
case "pptx":
try (XMLSlideShow ppt = new XMLSlideShow(is);
SlideShowExtractor extractor = new SlideShowExtractor(ppt)) {
return extractor.getText();
}
default:
log.warn("Unsupported file extension for text extraction: {}", ext);
return "";
}
} catch (Exception e) {
log.error("Failed to extract text from file type: " + ext, e);
return "";
}
}
}

View File

@@ -0,0 +1,34 @@
package com.hotwj.platform.common.utils;
import cn.hutool.crypto.digest.BCrypt;
import lombok.extern.slf4j.Slf4j;
/**
* 密码工具类
*
* @author shihongwei
* @date 2025-12-10
*/
@Slf4j
public class PasswordUtils {
/**
* 默认密码规则:手机号+hot
*
* @param phone
* @return
*/
public static String createDefaultPassword(String phone) {
return BCrypt.hashpw(phone + "hot");
}
/**
* 通过明文创建密文
*
* @param password
* @return
*/
public static String createPassword(String password) {
return BCrypt.hashpw(password);
}
}

View File

@@ -0,0 +1,381 @@
package com.hotwj.platform.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.fontbox.ttf.TrueTypeCollection;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.util.Matrix;
import org.springframework.core.io.ClassPathResource;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* PDF Watermark Utility
* Adds text watermarks to PDF files using PDFBox.
*
* @author shihongwei
* @date 2026-01-02
*/
@Slf4j
public class PdfWatermarkUtil {
private static final String DEFAULT_APP_NAME = "HOT交通安全管理清单平台";
private static final String DEFAULT_WATERMARK_TEXT = "HOT交通安全\n管理清单平台";
private static final float WATERMARK_ALPHA = 0.15f;
private static final float PAGE_NUMBER_ALPHA = 1.0f;
private static final int WATERMARK_FONT_SIZE = 18;
private static final float PAGE_NUMBER_FONT_SIZE = 7.5f;
private static final int WATERMARK_ANGLE = -30;
private static final int WATERMARK_GAP = 200;
private static volatile byte[] cachedFontBytes;
/**
* Lazy loads the font bytes from classpath
*/
private static byte[] getFontBytes() {
if (cachedFontBytes != null) {
return cachedFontBytes;
}
synchronized (PdfWatermarkUtil.class) {
if (cachedFontBytes == null) {
try {
ClassPathResource fontResource = new ClassPathResource("fonts/simsun.ttc");
if (fontResource.exists()) {
try (InputStream is = fontResource.getInputStream()) {
cachedFontBytes = is.readAllBytes();
}
} else {
log.warn("Watermark font file not found at fonts/simsun.ttc");
}
} catch (IOException e) {
log.error("Failed to load watermark font", e);
}
}
}
return cachedFontBytes;
}
/**
* Adds a text watermark to the provided PDF bytes (optimized for Landscape A4).
*
* @param pdfBytes The original PDF bytes
* @param appName The text to use as watermark
* @return The PDF bytes with watermark added
*/
public static byte[] addWatermarkLandscape(byte[] pdfBytes, String appName) {
return addWatermark(pdfBytes, appName);
}
/**
* Adds a text watermark to the provided PDF bytes.
*
* @param pdfBytes The original PDF bytes
* @param appName The text to use as watermark (usually application name)
* @return The PDF bytes with watermark added
*/
public static byte[] addWatermark(byte[] pdfBytes, String appName) {
byte[] fontBytes = getFontBytes();
if (fontBytes == null) {
log.warn("Watermark font not loaded, skipping watermark.");
return pdfBytes;
}
String wmText = formatWatermarkText(appName);
try (PDDocument doc = PDDocument.load(pdfBytes)) {
PDFont font = loadFont(doc, fontBytes);
if (font == null) {
return pdfBytes;
}
PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
r0.setNonStrokingAlphaConstant(WATERMARK_ALPHA);
String[] lines = wmText.split("\n|\\\\n");
for (PDPage page : doc.getPages()) {
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
cs.setGraphicsStateParameters(r0);
cs.setFont(font, WATERMARK_FONT_SIZE);
cs.setNonStrokingColor(Color.BLACK);
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
for (int x = 0; x < pageWidth; x += WATERMARK_GAP) {
for (int y = 0; y < pageHeight; y += WATERMARK_GAP) {
drawWatermarkText(cs, lines, x, y);
}
}
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.save(baos);
return baos.toByteArray();
} catch (Exception e) {
throw new RuntimeException("Failed to add watermark to PDF", e);
}
}
private static PDFont loadFont(PDDocument doc, byte[] fontBytes) {
try (InputStream is = new ByteArrayInputStream(fontBytes)) {
TrueTypeCollection ttc = new TrueTypeCollection(is);
return PDType0Font.load(doc, ttc.getFontByName("SimSun"), true);
} catch (Exception e) {
log.error("Error loading font from cached bytes", e);
return null;
}
}
private static void drawWatermarkText(PDPageContentStream cs, String[] lines, float x, float y) throws IOException {
cs.beginText();
// Add offset to center within the grid cell roughly
// Shift y up by 100 (instead of 50) to prevent bottom row cutoff
Matrix matrix = Matrix.getRotateInstance(Math.toRadians(WATERMARK_ANGLE), x + 50, y + 100);
cs.setTextMatrix(matrix);
float leading = 20f;
for (String line : lines) {
cs.showText(line);
cs.newLineAtOffset(0, -leading);
}
cs.endText();
}
private static String formatWatermarkText(String appName) {
String wmText = appName;
if (wmText == null || wmText.isEmpty() || DEFAULT_APP_NAME.equals(wmText)) {
return DEFAULT_WATERMARK_TEXT;
}
if (wmText.length() > 10 && !wmText.contains("<br>") && !wmText.contains("\n")) {
int mid = wmText.length() / 2;
return wmText.substring(0, mid) + "\n" + wmText.substring(mid);
}
return wmText;
}
public static byte[] addSealBottomRight(byte[] pdfBytes, byte[] sealImageBytes) {
if (pdfBytes == null || sealImageBytes == null || sealImageBytes.length == 0) {
return pdfBytes;
}
try (PDDocument doc = PDDocument.load(pdfBytes)) {
PDImageXObject image = PDImageXObject.createFromByteArray(doc, sealImageBytes, "seal");
PDFRenderer renderer = new PDFRenderer(doc);
float imageWidth = image.getWidth();
float imageHeight = image.getHeight();
int pageIndex = 0;
for (PDPage page : doc.getPages()) {
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
float targetWidth = pageWidth * 0.18f;
float scale = targetWidth / imageWidth;
float targetHeight = imageHeight * scale;
float marginX = pageWidth * 0.04f;
float marginY = pageHeight * 0.04f;
float x = pageWidth - targetWidth - marginX;
float y = marginY;
try {
BufferedImage pageImage = renderer.renderImageWithDPI(pageIndex, 110);
int width = pageImage.getWidth();
int height = pageImage.getHeight();
int denseRowThreshold = Math.max(20, (int) (width * 0.30f));
int denseColThreshold = Math.max(12, (int) (height * 0.06f));
int lastDenseRow = -1;
int rightDenseCol = -1;
for (int iy = 0; iy < height; iy++) {
int darkCount = 0;
for (int ix = 0; ix < width; ix++) {
int rgb = pageImage.getRGB(ix, iy);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
if (r < 120 || g < 120 || b < 120) {
darkCount++;
}
}
if (darkCount >= denseRowThreshold) {
lastDenseRow = iy;
}
}
for (int ix = 0; ix < width; ix++) {
int darkCount = 0;
for (int iy = 0; iy < height; iy++) {
int rgb = pageImage.getRGB(ix, iy);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
if (r < 120 || g < 120 || b < 120) {
darkCount++;
}
}
if (darkCount >= denseColThreshold) {
rightDenseCol = ix;
}
}
if (lastDenseRow >= 0 && rightDenseCol >= 0) {
float contentRight = (rightDenseCol + 1f) * pageWidth / width;
float contentBottom = pageHeight - ((lastDenseRow + 1f) * pageHeight / height);
float insetX = targetWidth * 0.06f;
float insetY = targetHeight * 0.06f;
float sealX = contentRight - targetWidth - insetX;
float sealY = contentBottom + insetY;
float maxX = pageWidth - targetWidth - marginX;
float maxY = pageHeight - targetHeight - marginY;
float minX = marginX;
float minY = marginY;
x = Math.max(minX, Math.min(sealX, maxX));
y = Math.max(minY, Math.min(sealY, maxY));
}
} catch (Exception e) {
log.warn("Failed to detect table edge for seal placement on page {}", pageIndex + 1, e);
}
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
cs.drawImage(image, x, y, targetWidth, targetHeight);
}
pageIndex++;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.save(baos);
return baos.toByteArray();
} catch (Exception e) {
log.error("Failed to add seal to PDF", e);
return pdfBytes;
}
}
public static byte[] addPageNumbers(byte[] pdfBytes) {
byte[] fontBytes = getFontBytes();
if (fontBytes == null) {
return pdfBytes;
}
try (PDDocument doc = PDDocument.load(pdfBytes)) {
PDFont font = loadFont(doc, fontBytes);
if (font == null) {
return pdfBytes;
}
int total = doc.getNumberOfPages();
PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
r0.setNonStrokingAlphaConstant(PAGE_NUMBER_ALPHA);
int index = 1;
for (PDPage page : doc.getPages()) {
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
cs.setGraphicsStateParameters(r0);
cs.setFont(font, PAGE_NUMBER_FONT_SIZE);
float pageWidth = page.getMediaBox().getWidth();
float leftPaddingX = 28.35f;
float rightPaddingX = 18.0f;
float y = 24f;
cs.setNonStrokingColor(new Color(0x88, 0x88, 0x88));
cs.beginText();
cs.newLineAtOffset(leftPaddingX, y);
cs.showText("平台信息依实为准,信息使用自判");
cs.endText();
String pageLabel = "" + index + "/" + total + "";
float pageLabelWidth = font.getStringWidth(pageLabel) / 1000f * PAGE_NUMBER_FONT_SIZE;
float x = pageWidth - rightPaddingX - pageLabelWidth;
cs.setNonStrokingColor(Color.BLACK);
cs.beginText();
cs.newLineAtOffset(x, y);
cs.showText(pageLabel);
cs.endText();
}
index++;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.save(baos);
return baos.toByteArray();
} catch (Exception e) {
return pdfBytes;
}
}
public static byte[] addImageTopLeft(byte[] pdfBytes, byte[] imageBytes) {
return addImageTopLeft(pdfBytes, imageBytes, 0.18f, 0.04f);
}
public static byte[] addImageTopLeft(byte[] pdfBytes, byte[] imageBytes, float widthRatio, float marginRatio) {
if (pdfBytes == null || imageBytes == null || imageBytes.length == 0) {
return pdfBytes;
}
try (PDDocument doc = PDDocument.load(pdfBytes)) {
PDImageXObject image = PDImageXObject.createFromByteArray(doc, imageBytes, "wm_top_left");
float imageWidth = image.getWidth();
float imageHeight = image.getHeight();
for (PDPage page : doc.getPages()) {
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
float targetWidth = pageWidth * widthRatio;
float scale = targetWidth / imageWidth;
float targetHeight = imageHeight * scale;
float marginX = pageWidth * marginRatio;
float marginY = pageHeight * marginRatio;
float x = marginX;
float y = pageHeight - targetHeight - marginY;
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
cs.drawImage(image, x, y, targetWidth, targetHeight);
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.save(baos);
return baos.toByteArray();
} catch (Exception e) {
log.error("Failed to add top-left image to PDF", e);
return pdfBytes;
}
}
public static byte[] addImageTopRight(byte[] pdfBytes, byte[] imageBytes) {
return addImageTopRight(pdfBytes, imageBytes, 0.18f, 0.04f);
}
public static byte[] addImageTopRight(byte[] pdfBytes, byte[] imageBytes, float widthRatio, float marginRatio) {
if (pdfBytes == null || imageBytes == null || imageBytes.length == 0) {
return pdfBytes;
}
try (PDDocument doc = PDDocument.load(pdfBytes)) {
PDImageXObject image = PDImageXObject.createFromByteArray(doc, imageBytes, "wm_top_right");
float imageWidth = image.getWidth();
float imageHeight = image.getHeight();
for (PDPage page : doc.getPages()) {
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
float targetWidth = pageWidth * widthRatio;
float scale = targetWidth / imageWidth;
float targetHeight = imageHeight * scale;
float marginX = pageWidth * marginRatio;
float marginY = pageHeight * marginRatio;
float x = pageWidth - targetWidth - marginX;
float y = pageHeight - targetHeight - marginY;
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
cs.drawImage(image, x, y, targetWidth, targetHeight);
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.save(baos);
return baos.toByteArray();
} catch (Exception e) {
log.error("Failed to add top-right image to PDF", e);
return pdfBytes;
}
}
}

View File

@@ -0,0 +1,94 @@
package com.hotwj.platform.common.utils;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
/**
* 时间范围工具类
*/
public class TimeRangeUtil {
public static class TimeRange {
private final Date startTime;
private final Date endTime;
public TimeRange(Date startTime, Date endTime) {
this.startTime = startTime;
this.endTime = endTime;
}
public Date getStartTime() {
return startTime;
}
public Date getEndTime() {
return endTime;
}
}
public static TimeRange getCurrentWeek() {
LocalDate today = LocalDate.now();
LocalDate startOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
LocalDate endOfWeek = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
return new TimeRange(toDate(startOfWeek), toDate(endOfWeek));
}
public static TimeRange getCurrentMonth() {
LocalDate today = LocalDate.now();
LocalDate startOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
LocalDate endOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
return new TimeRange(toDate(startOfMonth), toDate(endOfMonth));
}
public static TimeRange getCurrentQuarter() {
LocalDate today = LocalDate.now();
int month = today.getMonthValue();
int quarterStartMonth = month - (month - 1) % 3;
LocalDate startOfQuarter = today.withMonth(quarterStartMonth).with(TemporalAdjusters.firstDayOfMonth());
LocalDate endOfQuarter = startOfQuarter.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth());
return new TimeRange(toDate(startOfQuarter), toDate(endOfQuarter));
}
public static TimeRange getCurrentHalfYear() {
LocalDate today = LocalDate.now();
int month = today.getMonthValue();
LocalDate startOfHalfYear;
LocalDate endOfHalfYear;
if (month <= 6) {
startOfHalfYear = LocalDate.of(today.getYear(), 1, 1);
endOfHalfYear = LocalDate.of(today.getYear(), 6, 30);
} else {
startOfHalfYear = LocalDate.of(today.getYear(), 7, 1);
endOfHalfYear = LocalDate.of(today.getYear(), 12, 31);
}
return new TimeRange(toDate(startOfHalfYear), toDate(endOfHalfYear));
}
public static TimeRange getCurrentYear() {
LocalDate today = LocalDate.now();
LocalDate startOfYear = today.with(TemporalAdjusters.firstDayOfYear());
LocalDate endOfYear = today.with(TemporalAdjusters.lastDayOfYear());
return new TimeRange(toDate(startOfYear), toDate(endOfYear));
}
public static int getCurrentQuarterNumber() {
return (LocalDate.now().getMonthValue() - 1) / 3 + 1;
}
public static String getCurrentHalfYearDescription() {
return LocalDate.now().getMonthValue() <= 6 ? "上半年" : "下半年";
}
public static String formatDate(Date date, String pattern) {
if (date == null) return "";
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(DateTimeFormatter.ofPattern(pattern));
}
private static Date toDate(LocalDate localDate) {
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
}

View File

@@ -0,0 +1,62 @@
package com.hotwj.platform.common.vo;
import lombok.Data;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@Data
public class AddressVo {
private Long id;
private String label;
private String value;
private List<AddressVo> children;
public static List<AddressVo> buildTree(List<AddressVo> list) {
Map<String, AddressVo> map = new HashMap<>();
List<AddressVo> roots = new ArrayList<>();
for (AddressVo vo : list) {
if (vo != null && vo.getValue() != null) {
map.put(vo.getValue(), vo);
}
}
for (AddressVo vo : list) {
if (vo == null) {
continue;
}
String code = vo.getValue();
String parent = parentCode(code);
AddressVo p = parent == null ? null : map.get(parent);
if (p == null) {
roots.add(vo);
} else {
List<AddressVo> c = p.getChildren();
if (c == null) {
c = new ArrayList<>();
p.setChildren(c);
}
c.add(vo);
}
}
return roots;
}
private static String parentCode(String code) {
if (code == null) {
return null;
}
String c = code.trim();
if (c.length() == 6) {
if (c.endsWith("0000")) {
return null;
}
if (c.endsWith("00")) {
return c.substring(0, 2) + "0000";
}
return c.substring(0, 4) + "00";
}
return null;
}
}

View File

@@ -0,0 +1,117 @@
package com.hotwj.platform.config.accidentLevelConfig.controller;
import com.hotwj.platform.config.accidentLevelConfig.domain.bo.HotAccidentLevelConfigBo;
import com.hotwj.platform.config.accidentLevelConfig.domain.vo.HotAccidentLevelConfigVo;
import com.hotwj.platform.config.accidentLevelConfig.service.IHotAccidentLevelConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 事故等级划分
*
* @author shihongwei
* @date 2026-01-06
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/accidentLevelConfig")
@Tag(name = "事故等级划分", description = "事故等级划分管理")
public class HotAccidentLevelConfigController extends BaseController {
private final IHotAccidentLevelConfigService hotAccidentLevelConfigService;
/**
* 查询事故等级划分列表
*/
//@SaCheckPermission("config:accidentLevelConfig:list")
@GetMapping("/list")
@Operation(summary = "分页查询事故等级划分列表")
public TableDataInfo<HotAccidentLevelConfigVo> list(HotAccidentLevelConfigBo bo, PageQuery pageQuery) {
return hotAccidentLevelConfigService.queryPageList(bo, pageQuery);
}
/**
* 导出事故等级划分列表
*/
//@SaCheckPermission("config:accidentLevelConfig:export")
@Log(title = "事故等级划分", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "导出事故等级划分列表")
public void export(HotAccidentLevelConfigBo bo, HttpServletResponse response) {
List<HotAccidentLevelConfigVo> list = hotAccidentLevelConfigService.queryList(bo);
ExcelUtil.exportExcel(list, "事故等级划分", HotAccidentLevelConfigVo.class, response);
}
/**
* 获取事故等级划分详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:accidentLevelConfig:query")
@GetMapping("/{id}")
@Operation(summary = "获取事故等级划分详细信息")
public R<HotAccidentLevelConfigVo> getInfo(@NotNull(message = "主键不能为空")
@Parameter(name = "id", description = "主键", required = true, example = "1")
@PathVariable Long id) {
return R.ok(hotAccidentLevelConfigService.queryById(id));
}
/**
* 新增事故等级划分
*/
//@SaCheckPermission("config:accidentLevelConfig:add")
@Log(title = "事故等级划分", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@Operation(summary = "新增事故等级划分")
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotAccidentLevelConfigBo bo) {
return toAjax(hotAccidentLevelConfigService.insertByBo(bo));
}
/**
* 修改事故等级划分
*/
//@SaCheckPermission("config:accidentLevelConfig:edit")
@Log(title = "事故等级划分", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@Operation(summary = "修改事故等级划分")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotAccidentLevelConfigBo bo) {
return toAjax(hotAccidentLevelConfigService.updateByBo(bo));
}
/**
* 删除事故等级划分
*
* @param ids 主键串
*/
//@SaCheckPermission("config:accidentLevelConfig:remove")
@Log(title = "事故等级划分", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@Operation(summary = "删除事故等级划分")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
@PathVariable Long[] ids) {
return toAjax(hotAccidentLevelConfigService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,69 @@
package com.hotwj.platform.config.accidentLevelConfig.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 事故等级划分对象 hot_accident_level_config
*
* @author shihongwei
* @date 2026-01-06
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_accident_level_config")
public class HotAccidentLevelConfig extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 风险值小值
*/
private Long minRiskValue;
/**
* 风险值大值
*/
private Long maxRiskValue;
/**
* 评价分级
*/
private String levelName;
/**
* 管控级别
*/
private String controlLevel;
/**
* 管控措施级别
*/
private String controlMeasureLevel;
/**
* 完成期限
*/
private String deadlineDesc;
/**
* 0=正常, 1=已删除
*/
@TableLogic
private Long isDeleted;
}

View File

@@ -0,0 +1,72 @@
package com.hotwj.platform.config.accidentLevelConfig.domain.bo;
import com.hotwj.platform.config.accidentLevelConfig.domain.HotAccidentLevelConfig;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 事故等级划分业务对象 hot_accident_level_config
*
* @author shihongwei
* @date 2026-01-06
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotAccidentLevelConfig.class, reverseConvertGenerate = false)
public class HotAccidentLevelConfigBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 风险值小值
*/
@NotNull(message = "风险值小值不能为空", groups = {AddGroup.class, EditGroup.class})
private Long minRiskValue;
/**
* 风险值大值
*/
@NotNull(message = "风险值大值不能为空", groups = {AddGroup.class, EditGroup.class})
private Long maxRiskValue;
/**
* 评价分级
*/
@NotBlank(message = "评价分级不能为空", groups = {AddGroup.class, EditGroup.class})
private String levelName;
/**
* 管控级别
*/
@NotBlank(message = "管控级别不能为空", groups = {AddGroup.class, EditGroup.class})
private String controlLevel;
/**
* 管控措施级别
*/
@NotBlank(message = "管控措施级别不能为空", groups = {AddGroup.class, EditGroup.class})
private String controlMeasureLevel;
/**
* 完成期限
*/
@NotBlank(message = "完成期限不能为空", groups = {AddGroup.class, EditGroup.class})
private String deadlineDesc;
/**
* 0=正常, 1=已删除
*/
private Long isDeleted;
}

View File

@@ -0,0 +1,76 @@
package com.hotwj.platform.config.accidentLevelConfig.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.accidentLevelConfig.domain.HotAccidentLevelConfig;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 事故等级划分视图对象 hot_accident_level_config
*
* @author shihongwei
* @date 2026-01-06
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotAccidentLevelConfig.class)
public class HotAccidentLevelConfigVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 风险值小值
*/
@ExcelProperty(value = "风险值小值")
private Long minRiskValue;
/**
* 风险值大值
*/
@ExcelProperty(value = "风险值大值")
private Long maxRiskValue;
/**
* 评价分级
*/
@ExcelProperty(value = "评价分级")
private String levelName;
/**
* 管控级别
*/
@ExcelProperty(value = "管控级别")
private String controlLevel;
/**
* 管控措施级别
*/
@ExcelProperty(value = "管控措施级别")
private String controlMeasureLevel;
/**
* 完成期限
*/
@ExcelProperty(value = "完成期限")
private String deadlineDesc;
/**
* 0=正常, 1=已删除
*/
@ExcelProperty(value = "0=正常, 1=已删除")
private Long isDeleted;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.accidentLevelConfig.mapper;
import com.hotwj.platform.config.accidentLevelConfig.domain.HotAccidentLevelConfig;
import com.hotwj.platform.config.accidentLevelConfig.domain.vo.HotAccidentLevelConfigVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 事故等级划分Mapper接口
*
* @author shihongwei
* @date 2026-01-06
*/
@Mapper
public interface HotAccidentLevelConfigMapper extends BaseMapperPlus<HotAccidentLevelConfig, HotAccidentLevelConfigVo> {
}

View File

@@ -0,0 +1,68 @@
package com.hotwj.platform.config.accidentLevelConfig.service;
import com.hotwj.platform.config.accidentLevelConfig.domain.bo.HotAccidentLevelConfigBo;
import com.hotwj.platform.config.accidentLevelConfig.domain.vo.HotAccidentLevelConfigVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 事故等级划分Service接口
*
* @author shihongwei
* @date 2026-01-06
*/
public interface IHotAccidentLevelConfigService {
/**
* 查询事故等级划分
*
* @param id 主键
* @return 事故等级划分
*/
HotAccidentLevelConfigVo queryById(Long id);
/**
* 分页查询事故等级划分列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 事故等级划分分页列表
*/
TableDataInfo<HotAccidentLevelConfigVo> queryPageList(HotAccidentLevelConfigBo bo, PageQuery pageQuery);
/**
* 查询符合条件的事故等级划分列表
*
* @param bo 查询条件
* @return 事故等级划分列表
*/
List<HotAccidentLevelConfigVo> queryList(HotAccidentLevelConfigBo bo);
/**
* 新增事故等级划分
*
* @param bo 事故等级划分
* @return 是否新增成功
*/
Boolean insertByBo(HotAccidentLevelConfigBo bo);
/**
* 修改事故等级划分
*
* @param bo 事故等级划分
* @return 是否修改成功
*/
Boolean updateByBo(HotAccidentLevelConfigBo bo);
/**
* 校验并批量删除事故等级划分信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,138 @@
package com.hotwj.platform.config.accidentLevelConfig.service.impl;
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.hotwj.platform.config.accidentLevelConfig.domain.HotAccidentLevelConfig;
import com.hotwj.platform.config.accidentLevelConfig.domain.bo.HotAccidentLevelConfigBo;
import com.hotwj.platform.config.accidentLevelConfig.domain.vo.HotAccidentLevelConfigVo;
import com.hotwj.platform.config.accidentLevelConfig.mapper.HotAccidentLevelConfigMapper;
import com.hotwj.platform.config.accidentLevelConfig.service.IHotAccidentLevelConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
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.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 事故等级划分Service业务层处理
*
* @author shihongwei
* @date 2026-01-06
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotAccidentLevelConfigServiceImpl implements IHotAccidentLevelConfigService {
private final HotAccidentLevelConfigMapper baseMapper;
/**
* 查询事故等级划分
*
* @param id 主键
* @return 事故等级划分
*/
@Override
public HotAccidentLevelConfigVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询事故等级划分列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 事故等级划分分页列表
*/
@Override
public TableDataInfo<HotAccidentLevelConfigVo> queryPageList(HotAccidentLevelConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotAccidentLevelConfig> lqw = buildQueryWrapper(bo);
Page<HotAccidentLevelConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的事故等级划分列表
*
* @param bo 查询条件
* @return 事故等级划分列表
*/
@Override
public List<HotAccidentLevelConfigVo> queryList(HotAccidentLevelConfigBo bo) {
LambdaQueryWrapper<HotAccidentLevelConfig> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<HotAccidentLevelConfig> buildQueryWrapper(HotAccidentLevelConfigBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotAccidentLevelConfig> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotAccidentLevelConfig::getId);
lqw.eq(bo.getMinRiskValue() != null, HotAccidentLevelConfig::getMinRiskValue, bo.getMinRiskValue());
lqw.eq(bo.getMaxRiskValue() != null, HotAccidentLevelConfig::getMaxRiskValue, bo.getMaxRiskValue());
lqw.like(StringUtils.isNotBlank(bo.getLevelName()), HotAccidentLevelConfig::getLevelName, bo.getLevelName());
lqw.eq(StringUtils.isNotBlank(bo.getControlLevel()), HotAccidentLevelConfig::getControlLevel, bo.getControlLevel());
lqw.eq(StringUtils.isNotBlank(bo.getControlMeasureLevel()), HotAccidentLevelConfig::getControlMeasureLevel, bo.getControlMeasureLevel());
lqw.eq(StringUtils.isNotBlank(bo.getDeadlineDesc()), HotAccidentLevelConfig::getDeadlineDesc, bo.getDeadlineDesc());
lqw.eq(bo.getIsDeleted() != null, HotAccidentLevelConfig::getIsDeleted, bo.getIsDeleted());
return lqw;
}
/**
* 新增事故等级划分
*
* @param bo 事故等级划分
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotAccidentLevelConfigBo bo) {
HotAccidentLevelConfig add = MapstructUtils.convert(bo, HotAccidentLevelConfig.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改事故等级划分
*
* @param bo 事故等级划分
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotAccidentLevelConfigBo bo) {
HotAccidentLevelConfig update = MapstructUtils.convert(bo, HotAccidentLevelConfig.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotAccidentLevelConfig entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除事故等级划分信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,117 @@
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.controller;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.bo.HotAccidentLikelihoodLevelConfigBo;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.vo.HotAccidentLikelihoodLevelConfigVo;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.service.IHotAccidentLikelihoodLevelConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 事故等级划分(可能性)
*
* @author shihongwei
* @date 2026-01-05
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/accidentLikelihoodLevelConfig")
@Tag(name = "事故等级划分(可能性)", description = "事故等级划分(可能性)管理")
public class HotAccidentLikelihoodLevelConfigController extends BaseController {
private final IHotAccidentLikelihoodLevelConfigService hotAccidentLikelihoodLevelConfigService;
/**
* 查询事故等级划分(可能性)列表
*/
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:list")
@GetMapping("/list")
@Operation(summary = "分页查询事故等级划分(可能性)列表")
public TableDataInfo<HotAccidentLikelihoodLevelConfigVo> list(HotAccidentLikelihoodLevelConfigBo bo, PageQuery pageQuery) {
return hotAccidentLikelihoodLevelConfigService.queryPageList(bo, pageQuery);
}
/**
* 导出事故等级划分(可能性)列表
*/
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:export")
@Log(title = "事故等级划分(可能性)", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "导出事故等级划分(可能性)列表")
public void export(HotAccidentLikelihoodLevelConfigBo bo, HttpServletResponse response) {
List<HotAccidentLikelihoodLevelConfigVo> list = hotAccidentLikelihoodLevelConfigService.queryList(bo);
ExcelUtil.exportExcel(list, "事故等级划分(可能性)", HotAccidentLikelihoodLevelConfigVo.class, response);
}
/**
* 获取事故等级划分(可能性)详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:query")
@GetMapping("/{id}")
@Operation(summary = "获取事故等级划分(可能性)详细信息")
public R<HotAccidentLikelihoodLevelConfigVo> getInfo(@NotNull(message = "主键不能为空")
@Parameter(name = "id", description = "主键", required = true, example = "1")
@PathVariable Long id) {
return R.ok(hotAccidentLikelihoodLevelConfigService.queryById(id));
}
/**
* 新增事故等级划分(可能性)
*/
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:add")
@Log(title = "事故等级划分(可能性)", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@Operation(summary = "新增事故等级划分(可能性)")
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotAccidentLikelihoodLevelConfigBo bo) {
return toAjax(hotAccidentLikelihoodLevelConfigService.insertByBo(bo));
}
/**
* 修改事故等级划分(可能性)
*/
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:edit")
@Log(title = "事故等级划分(可能性)", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@Operation(summary = "修改事故等级划分(可能性)")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotAccidentLikelihoodLevelConfigBo bo) {
return toAjax(hotAccidentLikelihoodLevelConfigService.updateByBo(bo));
}
/**
* 删除事故等级划分(可能性)
*
* @param ids 主键串
*/
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:remove")
@Log(title = "事故等级划分(可能性)", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@Operation(summary = "删除事故等级划分(可能性)")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
@PathVariable Long[] ids) {
return toAjax(hotAccidentLikelihoodLevelConfigService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,49 @@
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 事故等级划分(可能性)对象 hot_accident_likelihood_level_config
*
* @author shihongwei
* @date 2026-01-05
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_accident_likelihood_level_config")
public class HotAccidentLikelihoodLevelConfig extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 取值(级别)
*/
private Long levelValue;
/**
* 判定标准
*/
private String criterion;
/**
* 0=正常, 1=已删除
*/
@TableLogic
private Long isDeleted;
}

View File

@@ -0,0 +1,48 @@
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.bo;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.HotAccidentLikelihoodLevelConfig;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 事故等级划分(可能性)业务对象 hot_accident_likelihood_level_config
*
* @author shihongwei
* @date 2026-01-05
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotAccidentLikelihoodLevelConfig.class, reverseConvertGenerate = false)
public class HotAccidentLikelihoodLevelConfigBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 取值(级别)
*/
@NotNull(message = "取值(级别)不能为空", groups = {AddGroup.class, EditGroup.class})
private Long levelValue;
/**
* 判定标准
*/
@NotBlank(message = "判定标准不能为空", groups = {AddGroup.class, EditGroup.class})
private String criterion;
/**
* 0=正常, 1=已删除
*/
private Long isDeleted;
}

View File

@@ -0,0 +1,55 @@
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.HotAccidentLikelihoodLevelConfig;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import java.io.Serial;
import java.io.Serializable;
/**
* 事故等级划分(可能性)视图对象 hot_accident_likelihood_level_config
*
* @author shihongwei
* @date 2026-01-05
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotAccidentLikelihoodLevelConfig.class)
public class HotAccidentLikelihoodLevelConfigVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 取值(级别)
*/
@ExcelProperty(value = "取值", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "级=别")
private Long levelValue;
/**
* 判定标准
*/
@ExcelProperty(value = "判定标准")
private String criterion;
/**
* 0=正常, 1=已删除
*/
@ExcelProperty(value = "0=正常, 1=已删除")
private Long isDeleted;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.mapper;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.HotAccidentLikelihoodLevelConfig;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.vo.HotAccidentLikelihoodLevelConfigVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 事故等级划分可能性Mapper接口
*
* @author shihongwei
* @date 2026-01-05
*/
@Mapper
public interface HotAccidentLikelihoodLevelConfigMapper extends BaseMapperPlus<HotAccidentLikelihoodLevelConfig, HotAccidentLikelihoodLevelConfigVo> {
}

View File

@@ -0,0 +1,68 @@
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.service;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.bo.HotAccidentLikelihoodLevelConfigBo;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.vo.HotAccidentLikelihoodLevelConfigVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 事故等级划分可能性Service接口
*
* @author shihongwei
* @date 2026-01-05
*/
public interface IHotAccidentLikelihoodLevelConfigService {
/**
* 查询事故等级划分(可能性)
*
* @param id 主键
* @return 事故等级划分(可能性)
*/
HotAccidentLikelihoodLevelConfigVo queryById(Long id);
/**
* 分页查询事故等级划分(可能性)列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 事故等级划分(可能性)分页列表
*/
TableDataInfo<HotAccidentLikelihoodLevelConfigVo> queryPageList(HotAccidentLikelihoodLevelConfigBo bo, PageQuery pageQuery);
/**
* 查询符合条件的事故等级划分(可能性)列表
*
* @param bo 查询条件
* @return 事故等级划分(可能性)列表
*/
List<HotAccidentLikelihoodLevelConfigVo> queryList(HotAccidentLikelihoodLevelConfigBo bo);
/**
* 新增事故等级划分(可能性)
*
* @param bo 事故等级划分(可能性)
* @return 是否新增成功
*/
Boolean insertByBo(HotAccidentLikelihoodLevelConfigBo bo);
/**
* 修改事故等级划分(可能性)
*
* @param bo 事故等级划分(可能性)
* @return 是否修改成功
*/
Boolean updateByBo(HotAccidentLikelihoodLevelConfigBo bo);
/**
* 校验并批量删除事故等级划分(可能性)信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,134 @@
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.service.impl;
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.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.HotAccidentLikelihoodLevelConfig;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.bo.HotAccidentLikelihoodLevelConfigBo;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.vo.HotAccidentLikelihoodLevelConfigVo;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.mapper.HotAccidentLikelihoodLevelConfigMapper;
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.service.IHotAccidentLikelihoodLevelConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
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.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 事故等级划分可能性Service业务层处理
*
* @author shihongwei
* @date 2026-01-05
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotAccidentLikelihoodLevelConfigServiceImpl implements IHotAccidentLikelihoodLevelConfigService {
private final HotAccidentLikelihoodLevelConfigMapper baseMapper;
/**
* 查询事故等级划分(可能性)
*
* @param id 主键
* @return 事故等级划分(可能性)
*/
@Override
public HotAccidentLikelihoodLevelConfigVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询事故等级划分(可能性)列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 事故等级划分(可能性)分页列表
*/
@Override
public TableDataInfo<HotAccidentLikelihoodLevelConfigVo> queryPageList(HotAccidentLikelihoodLevelConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotAccidentLikelihoodLevelConfig> lqw = buildQueryWrapper(bo);
Page<HotAccidentLikelihoodLevelConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的事故等级划分(可能性)列表
*
* @param bo 查询条件
* @return 事故等级划分(可能性)列表
*/
@Override
public List<HotAccidentLikelihoodLevelConfigVo> queryList(HotAccidentLikelihoodLevelConfigBo bo) {
LambdaQueryWrapper<HotAccidentLikelihoodLevelConfig> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<HotAccidentLikelihoodLevelConfig> buildQueryWrapper(HotAccidentLikelihoodLevelConfigBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotAccidentLikelihoodLevelConfig> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotAccidentLikelihoodLevelConfig::getId);
lqw.eq(bo.getLevelValue() != null, HotAccidentLikelihoodLevelConfig::getLevelValue, bo.getLevelValue());
lqw.eq(StringUtils.isNotBlank(bo.getCriterion()), HotAccidentLikelihoodLevelConfig::getCriterion, bo.getCriterion());
lqw.eq(bo.getIsDeleted() != null, HotAccidentLikelihoodLevelConfig::getIsDeleted, bo.getIsDeleted());
return lqw;
}
/**
* 新增事故等级划分(可能性)
*
* @param bo 事故等级划分(可能性)
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotAccidentLikelihoodLevelConfigBo bo) {
HotAccidentLikelihoodLevelConfig add = MapstructUtils.convert(bo, HotAccidentLikelihoodLevelConfig.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改事故等级划分(可能性)
*
* @param bo 事故等级划分(可能性)
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotAccidentLikelihoodLevelConfigBo bo) {
HotAccidentLikelihoodLevelConfig update = MapstructUtils.convert(bo, HotAccidentLikelihoodLevelConfig.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotAccidentLikelihoodLevelConfig entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除事故等级划分(可能性)信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,117 @@
package com.hotwj.platform.config.accidentSeverityLevelConfig.controller;
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.bo.HotAccidentSeverityLevelConfigBo;
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.vo.HotAccidentSeverityLevelConfigVo;
import com.hotwj.platform.config.accidentSeverityLevelConfig.service.IHotAccidentSeverityLevelConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 事故等级划分(严重程度)
*
* @author shihongwei
* @date 2026-01-05
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/accidentSeverityLevelConfig")
@Tag(name = "事故等级划分(严重程度)", description = "事故等级划分(严重程度)管理")
public class HotAccidentSeverityLevelConfigController extends BaseController {
private final IHotAccidentSeverityLevelConfigService hotAccidentSeverityLevelConfigService;
/**
* 查询事故等级划分(严重程度)列表
*/
//@SaCheckPermission("config:accidentSeverityLevelConfig:list")
@GetMapping("/list")
@Operation(summary = "分页查询事故等级划分(严重程度)列表")
public TableDataInfo<HotAccidentSeverityLevelConfigVo> list(HotAccidentSeverityLevelConfigBo bo, PageQuery pageQuery) {
return hotAccidentSeverityLevelConfigService.queryPageList(bo, pageQuery);
}
/**
* 导出事故等级划分(严重程度)列表
*/
//@SaCheckPermission("config:accidentSeverityLevelConfig:export")
@Log(title = "事故等级划分(严重程度)", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "导出事故等级划分(严重程度)列表")
public void export(HotAccidentSeverityLevelConfigBo bo, HttpServletResponse response) {
List<HotAccidentSeverityLevelConfigVo> list = hotAccidentSeverityLevelConfigService.queryList(bo);
ExcelUtil.exportExcel(list, "事故等级划分(严重程度)", HotAccidentSeverityLevelConfigVo.class, response);
}
/**
* 获取事故等级划分(严重程度)详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:accidentSeverityLevelConfig:query")
@GetMapping("/{id}")
@Operation(summary = "获取事故等级划分(严重程度)详细信息")
public R<HotAccidentSeverityLevelConfigVo> getInfo(@NotNull(message = "主键不能为空")
@Parameter(name = "id", description = "主键", required = true, example = "1")
@PathVariable Long id) {
return R.ok(hotAccidentSeverityLevelConfigService.queryById(id));
}
/**
* 新增事故等级划分(严重程度)
*/
//@SaCheckPermission("config:accidentSeverityLevelConfig:add")
@Log(title = "事故等级划分(严重程度)", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@Operation(summary = "新增事故等级划分(严重程度)")
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotAccidentSeverityLevelConfigBo bo) {
return toAjax(hotAccidentSeverityLevelConfigService.insertByBo(bo));
}
/**
* 修改事故等级划分(严重程度)
*/
//@SaCheckPermission("config:accidentSeverityLevelConfig:edit")
@Log(title = "事故等级划分(严重程度)", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@Operation(summary = "修改事故等级划分(严重程度)")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotAccidentSeverityLevelConfigBo bo) {
return toAjax(hotAccidentSeverityLevelConfigService.updateByBo(bo));
}
/**
* 删除事故等级划分(严重程度)
*
* @param ids 主键串
*/
//@SaCheckPermission("config:accidentSeverityLevelConfig:remove")
@Log(title = "事故等级划分(严重程度)", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@Operation(summary = "删除事故等级划分(严重程度)")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
@PathVariable Long[] ids) {
return toAjax(hotAccidentSeverityLevelConfigService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,64 @@
package com.hotwj.platform.config.accidentSeverityLevelConfig.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 事故等级划分(严重程度)对象 hot_accident_severity_level_config
*
* @author shihongwei
* @date 2026-01-05
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_accident_severity_level_config")
public class HotAccidentSeverityLevelConfig extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 取值(级别)
*/
private Long levelValue;
/**
* 法律法规及其他要求
*/
private String lawRequirement;
/**
* 人员
*/
private String personnelDescription;
/**
* 直接经济损失
*/
private String directEconomicLoss;
/**
* 企业形象(社会影响)
*/
private String enterpriseReputation;
/**
* 0=正常, 1=已删除
*/
@TableLogic
private Long isDeleted;
}

View File

@@ -0,0 +1,66 @@
package com.hotwj.platform.config.accidentSeverityLevelConfig.domain.bo;
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.HotAccidentSeverityLevelConfig;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 事故等级划分(严重程度)业务对象 hot_accident_severity_level_config
*
* @author shihongwei
* @date 2026-01-05
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotAccidentSeverityLevelConfig.class, reverseConvertGenerate = false)
public class HotAccidentSeverityLevelConfigBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 取值(级别)
*/
@NotNull(message = "取值(级别)不能为空", groups = {AddGroup.class, EditGroup.class})
private Long levelValue;
/**
* 法律法规及其他要求
*/
@NotBlank(message = "法律法规及其他要求不能为空", groups = {AddGroup.class, EditGroup.class})
private String lawRequirement;
/**
* 人员
*/
@NotBlank(message = "人员不能为空", groups = {AddGroup.class, EditGroup.class})
private String personnelDescription;
/**
* 直接经济损失
*/
@NotBlank(message = "直接经济损失不能为空", groups = {AddGroup.class, EditGroup.class})
private String directEconomicLoss;
/**
* 企业形象(社会影响)
*/
@NotBlank(message = "企业形象(社会影响)不能为空", groups = {AddGroup.class, EditGroup.class})
private String enterpriseReputation;
/**
* 0=正常, 1=已删除
*/
private Long isDeleted;
}

View File

@@ -0,0 +1,74 @@
package com.hotwj.platform.config.accidentSeverityLevelConfig.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.HotAccidentSeverityLevelConfig;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import java.io.Serial;
import java.io.Serializable;
/**
* 事故等级划分(严重程度)视图对象 hot_accident_severity_level_config
*
* @author shihongwei
* @date 2026-01-05
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotAccidentSeverityLevelConfig.class)
public class HotAccidentSeverityLevelConfigVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 取值(级别)
*/
@ExcelProperty(value = "取值", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "级=别")
private Long levelValue;
/**
* 法律法规及其他要求
*/
@ExcelProperty(value = "法律法规及其他要求")
private String lawRequirement;
/**
* 人员
*/
@ExcelProperty(value = "人员")
private String personnelDescription;
/**
* 直接经济损失
*/
@ExcelProperty(value = "直接经济损失")
private String directEconomicLoss;
/**
* 企业形象(社会影响)
*/
@ExcelProperty(value = "企业形象", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "社=会影响")
private String enterpriseReputation;
/**
* 0=正常, 1=已删除
*/
@ExcelProperty(value = "0=正常, 1=已删除")
private Long isDeleted;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.accidentSeverityLevelConfig.mapper;
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.HotAccidentSeverityLevelConfig;
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.vo.HotAccidentSeverityLevelConfigVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 事故等级划分严重程度Mapper接口
*
* @author shihongwei
* @date 2026-01-05
*/
@Mapper
public interface HotAccidentSeverityLevelConfigMapper extends BaseMapperPlus<HotAccidentSeverityLevelConfig, HotAccidentSeverityLevelConfigVo> {
}

View File

@@ -0,0 +1,68 @@
package com.hotwj.platform.config.accidentSeverityLevelConfig.service;
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.bo.HotAccidentSeverityLevelConfigBo;
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.vo.HotAccidentSeverityLevelConfigVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 事故等级划分严重程度Service接口
*
* @author shihongwei
* @date 2026-01-05
*/
public interface IHotAccidentSeverityLevelConfigService {
/**
* 查询事故等级划分(严重程度)
*
* @param id 主键
* @return 事故等级划分(严重程度)
*/
HotAccidentSeverityLevelConfigVo queryById(Long id);
/**
* 分页查询事故等级划分(严重程度)列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 事故等级划分(严重程度)分页列表
*/
TableDataInfo<HotAccidentSeverityLevelConfigVo> queryPageList(HotAccidentSeverityLevelConfigBo bo, PageQuery pageQuery);
/**
* 查询符合条件的事故等级划分(严重程度)列表
*
* @param bo 查询条件
* @return 事故等级划分(严重程度)列表
*/
List<HotAccidentSeverityLevelConfigVo> queryList(HotAccidentSeverityLevelConfigBo bo);
/**
* 新增事故等级划分(严重程度)
*
* @param bo 事故等级划分(严重程度)
* @return 是否新增成功
*/
Boolean insertByBo(HotAccidentSeverityLevelConfigBo bo);
/**
* 修改事故等级划分(严重程度)
*
* @param bo 事故等级划分(严重程度)
* @return 是否修改成功
*/
Boolean updateByBo(HotAccidentSeverityLevelConfigBo bo);
/**
* 校验并批量删除事故等级划分(严重程度)信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,137 @@
package com.hotwj.platform.config.accidentSeverityLevelConfig.service.impl;
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.hotwj.platform.config.accidentSeverityLevelConfig.domain.HotAccidentSeverityLevelConfig;
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.bo.HotAccidentSeverityLevelConfigBo;
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.vo.HotAccidentSeverityLevelConfigVo;
import com.hotwj.platform.config.accidentSeverityLevelConfig.mapper.HotAccidentSeverityLevelConfigMapper;
import com.hotwj.platform.config.accidentSeverityLevelConfig.service.IHotAccidentSeverityLevelConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
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.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 事故等级划分严重程度Service业务层处理
*
* @author shihongwei
* @date 2026-01-05
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotAccidentSeverityLevelConfigServiceImpl implements IHotAccidentSeverityLevelConfigService {
private final HotAccidentSeverityLevelConfigMapper baseMapper;
/**
* 查询事故等级划分(严重程度)
*
* @param id 主键
* @return 事故等级划分(严重程度)
*/
@Override
public HotAccidentSeverityLevelConfigVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询事故等级划分(严重程度)列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 事故等级划分(严重程度)分页列表
*/
@Override
public TableDataInfo<HotAccidentSeverityLevelConfigVo> queryPageList(HotAccidentSeverityLevelConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotAccidentSeverityLevelConfig> lqw = buildQueryWrapper(bo);
Page<HotAccidentSeverityLevelConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的事故等级划分(严重程度)列表
*
* @param bo 查询条件
* @return 事故等级划分(严重程度)列表
*/
@Override
public List<HotAccidentSeverityLevelConfigVo> queryList(HotAccidentSeverityLevelConfigBo bo) {
LambdaQueryWrapper<HotAccidentSeverityLevelConfig> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<HotAccidentSeverityLevelConfig> buildQueryWrapper(HotAccidentSeverityLevelConfigBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotAccidentSeverityLevelConfig> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotAccidentSeverityLevelConfig::getId);
lqw.eq(bo.getLevelValue() != null, HotAccidentSeverityLevelConfig::getLevelValue, bo.getLevelValue());
lqw.eq(StringUtils.isNotBlank(bo.getLawRequirement()), HotAccidentSeverityLevelConfig::getLawRequirement, bo.getLawRequirement());
lqw.eq(StringUtils.isNotBlank(bo.getPersonnelDescription()), HotAccidentSeverityLevelConfig::getPersonnelDescription, bo.getPersonnelDescription());
lqw.eq(StringUtils.isNotBlank(bo.getDirectEconomicLoss()), HotAccidentSeverityLevelConfig::getDirectEconomicLoss, bo.getDirectEconomicLoss());
lqw.eq(StringUtils.isNotBlank(bo.getEnterpriseReputation()), HotAccidentSeverityLevelConfig::getEnterpriseReputation, bo.getEnterpriseReputation());
lqw.eq(bo.getIsDeleted() != null, HotAccidentSeverityLevelConfig::getIsDeleted, bo.getIsDeleted());
return lqw;
}
/**
* 新增事故等级划分(严重程度)
*
* @param bo 事故等级划分(严重程度)
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotAccidentSeverityLevelConfigBo bo) {
HotAccidentSeverityLevelConfig add = MapstructUtils.convert(bo, HotAccidentSeverityLevelConfig.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改事故等级划分(严重程度)
*
* @param bo 事故等级划分(严重程度)
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotAccidentSeverityLevelConfigBo bo) {
HotAccidentSeverityLevelConfig update = MapstructUtils.convert(bo, HotAccidentSeverityLevelConfig.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotAccidentSeverityLevelConfig entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除事故等级划分(严重程度)信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,117 @@
package com.hotwj.platform.config.companyBasicConfig.controller;
import com.hotwj.platform.config.companyBasicConfig.domain.bo.HotCompanyBasicConfigBo;
import com.hotwj.platform.config.companyBasicConfig.domain.vo.HotCompanyBasicConfigVo;
import com.hotwj.platform.config.companyBasicConfig.service.IHotCompanyBasicConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 企业基础配置
*
* @author shihongwei
* @date 2025-12-29
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/companyBasicConfig")
@Tag(name = "企业基础配置", description = "企业基础配置管理")
public class HotCompanyBasicConfigController extends BaseController {
private final IHotCompanyBasicConfigService hotCompanyBasicConfigService;
/**
* 查询企业基础配置列表
*/
//@SaCheckPermission("config:companyBasicConfig:list")
@GetMapping("/list")
@Operation(summary = "分页查询企业基础配置列表")
public TableDataInfo<HotCompanyBasicConfigVo> list(HotCompanyBasicConfigBo bo, PageQuery pageQuery) {
return hotCompanyBasicConfigService.queryPageList(bo, pageQuery);
}
/**
* 导出企业基础配置列表
*/
//@SaCheckPermission("config:companyBasicConfig:export")
@Log(title = "企业基础配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "导出企业基础配置列表")
public void export(HotCompanyBasicConfigBo bo, HttpServletResponse response) {
List<HotCompanyBasicConfigVo> list = hotCompanyBasicConfigService.queryList(bo);
ExcelUtil.exportExcel(list, "企业基础配置", HotCompanyBasicConfigVo.class, response);
}
/**
* 获取企业基础配置详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:companyBasicConfig:query")
@GetMapping("/{id}")
@Operation(summary = "获取企业基础配置详细信息")
public R<HotCompanyBasicConfigVo> getInfo(@NotNull(message = "主键不能为空")
@Parameter(name = "id", description = "主键", required = true, example = "1")
@PathVariable Long id) {
return R.ok(hotCompanyBasicConfigService.queryById(id));
}
/**
* 新增企业基础配置
*/
//@SaCheckPermission("config:companyBasicConfig:add")
@Log(title = "企业基础配置", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@Operation(summary = "新增企业基础配置")
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotCompanyBasicConfigBo bo) {
return toAjax(hotCompanyBasicConfigService.insertByBo(bo));
}
/**
* 修改企业基础配置
*/
//@SaCheckPermission("config:companyBasicConfig:edit")
@Log(title = "企业基础配置", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@Operation(summary = "修改企业基础配置")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotCompanyBasicConfigBo bo) {
return toAjax(hotCompanyBasicConfigService.updateByBo(bo));
}
/**
* 删除企业基础配置
*
* @param ids 主键串
*/
//@SaCheckPermission("config:companyBasicConfig:remove")
@Log(title = "企业基础配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@Operation(summary = "删除企业基础配置")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
@PathVariable Long[] ids) {
return toAjax(hotCompanyBasicConfigService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,84 @@
package com.hotwj.platform.config.companyBasicConfig.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 企业基础配置对象 hot_company_basic_config
*
* @author shihongwei
* @date 2025-12-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_company_basic_config")
public class HotCompanyBasicConfig extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 是否补学 0=关闭 1=开启
*/
private Long makeUpStudyEnabled;
/**
* 禁学区间是否开启 0=关闭 1=开启
*/
private Long forbidPeriodEnabled;
/**
* 禁学开始时间
*/
private String forbidStartTime;
/**
* 禁学结束时间
*/
private String forbidEndTime;
/**
* 学习短信提醒是否开启 0=关闭 1=开启
*/
private Long studySmsEnabled;
/**
* 剩余短信数量
*/
private Long remainingSmsCount;
/**
* 0=正常, 1=已删除
*/
@TableLogic
private Long isDeleted;
/**
* 隐患排查规则1=周 2=月 3=季度 4=半年 5=年)
*/
private Long hiddenDangerRole;
/**
* 隐患排查规则是否启用0=否 1=是)
*/
private Long roleIsEnable;
}

View File

@@ -0,0 +1,86 @@
package com.hotwj.platform.config.companyBasicConfig.domain.bo;
import com.hotwj.platform.config.companyBasicConfig.domain.HotCompanyBasicConfig;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 企业基础配置业务对象 hot_company_basic_config
*
* @author shihongwei
* @date 2025-12-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotCompanyBasicConfig.class, reverseConvertGenerate = false)
public class HotCompanyBasicConfigBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 公司ID
*/
@NotNull(message = "公司ID不能为空", groups = {AddGroup.class, EditGroup.class})
private Long companyId;
/**
* 是否补学 0=关闭 1=开启
*/
@NotNull(message = "是否补学 0=关闭 1=开启不能为空", groups = {AddGroup.class, EditGroup.class})
private Long makeUpStudyEnabled;
/**
* 禁学区间是否开启 0=关闭 1=开启
*/
@NotNull(message = "禁学区间是否开启 0=关闭 1=开启不能为空", groups = {AddGroup.class, EditGroup.class})
private Long forbidPeriodEnabled;
/**
* 禁学开始时间
*/
private String forbidStartTime;
/**
* 禁学结束时间
*/
private String forbidEndTime;
/**
* 学习短信提醒是否开启 0=关闭 1=开启
*/
@NotNull(message = "学习短信提醒是否开启 0=关闭 1=开启不能为空", groups = {AddGroup.class, EditGroup.class})
private Long studySmsEnabled;
/**
* 剩余短信数量
*/
@NotNull(message = "剩余短信数量不能为空", groups = {AddGroup.class, EditGroup.class})
private Long remainingSmsCount;
/**
* 0=正常, 1=已删除
*/
// @NotNull(message = "0=正常, 1=已删除不能为空", groups = {AddGroup.class, EditGroup.class})
private Long isDeleted;
/**
* 隐患排查规则1=周 2=月 3=季度 4=半年 5=年)
*/
private Long hiddenDangerRole;
/**
* 隐患排查规则是否启用0=否 1=是)
*/
private Long roleIsEnable;
}

View File

@@ -0,0 +1,91 @@
package com.hotwj.platform.config.companyBasicConfig.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.companyBasicConfig.domain.HotCompanyBasicConfig;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 企业基础配置视图对象 hot_company_basic_config
*
* @author shihongwei
* @date 2025-12-29
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotCompanyBasicConfig.class)
public class HotCompanyBasicConfigVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 公司ID
*/
@ExcelProperty(value = "公司ID")
private Long companyId;
/**
* 是否补学 0=关闭 1=开启
*/
@ExcelProperty(value = "是否补学 0=关闭 1=开启")
private Long makeUpStudyEnabled;
/**
* 禁学区间是否开启 0=关闭 1=开启
*/
@ExcelProperty(value = "禁学区间是否开启 0=关闭 1=开启")
private Long forbidPeriodEnabled;
/**
* 禁学开始时间
*/
@ExcelProperty(value = "禁学开始时间")
private String forbidStartTime;
/**
* 禁学结束时间
*/
@ExcelProperty(value = "禁学结束时间")
private String forbidEndTime;
/**
* 学习短信提醒是否开启 0=关闭 1=开启
*/
@ExcelProperty(value = "学习短信提醒是否开启 0=关闭 1=开启")
private Long studySmsEnabled;
/**
* 剩余短信数量
*/
@ExcelProperty(value = "剩余短信数量")
private Long remainingSmsCount;
/**
* 0=正常, 1=已删除
*/
@ExcelProperty(value = "0=正常, 1=已删除")
private Long isDeleted;
// private Long isChecked;
/**
* 隐患排查规则1=周 2=月 3=季度 4=半年 5=年)
*/
private Long hiddenDangerRole;
/**
* 隐患排查规则是否启用0=否 1=是)
*/
private Long roleIsEnable;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.companyBasicConfig.mapper;
import com.hotwj.platform.config.companyBasicConfig.domain.HotCompanyBasicConfig;
import com.hotwj.platform.config.companyBasicConfig.domain.vo.HotCompanyBasicConfigVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 企业基础配置Mapper接口
*
* @author shihongwei
* @date 2025-12-29
*/
@Mapper
public interface HotCompanyBasicConfigMapper extends BaseMapperPlus<HotCompanyBasicConfig, HotCompanyBasicConfigVo> {
}

View File

@@ -0,0 +1,68 @@
package com.hotwj.platform.config.companyBasicConfig.service;
import com.hotwj.platform.config.companyBasicConfig.domain.bo.HotCompanyBasicConfigBo;
import com.hotwj.platform.config.companyBasicConfig.domain.vo.HotCompanyBasicConfigVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 企业基础配置Service接口
*
* @author shihongwei
* @date 2025-12-29
*/
public interface IHotCompanyBasicConfigService {
/**
* 查询企业基础配置
*
* @param id 主键
* @return 企业基础配置
*/
HotCompanyBasicConfigVo queryById(Long id);
/**
* 分页查询企业基础配置列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 企业基础配置分页列表
*/
TableDataInfo<HotCompanyBasicConfigVo> queryPageList(HotCompanyBasicConfigBo bo, PageQuery pageQuery);
/**
* 查询符合条件的企业基础配置列表
*
* @param bo 查询条件
* @return 企业基础配置列表
*/
List<HotCompanyBasicConfigVo> queryList(HotCompanyBasicConfigBo bo);
/**
* 新增企业基础配置
*
* @param bo 企业基础配置
* @return 是否新增成功
*/
Boolean insertByBo(HotCompanyBasicConfigBo bo);
/**
* 修改企业基础配置
*
* @param bo 企业基础配置
* @return 是否修改成功
*/
Boolean updateByBo(HotCompanyBasicConfigBo bo);
/**
* 校验并批量删除企业基础配置信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,213 @@
package com.hotwj.platform.config.companyBasicConfig.service.impl;
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.hotwj.platform.config.companyBasicConfig.domain.HotCompanyBasicConfig;
import com.hotwj.platform.config.companyBasicConfig.domain.bo.HotCompanyBasicConfigBo;
import com.hotwj.platform.config.companyBasicConfig.domain.vo.HotCompanyBasicConfigVo;
import com.hotwj.platform.config.companyBasicConfig.mapper.HotCompanyBasicConfigMapper;
import com.hotwj.platform.config.companyBasicConfig.service.IHotCompanyBasicConfigService;
import com.hotwj.platform.driverManagement.driver.domain.HotDriver;
import com.hotwj.platform.driverManagement.driver.mapper.HotDriverMapper;
import com.hotwj.platform.noticeManagerment.systemNotification.domain.bo.HotSystemNotificationGroupBo;
import com.hotwj.platform.noticeManagerment.systemNotification.service.IHotSystemNotificationService;
import com.hotwj.platform.resourceManagement.companySafetyManager.domain.HotCompanySafetyManager;
import com.hotwj.platform.resourceManagement.companySafetyManager.mapper.HotCompanySafetyManagerMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 企业基础配置Service业务层处理
*
* @author shihongwei
* @date 2025-12-29
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotCompanyBasicConfigServiceImpl implements IHotCompanyBasicConfigService {
private final HotCompanyBasicConfigMapper baseMapper;
private final HotCompanySafetyManagerMapper managerMapper;
private final HotDriverMapper driverMapper;
private final IHotSystemNotificationService notificationService;
/**
* 查询企业基础配置
*
* @param id 主键
* @return 企业基础配置
*/
@Override
public HotCompanyBasicConfigVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询企业基础配置列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 企业基础配置分页列表
*/
@Override
public TableDataInfo<HotCompanyBasicConfigVo> queryPageList(HotCompanyBasicConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotCompanyBasicConfig> lqw = buildQueryWrapper(bo);
Page<HotCompanyBasicConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的企业基础配置列表
*
* @param bo 查询条件
* @return 企业基础配置列表
*/
@Override
public List<HotCompanyBasicConfigVo> queryList(HotCompanyBasicConfigBo bo) {
LambdaQueryWrapper<HotCompanyBasicConfig> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<HotCompanyBasicConfig> buildQueryWrapper(HotCompanyBasicConfigBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotCompanyBasicConfig> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotCompanyBasicConfig::getId);
lqw.eq(bo.getCompanyId() != null, HotCompanyBasicConfig::getCompanyId, bo.getCompanyId());
lqw.eq(bo.getMakeUpStudyEnabled() != null, HotCompanyBasicConfig::getMakeUpStudyEnabled, bo.getMakeUpStudyEnabled());
lqw.eq(bo.getForbidPeriodEnabled() != null, HotCompanyBasicConfig::getForbidPeriodEnabled, bo.getForbidPeriodEnabled());
lqw.eq(bo.getForbidStartTime() != null, HotCompanyBasicConfig::getForbidStartTime, bo.getForbidStartTime());
lqw.eq(bo.getForbidEndTime() != null, HotCompanyBasicConfig::getForbidEndTime, bo.getForbidEndTime());
lqw.eq(bo.getStudySmsEnabled() != null, HotCompanyBasicConfig::getStudySmsEnabled, bo.getStudySmsEnabled());
lqw.eq(bo.getRemainingSmsCount() != null, HotCompanyBasicConfig::getRemainingSmsCount, bo.getRemainingSmsCount());
lqw.eq(bo.getIsDeleted() != null, HotCompanyBasicConfig::getIsDeleted, bo.getIsDeleted());
return lqw;
}
/**
* 新增企业基础配置
*
* @param bo 企业基础配置
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotCompanyBasicConfigBo bo) {
HotCompanyBasicConfig add = MapstructUtils.convert(bo, HotCompanyBasicConfig.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
if (add.getCompanyId() != null
&& add.getForbidPeriodEnabled() != null && Long.valueOf(1L).equals(add.getForbidPeriodEnabled())
&& add.getForbidStartTime() != null && add.getForbidEndTime() != null) {
notifyForbidPeriod(add.getCompanyId(), add.getForbidStartTime(), add.getForbidEndTime());
}
}
return flag;
}
/**
* 修改企业基础配置
*
* @param bo 企业基础配置
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotCompanyBasicConfigBo bo) {
HotCompanyBasicConfig update = MapstructUtils.convert(bo, HotCompanyBasicConfig.class);
validEntityBeforeSave(update);
boolean flag = baseMapper.updateById(update) > 0;
if (flag) {
HotCompanyBasicConfig cfg = baseMapper.selectById(update.getId());
if (cfg != null
&& cfg.getCompanyId() != null
&& cfg.getForbidPeriodEnabled() != null && Long.valueOf(1L).equals(cfg.getForbidPeriodEnabled())
&& cfg.getForbidStartTime() != null && cfg.getForbidEndTime() != null) {
notifyForbidPeriod(cfg.getCompanyId(), bo.getForbidStartTime(), bo.getForbidEndTime());
}
}
return flag;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotCompanyBasicConfig entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除企业基础配置信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
//通知
private void notifyForbidPeriod(Long companyId, String startTime, String endTime) {
List<HotCompanySafetyManager> managers = managerMapper.selectList(
Wrappers.<HotCompanySafetyManager>lambdaQuery()
.eq(HotCompanySafetyManager::getCompanyId, companyId)
.eq(HotCompanySafetyManager::getIsDeleted, 0L)
.eq(HotCompanySafetyManager::getIsResigned, 0L)
.eq(HotCompanySafetyManager::getStatus, 1L)
);
List<HotDriver> drivers = driverMapper.selectList(
Wrappers.<HotDriver>lambdaQuery()
.eq(HotDriver::getCompanyId, companyId)
.eq(HotDriver::getIsDeleted, 0L)
.eq(HotDriver::getStatus, 1L)
);
String content = "企业已配置禁学期间:" + startTime + "" + endTime + ",期间禁止学习。";
if (managers != null && !managers.isEmpty()) {
List<String> receiverIds = managers.stream().map(m -> String.valueOf(m.getId())).toList();
HotSystemNotificationGroupBo bos = new HotSystemNotificationGroupBo();
bos.setLevel("普通");
bos.setContent(content);
bos.setSourceType("企业管理");
bos.setSenderType("SYSTEM");
bos.setReceiverType("管理员");
bos.setReceiverIds(receiverIds);
bos.setIsDeleted(0L);
try {
notificationService.insertByBo(bos);
} catch (Exception e) {
log.warn("禁学期间通知发送失败 companyId={} type=manager", companyId, e);
}
}
if (drivers != null && !drivers.isEmpty()) {
List<String> receiverIds = drivers.stream().map(HotDriver::getId).toList();
HotSystemNotificationGroupBo bos = new HotSystemNotificationGroupBo();
bos.setLevel("普通");
bos.setContent(content);
bos.setSourceType("企业管理");
bos.setSenderType("SYSTEM");
bos.setReceiverType("驾驶员");
bos.setReceiverIds(receiverIds);
bos.setIsDeleted(0L);
try {
notificationService.insertByBo(bos);
} catch (Exception e) {
log.warn("禁学期间通知发送失败 companyId={} type=driver", companyId, e);
}
}
}
}

View File

@@ -0,0 +1,117 @@
package com.hotwj.platform.config.companyDeptConfig.controller;
import com.hotwj.platform.config.companyDeptConfig.domain.bo.HotCompanyDeptConfigBo;
import com.hotwj.platform.config.companyDeptConfig.domain.vo.HotCompanyDeptConfigVo;
import com.hotwj.platform.config.companyDeptConfig.service.IHotCompanyDeptConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 企业部门配置
*
* @author shihongwei
* @date 2025-12-29
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/companyDeptConfig")
@Tag(name = "企业部门配置", description = "企业部门配置管理")
public class HotCompanyDeptConfigController extends BaseController {
private final IHotCompanyDeptConfigService hotCompanyDeptConfigService;
/**
* 查询企业部门配置列表
*/
//@SaCheckPermission("config:companyDeptConfig:list")
@GetMapping("/list")
@Operation(summary = "分页查询企业部门配置列表")
public TableDataInfo<HotCompanyDeptConfigVo> list(HotCompanyDeptConfigBo bo, PageQuery pageQuery) {
return hotCompanyDeptConfigService.queryPageList(bo, pageQuery);
}
/**
* 导出企业部门配置列表
*/
//@SaCheckPermission("config:companyDeptConfig:export")
@Log(title = "企业部门配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "导出企业部门配置列表")
public void export(HotCompanyDeptConfigBo bo, HttpServletResponse response) {
List<HotCompanyDeptConfigVo> list = hotCompanyDeptConfigService.queryList(bo);
ExcelUtil.exportExcel(list, "企业部门配置", HotCompanyDeptConfigVo.class, response);
}
/**
* 获取企业部门配置详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:companyDeptConfig:query")
@GetMapping("/{id}")
@Operation(summary = "获取企业部门配置详细信息")
public R<HotCompanyDeptConfigVo> getInfo(@NotNull(message = "主键不能为空")
@Parameter(name = "id", description = "主键", required = true, example = "1")
@PathVariable Long id) {
return R.ok(hotCompanyDeptConfigService.queryById(id));
}
/**
* 新增企业部门配置
*/
//@SaCheckPermission("config:companyDeptConfig:add")
@Log(title = "企业部门配置", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@Operation(summary = "新增企业部门配置")
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotCompanyDeptConfigBo bo) {
return toAjax(hotCompanyDeptConfigService.insertByBo(bo));
}
/**
* 修改企业部门配置
*/
//@SaCheckPermission("config:companyDeptConfig:edit")
@Log(title = "企业部门配置", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@Operation(summary = "修改企业部门配置")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotCompanyDeptConfigBo bo) {
return toAjax(hotCompanyDeptConfigService.updateByBo(bo));
}
/**
* 删除企业部门配置
*
* @param ids 主键串
*/
//@SaCheckPermission("config:companyDeptConfig:remove")
@Log(title = "企业部门配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@Operation(summary = "删除企业部门配置")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
@PathVariable Long[] ids) {
return toAjax(hotCompanyDeptConfigService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,54 @@
package com.hotwj.platform.config.companyDeptConfig.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 企业部门配置对象 hot_company_dept_config
*
* @author shihongwei
* @date 2025-12-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_company_dept_config")
public class HotCompanyDeptConfig extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 部门名称
*/
private String deptName;
/**
* 部门代码,要求大写字母
*/
private String deptCode;
/**
* 0=正常, 1=已删除
*/
@TableLogic
private Long isDeleted;
}

View File

@@ -0,0 +1,55 @@
package com.hotwj.platform.config.companyDeptConfig.domain.bo;
import com.hotwj.platform.config.companyDeptConfig.domain.HotCompanyDeptConfig;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 企业部门配置业务对象 hot_company_dept_config
*
* @author shihongwei
* @date 2025-12-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotCompanyDeptConfig.class, reverseConvertGenerate = false)
public class HotCompanyDeptConfigBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 公司ID
*/
@NotNull(message = "公司ID不能为空", groups = {AddGroup.class, EditGroup.class})
private Long companyId;
/**
* 部门名称
*/
@NotBlank(message = "部门名称不能为空", groups = {AddGroup.class, EditGroup.class})
private String deptName;
/**
* 部门代码,要求大写字母
*/
@NotBlank(message = "部门代码,要求大写字母不能为空", groups = {AddGroup.class, EditGroup.class})
private String deptCode;
/**
* 0=正常, 1=已删除
*/
// @NotNull(message = "0=正常, 1=已删除不能为空", groups = {AddGroup.class, EditGroup.class})
private Long isDeleted;
}

View File

@@ -0,0 +1,58 @@
package com.hotwj.platform.config.companyDeptConfig.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.companyDeptConfig.domain.HotCompanyDeptConfig;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 企业部门配置视图对象 hot_company_dept_config
*
* @author shihongwei
* @date 2025-12-29
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotCompanyDeptConfig.class)
public class HotCompanyDeptConfigVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 公司ID
*/
@ExcelProperty(value = "公司ID")
private Long companyId;
/**
* 部门名称
*/
@ExcelProperty(value = "部门名称")
private String deptName;
/**
* 部门代码,要求大写字母
*/
@ExcelProperty(value = "部门代码,要求大写字母")
private String deptCode;
/**
* 0=正常, 1=已删除
*/
@ExcelProperty(value = "0=正常, 1=已删除")
private Long isDeleted;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.companyDeptConfig.mapper;
import com.hotwj.platform.config.companyDeptConfig.domain.HotCompanyDeptConfig;
import com.hotwj.platform.config.companyDeptConfig.domain.vo.HotCompanyDeptConfigVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 企业部门配置Mapper接口
*
* @author shihongwei
* @date 2025-12-29
*/
@Mapper
public interface HotCompanyDeptConfigMapper extends BaseMapperPlus<HotCompanyDeptConfig, HotCompanyDeptConfigVo> {
}

View File

@@ -0,0 +1,68 @@
package com.hotwj.platform.config.companyDeptConfig.service;
import com.hotwj.platform.config.companyDeptConfig.domain.bo.HotCompanyDeptConfigBo;
import com.hotwj.platform.config.companyDeptConfig.domain.vo.HotCompanyDeptConfigVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 企业部门配置Service接口
*
* @author shihongwei
* @date 2025-12-29
*/
public interface IHotCompanyDeptConfigService {
/**
* 查询企业部门配置
*
* @param id 主键
* @return 企业部门配置
*/
HotCompanyDeptConfigVo queryById(Long id);
/**
* 分页查询企业部门配置列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 企业部门配置分页列表
*/
TableDataInfo<HotCompanyDeptConfigVo> queryPageList(HotCompanyDeptConfigBo bo, PageQuery pageQuery);
/**
* 查询符合条件的企业部门配置列表
*
* @param bo 查询条件
* @return 企业部门配置列表
*/
List<HotCompanyDeptConfigVo> queryList(HotCompanyDeptConfigBo bo);
/**
* 新增企业部门配置
*
* @param bo 企业部门配置
* @return 是否新增成功
*/
Boolean insertByBo(HotCompanyDeptConfigBo bo);
/**
* 修改企业部门配置
*
* @param bo 企业部门配置
* @return 是否修改成功
*/
Boolean updateByBo(HotCompanyDeptConfigBo bo);
/**
* 校验并批量删除企业部门配置信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,144 @@
package com.hotwj.platform.config.companyDeptConfig.service.impl;
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.hotwj.platform.config.companyDeptConfig.domain.HotCompanyDeptConfig;
import com.hotwj.platform.config.companyDeptConfig.domain.bo.HotCompanyDeptConfigBo;
import com.hotwj.platform.config.companyDeptConfig.domain.vo.HotCompanyDeptConfigVo;
import com.hotwj.platform.config.companyDeptConfig.mapper.HotCompanyDeptConfigMapper;
import com.hotwj.platform.config.companyDeptConfig.service.IHotCompanyDeptConfigService;
import com.hotwj.platform.resourceManagement.companySafetyManager.domain.HotCompanySafetyManager;
import com.hotwj.platform.resourceManagement.companySafetyManager.mapper.HotCompanySafetyManagerMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
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.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 企业部门配置Service业务层处理
*
* @author shihongwei
* @date 2025-12-29
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotCompanyDeptConfigServiceImpl implements IHotCompanyDeptConfigService {
private final HotCompanyDeptConfigMapper baseMapper;
private final HotCompanySafetyManagerMapper safetyManagerMapper;
/**
* 查询企业部门配置
*
* @param id 主键
* @return 企业部门配置
*/
@Override
public HotCompanyDeptConfigVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询企业部门配置列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 企业部门配置分页列表
*/
@Override
public TableDataInfo<HotCompanyDeptConfigVo> queryPageList(HotCompanyDeptConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotCompanyDeptConfig> lqw = buildQueryWrapper(bo);
Page<HotCompanyDeptConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的企业部门配置列表
*
* @param bo 查询条件
* @return 企业部门配置列表
*/
@Override
public List<HotCompanyDeptConfigVo> queryList(HotCompanyDeptConfigBo bo) {
LambdaQueryWrapper<HotCompanyDeptConfig> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<HotCompanyDeptConfig> buildQueryWrapper(HotCompanyDeptConfigBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotCompanyDeptConfig> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotCompanyDeptConfig::getId);
lqw.eq(bo.getCompanyId() != null, HotCompanyDeptConfig::getCompanyId, bo.getCompanyId());
lqw.like(StringUtils.isNotBlank(bo.getDeptName()), HotCompanyDeptConfig::getDeptName, bo.getDeptName());
lqw.eq(StringUtils.isNotBlank(bo.getDeptCode()), HotCompanyDeptConfig::getDeptCode, bo.getDeptCode());
lqw.eq(bo.getIsDeleted() != null, HotCompanyDeptConfig::getIsDeleted, bo.getIsDeleted());
return lqw;
}
/**
* 新增企业部门配置
*
* @param bo 企业部门配置
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotCompanyDeptConfigBo bo) {
HotCompanyDeptConfig add = MapstructUtils.convert(bo, HotCompanyDeptConfig.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改企业部门配置
*
* @param bo 企业部门配置
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotCompanyDeptConfigBo bo) {
HotCompanyDeptConfig update = MapstructUtils.convert(bo, HotCompanyDeptConfig.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotCompanyDeptConfig entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除企业部门配置信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
Long count = safetyManagerMapper.selectCount(Wrappers.<HotCompanySafetyManager>lambdaQuery()
.in(HotCompanySafetyManager::getDeptId, ids)
.eq(HotCompanySafetyManager::getIsResigned, 0L));
if (count > 0) {
throw new ServiceException("该部门有未离职人员不可删除");
}
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,117 @@
package com.hotwj.platform.config.course.controller;
import com.hotwj.platform.config.course.domain.bo.HotCourseBo;
import com.hotwj.platform.config.course.domain.vo.HotCourseVo;
import com.hotwj.platform.config.course.service.IHotCourseService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 课程库
*
* @author shihongwei
* @date 2025-12-23
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/course")
@Tag(name = "课程库", description = "课程库管理")
public class HotCourseController extends BaseController {
private final IHotCourseService hotCourseService;
/**
* 查询课程库列表
*/
//@SaCheckPermission("config:course:list")
@GetMapping("/list")
@Operation(summary = "分页查询课程库列表")
public TableDataInfo<HotCourseVo> list(HotCourseBo bo, PageQuery pageQuery) {
return hotCourseService.queryPageList(bo, pageQuery);
}
/**
* 导出课程库列表
*/
//@SaCheckPermission("config:course:export")
@Log(title = "课程库", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "导出课程库列表")
public void export(HotCourseBo bo, HttpServletResponse response) {
List<HotCourseVo> list = hotCourseService.queryList(bo);
ExcelUtil.exportExcel(list, "课程库", HotCourseVo.class, response);
}
/**
* 获取课程库详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:course:query")
@GetMapping("/{id}")
@Operation(summary = "获取课程库详细信息")
public R<HotCourseVo> getInfo(@NotNull(message = "主键不能为空")
@Parameter(name = "id", description = "主键", required = true, example = "1")
@PathVariable Long id) {
return R.ok(hotCourseService.queryById(id));
}
/**
* 新增课程库
*/
//@SaCheckPermission("config:course:add")
@Log(title = "课程库", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@Operation(summary = "新增课程库")
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotCourseBo bo) {
return toAjax(hotCourseService.insertByBo(bo));
}
/**
* 修改课程库
*/
//@SaCheckPermission("config:course:edit")
@Log(title = "课程库", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@Operation(summary = "修改课程库")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotCourseBo bo) {
return toAjax(hotCourseService.updateByBo(bo));
}
/**
* 删除课程库
*
* @param ids 主键串
*/
//@SaCheckPermission("config:course:remove")
@Log(title = "课程库", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@Operation(summary = "删除课程库")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
@PathVariable Long[] ids) {
return toAjax(hotCourseService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,100 @@
package com.hotwj.platform.config.course.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
import java.math.BigDecimal;
/**
* 课程库对象 hot_course
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_course")
public class HotCourse extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 课程名称
*/
private String name;
/**
* 教育类型字典编码
*/
private String trainingTypeCode;
/**
* 教育类型子集编码集(JSON/逗号分隔)
*/
private String trainingSubtypeCodes;
/**
* 课程描述
*/
private String description;
/**
* 封面/预览图URL
*/
private String coverUrl;
/**
* 课程文件URL(PDF/图片)
*/
private String materialUrl;
/**
* 文件学习时长(秒)
*/
private Long learningDuration;
/**
* 课时
*/
private BigDecimal classHours;
/**
* 课程内容(富文本)
*/
private String content;
/**
* 状态1=启用 0=禁用
*/
private Long status;
/**
* 备注
*/
private String remark;
/**
* 0=正常, 1=已删除
*/
@TableLogic
private Long isDeleted;
}

View File

@@ -0,0 +1,96 @@
package com.hotwj.platform.config.course.domain.bo;
import com.hotwj.platform.config.course.domain.HotCourse;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.math.BigDecimal;
/**
* 课程库业务对象 hot_course
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotCourse.class, reverseConvertGenerate = false)
public class HotCourseBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 课程名称
*/
private String name;
/**
* 教育类型字典编码
*/
private String trainingTypeCode;
/**
* 教育类型子集编码集(JSON/逗号分隔)
*/
private String trainingSubtypeCodes;
/**
* 课程描述
*/
private String description;
/**
* 封面/预览图URL
*/
private String coverUrl;
/**
* 课程文件URL(PDF/图片)
*/
private String materialUrl;
/**
* 文件学习时长(秒)
*/
private Long learningDuration;
/**
* 课时
*/
private BigDecimal classHours;
/**
* 课程内容(富文本)
*/
private String content;
/**
* 状态1=启用 0=禁用
*/
private Long status;
/**
* 备注
*/
private String remark;
/**
* 0=正常, 1=已删除
*/
private Long isDeleted;
}

View File

@@ -0,0 +1,115 @@
package com.hotwj.platform.config.course.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.course.domain.HotCourse;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 课程库视图对象 hot_course
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotCourse.class)
public class HotCourseVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 公司ID
*/
@ExcelProperty(value = "公司ID")
private Long companyId;
/**
* 课程名称
*/
@ExcelProperty(value = "课程名称")
private String name;
/**
* 教育类型字典编码
*/
@ExcelProperty(value = "教育类型字典编码")
private String trainingTypeCode;
/**
* 教育类型子集编码集(JSON/逗号分隔)
*/
@ExcelProperty(value = "教育类型子集编码集(JSON/逗号分隔)")
private String trainingSubtypeCodes;
/**
* 课程描述
*/
@ExcelProperty(value = "课程描述")
private String description;
/**
* 封面/预览图URL
*/
@ExcelProperty(value = "封面/预览图URL")
private String coverUrl;
/**
* 课程文件URL(PDF/图片)
*/
@ExcelProperty(value = "课程文件URL(PDF/图片)")
private String materialUrl;
/**
* 文件学习时长(秒)
*/
@ExcelProperty(value = "文件学习时长(秒)")
private Long learningDuration;
/**
* 课时
*/
@ExcelProperty(value = "课时")
private BigDecimal classHours;
/**
* 课程内容(富文本)
*/
@ExcelProperty(value = "课程内容(富文本)")
private String content;
/**
* 状态1=启用 0=禁用
*/
@ExcelProperty(value = "状态1=启用 0=禁用")
private Long status;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 0=正常, 1=已删除
*/
@ExcelProperty(value = "0=正常, 1=已删除")
private Long isDeleted;
private Date createTime;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.course.mapper;
import com.hotwj.platform.config.course.domain.HotCourse;
import com.hotwj.platform.config.course.domain.vo.HotCourseVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 课程库Mapper接口
*
* @author shihongwei
* @date 2025-12-23
*/
@Mapper
public interface HotCourseMapper extends BaseMapperPlus<HotCourse, HotCourseVo> {
}

View File

@@ -0,0 +1,68 @@
package com.hotwj.platform.config.course.service;
import com.hotwj.platform.config.course.domain.bo.HotCourseBo;
import com.hotwj.platform.config.course.domain.vo.HotCourseVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 课程库Service接口
*
* @author shihongwei
* @date 2025-12-23
*/
public interface IHotCourseService {
/**
* 查询课程库
*
* @param id 主键
* @return 课程库
*/
HotCourseVo queryById(Long id);
/**
* 分页查询课程库列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 课程库分页列表
*/
TableDataInfo<HotCourseVo> queryPageList(HotCourseBo bo, PageQuery pageQuery);
/**
* 查询符合条件的课程库列表
*
* @param bo 查询条件
* @return 课程库列表
*/
List<HotCourseVo> queryList(HotCourseBo bo);
/**
* 新增课程库
*
* @param bo 课程库
* @return 是否新增成功
*/
Boolean insertByBo(HotCourseBo bo);
/**
* 修改课程库
*
* @param bo 课程库
* @return 是否修改成功
*/
Boolean updateByBo(HotCourseBo bo);
/**
* 校验并批量删除课程库信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,145 @@
package com.hotwj.platform.config.course.service.impl;
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.hotwj.platform.config.course.domain.HotCourse;
import com.hotwj.platform.config.course.domain.bo.HotCourseBo;
import com.hotwj.platform.config.course.domain.vo.HotCourseVo;
import com.hotwj.platform.config.course.mapper.HotCourseMapper;
import com.hotwj.platform.config.course.service.IHotCourseService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
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.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 课程库Service业务层处理
*
* @author shihongwei
* @date 2025-12-23
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotCourseServiceImpl implements IHotCourseService {
private final HotCourseMapper baseMapper;
/**
* 查询课程库
*
* @param id 主键
* @return 课程库
*/
@Override
public HotCourseVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询课程库列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 课程库分页列表
*/
@Override
public TableDataInfo<HotCourseVo> queryPageList(HotCourseBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotCourse> lqw = buildQueryWrapper(bo);
Page<HotCourseVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的课程库列表
*
* @param bo 查询条件
* @return 课程库列表
*/
@Override
public List<HotCourseVo> queryList(HotCourseBo bo) {
LambdaQueryWrapper<HotCourse> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<HotCourse> buildQueryWrapper(HotCourseBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotCourse> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotCourse::getId);
lqw.eq(bo.getCompanyId() != null, HotCourse::getCompanyId, bo.getCompanyId());
lqw.like(StringUtils.isNotBlank(bo.getName()), HotCourse::getName, bo.getName());
lqw.eq(StringUtils.isNotBlank(bo.getTrainingTypeCode()), HotCourse::getTrainingTypeCode, bo.getTrainingTypeCode());
lqw.eq(StringUtils.isNotBlank(bo.getTrainingSubtypeCodes()), HotCourse::getTrainingSubtypeCodes, bo.getTrainingSubtypeCodes());
lqw.eq(StringUtils.isNotBlank(bo.getDescription()), HotCourse::getDescription, bo.getDescription());
lqw.eq(StringUtils.isNotBlank(bo.getCoverUrl()), HotCourse::getCoverUrl, bo.getCoverUrl());
lqw.eq(StringUtils.isNotBlank(bo.getMaterialUrl()), HotCourse::getMaterialUrl, bo.getMaterialUrl());
lqw.eq(bo.getLearningDuration() != null, HotCourse::getLearningDuration, bo.getLearningDuration());
lqw.eq(bo.getClassHours() != null, HotCourse::getClassHours, bo.getClassHours());
lqw.eq(StringUtils.isNotBlank(bo.getContent()), HotCourse::getContent, bo.getContent());
lqw.eq(bo.getStatus() != null, HotCourse::getStatus, bo.getStatus());
lqw.eq(bo.getIsDeleted() != null, HotCourse::getIsDeleted, bo.getIsDeleted());
lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
HotCourse::getCreateTime, params.get("beginTime"), params.get("endTime"));
return lqw;
}
/**
* 新增课程库
*
* @param bo 课程库
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotCourseBo bo) {
HotCourse add = MapstructUtils.convert(bo, HotCourse.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改课程库
*
* @param bo 课程库
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotCourseBo bo) {
HotCourse update = MapstructUtils.convert(bo, HotCourse.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotCourse entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除课程库信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,117 @@
package com.hotwj.platform.config.courseResource.controller;
import com.hotwj.platform.config.courseResource.domain.bo.HotCourseResourceBo;
import com.hotwj.platform.config.courseResource.domain.vo.HotCourseResourceVo;
import com.hotwj.platform.config.courseResource.service.IHotCourseResourceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 课程-资源关联
*
* @author shihongwei
* @date 2025-12-23
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/courseResource")
@Tag(name = "课程-资源关联", description = "课程-资源关联管理")
public class HotCourseResourceController extends BaseController {
private final IHotCourseResourceService hotCourseResourceService;
/**
* 查询课程-资源关联列表
*/
//@SaCheckPermission("config:courseResource:list")
@GetMapping("/list")
@Operation(summary = "分页查询课程-资源关联列表")
public TableDataInfo<HotCourseResourceVo> list(HotCourseResourceBo bo, PageQuery pageQuery) {
return hotCourseResourceService.queryPageList(bo, pageQuery);
}
/**
* 导出课程-资源关联列表
*/
//@SaCheckPermission("config:courseResource:export")
@Log(title = "课程-资源关联", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "导出课程-资源关联列表")
public void export(HotCourseResourceBo bo, HttpServletResponse response) {
List<HotCourseResourceVo> list = hotCourseResourceService.queryList(bo);
ExcelUtil.exportExcel(list, "课程-资源关联", HotCourseResourceVo.class, response);
}
/**
* 获取课程-资源关联详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:courseResource:query")
@GetMapping("/{id}")
@Operation(summary = "获取课程-资源关联详细信息")
public R<HotCourseResourceVo> getInfo(@NotNull(message = "主键不能为空")
@Parameter(name = "id", description = "主键", required = true, example = "1")
@PathVariable Long id) {
return R.ok(hotCourseResourceService.queryById(id));
}
/**
* 新增课程-资源关联
*/
//@SaCheckPermission("config:courseResource:add")
@Log(title = "课程-资源关联", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@Operation(summary = "新增课程-资源关联")
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotCourseResourceBo bo) {
return toAjax(hotCourseResourceService.insertByBo(bo));
}
/**
* 修改课程-资源关联
*/
//@SaCheckPermission("config:courseResource:edit")
@Log(title = "课程-资源关联", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@Operation(summary = "修改课程-资源关联")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotCourseResourceBo bo) {
return toAjax(hotCourseResourceService.updateByBo(bo));
}
/**
* 删除课程-资源关联
*
* @param ids 主键串
*/
//@SaCheckPermission("config:courseResource:remove")
@Log(title = "课程-资源关联", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@Operation(summary = "删除课程-资源关联")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
@PathVariable Long[] ids) {
return toAjax(hotCourseResourceService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,57 @@
package com.hotwj.platform.config.courseResource.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 课程-资源关联对象 hot_course_resource
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_course_resource")
public class HotCourseResource extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 课程ID
*/
private Long courseId;
/**
* 资源类型1=视频 2=音频 3=题目
*/
private Long resourceType;
/**
* 资源ID(根据类型关联不同表)
*/
private Long resourceId;
/**
* 排序值
*/
private Long sortOrder;
}

View File

@@ -0,0 +1,58 @@
package com.hotwj.platform.config.courseResource.domain.bo;
import com.hotwj.platform.config.courseResource.domain.HotCourseResource;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 课程-资源关联业务对象 hot_course_resource
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotCourseResource.class, reverseConvertGenerate = false)
public class HotCourseResourceBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 课程ID
*/
@NotNull(message = "课程ID不能为空", groups = {AddGroup.class, EditGroup.class})
private Long courseId;
/**
* 资源类型1=视频 2=音频 3=题目
*/
@NotNull(message = "资源类型1=视频 2=音频 3=题目不能为空", groups = {AddGroup.class, EditGroup.class})
private Long resourceType;
/**
* 资源ID(根据类型关联不同表)
*/
@NotNull(message = "资源ID(根据类型关联不同表)不能为空", groups = {AddGroup.class, EditGroup.class})
private Long resourceId;
/**
* 排序值
*/
private Long sortOrder;
}

View File

@@ -0,0 +1,64 @@
package com.hotwj.platform.config.courseResource.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.courseResource.domain.HotCourseResource;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 课程-资源关联视图对象 hot_course_resource
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotCourseResource.class)
public class HotCourseResourceVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 公司ID
*/
@ExcelProperty(value = "公司ID")
private Long companyId;
/**
* 课程ID
*/
@ExcelProperty(value = "课程ID")
private Long courseId;
/**
* 资源类型1=视频 2=音频 3=题目
*/
@ExcelProperty(value = "资源类型1=视频 2=音频 3=题目")
private Long resourceType;
/**
* 资源ID(根据类型关联不同表)
*/
@ExcelProperty(value = "资源ID(根据类型关联不同表)")
private Long resourceId;
/**
* 排序值
*/
@ExcelProperty(value = "排序值")
private Long sortOrder;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.courseResource.mapper;
import com.hotwj.platform.config.courseResource.domain.HotCourseResource;
import com.hotwj.platform.config.courseResource.domain.vo.HotCourseResourceVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 课程-资源关联Mapper接口
*
* @author shihongwei
* @date 2025-12-23
*/
@Mapper
public interface HotCourseResourceMapper extends BaseMapperPlus<HotCourseResource, HotCourseResourceVo> {
}

View File

@@ -0,0 +1,68 @@
package com.hotwj.platform.config.courseResource.service;
import com.hotwj.platform.config.courseResource.domain.bo.HotCourseResourceBo;
import com.hotwj.platform.config.courseResource.domain.vo.HotCourseResourceVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 课程-资源关联Service接口
*
* @author shihongwei
* @date 2025-12-23
*/
public interface IHotCourseResourceService {
/**
* 查询课程-资源关联
*
* @param id 主键
* @return 课程-资源关联
*/
HotCourseResourceVo queryById(Long id);
/**
* 分页查询课程-资源关联列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 课程-资源关联分页列表
*/
TableDataInfo<HotCourseResourceVo> queryPageList(HotCourseResourceBo bo, PageQuery pageQuery);
/**
* 查询符合条件的课程-资源关联列表
*
* @param bo 查询条件
* @return 课程-资源关联列表
*/
List<HotCourseResourceVo> queryList(HotCourseResourceBo bo);
/**
* 新增课程-资源关联
*
* @param bo 课程-资源关联
* @return 是否新增成功
*/
Boolean insertByBo(HotCourseResourceBo bo);
/**
* 修改课程-资源关联
*
* @param bo 课程-资源关联
* @return 是否修改成功
*/
Boolean updateByBo(HotCourseResourceBo bo);
/**
* 校验并批量删除课程-资源关联信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,135 @@
package com.hotwj.platform.config.courseResource.service.impl;
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.hotwj.platform.config.courseResource.domain.HotCourseResource;
import com.hotwj.platform.config.courseResource.domain.bo.HotCourseResourceBo;
import com.hotwj.platform.config.courseResource.domain.vo.HotCourseResourceVo;
import com.hotwj.platform.config.courseResource.mapper.HotCourseResourceMapper;
import com.hotwj.platform.config.courseResource.service.IHotCourseResourceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 课程-资源关联Service业务层处理
*
* @author shihongwei
* @date 2025-12-23
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotCourseResourceServiceImpl implements IHotCourseResourceService {
private final HotCourseResourceMapper baseMapper;
/**
* 查询课程-资源关联
*
* @param id 主键
* @return 课程-资源关联
*/
@Override
public HotCourseResourceVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询课程-资源关联列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 课程-资源关联分页列表
*/
@Override
public TableDataInfo<HotCourseResourceVo> queryPageList(HotCourseResourceBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotCourseResource> lqw = buildQueryWrapper(bo);
Page<HotCourseResourceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的课程-资源关联列表
*
* @param bo 查询条件
* @return 课程-资源关联列表
*/
@Override
public List<HotCourseResourceVo> queryList(HotCourseResourceBo bo) {
LambdaQueryWrapper<HotCourseResource> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<HotCourseResource> buildQueryWrapper(HotCourseResourceBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotCourseResource> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotCourseResource::getId);
lqw.eq(bo.getCompanyId() != null, HotCourseResource::getCompanyId, bo.getCompanyId());
lqw.eq(bo.getCourseId() != null, HotCourseResource::getCourseId, bo.getCourseId());
lqw.eq(bo.getResourceType() != null, HotCourseResource::getResourceType, bo.getResourceType());
lqw.eq(bo.getResourceId() != null, HotCourseResource::getResourceId, bo.getResourceId());
lqw.eq(bo.getSortOrder() != null, HotCourseResource::getSortOrder, bo.getSortOrder());
return lqw;
}
/**
* 新增课程-资源关联
*
* @param bo 课程-资源关联
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotCourseResourceBo bo) {
HotCourseResource add = MapstructUtils.convert(bo, HotCourseResource.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改课程-资源关联
*
* @param bo 课程-资源关联
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotCourseResourceBo bo) {
HotCourseResource update = MapstructUtils.convert(bo, HotCourseResource.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotCourseResource entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除课程-资源关联信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,125 @@
package com.hotwj.platform.config.dispatchTemplate.controller;
import com.hotwj.platform.config.dispatchTemplate.domain.bo.HotDispatchTemplateBo;
import com.hotwj.platform.config.dispatchTemplate.domain.vo.HotDispatchTemplateVo;
import com.hotwj.platform.config.dispatchTemplate.service.IHotDispatchTemplateService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 下发模板
*
* @author shihongwei
* @date 2026-02-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/dispatchTemplate")
@Tag(name = "下发模板", description = "下发模板管理")
public class HotDispatchTemplateController extends BaseController {
private final IHotDispatchTemplateService hotDispatchTemplateService;
/**
* 查询下发模板列表
*/
//@SaCheckPermission("config:dispatchTemplate:list")
@GetMapping("/list")
@Operation(summary = "分页查询下发模板列表")
public TableDataInfo<HotDispatchTemplateVo> list(HotDispatchTemplateBo bo, PageQuery pageQuery) {
return hotDispatchTemplateService.queryPageList(bo, pageQuery);
}
/**
* 导出下发模板列表
*/
//@SaCheckPermission("config:dispatchTemplate:export")
@Log(title = "下发模板", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "导出下发模板列表")
public void export(HotDispatchTemplateBo bo, HttpServletResponse response) {
List<HotDispatchTemplateVo> list = hotDispatchTemplateService.queryList(bo);
ExcelUtil.exportExcel(list, "下发模板", HotDispatchTemplateVo.class, response);
}
/**
* 获取下发模板详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:dispatchTemplate:query")
@GetMapping("/{id}")
@Operation(summary = "获取下发模板详细信息")
public R<HotDispatchTemplateVo> getInfo(@NotNull(message = "主键不能为空")
@Parameter(name = "id", description = "主键", required = true, example = "1")
@PathVariable Long id) {
return R.ok(hotDispatchTemplateService.queryById(id));
}
/**
* 新增下发模板
*/
//@SaCheckPermission("config:dispatchTemplate:add")
@Log(title = "下发模板", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@Operation(summary = "新增下发模板")
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotDispatchTemplateBo bo) {
return toAjax(hotDispatchTemplateService.insertByBo(bo));
}
/**
* 修改下发模板
*/
//@SaCheckPermission("config:dispatchTemplate:edit")
@Log(title = "下发模板", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@Operation(summary = "修改下发模板")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotDispatchTemplateBo bo) {
return toAjax(hotDispatchTemplateService.updateByBo(bo));
}
/**
* 删除下发模板
*
* @param ids 主键串
*/
//@SaCheckPermission("config:dispatchTemplate:remove")
@Log(title = "下发模板", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@Operation(summary = "删除下发模板")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
@PathVariable Long[] ids) {
return toAjax(hotDispatchTemplateService.deleteWithValidByIds(List.of(ids), true));
}
@Log(title = "下发模板", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/useDefault")
@Operation(summary = "采用默认配置")
public R<Void> useDefault() {
return toAjax(hotDispatchTemplateService.useDefault());
}
}

View File

@@ -0,0 +1,64 @@
package com.hotwj.platform.config.dispatchTemplate.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 下发模板对象 hot_dispatch_template
*
* @author shihongwei
* @date 2026-02-15
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_dispatch_template")
public class HotDispatchTemplate extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 公司ID由应用层保证必填
*/
private Long companyId;
/**
* 模板名称
*/
private String templateName;
/**
* 模板类型(字典)
*/
private String templateType;
/**
* 样式图OSS附件ID
*/
private String styleOssId;
/**
* 内容(富文本)
*/
private String content;
/**
* 0=正常, 1=已删除
*/
@TableLogic
private Long isDeleted;
}

View File

@@ -0,0 +1,59 @@
package com.hotwj.platform.config.dispatchTemplate.domain.bo;
import com.hotwj.platform.config.dispatchTemplate.domain.HotDispatchTemplate;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 下发模板业务对象 hot_dispatch_template
*
* @author shihongwei
* @date 2026-02-15
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotDispatchTemplate.class, reverseConvertGenerate = false)
public class HotDispatchTemplateBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 公司ID由应用层保证必填
*/
private Long companyId;
/**
* 模板名称
*/
private String templateName;
/**
* 模板类型(字典)
*/
private String templateType;
/**
* 样式图OSS附件ID
*/
private String styleOssId;
/**
* 内容(富文本)
*/
private String content;
/**
* 0=正常, 1=已删除
*/
private Long isDeleted;
}

View File

@@ -0,0 +1,87 @@
package com.hotwj.platform.config.dispatchTemplate.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.dispatchTemplate.domain.HotDispatchTemplate;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import java.io.Serial;
import java.io.Serializable;
/**
* 下发模板视图对象 hot_dispatch_template
*
* @author shihongwei
* @date 2026-02-15
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotDispatchTemplate.class)
public class HotDispatchTemplateVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 公司ID由应用层保证必填
*/
@ExcelProperty(value = "公司ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "由=应用层保证必填")
private Long companyId;
/**
* 模板名称
*/
@ExcelProperty(value = "模板名称")
private String templateName;
/**
* 模板类型(字典)
*/
@ExcelProperty(value = "模板类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "字=典")
private String templateType;
/**
* 样式图OSS附件ID
*/
@ExcelProperty(value = "样式图OSS附件ID")
private String styleOssId;
/**
* 内容(富文本)
*/
@ExcelProperty(value = "内容", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "富=文本")
private String content;
/**
* 创建者姓名
*/
@ExcelProperty(value = "创建者姓名")
private String createByName;
/**
* 更新者姓名
*/
@ExcelProperty(value = "更新者姓名")
private String updateByName;
/**
* 0=正常, 1=已删除
*/
@ExcelProperty(value = "0=正常, 1=已删除")
private Long isDeleted;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.dispatchTemplate.mapper;
import com.hotwj.platform.config.dispatchTemplate.domain.HotDispatchTemplate;
import com.hotwj.platform.config.dispatchTemplate.domain.vo.HotDispatchTemplateVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 下发模板Mapper接口
*
* @author shihongwei
* @date 2026-02-15
*/
@Mapper
public interface HotDispatchTemplateMapper extends BaseMapperPlus<HotDispatchTemplate, HotDispatchTemplateVo> {
}

View File

@@ -0,0 +1,70 @@
package com.hotwj.platform.config.dispatchTemplate.service;
import com.hotwj.platform.config.dispatchTemplate.domain.bo.HotDispatchTemplateBo;
import com.hotwj.platform.config.dispatchTemplate.domain.vo.HotDispatchTemplateVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 下发模板Service接口
*
* @author shihongwei
* @date 2026-02-15
*/
public interface IHotDispatchTemplateService {
/**
* 查询下发模板
*
* @param id 主键
* @return 下发模板
*/
HotDispatchTemplateVo queryById(Long id);
/**
* 分页查询下发模板列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 下发模板分页列表
*/
TableDataInfo<HotDispatchTemplateVo> queryPageList(HotDispatchTemplateBo bo, PageQuery pageQuery);
/**
* 查询符合条件的下发模板列表
*
* @param bo 查询条件
* @return 下发模板列表
*/
List<HotDispatchTemplateVo> queryList(HotDispatchTemplateBo bo);
/**
* 新增下发模板
*
* @param bo 下发模板
* @return 是否新增成功
*/
Boolean insertByBo(HotDispatchTemplateBo bo);
/**
* 修改下发模板
*
* @param bo 下发模板
* @return 是否修改成功
*/
Boolean updateByBo(HotDispatchTemplateBo bo);
/**
* 校验并批量删除下发模板信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
Boolean useDefault();
}

View File

@@ -0,0 +1,186 @@
package com.hotwj.platform.config.dispatchTemplate.service.impl;
import cn.hutool.core.collection.CollUtil;
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.hotwj.platform.config.dispatchTemplate.domain.HotDispatchTemplate;
import com.hotwj.platform.config.dispatchTemplate.domain.bo.HotDispatchTemplateBo;
import com.hotwj.platform.config.dispatchTemplate.domain.vo.HotDispatchTemplateVo;
import com.hotwj.platform.config.dispatchTemplate.mapper.HotDispatchTemplateMapper;
import com.hotwj.platform.config.dispatchTemplate.service.IHotDispatchTemplateService;
import com.hotwj.platform.resourceManagement.company.domain.vo.SysCompanyVo;
import com.hotwj.platform.resourceManagement.company.service.ISysCompanyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
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.common.satoken.utils.LoginHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 下发模板Service业务层处理
*
* @author shihongwei
* @date 2026-02-15
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotDispatchTemplateServiceImpl implements IHotDispatchTemplateService {
private final HotDispatchTemplateMapper baseMapper;
private final ISysCompanyService sysCompanyService;
/**
* 查询下发模板
*
* @param id 主键
* @return 下发模板
*/
@Override
public HotDispatchTemplateVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询下发模板列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 下发模板分页列表
*/
@Override
public TableDataInfo<HotDispatchTemplateVo> queryPageList(HotDispatchTemplateBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotDispatchTemplate> lqw = buildQueryWrapper(bo);
Page<HotDispatchTemplateVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的下发模板列表
*
* @param bo 查询条件
* @return 下发模板列表
*/
@Override
public List<HotDispatchTemplateVo> queryList(HotDispatchTemplateBo bo) {
LambdaQueryWrapper<HotDispatchTemplate> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean useDefault() {
Long companyId = LoginHelper.getCompanyId();
if (companyId == null) {
throw new ServiceException("当前登录用户无公司信息");
}
SysCompanyVo company = sysCompanyService.queryById(companyId);
if (company == null) {
throw new ServiceException("公司不存在");
}
Long count = baseMapper.selectCount(
Wrappers.lambdaQuery(HotDispatchTemplate.class)
.eq(HotDispatchTemplate::getCompanyId, companyId)
);
if (count != null && count > 0) {
throw new ServiceException("当前公司已存在下发模板配置,请先清除已存在数据");
}
List<HotDispatchTemplate> defaultConfigs = baseMapper.selectList(
Wrappers.lambdaQuery(HotDispatchTemplate.class)
.eq(HotDispatchTemplate::getCompanyId, 1L)
);
if (CollUtil.isEmpty(defaultConfigs)) {
throw new ServiceException("默认配置不存在,请联系管理员");
}
List<HotDispatchTemplate> newConfigs = new ArrayList<>();
for (HotDispatchTemplate cfg : defaultConfigs) {
HotDispatchTemplate newCfg = new HotDispatchTemplate();
newCfg.setCompanyId(companyId);
newCfg.setTemplateName(cfg.getTemplateName());
newCfg.setTemplateType(cfg.getTemplateType());
newCfg.setStyleOssId(cfg.getStyleOssId());
newCfg.setContent(cfg.getContent());
newCfg.setIsDeleted(0L);
newConfigs.add(newCfg);
}
return baseMapper.insertBatch(newConfigs);
}
private LambdaQueryWrapper<HotDispatchTemplate> buildQueryWrapper(HotDispatchTemplateBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotDispatchTemplate> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotDispatchTemplate::getId);
lqw.eq(bo.getCompanyId() != null, HotDispatchTemplate::getCompanyId, bo.getCompanyId());
lqw.like(StringUtils.isNotBlank(bo.getTemplateName()), HotDispatchTemplate::getTemplateName, bo.getTemplateName());
lqw.eq(StringUtils.isNotBlank(bo.getTemplateType()), HotDispatchTemplate::getTemplateType, bo.getTemplateType());
lqw.eq(bo.getStyleOssId() != null, HotDispatchTemplate::getStyleOssId, bo.getStyleOssId());
lqw.eq(StringUtils.isNotBlank(bo.getContent()), HotDispatchTemplate::getContent, bo.getContent());
lqw.like(StringUtils.isNotBlank(bo.getCreateByName()), HotDispatchTemplate::getCreateByName, bo.getCreateByName());
lqw.like(StringUtils.isNotBlank(bo.getUpdateByName()), HotDispatchTemplate::getUpdateByName, bo.getUpdateByName());
lqw.eq(bo.getIsDeleted() != null, HotDispatchTemplate::getIsDeleted, bo.getIsDeleted());
return lqw;
}
/**
* 新增下发模板
*
* @param bo 下发模板
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotDispatchTemplateBo bo) {
HotDispatchTemplate add = MapstructUtils.convert(bo, HotDispatchTemplate.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改下发模板
*
* @param bo 下发模板
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotDispatchTemplateBo bo) {
HotDispatchTemplate update = MapstructUtils.convert(bo, HotDispatchTemplate.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotDispatchTemplate entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除下发模板信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,129 @@
package com.hotwj.platform.config.driverAnnualAssessmentConfig.controller;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.bo.HotDriverAnnualAssessmentConfigBo;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.vo.HotDriverAnnualAssessmentConfigVo;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.service.IHotDriverAnnualAssessmentConfigService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 驾驶员年度考核配置
*
* @author shihongwei
* @date 2025-12-16
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/driverAnnualAssessmentConfig")
@Tag(name = "驾驶员年度考核配置", description = "年度考核配置管理")
public class HotDriverAnnualAssessmentConfigController extends BaseController {
private final IHotDriverAnnualAssessmentConfigService hotDriverAnnualAssessmentConfigService;
/**
* 查询驾驶员年度考核配置列表
*/
//@SaCheckPermission("config:driverAnnualAssessmentConfig:list")
@GetMapping("/list")
public TableDataInfo<HotDriverAnnualAssessmentConfigVo> list(HotDriverAnnualAssessmentConfigBo bo, PageQuery pageQuery) {
return hotDriverAnnualAssessmentConfigService.queryPageList(bo, pageQuery);
}
/**
* 导出驾驶员年度考核配置列表
*/
//@SaCheckPermission("config:driverAnnualAssessmentConfig:export")
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HotDriverAnnualAssessmentConfigBo bo, HttpServletResponse response) {
List<HotDriverAnnualAssessmentConfigVo> list = hotDriverAnnualAssessmentConfigService.queryList(bo);
ExcelUtil.exportExcel(list, "驾驶员年度考核配置", HotDriverAnnualAssessmentConfigVo.class, response);
}
/**
* 获取驾驶员年度考核配置详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:driverAnnualAssessmentConfig:query")
@GetMapping("/{id}")
public R<HotDriverAnnualAssessmentConfigVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(hotDriverAnnualAssessmentConfigService.queryById(id));
}
/**
* 新增驾驶员年度考核配置
*/
//@SaCheckPermission("config:driverAnnualAssessmentConfig:add")
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotDriverAnnualAssessmentConfigBo bo) {
return toAjax(hotDriverAnnualAssessmentConfigService.insertByBo(bo));
}
/**
* 修改驾驶员年度考核配置
*/
//@SaCheckPermission("config:driverAnnualAssessmentConfig:edit")
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotDriverAnnualAssessmentConfigBo bo) {
return toAjax(hotDriverAnnualAssessmentConfigService.updateByBo(bo));
}
/**
* 删除驾驶员年度考核配置
*
* @param ids 主键串
*/
//@SaCheckPermission("config:driverAnnualAssessmentConfig:remove")
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(hotDriverAnnualAssessmentConfigService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 采用默认配置
*/
//@SaCheckPermission("config:driverAnnualAssessmentConfig:add")
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/useDefault")
public R<Void> useDefault() {
return toAjax(hotDriverAnnualAssessmentConfigService.useDefault());
}
/**
* 一键清空
*/
//@SaCheckPermission("config:driverAnnualAssessmentConfig:remove")
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.DELETE)
@RepeatSubmit()
@PostMapping("/clearAll")
public R<Void> clearAll() {
return toAjax(hotDriverAnnualAssessmentConfigService.clearAll());
}
}

View File

@@ -0,0 +1,62 @@
package com.hotwj.platform.config.driverAnnualAssessmentConfig.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 驾驶员年度考核配置对象 hot_driver_annual_assessment_config
*
* @author shihongwei
* @date 2025-12-16
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_driver_annual_assessment_config")
public class HotDriverAnnualAssessmentConfig extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 考核内容
*/
private String content;
/**
* 分数
*/
private Long score;
/**
* 类型
*/
private String category;
/**
* 0=正常, 1=已删除
*/
@TableLogic
private Long isDeleted;
/**
* 是否启用
*/
private Long isEnabled;
}

View File

@@ -0,0 +1,58 @@
package com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.bo;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.HotDriverAnnualAssessmentConfig;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 驾驶员年度考核配置业务对象 hot_driver_annual_assessment_config
*
* @author shihongwei
* @date 2025-12-16
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotDriverAnnualAssessmentConfig.class, reverseConvertGenerate = false)
public class HotDriverAnnualAssessmentConfigBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 考核内容
*/
private String content;
/**
* 分数
*/
private Long score;
/**
* 类型
*/
private String category;
/**
* 0=正常, 1=已删除
*/
private Long isDeleted;
/**
* 是否启用
*/
private Long isEnabled;
}

View File

@@ -0,0 +1,67 @@
package com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.HotDriverAnnualAssessmentConfig;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 驾驶员年度考核配置视图对象 hot_driver_annual_assessment_config
*
* @author shihongwei
* @date 2025-12-16
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotDriverAnnualAssessmentConfig.class)
public class HotDriverAnnualAssessmentConfigVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 公司ID
*/
@ExcelProperty(value = "公司ID")
private Long companyId;
/**
* 考核内容
*/
@ExcelProperty(value = "考核内容")
private String content;
/**
* 分数
*/
@ExcelProperty(value = "分数")
private Long score;
/**
* 类型
*/
@ExcelProperty(value = "类型")
private String category;
/**
* 0=正常, 1=已删除
*/
@ExcelProperty(value = "0=正常, 1=已删除")
private Long isDeleted;
/**
* 是否启用
*/
private Long isEnabled;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.driverAnnualAssessmentConfig.mapper;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.HotDriverAnnualAssessmentConfig;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.vo.HotDriverAnnualAssessmentConfigVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 驾驶员年度考核配置Mapper接口
*
* @author shihongwei
* @date 2025-12-16
*/
@Mapper
public interface HotDriverAnnualAssessmentConfigMapper extends BaseMapperPlus<HotDriverAnnualAssessmentConfig, HotDriverAnnualAssessmentConfigVo> {
}

View File

@@ -0,0 +1,82 @@
package com.hotwj.platform.config.driverAnnualAssessmentConfig.service;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.bo.HotDriverAnnualAssessmentConfigBo;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.vo.HotDriverAnnualAssessmentConfigVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 驾驶员年度考核配置Service接口
*
* @author shihongwei
* @date 2025-12-16
*/
public interface IHotDriverAnnualAssessmentConfigService {
/**
* 查询驾驶员年度考核配置
*
* @param id 主键
* @return 驾驶员年度考核配置
*/
HotDriverAnnualAssessmentConfigVo queryById(Long id);
/**
* 分页查询驾驶员年度考核配置列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 驾驶员年度考核配置分页列表
*/
TableDataInfo<HotDriverAnnualAssessmentConfigVo> queryPageList(HotDriverAnnualAssessmentConfigBo bo, PageQuery pageQuery);
/**
* 查询符合条件的驾驶员年度考核配置列表
*
* @param bo 查询条件
* @return 驾驶员年度考核配置列表
*/
List<HotDriverAnnualAssessmentConfigVo> queryList(HotDriverAnnualAssessmentConfigBo bo);
/**
* 新增驾驶员年度考核配置
*
* @param bo 驾驶员年度考核配置
* @return 是否新增成功
*/
Boolean insertByBo(HotDriverAnnualAssessmentConfigBo bo);
/**
* 修改驾驶员年度考核配置
*
* @param bo 驾驶员年度考核配置
* @return 是否修改成功
*/
Boolean updateByBo(HotDriverAnnualAssessmentConfigBo bo);
/**
* 校验并批量删除驾驶员年度考核配置信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 采用默认配置
*
* @return 结果
*/
Boolean useDefault();
/**
* 清空当前公司所有配置
*
* @return 是否成功
*/
Boolean clearAll();
}

View File

@@ -0,0 +1,268 @@
package com.hotwj.platform.config.driverAnnualAssessmentConfig.service.impl;
import cn.hutool.core.collection.CollUtil;
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.hotwj.platform.config.driverAnnualAssessmentConfig.domain.HotDriverAnnualAssessmentConfig;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.bo.HotDriverAnnualAssessmentConfigBo;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.vo.HotDriverAnnualAssessmentConfigVo;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.mapper.HotDriverAnnualAssessmentConfigMapper;
import com.hotwj.platform.config.driverAnnualAssessmentConfig.service.IHotDriverAnnualAssessmentConfigService;
import com.hotwj.platform.resourceManagement.company.domain.vo.SysCompanyVo;
import com.hotwj.platform.resourceManagement.company.service.ISysCompanyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
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.common.satoken.utils.LoginHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 驾驶员年度考核配置Service业务层处理
*
* @author shihongwei
* @date 2025-12-16
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotDriverAnnualAssessmentConfigServiceImpl implements IHotDriverAnnualAssessmentConfigService {
private static final long ENABLED_STATUS = 1L;
private static final long DISABLED_STATUS = 0L;
private static final long MAX_ENABLED_TOTAL_SCORE = 100L;
private final HotDriverAnnualAssessmentConfigMapper baseMapper;
private final ISysCompanyService sysCompanyService;
/**
* 查询驾驶员年度考核配置
*
* @param id 主键
* @return 驾驶员年度考核配置
*/
@Override
public HotDriverAnnualAssessmentConfigVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean useDefault() {
Long companyId = LoginHelper.getCompanyId();
if (companyId == null) {
throw new ServiceException("当前登录用户无公司信息");
}
SysCompanyVo company = sysCompanyService.queryById(companyId);
if (company == null) {
throw new ServiceException("公司不存在");
}
// 校验当前公司是否已有配置
Long count = baseMapper.selectCount(
Wrappers.lambdaQuery(HotDriverAnnualAssessmentConfig.class)
.eq(HotDriverAnnualAssessmentConfig::getCompanyId, companyId)
);
if (count != null && count > 0) {
throw new ServiceException("当前公司已存在考核配置,请先清除已存在数据");
}
// 获取总部配置 (companyId = 1)
List<HotDriverAnnualAssessmentConfig> defaultConfigs = baseMapper.selectList(
Wrappers.lambdaQuery(HotDriverAnnualAssessmentConfig.class)
.eq(HotDriverAnnualAssessmentConfig::getCompanyId, 1L)
);
if (CollUtil.isEmpty(defaultConfigs)) {
throw new ServiceException("默认配置不存在,请联系管理员");
}
List<HotDriverAnnualAssessmentConfig> newConfigs = new ArrayList<>();
for (HotDriverAnnualAssessmentConfig cfg : defaultConfigs) {
HotDriverAnnualAssessmentConfig newCfg = new HotDriverAnnualAssessmentConfig();
// 复制属性排除ID和创建时间等
newCfg.setCompanyId(companyId);
newCfg.setContent(cfg.getContent());
newCfg.setScore(cfg.getScore());
newCfg.setCategory(cfg.getCategory());
newCfg.setIsDeleted(0L);
newConfigs.add(newCfg);
}
return baseMapper.insertBatch(newConfigs);
}
/**
* 分页查询驾驶员年度考核配置列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 驾驶员年度考核配置分页列表
*/
@Override
public TableDataInfo<HotDriverAnnualAssessmentConfigVo> queryPageList(HotDriverAnnualAssessmentConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotDriverAnnualAssessmentConfig> lqw = buildQueryWrapper(bo);
Page<HotDriverAnnualAssessmentConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的驾驶员年度考核配置列表
*
* @param bo 查询条件
* @return 驾驶员年度考核配置列表
*/
@Override
public List<HotDriverAnnualAssessmentConfigVo> queryList(HotDriverAnnualAssessmentConfigBo bo) {
LambdaQueryWrapper<HotDriverAnnualAssessmentConfig> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<HotDriverAnnualAssessmentConfig> buildQueryWrapper(HotDriverAnnualAssessmentConfigBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotDriverAnnualAssessmentConfig> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotDriverAnnualAssessmentConfig::getId);
lqw.eq(bo.getCompanyId() != null, HotDriverAnnualAssessmentConfig::getCompanyId, bo.getCompanyId());
lqw.eq(StringUtils.isNotBlank(bo.getContent()), HotDriverAnnualAssessmentConfig::getContent, bo.getContent());
lqw.eq(bo.getScore() != null, HotDriverAnnualAssessmentConfig::getScore, bo.getScore());
lqw.eq(StringUtils.isNotBlank(bo.getCategory()), HotDriverAnnualAssessmentConfig::getCategory, bo.getCategory());
lqw.eq(bo.getIsDeleted() != null, HotDriverAnnualAssessmentConfig::getIsDeleted, bo.getIsDeleted());
return lqw;
}
/**
* 新增驾驶员年度考核配置
*
* @param bo 驾驶员年度考核配置
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotDriverAnnualAssessmentConfigBo bo) {
HotDriverAnnualAssessmentConfig add = MapstructUtils.convert(bo, HotDriverAnnualAssessmentConfig.class);
Long companyId = resolveCompanyId(add.getCompanyId());
add.setCompanyId(companyId);
applyInsertEnabledRule(add, companyId);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改驾驶员年度考核配置
*
* @param bo 驾驶员年度考核配置
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotDriverAnnualAssessmentConfigBo bo) {
HotDriverAnnualAssessmentConfig update = MapstructUtils.convert(bo, HotDriverAnnualAssessmentConfig.class);
Long companyId = resolveCompanyId(update.getCompanyId());
update.setCompanyId(companyId);
validateUpdateEnabledRule(update, companyId);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotDriverAnnualAssessmentConfig entity) {
//TODO 做一些数据校验,如唯一约束
}
private Long resolveCompanyId(Long companyId) {
if (companyId != null) {
return companyId;
}
Long loginCompanyId = LoginHelper.getCompanyId();
if (loginCompanyId == null) {
throw new ServiceException("当前登录用户无公司信息");
}
return loginCompanyId;
}
private void applyInsertEnabledRule(HotDriverAnnualAssessmentConfig entity, Long companyId) {
Long isEnabled = entity.getIsEnabled();
if (isEnabled == null || isEnabled != ENABLED_STATUS) {
if (isEnabled == null) {
entity.setIsEnabled(DISABLED_STATUS);
}
return;
}
long enabledTotalScore = getEnabledTotalScore(companyId, null) + safeScore(entity.getScore());
if (enabledTotalScore > MAX_ENABLED_TOTAL_SCORE) {
entity.setIsEnabled(DISABLED_STATUS);
}
}
private void validateUpdateEnabledRule(HotDriverAnnualAssessmentConfig entity, Long companyId) {
if (entity.getIsEnabled() == null || entity.getIsEnabled() != ENABLED_STATUS) {
return;
}
long enabledTotalScore = getEnabledTotalScore(companyId, entity.getId()) + safeScore(entity.getScore());
if (enabledTotalScore > MAX_ENABLED_TOTAL_SCORE) {
throw new ServiceException("启用失败当前启用项总分值不能超过100分");
}
}
private long getEnabledTotalScore(Long companyId, Long excludeId) {
LambdaQueryWrapper<HotDriverAnnualAssessmentConfig> lqw = Wrappers.lambdaQuery();
lqw.eq(HotDriverAnnualAssessmentConfig::getCompanyId, companyId);
lqw.eq(HotDriverAnnualAssessmentConfig::getIsEnabled, ENABLED_STATUS);
lqw.ne(excludeId != null, HotDriverAnnualAssessmentConfig::getId, excludeId);
List<HotDriverAnnualAssessmentConfig> enabledConfigs = baseMapper.selectList(lqw);
return enabledConfigs.stream()
.map(HotDriverAnnualAssessmentConfig::getScore)
.filter(score -> score != null)
.mapToLong(Long::longValue)
.sum();
}
private long safeScore(Long score) {
return score == null ? 0L : score;
}
/**
* 校验并批量删除驾驶员年度考核配置信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean clearAll() {
Long companyId = LoginHelper.getCompanyId();
if (companyId == null) {
throw new ServiceException("当前登录用户无公司信息");
}
// 逻辑删除当前公司所有配置
return baseMapper.delete(
Wrappers.lambdaQuery(HotDriverAnnualAssessmentConfig.class)
.eq(HotDriverAnnualAssessmentConfig::getCompanyId, companyId)
) > 0;
}
}

View File

@@ -0,0 +1,127 @@
package com.hotwj.platform.config.examPaper.controller;
import com.hotwj.platform.config.examPaper.domain.bo.ExamPaperSaveQuestionsBo;
import com.hotwj.platform.config.examPaper.domain.bo.HotExamPaperBo;
import com.hotwj.platform.config.examPaper.domain.vo.ExamPaperSaveQuestionsResultVo;
import com.hotwj.platform.config.examPaper.domain.vo.HotExamPaperVo;
import com.hotwj.platform.config.examPaper.service.IHotExamPaperService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 试卷库
*
* @author shihongwei
* @date 2025-12-23
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/examPaper")
@Tag(name = "试卷库", description = "试卷库管理")
public class HotExamPaperController extends BaseController {
private final IHotExamPaperService hotExamPaperService;
/**
* 查询试卷库列表
*/
//@SaCheckPermission("config:examPaper:list")
@GetMapping("/list")
@Operation(summary = "分页查询试卷库列表")
public TableDataInfo<HotExamPaperVo> list(HotExamPaperBo bo, PageQuery pageQuery) {
return hotExamPaperService.queryPageList(bo, pageQuery);
}
/**
* 导出试卷库列表
*/
//@SaCheckPermission("config:examPaper:export")
@Log(title = "试卷库", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "导出试卷库列表")
public void export(HotExamPaperBo bo, HttpServletResponse response) {
List<HotExamPaperVo> list = hotExamPaperService.queryList(bo);
ExcelUtil.exportExcel(list, "试卷库", HotExamPaperVo.class, response);
}
/**
* 获取试卷库详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:examPaper:query")
@GetMapping("/{id}")
@Operation(summary = "获取试卷库详细信息")
public R<HotExamPaperVo> getInfo(@NotNull(message = "主键不能为空")
@Parameter(name = "id", description = "主键", required = true, example = "1")
@PathVariable Long id) {
return R.ok(hotExamPaperService.queryById(id));
}
/**
* 新增试卷库
*/
//@SaCheckPermission("config:examPaper:add")
@Log(title = "试卷库", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@Operation(summary = "新增试卷库")
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotExamPaperBo bo) {
return toAjax(hotExamPaperService.insertByBo(bo));
}
/**
* 修改试卷库
*/
//@SaCheckPermission("config:examPaper:edit")
@Log(title = "试卷库", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@Operation(summary = "修改试卷库")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotExamPaperBo bo) {
return toAjax(hotExamPaperService.updateByBo(bo));
}
@Log(title = "试卷库", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/saveQuestions")
@Operation(summary = "试卷题目批量保存")
public R<ExamPaperSaveQuestionsResultVo> saveQuestions(@Validated @RequestBody ExamPaperSaveQuestionsBo bo) {
return R.ok(hotExamPaperService.saveQuestions(bo));
}
/**
* 删除试卷库
*
* @param ids 主键串
*/
//@SaCheckPermission("config:examPaper:remove")
@Log(title = "试卷库", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@Operation(summary = "删除试卷库")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
@PathVariable Long[] ids) {
return toAjax(hotExamPaperService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -0,0 +1,89 @@
package com.hotwj.platform.config.examPaper.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 试卷库对象 hot_exam_paper
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_exam_paper")
public class HotExamPaper extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 试卷名称
*/
private String name;
/**
* 试卷分类字典编码
*/
private String categoryCode;
/**
* 教育类型字典编码
*/
private String trainingTypeCode;
/**
* 教育类型子集编码集(JSON/逗号分隔)
*/
private String trainingSubtypeCodes;
/**
* 检测题数
*/
private Long questionCount;
/**
* 试卷总分
*/
private Long totalScore;
/**
* 及格分数
*/
private Long passScore;
/**
* 状态1=启用 0=禁用
*/
private Long status;
/**
* 备注
*/
private String remark;
/**
* 0=正常, 1=已删除
*/
@TableLogic
private Long isDeleted;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.examPaper.domain.bo;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Data
public class ExamPaperSaveQuestionsBo {
@NotNull(message = "试卷ID不能为空")
private Long paperId;
@NotNull(message = "题目类型不能为空")
private String questionType;
private List<Long> questions;
}

View File

@@ -0,0 +1,84 @@
package com.hotwj.platform.config.examPaper.domain.bo;
import com.hotwj.platform.config.examPaper.domain.HotExamPaper;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 试卷库业务对象 hot_exam_paper
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotExamPaper.class, reverseConvertGenerate = false)
public class HotExamPaperBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 试卷名称
*/
private String name;
/**
* 试卷分类字典编码
*/
private String categoryCode;
/**
* 教育类型字典编码
*/
private String trainingTypeCode;
/**
* 教育类型子集编码集(JSON/逗号分隔)
*/
private String trainingSubtypeCodes;
/**
* 检测题数
*/
private Long questionCount;
/**
* 试卷总分
*/
private Long totalScore;
/**
* 及格分数
*/
private Long passScore;
/**
* 状态1=启用 0=禁用
*/
private Long status;
/**
* 备注
*/
private String remark;
/**
* 0=正常, 1=已删除
*/
private Long isDeleted;
}

View File

@@ -0,0 +1,16 @@
package com.hotwj.platform.config.examPaper.domain.vo;
import lombok.Data;
@Data
public class ExamPaperSaveQuestionsResultVo {
private Long totalScore;
private Long passScore;
private Long questionCount;
private Long singleChoiceCount;
private Long multiChoiceCount;
private Long judgeCount;
private Long singleChoiceScore;
private Long multiChoiceScore;
private Long judgeScore;
}

View File

@@ -0,0 +1,114 @@
package com.hotwj.platform.config.examPaper.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.examPaper.domain.HotExamPaper;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 试卷库视图对象 hot_exam_paper
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotExamPaper.class)
public class HotExamPaperVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 公司ID
*/
@ExcelProperty(value = "公司ID")
private Long companyId;
/**
* 试卷名称
*/
@ExcelProperty(value = "试卷名称")
private String name;
/**
* 试卷分类字典编码
*/
@ExcelProperty(value = "试卷分类字典编码")
private String categoryCode;
/**
* 教育类型字典编码
*/
@ExcelProperty(value = "教育类型字典编码")
private String trainingTypeCode;
/**
* 教育类型子集编码集(JSON/逗号分隔)
*/
@ExcelProperty(value = "教育类型子集编码集(JSON/逗号分隔)")
private String trainingSubtypeCodes;
/**
* 检测题数
*/
@ExcelProperty(value = "检测题数")
private Long questionCount;
/**
* 试卷总分
*/
@ExcelProperty(value = "试卷总分")
private Long totalScore;
/**
* 及格分数
*/
@ExcelProperty(value = "及格分数")
private Long passScore;
/**
* 状态1=启用 0=禁用
*/
@ExcelProperty(value = "状态1=启用 0=禁用")
private Long status;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 0=正常, 1=已删除
*/
@ExcelProperty(value = "0=正常, 1=已删除")
private Long isDeleted;
private Date createTime;
private Long singleChoiceCount;
private Long multiChoiceCount;
private Long judgeCount;
private Long singleChoiceScore;
private Long multiChoiceScore;
private Long judgeScore;
}

View File

@@ -0,0 +1,17 @@
package com.hotwj.platform.config.examPaper.mapper;
import com.hotwj.platform.config.examPaper.domain.HotExamPaper;
import com.hotwj.platform.config.examPaper.domain.vo.HotExamPaperVo;
import org.apache.ibatis.annotations.Mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 试卷库Mapper接口
*
* @author shihongwei
* @date 2025-12-23
*/
@Mapper
public interface HotExamPaperMapper extends BaseMapperPlus<HotExamPaper, HotExamPaperVo> {
}

View File

@@ -0,0 +1,72 @@
package com.hotwj.platform.config.examPaper.service;
import com.hotwj.platform.config.examPaper.domain.bo.ExamPaperSaveQuestionsBo;
import com.hotwj.platform.config.examPaper.domain.bo.HotExamPaperBo;
import com.hotwj.platform.config.examPaper.domain.vo.ExamPaperSaveQuestionsResultVo;
import com.hotwj.platform.config.examPaper.domain.vo.HotExamPaperVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 试卷库Service接口
*
* @author shihongwei
* @date 2025-12-23
*/
public interface IHotExamPaperService {
/**
* 查询试卷库
*
* @param id 主键
* @return 试卷库
*/
HotExamPaperVo queryById(Long id);
/**
* 分页查询试卷库列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 试卷库分页列表
*/
TableDataInfo<HotExamPaperVo> queryPageList(HotExamPaperBo bo, PageQuery pageQuery);
/**
* 查询符合条件的试卷库列表
*
* @param bo 查询条件
* @return 试卷库列表
*/
List<HotExamPaperVo> queryList(HotExamPaperBo bo);
/**
* 新增试卷库
*
* @param bo 试卷库
* @return 是否新增成功
*/
Boolean insertByBo(HotExamPaperBo bo);
/**
* 修改试卷库
*
* @param bo 试卷库
* @return 是否修改成功
*/
Boolean updateByBo(HotExamPaperBo bo);
ExamPaperSaveQuestionsResultVo saveQuestions(ExamPaperSaveQuestionsBo bo);
/**
* 校验并批量删除试卷库信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,333 @@
package com.hotwj.platform.config.examPaper.service.impl;
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.hotwj.platform.config.examPaper.domain.HotExamPaper;
import com.hotwj.platform.config.examPaper.domain.bo.ExamPaperSaveQuestionsBo;
import com.hotwj.platform.config.examPaper.domain.bo.HotExamPaperBo;
import com.hotwj.platform.config.examPaper.domain.vo.ExamPaperSaveQuestionsResultVo;
import com.hotwj.platform.config.examPaper.domain.vo.HotExamPaperVo;
import com.hotwj.platform.config.examPaper.mapper.HotExamPaperMapper;
import com.hotwj.platform.config.examPaper.service.IHotExamPaperService;
import com.hotwj.platform.config.examPaperQuestion.domain.HotExamPaperQuestion;
import com.hotwj.platform.config.examPaperQuestion.mapper.HotExamPaperQuestionMapper;
import com.hotwj.platform.config.questionBank.domain.HotQuestionBank;
import com.hotwj.platform.config.questionBank.mapper.HotQuestionBankMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
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.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
/**
* 试卷库Service业务层处理
*
* @author shihongwei
* @date 2025-12-23
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotExamPaperServiceImpl implements IHotExamPaperService {
private final HotExamPaperMapper baseMapper;
private final HotExamPaperQuestionMapper examPaperQuestionMapper;
private final HotQuestionBankMapper questionBankMapper;
/**
* 查询试卷库
*
* @param id 主键
* @return 试卷库
*/
@Override
public HotExamPaperVo queryById(Long id) {
HotExamPaperVo vo = baseMapper.selectVoById(id);
if (vo == null || vo.getId() == null) {
return vo;
}
List<HotExamPaperQuestion> relations = examPaperQuestionMapper.selectList(
Wrappers.<HotExamPaperQuestion>lambdaQuery()
.eq(HotExamPaperQuestion::getPaperId, vo.getId())
);
if (relations == null || relations.isEmpty()) {
vo.setSingleChoiceCount(0L);
vo.setMultiChoiceCount(0L);
vo.setJudgeCount(0L);
vo.setSingleChoiceScore(0L);
vo.setMultiChoiceScore(0L);
vo.setJudgeScore(0L);
return vo;
}
long singleCount = 0L;
long multiCount = 0L;
long judgeCount = 0L;
long singleScore = 0L;
long multiScore = 0L;
long judgeScore = 0L;
for (HotExamPaperQuestion r : relations) {
if (r == null) {
continue;
}
long score = r.getScore() == null ? 0L : r.getScore();
String t = r.getQuestionType();
if ("1".equals(t)) {
singleCount++;
singleScore += score;
} else if ("2".equals(t)) {
multiCount++;
multiScore += score;
} else if ("3".equals(t)) {
judgeCount++;
judgeScore += score;
}
}
vo.setSingleChoiceCount(singleCount);
vo.setMultiChoiceCount(multiCount);
vo.setJudgeCount(judgeCount);
vo.setSingleChoiceScore(singleScore);
vo.setMultiChoiceScore(multiScore);
vo.setJudgeScore(judgeScore);
return vo;
}
/**
* 分页查询试卷库列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 试卷库分页列表
*/
@Override
public TableDataInfo<HotExamPaperVo> queryPageList(HotExamPaperBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotExamPaper> lqw = buildQueryWrapper(bo);
Page<HotExamPaperVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的试卷库列表
*
* @param bo 查询条件
* @return 试卷库列表
*/
@Override
public List<HotExamPaperVo> queryList(HotExamPaperBo bo) {
LambdaQueryWrapper<HotExamPaper> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<HotExamPaper> buildQueryWrapper(HotExamPaperBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotExamPaper> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotExamPaper::getId);
// lqw.eq(bo.getCompanyId() != null, HotExamPaper::getCompanyId, bo.getCompanyId());
lqw.like(StringUtils.isNotBlank(bo.getName()), HotExamPaper::getName, bo.getName());
lqw.eq(StringUtils.isNotBlank(bo.getCategoryCode()), HotExamPaper::getCategoryCode, bo.getCategoryCode());
lqw.eq(StringUtils.isNotBlank(bo.getTrainingTypeCode()), HotExamPaper::getTrainingTypeCode, bo.getTrainingTypeCode());
lqw.eq(StringUtils.isNotBlank(bo.getTrainingSubtypeCodes()), HotExamPaper::getTrainingSubtypeCodes, bo.getTrainingSubtypeCodes());
lqw.eq(bo.getQuestionCount() != null, HotExamPaper::getQuestionCount, bo.getQuestionCount());
lqw.eq(bo.getTotalScore() != null, HotExamPaper::getTotalScore, bo.getTotalScore());
lqw.eq(bo.getPassScore() != null, HotExamPaper::getPassScore, bo.getPassScore());
lqw.eq(bo.getStatus() != null, HotExamPaper::getStatus, bo.getStatus());
lqw.eq(bo.getIsDeleted() != null, HotExamPaper::getIsDeleted, bo.getIsDeleted());
lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
HotExamPaper::getCreateTime, params.get("beginTime"), params.get("endTime"));
return lqw;
}
/**
* 新增试卷库
*
* @param bo 试卷库
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotExamPaperBo bo) {
HotExamPaper add = MapstructUtils.convert(bo, HotExamPaper.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改试卷库
*
* @param bo 试卷库
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotExamPaperBo bo) {
HotExamPaper update = MapstructUtils.convert(bo, HotExamPaper.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
@Transactional(rollbackFor = Exception.class)
@Override
public ExamPaperSaveQuestionsResultVo saveQuestions(ExamPaperSaveQuestionsBo bo) {
if (bo == null || bo.getPaperId() == null) {
throw new ServiceException("试卷ID不能为空");
}
if (StringUtils.isBlank(bo.getQuestionType())) {
throw new ServiceException("题目类型不能为空");
}
String targetType = bo.getQuestionType();
if (!"1".equals(targetType) && !"2".equals(targetType) && !"3".equals(targetType)) {
throw new ServiceException("题目类型不合法");
}
HotExamPaper paper = baseMapper.selectById(bo.getPaperId());
if (paper == null || (paper.getIsDeleted() != null && paper.getIsDeleted() == 1L)) {
throw new ServiceException("试卷不存在");
}
Set<Long> questionIdSet = new LinkedHashSet<>();
if (bo.getQuestions() != null) {
for (Long id : bo.getQuestions()) {
if (id != null) {
questionIdSet.add(id);
}
}
}
List<Long> questionIds = questionIdSet.stream().toList();
Map<Long, HotQuestionBank> questionMap = questionIds.isEmpty() ? Map.of() :
questionBankMapper.selectList(
Wrappers.<HotQuestionBank>lambdaQuery()
.in(HotQuestionBank::getId, questionIds)
.eq(HotQuestionBank::getIsDeleted, 0L)
.eq(paper.getCompanyId() != null, HotQuestionBank::getCompanyId, paper.getCompanyId())
).stream().filter(Objects::nonNull).collect(Collectors.toMap(HotQuestionBank::getId, q -> q, (a, b) -> a));
if (questionMap.size() != questionIds.size()) {
throw new ServiceException("题目列表包含不存在或已删除的题目");
}
for (HotQuestionBank q : questionMap.values()) {
if (q == null || q.getQuestionType() == null) {
throw new ServiceException("题目类型不能为空");
}
if (!targetType.equals(String.valueOf(q.getQuestionType()))) {
throw new ServiceException("题目列表包含非当前题型的题目");
}
}
examPaperQuestionMapper.delete(
Wrappers.<HotExamPaperQuestion>lambdaQuery()
.eq(HotExamPaperQuestion::getPaperId, paper.getId())
.eq(HotExamPaperQuestion::getQuestionType, targetType)
);
List<HotExamPaperQuestion> relations = new ArrayList<>(questionIds.size());
long sortOrder = 1L;
for (Long questionId : questionIds) {
HotQuestionBank q = questionMap.get(questionId);
long score = q.getScore() == null ? 0L : q.getScore();
HotExamPaperQuestion r = new HotExamPaperQuestion();
r.setCompanyId(paper.getCompanyId());
r.setPaperId(paper.getId());
r.setQuestionId(questionId);
r.setQuestionType(targetType);
r.setSortOrder(sortOrder++);
r.setScore(score);
relations.add(r);
}
if (!relations.isEmpty()) {
examPaperQuestionMapper.insertBatch(relations);
}
List<HotExamPaperQuestion> allRelations = examPaperQuestionMapper.selectList(
Wrappers.<HotExamPaperQuestion>lambdaQuery()
.eq(HotExamPaperQuestion::getPaperId, paper.getId())
);
long questionCount = 0L;
long totalScore = 0L;
long singleCount = 0L;
long multiCount = 0L;
long judgeCount = 0L;
long singleChoiceScore = 0L;
long multiChoiceScore = 0L;
long judgeScore = 0L;
if (allRelations != null) {
for (HotExamPaperQuestion r : allRelations) {
if (r == null) {
continue;
}
questionCount++;
long score = r.getScore() == null ? 0L : r.getScore();
totalScore += score;
if ("1".equals(r.getQuestionType())) {
singleCount++;
singleChoiceScore += score;
} else if ("2".equals(r.getQuestionType())) {
multiCount++;
multiChoiceScore += score;
} else if ("3".equals(r.getQuestionType())) {
judgeCount++;
judgeScore += score;
}
}
}
baseMapper.update(
null,
Wrappers.<HotExamPaper>lambdaUpdate()
.set(HotExamPaper::getQuestionCount, questionCount)
.set(HotExamPaper::getTotalScore, totalScore)
.eq(HotExamPaper::getId, paper.getId())
);
ExamPaperSaveQuestionsResultVo result = new ExamPaperSaveQuestionsResultVo();
result.setQuestionCount(questionCount);
result.setTotalScore(totalScore);
result.setPassScore(paper.getPassScore());
result.setSingleChoiceCount(singleCount);
result.setMultiChoiceCount(multiCount);
result.setJudgeCount(judgeCount);
result.setSingleChoiceScore(singleChoiceScore);
result.setMultiChoiceScore(multiChoiceScore);
result.setJudgeScore(judgeScore);
return result;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotExamPaper entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除试卷库信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@@ -0,0 +1,124 @@
package com.hotwj.platform.config.examPaperQuestion.controller;
import com.hotwj.platform.config.examPaperQuestion.domain.bo.HotExamPaperQuestionBo;
import com.hotwj.platform.config.examPaperQuestion.domain.vo.ExamPaperQuestionsGroupedVo;
import com.hotwj.platform.config.examPaperQuestion.domain.vo.HotExamPaperQuestionVo;
import com.hotwj.platform.config.examPaperQuestion.service.IHotExamPaperQuestionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
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.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 试卷-题目关联
*
* @author shihongwei
* @date 2025-12-23
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/config/examPaperQuestion")
@Tag(name = "试卷-题目关联", description = "试卷-题目关联管理")
public class HotExamPaperQuestionController extends BaseController {
private final IHotExamPaperQuestionService hotExamPaperQuestionService;
/**
* 查询试卷-题目关联列表
*/
//@SaCheckPermission("config:examPaperQuestion:list")
@GetMapping("/list")
@Operation(summary = "分页查询试卷-题目关联列表")
public TableDataInfo<HotExamPaperQuestionVo> list(HotExamPaperQuestionBo bo, PageQuery pageQuery) {
return hotExamPaperQuestionService.queryPageList(bo, pageQuery);
}
/**
* 导出试卷-题目关联列表
*/
//@SaCheckPermission("config:examPaperQuestion:export")
@Log(title = "试卷-题目关联", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@Operation(summary = "导出试卷-题目关联列表")
public void export(HotExamPaperQuestionBo bo, HttpServletResponse response) {
List<HotExamPaperQuestionVo> list = hotExamPaperQuestionService.queryList(bo);
ExcelUtil.exportExcel(list, "试卷-题目关联", HotExamPaperQuestionVo.class, response);
}
/**
* 获取试卷-题目关联详细信息
*
* @param id 主键
*/
//@SaCheckPermission("config:examPaperQuestion:query")
@GetMapping("/{id}")
@Operation(summary = "获取试卷-题目关联详细信息")
public R<HotExamPaperQuestionVo> getInfo(@NotNull(message = "主键不能为空")
@Parameter(name = "id", description = "主键", required = true, example = "1")
@PathVariable Long id) {
return R.ok(hotExamPaperQuestionService.queryById(id));
}
/**
* 新增试卷-题目关联
*/
//@SaCheckPermission("config:examPaperQuestion:add")
@Log(title = "试卷-题目关联", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@Operation(summary = "新增试卷-题目关联")
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotExamPaperQuestionBo bo) {
return toAjax(hotExamPaperQuestionService.insertByBo(bo));
}
/**
* 修改试卷-题目关联
*/
//@SaCheckPermission("config:examPaperQuestion:edit")
@Log(title = "试卷-题目关联", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@Operation(summary = "修改试卷-题目关联")
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotExamPaperQuestionBo bo) {
return toAjax(hotExamPaperQuestionService.updateByBo(bo));
}
/**
* 删除试卷-题目关联
*
* @param ids 主键串
*/
//@SaCheckPermission("config:examPaperQuestion:remove")
@Log(title = "试卷-题目关联", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@Operation(summary = "删除试卷-题目关联")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
@PathVariable Long[] ids) {
return toAjax(hotExamPaperQuestionService.deleteWithValidByIds(List.of(ids), true));
}
@GetMapping("/groupedQuestionBank")
@Operation(summary = "按试卷查询题库题目并按题型分组")
public R<ExamPaperQuestionsGroupedVo> groupedQuestionBank(@RequestParam Long paperId) {
return R.ok(hotExamPaperQuestionService.queryGroupedQuestionBankByPaperId(paperId));
}
}

View File

@@ -0,0 +1,62 @@
package com.hotwj.platform.config.examPaperQuestion.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 试卷-题目关联对象 hot_exam_paper_question
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("hot_exam_paper_question")
public class HotExamPaperQuestion extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 试卷ID
*/
private Long paperId;
/**
* 题目ID
*/
private Long questionId;
/**
* 问题类型
*/
private String questionType;
/**
* 排序值
*/
private Long sortOrder;
/**
* 题目分值(若为空则使用原题分值)
*/
private Long score;
}

View File

@@ -0,0 +1,62 @@
package com.hotwj.platform.config.examPaperQuestion.domain.bo;
import com.hotwj.platform.config.examPaperQuestion.domain.HotExamPaperQuestion;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/**
* 试卷-题目关联业务对象 hot_exam_paper_question
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = HotExamPaperQuestion.class, reverseConvertGenerate = false)
public class HotExamPaperQuestionBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
private Long id;
/**
* 公司ID
*/
private Long companyId;
/**
* 试卷ID
*/
@NotNull(message = "试卷ID不能为空", groups = {AddGroup.class, EditGroup.class})
private Long paperId;
/**
* 题目ID
*/
@NotNull(message = "题目ID不能为空", groups = {AddGroup.class, EditGroup.class})
private Long questionId;
/**
* 问题类型
*/
private String questionType;
/**
* 排序值
*/
private Long sortOrder;
/**
* 题目分值(若为空则使用原题分值)
*/
private Long score;
}

View File

@@ -0,0 +1,122 @@
package com.hotwj.platform.config.examPaperQuestion.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class ExamPaperQuestionDetailVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 试卷-题目关联表主键hot_exam_paper_question.id
*/
private Long relationId;
/**
* 试卷IDhot_exam_paper_question.paper_id
*/
private Long paperId;
/**
* 题目IDhot_exam_paper_question.question_id / hot_question_bank.id
*/
private Long questionId;
/**
* 题目类型关联表字段1=单选 2=多选 3=判断)
*/
private String questionType;
/**
* 题目排序值hot_exam_paper_question.sort_order
*/
private Long sortOrder;
/**
* 题目分值关联表字段hot_exam_paper_question.score
*/
private Long score;
/**
* 难度1=普通 2=困难 3=极难
*/
private Long difficulty;
/**
* 题库题目所属公司IDhot_question_bank.company_id
*/
private Long questionCompanyId;
/**
* 题库题目类型题库字段hot_question_bank.question_type
*/
private Long questionTypeNum;
/**
* 教育类型字典编码hot_question_bank.training_type_code
*/
private String trainingTypeCode;
/**
* 教育类型子集编码集hot_question_bank.training_subtype_codes
*/
private String trainingSubtypeCodes;
/**
* 题干描述hot_question_bank.question_desc
*/
private String questionDesc;
/**
* 题目插图URLhot_question_bank.image_url
*/
private String imageUrl;
/**
* 选项Ahot_question_bank.option_a
*/
private String optionA;
/**
* 选项Bhot_question_bank.option_b
*/
private String optionB;
/**
* 选项Chot_question_bank.option_c
*/
private String optionC;
/**
* 选项Dhot_question_bank.option_d
*/
private String optionD;
/**
* 选项Ehot_question_bank.option_e
*/
private String optionE;
/**
* 选项Fhot_question_bank.option_f
*/
private String optionF;
/**
* 标准答案hot_question_bank.correct_answers
*/
private String correctAnswers;
/**
* 题库题目分值hot_question_bank.score
*/
private Long questionScore;
/**
* 题库题目逻辑删除标记hot_question_bank.is_deleted
*/
private Long questionIsDeleted;
}

View File

@@ -0,0 +1,12 @@
package com.hotwj.platform.config.examPaperQuestion.domain.vo;
import lombok.Data;
import java.util.List;
@Data
public class ExamPaperQuestionsGroupedVo {
private List<ExamPaperQuestionDetailVo> singleChoiceList;
private List<ExamPaperQuestionDetailVo> multiChoiceList;
private List<ExamPaperQuestionDetailVo> judgeList;
}

View File

@@ -0,0 +1,69 @@
package com.hotwj.platform.config.examPaperQuestion.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.hotwj.platform.config.examPaperQuestion.domain.HotExamPaperQuestion;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 试卷-题目关联视图对象 hot_exam_paper_question
*
* @author shihongwei
* @date 2025-12-23
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = HotExamPaperQuestion.class)
public class HotExamPaperQuestionVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 公司ID
*/
@ExcelProperty(value = "公司ID")
private Long companyId;
/**
* 试卷ID
*/
@ExcelProperty(value = "试卷ID")
private Long paperId;
/**
* 题目ID
*/
@ExcelProperty(value = "题目ID")
private Long questionId;
/**
* 问题类型
*/
private String questionType;
/**
* 排序值
*/
@ExcelProperty(value = "排序值")
private Long sortOrder;
/**
* 题目分值(若为空则使用原题分值)
*/
@ExcelProperty(value = "题目分值(若为空则使用原题分值)")
private Long score;
}

View File

@@ -0,0 +1,22 @@
package com.hotwj.platform.config.examPaperQuestion.mapper;
import com.hotwj.platform.config.examPaperQuestion.domain.HotExamPaperQuestion;
import com.hotwj.platform.config.examPaperQuestion.domain.vo.ExamPaperQuestionDetailVo;
import com.hotwj.platform.config.examPaperQuestion.domain.vo.HotExamPaperQuestionVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import java.util.List;
/**
* 试卷-题目关联Mapper接口
*
* @author shihongwei
* @date 2025-12-23
*/
@Mapper
public interface HotExamPaperQuestionMapper extends BaseMapperPlus<HotExamPaperQuestion, HotExamPaperQuestionVo> {
List<ExamPaperQuestionDetailVo> selectPaperQuestionDetailList(@Param("paperId") Long paperId);
}

View File

@@ -0,0 +1,71 @@
package com.hotwj.platform.config.examPaperQuestion.service;
import com.hotwj.platform.config.examPaperQuestion.domain.bo.HotExamPaperQuestionBo;
import com.hotwj.platform.config.examPaperQuestion.domain.vo.ExamPaperQuestionsGroupedVo;
import com.hotwj.platform.config.examPaperQuestion.domain.vo.HotExamPaperQuestionVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
/**
* 试卷-题目关联Service接口
*
* @author shihongwei
* @date 2025-12-23
*/
public interface IHotExamPaperQuestionService {
/**
* 查询试卷-题目关联
*
* @param id 主键
* @return 试卷-题目关联
*/
HotExamPaperQuestionVo queryById(Long id);
/**
* 分页查询试卷-题目关联列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 试卷-题目关联分页列表
*/
TableDataInfo<HotExamPaperQuestionVo> queryPageList(HotExamPaperQuestionBo bo, PageQuery pageQuery);
/**
* 查询符合条件的试卷-题目关联列表
*
* @param bo 查询条件
* @return 试卷-题目关联列表
*/
List<HotExamPaperQuestionVo> queryList(HotExamPaperQuestionBo bo);
/**
* 新增试卷-题目关联
*
* @param bo 试卷-题目关联
* @return 是否新增成功
*/
Boolean insertByBo(HotExamPaperQuestionBo bo);
/**
* 修改试卷-题目关联
*
* @param bo 试卷-题目关联
* @return 是否修改成功
*/
Boolean updateByBo(HotExamPaperQuestionBo bo);
/**
* 校验并批量删除试卷-题目关联信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
ExamPaperQuestionsGroupedVo queryGroupedQuestionBankByPaperId(Long paperId);
}

View File

@@ -0,0 +1,174 @@
package com.hotwj.platform.config.examPaperQuestion.service.impl;
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.hotwj.platform.config.examPaperQuestion.domain.HotExamPaperQuestion;
import com.hotwj.platform.config.examPaperQuestion.domain.bo.HotExamPaperQuestionBo;
import com.hotwj.platform.config.examPaperQuestion.domain.vo.ExamPaperQuestionDetailVo;
import com.hotwj.platform.config.examPaperQuestion.domain.vo.ExamPaperQuestionsGroupedVo;
import com.hotwj.platform.config.examPaperQuestion.domain.vo.HotExamPaperQuestionVo;
import com.hotwj.platform.config.examPaperQuestion.mapper.HotExamPaperQuestionMapper;
import com.hotwj.platform.config.examPaperQuestion.service.IHotExamPaperQuestionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
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.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 试卷-题目关联Service业务层处理
*
* @author shihongwei
* @date 2025-12-23
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class HotExamPaperQuestionServiceImpl implements IHotExamPaperQuestionService {
private final HotExamPaperQuestionMapper baseMapper;
/**
* 查询试卷-题目关联
*
* @param id 主键
* @return 试卷-题目关联
*/
@Override
public HotExamPaperQuestionVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询试卷-题目关联列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 试卷-题目关联分页列表
*/
@Override
public TableDataInfo<HotExamPaperQuestionVo> queryPageList(HotExamPaperQuestionBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<HotExamPaperQuestion> lqw = buildQueryWrapper(bo);
Page<HotExamPaperQuestionVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的试卷-题目关联列表
*
* @param bo 查询条件
* @return 试卷-题目关联列表
*/
@Override
public List<HotExamPaperQuestionVo> queryList(HotExamPaperQuestionBo bo) {
LambdaQueryWrapper<HotExamPaperQuestion> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<HotExamPaperQuestion> buildQueryWrapper(HotExamPaperQuestionBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<HotExamPaperQuestion> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(HotExamPaperQuestion::getId);
lqw.eq(bo.getCompanyId() != null, HotExamPaperQuestion::getCompanyId, bo.getCompanyId());
lqw.eq(bo.getQuestionType() != null, HotExamPaperQuestion::getQuestionType, bo.getQuestionType());
lqw.eq(bo.getPaperId() != null, HotExamPaperQuestion::getPaperId, bo.getPaperId());
lqw.eq(bo.getQuestionId() != null, HotExamPaperQuestion::getQuestionId, bo.getQuestionId());
lqw.eq(bo.getSortOrder() != null, HotExamPaperQuestion::getSortOrder, bo.getSortOrder());
lqw.eq(bo.getScore() != null, HotExamPaperQuestion::getScore, bo.getScore());
return lqw;
}
/**
* 新增试卷-题目关联
*
* @param bo 试卷-题目关联
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(HotExamPaperQuestionBo bo) {
HotExamPaperQuestion add = MapstructUtils.convert(bo, HotExamPaperQuestion.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改试卷-题目关联
*
* @param bo 试卷-题目关联
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(HotExamPaperQuestionBo bo) {
HotExamPaperQuestion update = MapstructUtils.convert(bo, HotExamPaperQuestion.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(HotExamPaperQuestion entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除试卷-题目关联信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public ExamPaperQuestionsGroupedVo queryGroupedQuestionBankByPaperId(Long paperId) {
if (paperId == null) {
throw new ServiceException("试卷ID不能为空");
}
List<ExamPaperQuestionDetailVo> list = baseMapper.selectPaperQuestionDetailList(paperId);
List<ExamPaperQuestionDetailVo> single = new ArrayList<>();
List<ExamPaperQuestionDetailVo> multi = new ArrayList<>();
List<ExamPaperQuestionDetailVo> judge = new ArrayList<>();
if (list != null) {
for (ExamPaperQuestionDetailVo vo : list) {
if (vo == null) {
continue;
}
String t = vo.getQuestionType();
if ("1".equals(t)) {
single.add(vo);
} else if ("2".equals(t)) {
multi.add(vo);
} else if ("3".equals(t)) {
judge.add(vo);
} else if (StringUtils.isNotBlank(t)) {
single.add(vo);
}
}
}
ExamPaperQuestionsGroupedVo resp = new ExamPaperQuestionsGroupedVo();
resp.setSingleChoiceList(single);
resp.setMultiChoiceList(multi);
resp.setJudgeList(judge);
return resp;
}
}

View File

@@ -0,0 +1,110 @@
package com.hotwj.platform.config.hiddenDanger.strategy;
import com.hotwj.platform.flow.callback.IFlowCallback;
import com.hotwj.platform.flow.event.StartFlowEvent;
import com.hotwj.platform.securityManagement.hiddenDanger.domain.HotHiddenDanger;
import com.hotwj.platform.securityManagement.hiddenDanger.domain.bo.HotHiddenDangerBo;
import com.hotwj.platform.securityManagement.hiddenDanger.mapper.HotHiddenDangerMapper;
import com.hotwj.platform.securityManagement.hiddenDangerInspection.domain.HotHiddenDangerInspection;
import com.hotwj.platform.securityManagement.hiddenDangerInspection.mapper.HotHiddenDangerInspectionMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
/**
* 隐患排查流程回调
*
* @author shihongwei
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class HiddenDangerCheckCallback implements IFlowCallback {
private final HotHiddenDangerInspectionMapper inspectMapper;
private final HotHiddenDangerMapper hiddenDangerMapper;
private final ApplicationEventPublisher eventPublisher;
@Override
public String getFlowCode() {
return "HIDDEN_DANGER_CHECK";
}
@Override
public void onProcessEnd(String instanceId, String businessId, String flowCode, boolean success) {
log.info("隐患排查流程结束回调: businessId={}, success={}", businessId, success);
Long id = Long.parseLong(businessId);
HotHiddenDangerInspection inspection = inspectMapper.selectById(id);
if (inspection != null) {
if (success) {
inspection.setStatus(3L);
} else {
inspection.setStatus(6L);
log.info("隐患排查流程被驳回或非正常结束: {}", businessId);
}
if (inspection.getAuditHasDanger() != null && inspection.getAuditHasDanger() == 1L) {
createHiddenDangerFlow(inspection);
}
inspectMapper.updateById(inspection);
}
}
/**
* 创建隐患治理流程
*/
private void createHiddenDangerFlow(HotHiddenDangerInspection inspection) {
log.info("隐患排查发现隐患自动创建隐患治理流程业务ID: {}", inspection.getId());
HotHiddenDangerBo dangerBo = new HotHiddenDangerBo();
dangerBo.setCompanyId(inspection.getCompanyId());
dangerBo.setCheckTime(inspection.getCheckDate());
dangerBo.setCheckerId(inspection.getCheckerId());
dangerBo.setCheckerName(inspection.getCheckerName());
dangerBo.setDescription(inspection.getDangerDesc());
dangerBo.setEvidenceUrls(inspection.getAttachmentUrl());
// 生成隐患编号 YH-时间戳
dangerBo.setDangerNo("YH-" + System.currentTimeMillis() / 1000);
// 设置评估人
dangerBo.setEvaluatorId(inspection.getEvaluatorId());
dangerBo.setEvaluatorName(inspection.getEvaluatorName());
// 映射隐患来源类型
dangerBo.setSourceName(inspection.getProjectName());
dangerBo.setSourceId(String.valueOf(inspection.getId()));
dangerBo.setSourceType(inspection.getProjectType());
dangerBo.setDataSource(1L); // 1=日常排查
// 隐患名称
String dangerName = "隐患排查";
dangerBo.setDangerName(dangerName);
dangerBo.setStatus(0L); // 0=待评估
HotHiddenDanger danger = MapstructUtils.convert(dangerBo, HotHiddenDanger.class);
hiddenDangerMapper.insert(danger);
// 2. 启动隐患治理流程
String initiator = LoginHelper.getBusinessUserId();
String rectifierId = String.valueOf(inspection.getEvaluatorId());
// 使用事件发布解耦
StartFlowEvent startFlowEvent = new StartFlowEvent(this,
"HIDDEN_DANGER_GOVERNANCE",
String.valueOf(danger.getId()),
inspection.getCompanyId(),
initiator,
rectifierId
);
eventPublisher.publishEvent(startFlowEvent);
if (startFlowEvent.getInstanceId() != null) {
danger.setInstanceId(startFlowEvent.getInstanceId());
danger.setFlowStatus("SUBMITTED");
hiddenDangerMapper.updateById(danger);
}
}
}

View File

@@ -0,0 +1,87 @@
package com.hotwj.platform.config.hiddenDanger.strategy;
import com.hotwj.platform.flow.domain.SysFlowInstance;
import com.hotwj.platform.flow.domain.dto.FlowNextDto;
import com.hotwj.platform.flow.strategy.IFlowStrategy;
import com.hotwj.platform.securityManagement.hiddenDangerInspection.domain.HotHiddenDangerInspection;
import com.hotwj.platform.securityManagement.hiddenDangerInspection.mapper.HotHiddenDangerInspectionMapper;
import com.hotwj.platform.securityManagement.hiddenDangerPlan.domain.HotHiddenDangerPlan;
import com.hotwj.platform.securityManagement.hiddenDangerPlan.mapper.HotHiddenDangerPlanMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
/**
* 隐患排查流程策略
*
* @author shihongwei
* @date 2026-01-25
*/
@Component
public class HiddenDangerCheckStrategy implements IFlowStrategy {
@Resource
private HotHiddenDangerInspectionMapper inspectMapper;
@Resource
private HotHiddenDangerPlanMapper planMapper;
@Override
public String getFlowCode() {
return "HIDDEN_DANGER_CHECK";
}
@Override
public String getFlowName() {
return "隐患排查";
}
@Override
public FlowNextDto next(SysFlowInstance instance, String currentNodeCode) {
// 简单流程:只有一级审批,审批通过即结束
return null;
}
@Override
public FlowNextDto getInitialNode(String businessId) {
return getNextNode(businessId);
}
private FlowNextDto getNextNode(String id) {
// 待办名称规则:(排查计划名称)(排查项名称)审核
String inspectItemName = "未知排查项";
String planName = "未知计划";
try {
if (id != null) {
HotHiddenDangerInspection inspection = inspectMapper.selectById(id);
if (inspection != null) {
// 处理排查项名称
if (inspection.getProjectName() != null) {
if (Long.valueOf(3L).equals(inspection.getProjectType())) {
// 刘浩然(513019199308195132)
// 人员特殊处理,保护隐私 ,支持中英文括号
inspectItemName = inspection.getProjectName().replaceAll("[\\(].*?[\\)]", "");
} else {
inspectItemName = inspection.getProjectName();
}
}
// 处理计划名称
if (inspection.getPlanId() != null) {
HotHiddenDangerPlan plan = planMapper.selectById(inspection.getPlanId());
if (plan != null && plan.getPlanName() != null) {
planName = plan.getPlanName();
}
}
}
}
} catch (Exception e) {
// 忽略异常,使用默认值
}
String nodeName = String.format("%s%s审核", planName, inspectItemName);
return new FlowNextDto("NODE_CHECK_AUDIT", nodeName, null);
}
}

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