first commit
This commit is contained in:
96
pom.xml
Normal file
96
pom.xml
Normal file
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.15</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<groupId>com.discipline</groupId>
|
||||
<artifactId>report</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>discipline-report</name>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Boot核心依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MySQL驱动 -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 二维码生成ZXing -->
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>3.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>javase</artifactId>
|
||||
<version>3.5.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- 测试依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.discipline.report;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
|
||||
import com.discipline.report.config.CustomConfigProperties;
|
||||
import com.discipline.report.config.FileUploadProperties;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.discipline.report.mapper")
|
||||
@EnableConfigurationProperties({CustomConfigProperties.class, FileUploadProperties.class})
|
||||
public class DisciplineReportApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DisciplineReportApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.discipline.report.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 自定义配置属性
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "custom")
|
||||
public class CustomConfigProperties {
|
||||
private String disciplineEmail; // 纪委接收邮箱
|
||||
private String h5IndexUrl; // H5首页URL
|
||||
private String tipContent; // 填报提示文案
|
||||
private String qrCodeFixedUrl; // 二维码固定URL
|
||||
private String emailFrom; // 发件人邮箱
|
||||
|
||||
private String emailSubject;
|
||||
private String emailContent;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.discipline.report.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* 文件上传配置属性
|
||||
*/
|
||||
@Slf4j
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "discipline.file.upload")
|
||||
public class FileUploadProperties {
|
||||
private String path; // 文件上传路径
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
try {
|
||||
Files.createDirectories(Paths.get(path));
|
||||
} catch (Exception e) {
|
||||
log.error("文件目录创建失败:{}", path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/main/java/com/discipline/report/config/WebMvcConfig.java
Normal file
21
src/main/java/com/discipline/report/config/WebMvcConfig.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.discipline.report.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* Web MVC配置
|
||||
*/
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedOriginPatterns("*")
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE")
|
||||
.allowedHeaders("*")
|
||||
.allowCredentials(true)
|
||||
.maxAge(3600);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.discipline.report.controller;
|
||||
|
||||
import com.discipline.report.config.CustomConfigProperties;
|
||||
import com.discipline.report.result.Result;
|
||||
import com.discipline.report.result.ResultUtil;
|
||||
import com.discipline.report.util.QrCodeUtil;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 二维码生成控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/discipline/qrcode")
|
||||
public class QrCodeController {
|
||||
@Resource
|
||||
private CustomConfigProperties config;
|
||||
|
||||
@GetMapping
|
||||
public Result<?> getQrCode() {
|
||||
try {
|
||||
String fixedUrl = config.getQrCodeFixedUrl();
|
||||
if (fixedUrl == null || fixedUrl.trim().isEmpty()) {
|
||||
return ResultUtil.error(500, "配置文件未配置二维码固定链接");
|
||||
}
|
||||
String qrCode = QrCodeUtil.createQrCode(fixedUrl);
|
||||
return ResultUtil.success(qrCode);
|
||||
} catch (Exception e) {
|
||||
return ResultUtil.error(500, "生成二维码失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.discipline.report.controller;
|
||||
import com.discipline.report.dto.ReportSubmitDTO;
|
||||
import com.discipline.report.result.Result;
|
||||
import com.discipline.report.result.ResultUtil;
|
||||
import com.discipline.report.service.ReportService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
/**
|
||||
* 举报提交控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/discipline/report")
|
||||
public class ReportController {
|
||||
@Resource
|
||||
private ReportService reportService;
|
||||
/**
|
||||
* 提交举报表单+附件
|
||||
*/
|
||||
@PostMapping("/submit")
|
||||
public Result submit(@Valid ReportSubmitDTO dto) {
|
||||
try {
|
||||
reportService.saveReportAndSendEmail(dto);
|
||||
return ResultUtil.success("举报提交成功");
|
||||
} catch (Exception e) {
|
||||
// 移除e.printStackTrace(),全局异常统一打印日志
|
||||
return ResultUtil.error(500, "系统异常,提交失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
29
src/main/java/com/discipline/report/dto/ReportSubmitDTO.java
Normal file
29
src/main/java/com/discipline/report/dto/ReportSubmitDTO.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package com.discipline.report.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 举报提交数据传输对象
|
||||
*/
|
||||
@Data
|
||||
public class ReportSubmitDTO {
|
||||
@NotNull(message = "是否匿名不能为空")
|
||||
private Boolean isAnonymous; // 是否匿名
|
||||
private String reporterName; // 举报人姓名
|
||||
@NotBlank(message = "举报内容不能为空")
|
||||
private String reportContent; // 举报内容
|
||||
private String contactInfo; // 联系方式
|
||||
private MultipartFile[] file; // 上传文件数组
|
||||
|
||||
public MultipartFile[] getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(MultipartFile[] file) {
|
||||
this.file = file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.discipline.report.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 举报邮件接收人配置实体
|
||||
*/
|
||||
@Data
|
||||
public class ReportEmailReceiver {
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 接收人姓名
|
||||
*/
|
||||
private String receiverName;
|
||||
|
||||
/**
|
||||
* 接收人邮箱地址
|
||||
*/
|
||||
private String receiverEmail;
|
||||
|
||||
/**
|
||||
* 接收类型:1-主送(TO) 2-抄送(CC)
|
||||
*/
|
||||
private Integer receiveType;
|
||||
|
||||
/**
|
||||
* 排序号
|
||||
*/
|
||||
private Integer sortNum;
|
||||
|
||||
/**
|
||||
* 状态:0-禁用 1-启用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
18
src/main/java/com/discipline/report/entity/ReportFile.java
Normal file
18
src/main/java/com/discipline/report/entity/ReportFile.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.discipline.report.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 举报文件实体
|
||||
*/
|
||||
@Data
|
||||
public class ReportFile {
|
||||
private Long id; // 主键ID
|
||||
private Long reportId; // 举报记录ID
|
||||
private String fileName; // 文件名
|
||||
private String filePath; // 文件路径
|
||||
private Long fileSize; // 文件大小
|
||||
private LocalDateTime createTime;// 创建时间
|
||||
}
|
||||
19
src/main/java/com/discipline/report/entity/ReportRecord.java
Normal file
19
src/main/java/com/discipline/report/entity/ReportRecord.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.discipline.report.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 举报记录实体
|
||||
*/
|
||||
@Data
|
||||
public class ReportRecord {
|
||||
private Long id; // 主键ID
|
||||
private Boolean isAnonymous; // 是否匿名
|
||||
private String reporterName; // 举报人姓名
|
||||
private String reportContent; // 举报内容
|
||||
private String contactInfo; // 联系方式
|
||||
private String emailStatus; // 邮件发送状态
|
||||
private LocalDateTime createTime;// 创建时间
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.discipline.report.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 业务异常类
|
||||
*/
|
||||
@Getter
|
||||
public class BusinessException extends RuntimeException {
|
||||
private final int code;
|
||||
|
||||
public BusinessException(int code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.discipline.report.exception;
|
||||
|
||||
import com.discipline.report.result.Result;
|
||||
import com.discipline.report.result.ResultUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
/**
|
||||
* 全局异常处理器
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
@ResponseBody
|
||||
public Result<?> businessException(BusinessException e) {
|
||||
log.error("业务异常:{}", e.getMessage());
|
||||
return ResultUtil.error(e.getCode(), e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
@ResponseBody
|
||||
public Result<?> validException(MethodArgumentNotValidException e) {
|
||||
String msg = e.getBindingResult().getFieldError().getDefaultMessage();
|
||||
log.error("参数校验异常:{}", msg);
|
||||
return ResultUtil.error(400, msg);
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public Result<?> exception(Exception e) {
|
||||
log.error("系统异常", e);
|
||||
return ResultUtil.error(500, "系统异常,请联系管理员");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.discipline.report.mapper;
|
||||
|
||||
import com.discipline.report.entity.ReportEmailReceiver;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 举报邮件接收人Mapper
|
||||
*/
|
||||
public interface ReportEmailReceiverMapper {
|
||||
/**
|
||||
* 根据接收类型查询启用的接收人列表
|
||||
* @param receiveType 接收类型 1-主送 2-抄送
|
||||
* @return 接收人列表
|
||||
*/
|
||||
List<ReportEmailReceiver> selectByReceiveType(@Param("receiveType") Integer receiveType);
|
||||
|
||||
/**
|
||||
* 查询所有启用的接收人
|
||||
* @return 接收人列表
|
||||
*/
|
||||
List<ReportEmailReceiver> selectAllEnabled();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.discipline.report.mapper;
|
||||
|
||||
import com.discipline.report.entity.ReportFile;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 举报文件数据访问接口
|
||||
*/
|
||||
@Mapper
|
||||
public interface ReportFileMapper {
|
||||
void insertBatch(@Param("files") List<ReportFile> files);
|
||||
List<ReportFile> selectByReportId(@Param("reportId") Long reportId);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.discipline.report.mapper;
|
||||
|
||||
import com.discipline.report.entity.ReportRecord;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 举报记录数据访问接口
|
||||
*/
|
||||
@Mapper
|
||||
public interface ReportRecordMapper {
|
||||
void insert(ReportRecord record);
|
||||
// 新增:根据主键更新邮件状态
|
||||
int updateById(ReportRecord record);
|
||||
}
|
||||
13
src/main/java/com/discipline/report/result/Result.java
Normal file
13
src/main/java/com/discipline/report/result/Result.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.discipline.report.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 统一返回结果类
|
||||
*/
|
||||
@Data
|
||||
public class Result<T> {
|
||||
private int code; // 响应码
|
||||
private String msg; // 响应消息
|
||||
private T data; // 响应数据
|
||||
}
|
||||
37
src/main/java/com/discipline/report/result/ResultUtil.java
Normal file
37
src/main/java/com/discipline/report/result/ResultUtil.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package com.discipline.report.result;
|
||||
|
||||
/**
|
||||
* 统一返回结果工具类
|
||||
*/
|
||||
public class ResultUtil {
|
||||
/**
|
||||
* 成功返回(带数据)
|
||||
*/
|
||||
public static <T> Result<T> success(T data) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(200);
|
||||
result.setMsg("成功");
|
||||
result.setData(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功返回(无数据)
|
||||
*/
|
||||
public static <T> Result<T> success() {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(200);
|
||||
result.setMsg("成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败返回
|
||||
*/
|
||||
public static <T> Result<T> error(int code, String msg) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(code);
|
||||
result.setMsg(msg);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.discipline.report.service;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 文件上传服务接口
|
||||
*/
|
||||
public interface FileUploadService {
|
||||
/**
|
||||
* 上传单个文件,返回本地全路径
|
||||
* @param file 前端上传文件
|
||||
* @return 本地磁盘全路径
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
String uploadFile(MultipartFile file) throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.discipline.report.service;
|
||||
|
||||
import com.discipline.report.entity.ReportEmailReceiver;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 举报邮件接收人服务接口
|
||||
*/
|
||||
public interface ReportEmailReceiverService {
|
||||
/**
|
||||
* 获取主送接收人邮箱列表
|
||||
* @return 邮箱数组
|
||||
*/
|
||||
String[] getToEmailArray();
|
||||
|
||||
/**
|
||||
* 获取抄送接收人邮箱列表
|
||||
* @return 邮箱数组
|
||||
*/
|
||||
String[] getCcEmailArray();
|
||||
|
||||
/**
|
||||
* 查询所有启用的接收人
|
||||
* @return 接收人列表
|
||||
*/
|
||||
List<ReportEmailReceiver> getAllEnabledReceivers();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.discipline.report.service;
|
||||
|
||||
import com.discipline.report.dto.ReportSubmitDTO;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 举报服务接口
|
||||
*/
|
||||
public interface ReportService {
|
||||
void saveReportAndSendEmail(ReportSubmitDTO dto) throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.discipline.report.service.impl;
|
||||
|
||||
import com.discipline.report.config.FileUploadProperties;
|
||||
import com.discipline.report.exception.BusinessException;
|
||||
import com.discipline.report.service.FileUploadService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 文件上传服务实现
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class FileUploadServiceImpl implements FileUploadService {
|
||||
// 修正注释:原注释写的10MB但值是50MB,保持值不变仅修正注释(可选)
|
||||
private static final long MAX_SIZE = 50*1024*1024; // 50MB
|
||||
|
||||
@Resource
|
||||
private FileUploadProperties uploadProperties;
|
||||
|
||||
@Override
|
||||
public String uploadFile(MultipartFile file) throws IOException {
|
||||
// 1. 校验文件是否为空
|
||||
if (file.isEmpty()) {
|
||||
throw new BusinessException(400, "上传文件不能为空");
|
||||
}
|
||||
// 2. 校验文件大小
|
||||
if (file.getSize() > MAX_SIZE) {
|
||||
throw new BusinessException(400, "文件大小不能超过50MB");
|
||||
}
|
||||
|
||||
// 3. 校验文件名是否为空(仅校验名称,不再校验后缀)
|
||||
String originalName = file.getOriginalFilename();
|
||||
if (originalName == null || originalName.trim().isEmpty()) {
|
||||
throw new BusinessException(400, "上传文件名称不能为空");
|
||||
}
|
||||
|
||||
// 4. 生成新文件名(兼容无后缀文件)
|
||||
String newFileName;
|
||||
int dotIndex = originalName.lastIndexOf(".");
|
||||
if (dotIndex == -1) {
|
||||
// 无后缀文件,直接用UUID作为文件名
|
||||
newFileName = UUID.randomUUID().toString();
|
||||
} else {
|
||||
// 有后缀文件,UUID + 原后缀
|
||||
String suffix = originalName.substring(dotIndex).toLowerCase();
|
||||
newFileName = UUID.randomUUID().toString() + suffix;
|
||||
}
|
||||
|
||||
// 5. 保存文件
|
||||
String uploadPath = uploadProperties.getPath();
|
||||
File dest = new File(uploadPath + File.separator + newFileName);
|
||||
// 确保上传目录存在(新增:防止目录不存在导致报错)
|
||||
if (!dest.getParentFile().exists()) {
|
||||
boolean mkdirs = dest.getParentFile().mkdirs();
|
||||
if (!mkdirs) {
|
||||
log.error("创建上传目录失败:{}", dest.getParentFile().getAbsolutePath());
|
||||
throw new BusinessException(500, "文件上传失败,创建目录失败");
|
||||
}
|
||||
}
|
||||
|
||||
file.transferTo(dest);
|
||||
log.info("文件上传成功:{}", dest.getAbsolutePath());
|
||||
|
||||
return dest.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.discipline.report.service.impl;
|
||||
|
||||
import com.discipline.report.entity.ReportEmailReceiver;
|
||||
import com.discipline.report.mapper.ReportEmailReceiverMapper;
|
||||
import com.discipline.report.service.ReportEmailReceiverService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 举报邮件接收人服务实现
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ReportEmailReceiverServiceImpl implements ReportEmailReceiverService {
|
||||
@Resource
|
||||
private ReportEmailReceiverMapper receiverMapper;
|
||||
|
||||
@Override
|
||||
public String[] getToEmailArray() {
|
||||
List<ReportEmailReceiver> toList = receiverMapper.selectByReceiveType(1);
|
||||
return toList.stream()
|
||||
.map(ReportEmailReceiver::getReceiverEmail)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getCcEmailArray() {
|
||||
List<ReportEmailReceiver> ccList = receiverMapper.selectByReceiveType(2);
|
||||
return ccList.stream()
|
||||
.map(ReportEmailReceiver::getReceiverEmail)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReportEmailReceiver> getAllEnabledReceivers() {
|
||||
return receiverMapper.selectAllEnabled();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
package com.discipline.report.service.impl;
|
||||
import com.discipline.report.config.CustomConfigProperties;
|
||||
import com.discipline.report.dto.ReportSubmitDTO;
|
||||
import com.discipline.report.entity.ReportFile;
|
||||
import com.discipline.report.entity.ReportRecord;
|
||||
import com.discipline.report.mapper.ReportFileMapper;
|
||||
import com.discipline.report.mapper.ReportRecordMapper;
|
||||
import com.discipline.report.service.FileUploadService;
|
||||
import com.discipline.report.service.ReportEmailReceiverService;
|
||||
import com.discipline.report.service.ReportService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import javax.annotation.Resource;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.io.File;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 举报服务实现类
|
||||
* 负责举报记录保存、文件上传、举报通知邮件发送
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ReportServiceImpl implements ReportService {
|
||||
/**
|
||||
* 邮件发送状态枚举
|
||||
*/
|
||||
private enum EmailStatus {
|
||||
PENDING("PENDING"), // 待发送
|
||||
SUCCESS("SUCCESS"), // 发送成功
|
||||
FAIL("FAIL"); // 发送失败
|
||||
private final String value;
|
||||
EmailStatus(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@Resource
|
||||
private ReportRecordMapper reportRecordMapper;
|
||||
@Resource
|
||||
private ReportFileMapper reportFileMapper;
|
||||
@Resource
|
||||
private FileUploadService fileUploadService;
|
||||
@Resource
|
||||
private JavaMailSender mailSender;
|
||||
@Resource
|
||||
private ReportEmailReceiverService receiverService;
|
||||
@Resource
|
||||
private CustomConfigProperties config;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveReportAndSendEmail(ReportSubmitDTO dto) throws Exception {
|
||||
// 1. 保存举报主记录
|
||||
ReportRecord reportRecord = saveReportRecord(dto);
|
||||
// 2. 处理举报附件并保存
|
||||
handleReportFiles(reportRecord.getId(), dto.getFile());
|
||||
// 3. 发送举报通知邮件
|
||||
sendReportNotificationEmail(reportRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存举报主记录
|
||||
*/
|
||||
private ReportRecord saveReportRecord(ReportSubmitDTO dto) {
|
||||
ReportRecord record = new ReportRecord();
|
||||
record.setIsAnonymous(dto.getIsAnonymous());
|
||||
// 优化:匿名自动清空姓名和联系方式
|
||||
if(Boolean.TRUE.equals(dto.getIsAnonymous())){
|
||||
record.setReporterName(null);
|
||||
record.setContactInfo(null);
|
||||
}else{
|
||||
record.setReporterName(dto.getReporterName());
|
||||
record.setContactInfo(dto.getContactInfo());
|
||||
}
|
||||
record.setReportContent(dto.getReportContent());
|
||||
record.setEmailStatus(EmailStatus.PENDING.getValue());
|
||||
record.setCreateTime(LocalDateTime.now());
|
||||
reportRecordMapper.insert(record);
|
||||
log.info("举报记录保存成功,举报ID:{}", record.getId());
|
||||
return record;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理举报附件上传并保存
|
||||
*/
|
||||
private void handleReportFiles(Long reportId, MultipartFile[] files) {
|
||||
if (files == null || files.length == 0) {
|
||||
log.info("举报ID:{} 无附件需要上传", reportId);
|
||||
return;
|
||||
}
|
||||
List<ReportFile> reportFiles = new ArrayList<>();
|
||||
for (MultipartFile file : files) {
|
||||
if (file.isEmpty()) {
|
||||
log.warn("举报ID:{} 存在空文件,跳过处理", reportId);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
String filePath = fileUploadService.uploadFile(file);
|
||||
ReportFile reportFile = new ReportFile();
|
||||
reportFile.setReportId(reportId);
|
||||
reportFile.setFileName(file.getOriginalFilename());
|
||||
reportFile.setFilePath(filePath);
|
||||
reportFile.setFileSize(file.getSize());
|
||||
reportFile.setCreateTime(LocalDateTime.now());
|
||||
reportFiles.add(reportFile);
|
||||
} catch (Exception e) {
|
||||
log.error("举报ID:{} 附件上传失败,文件名:{}", reportId, file.getOriginalFilename(), e);
|
||||
}
|
||||
}
|
||||
if (!reportFiles.isEmpty()) {
|
||||
reportFileMapper.insertBatch(reportFiles);
|
||||
log.info("举报ID:{} 成功保存{}个附件记录", reportId, reportFiles.size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送举报通知邮件(优化:添加附件 + 拼接举报详情正文)
|
||||
*/
|
||||
private void sendReportNotificationEmail(ReportRecord reportRecord) {
|
||||
Long reportId = reportRecord.getId();
|
||||
try {
|
||||
MimeMessage mimeMessage = mailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
|
||||
// 设置邮件基础信息
|
||||
helper.setFrom(config.getEmailFrom());
|
||||
String subject = config.getEmailSubject() != null ? config.getEmailSubject() : "新的举报通知";
|
||||
helper.setSubject(subject);
|
||||
|
||||
// ========== 核心:拼接举报详情到邮件正文 ==========
|
||||
String baseContent = config.getEmailContent() != null ? config.getEmailContent() : "<p>收到一条新的举报信息,请及时处理!</p>";
|
||||
StringBuilder sb = new StringBuilder(baseContent);
|
||||
sb.append("<hr>");
|
||||
sb.append("<p><strong>是否匿名:</strong>").append(reportRecord.getIsAnonymous() ? "是" : "否").append("</p>");
|
||||
if (!reportRecord.getIsAnonymous()) {
|
||||
sb.append("<p><strong>举报人:</strong>").append(reportRecord.getReporterName()).append("</p>");
|
||||
sb.append("<p><strong>联系方式:</strong>").append(reportRecord.getContactInfo()).append("</p>");
|
||||
}
|
||||
sb.append("<p><strong>举报内容:</strong>").append(reportRecord.getReportContent()).append("</p>");
|
||||
helper.setText(sb.toString(), true);
|
||||
// ================================================
|
||||
|
||||
// 获取主送、抄送邮箱
|
||||
String[] toEmails = receiverService.getToEmailArray();
|
||||
String[] ccEmails = receiverService.getCcEmailArray();
|
||||
|
||||
// 主送为空直接失败
|
||||
if (toEmails == null || toEmails.length == 0) {
|
||||
log.warn("举报ID:{} 邮件主送人为空,无法发送邮件", reportId);
|
||||
updateEmailStatus(reportRecord, EmailStatus.FAIL);
|
||||
return;
|
||||
}
|
||||
helper.setTo(toEmails);
|
||||
if (ccEmails != null && ccEmails.length > 0) {
|
||||
helper.setCc(ccEmails);
|
||||
}
|
||||
|
||||
// 查询附件并添加到邮件
|
||||
List<ReportFile> fileList = reportFileMapper.selectByReportId(reportId);
|
||||
for(ReportFile rf : fileList){
|
||||
File attachFile = new File(rf.getFilePath());
|
||||
if(attachFile.exists()){
|
||||
helper.addAttachment(rf.getFileName(), new FileSystemResource(attachFile));
|
||||
}else{
|
||||
log.warn("附件文件不存在,路径:{}",rf.getFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
// 发送邮件
|
||||
mailSender.send(mimeMessage);
|
||||
updateEmailStatus(reportRecord, EmailStatus.SUCCESS);
|
||||
log.info("举报邮件发送成功,举报ID:{},主送:{},抄送:{}",
|
||||
reportId,
|
||||
arrayToString(toEmails),
|
||||
arrayToString(ccEmails));
|
||||
} catch (Exception e) {
|
||||
log.error("举报邮件发送失败,举报ID:{}", reportId, e);
|
||||
updateEmailStatus(reportRecord, EmailStatus.FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新邮件状态
|
||||
*/
|
||||
private void updateEmailStatus(ReportRecord reportRecord, EmailStatus status) {
|
||||
reportRecord.setEmailStatus(status.getValue());
|
||||
reportRecordMapper.updateById(reportRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数组转字符串(空安全)
|
||||
*/
|
||||
private String arrayToString(String[] array) {
|
||||
if (array == null || array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
return String.join(",", array);
|
||||
}
|
||||
}
|
||||
62
src/main/java/com/discipline/report/util/EmailSendUtil.java
Normal file
62
src/main/java/com/discipline/report/util/EmailSendUtil.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package com.discipline.report.util;
|
||||
|
||||
import com.discipline.report.config.CustomConfigProperties;
|
||||
import com.discipline.report.entity.ReportFile;
|
||||
import com.discipline.report.entity.ReportRecord;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 邮件发送工具类
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class EmailSendUtil {
|
||||
@Resource
|
||||
private JavaMailSender mailSender;
|
||||
@Resource
|
||||
private CustomConfigProperties config;
|
||||
|
||||
public void sendReportEmail(ReportRecord record, List<ReportFile> fileList) throws MessagingException {
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
|
||||
|
||||
helper.setFrom(config.getEmailFrom());
|
||||
helper.setTo(config.getDisciplineEmail());
|
||||
helper.setSubject("【纪律举报】新举报信息提交");
|
||||
|
||||
// 构建邮件内容
|
||||
StringBuilder content = new StringBuilder();
|
||||
content.append("<h3>新举报信息</h3>");
|
||||
content.append("<p><strong>举报时间:</strong>").append(record.getCreateTime()).append("</p>");
|
||||
content.append("<p><strong>是否匿名:</strong>").append(record.getIsAnonymous() ? "是" : "否").append("</p>");
|
||||
if (!record.getIsAnonymous() && record.getReporterName() != null) {
|
||||
content.append("<p><strong>举报人:</strong>").append(record.getReporterName()).append("</p>");
|
||||
}
|
||||
if (record.getContactInfo() != null) {
|
||||
content.append("<p><strong>联系方式:</strong>").append(record.getContactInfo()).append("</p>");
|
||||
}
|
||||
content.append("<p><strong>举报内容:</strong><br/>").append(record.getReportContent().replace("\n", "<br/>")).append("</p>");
|
||||
|
||||
// 添加附件
|
||||
if (fileList != null && !fileList.isEmpty()) {
|
||||
content.append("<p><strong>附件列表:</strong></p>");
|
||||
for (ReportFile file : fileList) {
|
||||
content.append("<p>").append(file.getFileName()).append(" (").append(file.getFileSize()/1024).append("KB)").append("</p>");
|
||||
helper.addAttachment(file.getFileName(), new File(file.getFilePath()));
|
||||
}
|
||||
}
|
||||
|
||||
helper.setText(content.toString(), true);
|
||||
mailSender.send(message);
|
||||
log.info("举报邮件发送成功,收件人:{}", config.getDisciplineEmail());
|
||||
}
|
||||
}
|
||||
67
src/main/java/com/discipline/report/util/QrCodeUtil.java
Normal file
67
src/main/java/com/discipline/report/util/QrCodeUtil.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package com.discipline.report.util;
|
||||
|
||||
import com.google.zxing.*;
|
||||
import com.google.zxing.client.j2se.MatrixToImageWriter;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.qrcode.QRCodeWriter;
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
import org.springframework.util.Base64Utils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 二维码生成工具类(基于ZXing实现)
|
||||
* 用于生成固定尺寸、固定纠错级别的Base64格式二维码
|
||||
*/
|
||||
public class QrCodeUtil {
|
||||
// 固定配置:确保每次生成的二维码完全一致
|
||||
private static final int QR_CODE_SIZE = 300; // 二维码尺寸(300x300像素)
|
||||
private static final ErrorCorrectionLevel ERROR_CORRECTION = ErrorCorrectionLevel.H; // 高纠错级别(30%容错)
|
||||
private static final String IMAGE_FORMAT = "png"; // 图片格式
|
||||
private static final String CHARSET = "UTF-8"; // 字符编码
|
||||
private static final int MARGIN = 1; // 二维码边距(最小)
|
||||
|
||||
/**
|
||||
* 生成Base64格式的二维码图片
|
||||
* @param content 二维码内容(前端提供的固定URL)
|
||||
* @return Base64编码的图片字符串(带data:image/png;base64前缀)
|
||||
* @throws Exception 生成过程中的异常
|
||||
*/
|
||||
public static String createQrCode(String content) throws Exception {
|
||||
// 校验输入内容
|
||||
if (content == null || content.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("二维码链接不能为空");
|
||||
}
|
||||
|
||||
QRCodeWriter writer = new QRCodeWriter();
|
||||
|
||||
// 配置二维码参数(固定配置,确保结果一致)
|
||||
Map<EncodeHintType, Object> hints = new HashMap<>();
|
||||
hints.put(EncodeHintType.ERROR_CORRECTION, ERROR_CORRECTION);
|
||||
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
|
||||
hints.put(EncodeHintType.MARGIN, MARGIN);
|
||||
|
||||
// 生成固定尺寸的二维码矩阵
|
||||
BitMatrix matrix = writer.encode(
|
||||
content,
|
||||
BarcodeFormat.QR_CODE,
|
||||
QR_CODE_SIZE,
|
||||
QR_CODE_SIZE,
|
||||
hints
|
||||
);
|
||||
|
||||
// 转换为BufferedImage
|
||||
BufferedImage image = MatrixToImageWriter.toBufferedImage(matrix);
|
||||
|
||||
// 写入字节流并转换为Base64
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ImageIO.write(image, IMAGE_FORMAT, bos);
|
||||
|
||||
// 返回带前缀的Base64字符串(前端可直接显示)
|
||||
return "data:image/png;base64," + Base64Utils.encodeToString(bos.toByteArray());
|
||||
}
|
||||
}
|
||||
52
src/main/resources/application-dev.yml
Normal file
52
src/main/resources/application-dev.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
server:
|
||||
port: 8090
|
||||
spring:
|
||||
application:
|
||||
name: discipline-report
|
||||
# 数据库
|
||||
datasource:
|
||||
url: jdbc:mysql://10.73.199.164:1444/finedb?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
username: bigdata
|
||||
password: bigdata@2020
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
# 邮箱配置
|
||||
mail:
|
||||
host: smtp.163.com
|
||||
username: 18817503105@163.com
|
||||
password: NScs2Ct8YTniyBNP
|
||||
port: 465
|
||||
protocol: smtps
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
auth: true
|
||||
starttls:
|
||||
enable: true
|
||||
required: true
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 50MB
|
||||
max-request-size: 50MB
|
||||
|
||||
# Mybatis
|
||||
mybatis:
|
||||
mapper-locations: classpath:mapper/*.xml
|
||||
type-aliases-package: com.discipline.report.entity
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
|
||||
# 自定义配置【和CustomConfigProperties字段完全对齐】
|
||||
custom:
|
||||
h5-index-url: http://localhost
|
||||
tip-content: 请如实填写举报信息,我们将严格保密
|
||||
qr-code-fixed-url: http://10.15.33.107:3301/#/home
|
||||
email-from: 18817503105@163.com
|
||||
email-subject: 【系统提醒】新举报工单提交
|
||||
email-content: <p>系统收到一条新举报,请及时处理!</p>
|
||||
|
||||
# 文件上传(Windows开发路径)
|
||||
discipline:
|
||||
file:
|
||||
upload:
|
||||
path: D:/home/upload/report
|
||||
49
src/main/resources/application-prod.yml
Normal file
49
src/main/resources/application-prod.yml
Normal file
@@ -0,0 +1,49 @@
|
||||
server:
|
||||
port: 8090
|
||||
spring:
|
||||
application:
|
||||
name: discipline-report
|
||||
datasource:
|
||||
url: jdbc:mysql://10.73.199.144:3506/finedb?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
username: bigdata
|
||||
password: bigdata@2020
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
mail:
|
||||
host: smtp.163.com
|
||||
username: 18817503105@163.com
|
||||
password: NScs2Ct8YTniyBNP
|
||||
port: 465
|
||||
protocol: smtps
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
auth: true
|
||||
starttls:
|
||||
enable: true
|
||||
required: true
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 50MB
|
||||
max-request-size: 50MB
|
||||
|
||||
mybatis:
|
||||
mapper-locations: classpath:mapper/*.xml
|
||||
type-aliases-package: com.discipline.report.entity
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
|
||||
# 自定义配置
|
||||
custom:
|
||||
h5-index-url: https://isee.ahtrq.com
|
||||
tip-content: 请如实填写举报信息,我们将严格保密
|
||||
qr-code-fixed-url: https://isee.ahtrq.com:9081/gmo
|
||||
email-from: 18817503105@163.com
|
||||
email-subject: 【系统提醒】新举报工单提交
|
||||
email-content: <p>系统收到一条新举报,请及时处理!</p>
|
||||
|
||||
# Linux生产路径
|
||||
discipline:
|
||||
file:
|
||||
upload:
|
||||
path: /opt/ahtrq/discipline-report/upload/report
|
||||
3
src/main/resources/application.yml
Normal file
3
src/main/resources/application.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: prod
|
||||
32
src/main/resources/mapper/ReportEmailReceiverMapper.xml
Normal file
32
src/main/resources/mapper/ReportEmailReceiverMapper.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.discipline.report.mapper.ReportEmailReceiverMapper">
|
||||
<resultMap id="BaseResultMap" type="com.discipline.report.entity.ReportEmailReceiver">
|
||||
<id column="id" property="id"/>
|
||||
<result column="receiver_name" property="receiverName"/>
|
||||
<result column="receiver_email" property="receiverEmail"/>
|
||||
<result column="receive_type" property="receiveType"/>
|
||||
<result column="sort_num" property="sortNum"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, receiver_name, receiver_email, receive_type, sort_num, status, create_time, update_time
|
||||
</sql>
|
||||
|
||||
<select id="selectByReceiveType" resultMap="BaseResultMap">
|
||||
SELECT <include refid="Base_Column_List"/>
|
||||
FROM report_email_receiver
|
||||
WHERE status = 1 AND receive_type = #{receiveType}
|
||||
ORDER BY sort_num ASC, id ASC
|
||||
</select>
|
||||
|
||||
<select id="selectAllEnabled" resultMap="BaseResultMap">
|
||||
SELECT <include refid="Base_Column_List"/>
|
||||
FROM report_email_receiver
|
||||
WHERE status = 1
|
||||
ORDER BY receive_type ASC, sort_num ASC, id ASC
|
||||
</select>
|
||||
</mapper>
|
||||
19
src/main/resources/mapper/ReportFileMapper.xml
Normal file
19
src/main/resources/mapper/ReportFileMapper.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.discipline.report.mapper.ReportFileMapper">
|
||||
<insert id="insertBatch">
|
||||
INSERT INTO report_file (report_id, file_name, file_path, file_size, create_time)
|
||||
VALUES
|
||||
<foreach collection="files" item="file" separator=",">
|
||||
(#{file.reportId}, #{file.fileName}, #{file.filePath}, #{file.fileSize}, #{file.createTime})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<select id="selectByReportId" resultType="com.discipline.report.entity.ReportFile">
|
||||
SELECT id, report_id, file_name, file_path, file_size, create_time
|
||||
FROM report_file
|
||||
WHERE report_id = #{reportId}
|
||||
ORDER BY create_time DESC
|
||||
</select>
|
||||
</mapper>
|
||||
14
src/main/resources/mapper/ReportRecordMapper.xml
Normal file
14
src/main/resources/mapper/ReportRecordMapper.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.discipline.report.mapper.ReportRecordMapper">
|
||||
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
|
||||
INSERT INTO report_record (is_anonymous, reporter_name, report_content, contact_info, email_status, create_time)
|
||||
VALUES (#{isAnonymous}, #{reporterName}, #{reportContent}, #{contactInfo}, #{emailStatus}, #{createTime})
|
||||
</insert>
|
||||
<update id="updateById">
|
||||
UPDATE report_record
|
||||
SET email_status = #{emailStatus}
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
</mapper>
|
||||
6
src/main/resources/static/index.html
Normal file
6
src/main/resources/static/index.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>hello word!!!</h1>
|
||||
<p>this is a html page</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.discipline.report;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class DisciplineReportApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user