forked from liweijie/education
feat: 提交课表冲突检查相关功能模块
This commit is contained in:
+284
@@ -0,0 +1,284 @@
|
||||
package com.roomroot.web.controller.jwgl;
|
||||
|
||||
import com.roomroot.jwgl.service.TimetableConflictService;
|
||||
import com.roomroot.jwgl.unit.PageResult;
|
||||
import com.roomroot.jwgl.unit.Result;
|
||||
import com.roomroot.jwgl.unit.conflict.TimetableConflictDimension;
|
||||
import com.roomroot.jwgl.vo.timetableconflict.TimetableConflictCardVO;
|
||||
import com.roomroot.jwgl.vo.timetableconflict.TimetableConflictDetailVO;
|
||||
import com.roomroot.jwgl.vo.timetableconflict.TimetableConflictSummaryVO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 课表冲突检查控制器。
|
||||
* <p>
|
||||
* 【涉及数据库表总览】(每类冲突用到的具体表详见各方法内部注释):
|
||||
* <pre>
|
||||
* 核心表(必用):
|
||||
* 实施_课程表 SSKCB —— 日期、节次、年度、删除状态、课程科目编号
|
||||
* 实施_课程表_学员队 SSKCBXYD —— 课次与教学班次(学员队)的多对多关联
|
||||
* 实施_课程表_辅助教员 SSKCBFZJY —— 课次与教员(主讲/辅讲)的多对多关联
|
||||
* 实施_课程表_教室 SSKCBJS —— 课次与教室的多对多关联
|
||||
* 翻译表(可选,用于中文名展示;即使不存在也不会阻断聚合结果):
|
||||
* 学员队表 XYDB —— 班次中文名
|
||||
* 教员表 / 教研室人员 JYB / JYSX —— 教员姓名
|
||||
* 教室表 JSB —— 教室名称
|
||||
* 课表 KB —— 课程名称、课程类型(必修/选修)
|
||||
* </pre>
|
||||
* </p>
|
||||
*
|
||||
* @author management
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/timetable-conflict")
|
||||
public class TimetableConflictController {
|
||||
|
||||
/**
|
||||
* 课表冲突检查业务服务。
|
||||
* 内部维护 ConcurrentHashMap 按「年度_维度编码」为 key 缓存每次检查结果明细,
|
||||
* 避免重复执行 GROUP BY+HAVING COUNT 聚合 SQL。
|
||||
*/
|
||||
@Resource
|
||||
private TimetableConflictService timetableConflictService;
|
||||
|
||||
// =====================================================================
|
||||
// 接口 1:单维度冲突检查(原接口2,移除/summary后接口序号前移)
|
||||
// =====================================================================
|
||||
|
||||
/**
|
||||
* 执行指定维度的冲突检查。
|
||||
* <p>
|
||||
* 对应页面每张卡片右下角「检查」按钮。根据前端传入的 dimensionCode,
|
||||
* 分发到 Service → Mapper,执行对应的 GROUP BY + HAVING COUNT(DISTINCT) 聚合 SQL。
|
||||
* 执行完成后:① 结果写入缓存 ② 可选写落库表 ③ 返回该卡片的最新状态。
|
||||
* </p>
|
||||
* <p>
|
||||
* 不同 dimensionCode 用到的数据库表:
|
||||
* <ul>
|
||||
* <li>TEAM_CONFLICT(教学班时间冲突):
|
||||
* 实施_课程表 SSKCB + 实施_课程表_学员队 SSKCBXYD + 学员队表 XYDB + 课表 KB</li>
|
||||
* <li>ELECTIVE_REQUIRED_CONFLICT(必修选修冲突):
|
||||
* 实施_课程表 SSKCB + 实施_课程表_学员队 SSKCBXYD + 学员队表 XYDB + 课表 KB(课程类型字段)</li>
|
||||
* <li>TEACHER_CONFLICT(教员时间冲突):
|
||||
* 实施_课程表 SSKCB + 实施_课程表_辅助教员 SSKCBFZJY + 教员表 JYB/教研室人员 + 课表 KB</li>
|
||||
* <li>CLASSROOM_CONFLICT(教室时间冲突):
|
||||
* 实施_课程表 SSKCB + 实施_课程表_教室 SSKCBJS + 教室表 JSB + 课表 KB</li>
|
||||
* <li>GUARANTEE_CONFLICT(保障资源冲突,预留):
|
||||
* 课程保障明细表 KCBBZMX + 保障类别 BZLB,当前返回空不报错</li>
|
||||
* <li>EVENT_CONFLICT(活动事件冲突,预留):
|
||||
* 学期校历 XQ + 学员队期班历 XYJXQJB,当前返回空不报错</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @param body 请求体 JSON,结构:
|
||||
* {
|
||||
* "nd": 2026, // 年度,必需
|
||||
* "dimensionCode": "TEAM_CONFLICT", // 维度编码(见枚举 TimetableConflictDimension.code)
|
||||
* "writeToDb": false, // 【可选】是否同时写入"课表_冲突检查结果"表,默认 false
|
||||
* "jcpch": null // 【可选】批次号(writeToDb=true 时,不传则自动生成一个)
|
||||
* }
|
||||
* @return 单卡片检查结果 VO
|
||||
*/
|
||||
@PostMapping("/check")
|
||||
public Result<TimetableConflictCardVO> checkDimension(@RequestBody Map<String, Object> body) {
|
||||
// 1. 提取并校验参数
|
||||
Object ndObj = body.get("nd");
|
||||
if (ndObj == null) {
|
||||
return Result.badRequest("年度(nd)不能为空");
|
||||
}
|
||||
Integer nd = Integer.parseInt(String.valueOf(ndObj));
|
||||
|
||||
String code = (String) body.get("dimensionCode");
|
||||
TimetableConflictDimension dim = TimetableConflictDimension.of(code);
|
||||
if (dim == null) {
|
||||
return Result.badRequest("无效的冲突检查维度编码:dimensionCode=" + code);
|
||||
}
|
||||
|
||||
// 2. 新参数:是否落库 / 指定批次号
|
||||
boolean writeToDb = Boolean.TRUE.equals(body.get("writeToDb"));
|
||||
String jcpch = (String) body.get("jcpch");
|
||||
|
||||
// 3. 执行业务层单维度检查(内存 + 可选落库)
|
||||
TimetableConflictCardVO card = timetableConflictService.checkDimension(nd, dim, jcpch, writeToDb);
|
||||
|
||||
// 4. 组装提示信息(落库模式下把批次号带给前端,便于后续 /details 用 useDb 查询)
|
||||
String msg;
|
||||
if (writeToDb) {
|
||||
// 单维度 check:jcpch 传了就用传的,没传就是 service 内部生成的一个——这里拿不到内部生成的,
|
||||
// 只能提示"已落库";如果批次号对前端重要,建议前端调 /check-all 统一拿批次号。
|
||||
msg = "【" + card.getTitle() + "】检查完成(已落库),发现 "
|
||||
+ card.getConflictCount() + " 条冲突";
|
||||
} else {
|
||||
msg = "【" + card.getTitle() + "】检查完成,发现 "
|
||||
+ card.getConflictCount() + " 条冲突";
|
||||
}
|
||||
return Result.success(msg, card);
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// 接口 2:执行全部维度检查
|
||||
// =====================================================================
|
||||
|
||||
/**
|
||||
* 执行所有维度的课表冲突检查。
|
||||
* <p>
|
||||
* 对应页面右上角「执行全部检查」按钮。内部依次对 6 个维度调用 {@link #checkDimension}:
|
||||
* 教学班 → 必修选修 → 教员 → 教室 → 保障资源(占位) → 活动事件(占位)
|
||||
* 所有维度 SQL 执行完后汇总返回。fullyChecked 会被标记为 true。
|
||||
* </p>
|
||||
* <p>
|
||||
* 方案 A 落库模式:当 writeToDb=true 时,内部自动生成一个统一批次号(jcpch,格式 {@code 年度_时间戳毫秒}),
|
||||
* 6 个维度的所有冲突明细都会带上这个批次号一起写进【课表_冲突检查结果】表;
|
||||
* 返回的 Result.message 会把本次批次号拼在提示文字里,前端可以保存并在后续
|
||||
* {@code GET /details?useDb=true&jcpch=xxx} 中拉取该次检查的历史明细。
|
||||
* </p>
|
||||
*
|
||||
* @param body 请求体 JSON,结构:
|
||||
* {
|
||||
* "nd": 2026, // 年度,必需
|
||||
* "writeToDb": false // 【可选】true=同时写入"课表_冲突检查结果"表(生成统一批次号),默认 false
|
||||
* }
|
||||
* @return 完整汇总 VO(6 张卡片 + 总冲突数 + fullyChecked=true)。
|
||||
* 落库模式下 message 形如:"全维度检查完成(批次号:2026_20260821-153000-123),共发现 N 条冲突"
|
||||
*/
|
||||
@PostMapping("/check-all")
|
||||
public Result<TimetableConflictSummaryVO> checkAll(@RequestBody Map<String, Object> body) {
|
||||
Object ndObj = body.get("nd");
|
||||
if (ndObj == null) {
|
||||
return Result.badRequest("年度(nd)不能为空");
|
||||
}
|
||||
Integer nd = Integer.parseInt(String.valueOf(ndObj));
|
||||
|
||||
// 新参数:是否落库(=true 时 service 内部生成一个统一批次号,6 个维度共用)
|
||||
boolean writeToDb = Boolean.TRUE.equals(body.get("writeToDb"));
|
||||
|
||||
TimetableConflictSummaryVO result = timetableConflictService.checkAll(nd, writeToDb);
|
||||
|
||||
// 组装返回 message,落库模式带上批次号(前端保存后可在 /details 用 useDb=true 查询)
|
||||
String msg;
|
||||
if (writeToDb) {
|
||||
String batchNo = timetableConflictService.getLastBatchNo();
|
||||
msg = "全维度检查完成(批次号:" + batchNo + "),共发现 "
|
||||
+ result.getTotalConflictCount() + " 条冲突";
|
||||
} else {
|
||||
msg = "全维度检查完成,共发现 "
|
||||
+ result.getTotalConflictCount() + " 条冲突";
|
||||
}
|
||||
return Result.success(msg, result);
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// 接口 3:重置检查结果(清空缓存)
|
||||
// =====================================================================
|
||||
|
||||
/**
|
||||
* 重置当前学期的课表冲突检查结果。
|
||||
* <p>
|
||||
* 对应页面「重置」按钮。默认行为:
|
||||
* 清除 Service 层 ConcurrentHashMap 中所有以 "{nd}_" 开头的 key 的缓存记录,
|
||||
* 所有卡片恢复 checked=false / conflictCount=0 的初始状态。
|
||||
* </p>
|
||||
* <p>
|
||||
* 可选行为(clearDb=true):同步 DELETE 【课表_冲突检查结果】表中该年度的全部批次记录,
|
||||
* 用于"彻底清空历史检查痕迹"的场景(默认 false,保持历史,避免误删)。
|
||||
* </p>
|
||||
*
|
||||
* @param body 请求体 JSON,结构:
|
||||
* {
|
||||
* "nd": 2026, // 年度,必需
|
||||
* "clearDb": false // 【可选】true=同时清空落库表中该年度所有批次,默认 false
|
||||
* }
|
||||
* @return 重置后的汇总 VO(所有卡片均为未检查状态)
|
||||
*/
|
||||
@PostMapping("/reset")
|
||||
public Result<TimetableConflictSummaryVO> reset(@RequestBody Map<String, Object> body) {
|
||||
Object ndObj = body.get("nd");
|
||||
if (ndObj == null) {
|
||||
return Result.badRequest("年度(nd)不能为空");
|
||||
}
|
||||
Integer nd = Integer.parseInt(String.valueOf(ndObj));
|
||||
|
||||
// 新参数:是否同时清落库表(默认只清内存,保留历史)
|
||||
boolean clearDb = Boolean.TRUE.equals(body.get("clearDb"));
|
||||
|
||||
TimetableConflictSummaryVO result = timetableConflictService.reset(nd, clearDb);
|
||||
String msg = clearDb
|
||||
? "检查结果已重置(已同步清空落库表中该年度的所有历史批次)"
|
||||
: "检查结果已重置(仅清内存缓存,落库历史记录保留)";
|
||||
return Result.success(msg, result);
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// 接口 4:分页查询冲突明细
|
||||
// =====================================================================
|
||||
|
||||
/**
|
||||
* 分页查询冲突明细(页面下方"冲突明细"表格使用)。
|
||||
* <p>
|
||||
* <b>两种数据源(useDb 参数切换):</b>
|
||||
* <ul>
|
||||
* <li>useDb=false(默认,兼容旧前端):从 Service 内存缓存(ConcurrentHashMap)读。
|
||||
* <b>必须先点击单卡片"检查"按钮或"执行全部检查"后,才能查到对应明细。</b>
|
||||
* 若尚未检查 → 返回 records=[](前端显示"请先点击上方卡片「检查」按钮"的空状态)。</li>
|
||||
* <li>useDb=true(方案 A 落库模式):从【课表_冲突检查结果】表读。
|
||||
* 好处:JVM 重启不丢、可回看任意一次历史批次。
|
||||
* 此时 jcpch 参数有意义:传具体批次号 → 只查那一次;不传 → 自动取该年度的最新批次。</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @param nd 年度(学期过滤),必需
|
||||
* @param dimensionCode 维度编码(可选)。传 null / "ALL" 表示合并展示所有维度的冲突;
|
||||
* 也可传单一维度编码(如 "TEACHER_CONFLICT")只看教员冲突。
|
||||
* @param pageNum 当前页码(从 1 开始,默认 1)
|
||||
* @param pageSize 每页大小(默认 20 条)
|
||||
* @param useDb 【可选】true=从落库表查;false=从内存缓存查(默认)
|
||||
* @param jcpch 【可选,useDb=true 时生效】查哪一个检查批次号。
|
||||
* 不传则自动取该年度在 DB 中的"最新批次"(MAX 创建时间)。
|
||||
* @return 分页结果。每条明细包含:冲突号、课程、日期、节次、班次、教员、场地、责任单位
|
||||
*/
|
||||
@GetMapping("/details")
|
||||
public Result<PageResult<TimetableConflictDetailVO>> getDetails(
|
||||
@RequestParam(value = "nd") Integer nd,
|
||||
@RequestParam(value = "dimensionCode", required = false) String dimensionCode,
|
||||
@RequestParam(value = "pageNum", required = false) Integer pageNum,
|
||||
@RequestParam(value = "pageSize", required = false) Integer pageSize,
|
||||
@RequestParam(value = "useDb", required = false, defaultValue = "false") boolean useDb,
|
||||
@RequestParam(value = "jcpch", required = false) String jcpch) {
|
||||
|
||||
PageResult<TimetableConflictDetailVO> page
|
||||
= timetableConflictService.getDetailsPage(nd, dimensionCode, pageNum, pageSize, useDb, jcpch);
|
||||
String msg = useDb
|
||||
? "查询成功(数据源:落库表" + (jcpch != null && !jcpch.isEmpty() ? ",批次号=" + jcpch : ",最新批次") + ")"
|
||||
: "查询成功(数据源:内存缓存)";
|
||||
return Result.success(msg, page);
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// 接口 5:查询指定年度的检查批次号列表(落库模式辅助接口)
|
||||
// =====================================================================
|
||||
|
||||
/**
|
||||
* 查询指定年度的全部检查批次号(按创建时间倒序,最新排第一)。
|
||||
* <p>
|
||||
* 前端用途:"查看历史检查"下拉框,用户选择某次批次号后,
|
||||
* 再调用 {@code GET /details?useDb=true&jcpch=xxx} 拉取那次的明细。
|
||||
* </p>
|
||||
*
|
||||
* @param nd 年度,必需
|
||||
* @return 批次号字符串列表(空表示无历史)
|
||||
*/
|
||||
@GetMapping("/batch-nos")
|
||||
public Result<java.util.List<String>> listBatchNos(
|
||||
@RequestParam(value = "nd") Integer nd) {
|
||||
java.util.List<String> list = timetableConflictService.listBatchNos(nd);
|
||||
return Result.success("查询成功,共 " + list.size() + " 个批次", list);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
restart.include.json=/com.alibaba.fastjson2.*.jar
|
||||
@@ -0,0 +1,56 @@
|
||||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
# 达梦连接串:ip:端口,schema指定默认模式
|
||||
url: jdbc:dm://10.1.1.17:5236?schema=JIAOWU&useUnicode=true&characterEncoding=utf-8
|
||||
username: JIAOWU
|
||||
password: Jiaowu123
|
||||
driver-class-name: dm.jdbc.driver.DmDriver
|
||||
|
||||
# Druid 基础参数
|
||||
druid:
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置连接超时时间
|
||||
connectTimeout: 30000
|
||||
# 配置网络超时时间
|
||||
socketTimeout: 60000
|
||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
maxEvictableIdleTimeMillis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
webStatFilter:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: roomroot
|
||||
login-password: 123456
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: true
|
||||
slow-sql-millis: 1000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
db-type: dm
|
||||
@@ -0,0 +1,149 @@
|
||||
# 项目相关配置
|
||||
roomroot:
|
||||
# 名称
|
||||
name: roomroot
|
||||
# 版本
|
||||
version: 3.9.2
|
||||
# 版权年份
|
||||
copyrightYear: 2026
|
||||
# 文件路径 示例( Windows配置D:/roomroot/uploadPath,Linux配置 /home/roomroot/uploadPath)
|
||||
profile: D:/roomroot/uploadPath
|
||||
# 获取ip地址开关
|
||||
addressEnabled: false
|
||||
# 验证码类型 math 数字计算 char 字符验证
|
||||
captchaType: math
|
||||
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8080
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /api
|
||||
tomcat:
|
||||
# tomcat的URI编码
|
||||
uri-encoding: UTF-8
|
||||
# 连接数满后的排队数,默认为100
|
||||
accept-count: 1000
|
||||
threads:
|
||||
# tomcat最大线程数,默认为200
|
||||
max: 800
|
||||
# Tomcat启动初始化的线程数,默认值10
|
||||
min-spare: 100
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.roomroot: debug
|
||||
#org.springframework: warn
|
||||
|
||||
# 用户配置
|
||||
user:
|
||||
password:
|
||||
# 密码最大错误次数
|
||||
maxRetryCount: 5
|
||||
# 密码锁定时间(默认10分钟)
|
||||
lockTime: 10
|
||||
|
||||
# Spring配置
|
||||
spring:
|
||||
# 资源信息
|
||||
messages:
|
||||
# 国际化资源文件路径
|
||||
basename: i18n/messages
|
||||
profiles:
|
||||
active: druid
|
||||
# 文件上传
|
||||
servlet:
|
||||
multipart:
|
||||
# 单个文件大小
|
||||
max-file-size: 10MB
|
||||
# 设置总上传的文件大小
|
||||
max-request-size: 20MB
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
# 服务模块
|
||||
devtools:
|
||||
restart:
|
||||
# 热部署开关
|
||||
enabled: true
|
||||
data:
|
||||
# redis 配置
|
||||
redis:
|
||||
# 地址
|
||||
host: localhost
|
||||
# 端口,默认为6379
|
||||
port: 6379
|
||||
# 数据库索引
|
||||
database: 0
|
||||
# 密码
|
||||
password:
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 8
|
||||
# 连接池的最大数据库连接数
|
||||
max-active: 8
|
||||
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
|
||||
# token配置
|
||||
token:
|
||||
# 令牌自定义标识
|
||||
header: Authorization
|
||||
# 令牌密钥
|
||||
secret: abcdefghijklmnopqrstuvwxyz
|
||||
# 令牌有效期(默认30分钟)
|
||||
expireTime: 30
|
||||
|
||||
# MyBatis-Plus配置
|
||||
mybatis-plus:
|
||||
# 搜索指定包别名
|
||||
typeAliasesPackage: com.roomroot.**.domain
|
||||
# 配置mapper的扫描,找到所有的mapper.xml映射文件
|
||||
mapperLocations: classpath*:mapper/**/*Mapper.xml,classpath*:com/roomroot/**/mapper/*.xml
|
||||
# 加载全局的配置文件
|
||||
configLocation: classpath:mybatis/mybatis-config.xml
|
||||
|
||||
# Springdoc配置
|
||||
springdoc:
|
||||
api-docs:
|
||||
path: /v3/api-docs
|
||||
swagger-ui:
|
||||
enabled: true
|
||||
path: /swagger-ui.html
|
||||
tags-sorter: alpha
|
||||
group-configs:
|
||||
- group: 'default'
|
||||
display-name: '测试模块'
|
||||
paths-to-match: '/**'
|
||||
packages-to-scan: com.roomroot.web.controller.tool
|
||||
|
||||
# 防盗链配置
|
||||
referer:
|
||||
# 防盗链开关
|
||||
enabled: false
|
||||
# 允许的域名列表
|
||||
allowed-domains: localhost,127.0.0.1,roomroot.vip,www.roomroot.vip
|
||||
|
||||
# 防止XSS攻击
|
||||
xss:
|
||||
# 过滤开关
|
||||
enabled: true
|
||||
# 排除链接(多个用逗号分隔)
|
||||
excludes: /system/notice
|
||||
# 匹配链接
|
||||
urlPatterns: /system/*,/monitor/*,/tool/*
|
||||
|
||||
# 自定义内嵌Redis开关
|
||||
custom:
|
||||
embedded-redis:
|
||||
# dev环境true自动启动内嵌Redis;prod改为false使用外部Redis
|
||||
enable: false
|
||||
port: 6379
|
||||
max-memory: 128M
|
||||
@@ -0,0 +1,5 @@
|
||||
Application Version: ${roomroot.version}
|
||||
Spring Boot Version: ${spring-boot.version}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 启动开始 永不宕机 永无BUG //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
#错误消息
|
||||
not.null=* 必须填写
|
||||
user.jcaptcha.error=验证码错误
|
||||
user.jcaptcha.expire=验证码已失效
|
||||
user.not.exists=用户不存在/密码错误
|
||||
user.password.not.match=用户不存在/密码错误
|
||||
user.password.retry.limit.count=密码输入错误{0}次
|
||||
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
|
||||
user.password.delete=对不起,您的账号已被删除
|
||||
user.blocked=用户已封禁,请联系管理员
|
||||
role.blocked=角色已封禁,请联系管理员
|
||||
login.blocked=很遗憾,访问IP已被列入系统黑名单
|
||||
user.logout.success=退出成功
|
||||
|
||||
length.not.valid=长度必须在{min}到{max}个字符之间
|
||||
|
||||
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
|
||||
user.password.not.valid=* 5-50个字符
|
||||
|
||||
user.email.not.valid=邮箱格式错误
|
||||
user.mobile.phone.number.not.valid=手机号格式错误
|
||||
user.login.success=登录成功
|
||||
user.register.success=注册成功
|
||||
user.notfound=请重新登录
|
||||
user.forcelogout=管理员强制退出,请重新登录
|
||||
user.unknown.error=未知错误,请重新登录
|
||||
|
||||
##文件上传消息
|
||||
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
|
||||
upload.filename.exceed.length=上传的文件名最长{0}个字符
|
||||
|
||||
##权限
|
||||
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="/home/roomroot/logs" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统日志输出 -->
|
||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-info.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>INFO</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-error.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>ERROR</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 用户访问日志输出 -->
|
||||
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-user.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 按天回滚 daily -->
|
||||
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统模块日志级别控制 -->
|
||||
<logger name="com.roomroot" level="info" />
|
||||
<!-- Spring日志级别控制 -->
|
||||
<logger name="org.springframework" level="warn" />
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="file_info" />
|
||||
<appender-ref ref="file_error" />
|
||||
</root>
|
||||
|
||||
<!--系统用户操作日志-->
|
||||
<logger name="sys-user" level="info">
|
||||
<appender-ref ref="sys-user"/>
|
||||
</logger>
|
||||
</configuration>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE configuration
|
||||
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
<configuration>
|
||||
<!-- 全局参数 -->
|
||||
<settings>
|
||||
<!-- 使全局的映射器启用或禁用缓存 -->
|
||||
<setting name="cacheEnabled" value="true" />
|
||||
<!-- 允许JDBC 支持自动生成主键 -->
|
||||
<setting name="useGeneratedKeys" value="true" />
|
||||
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
|
||||
<setting name="defaultExecutorType" value="SIMPLE" />
|
||||
<!-- 指定 MyBatis 所用日志的具体实现 -->
|
||||
<setting name="logImpl" value="SLF4J" />
|
||||
<!-- 使用驼峰命名法转换字段 -->
|
||||
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
|
||||
</settings>
|
||||
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user