RuoYi通知公告:企业信息发布系统设计
前言:企业信息发布的关键需求
在企业信息化建设中,高效的信息发布系统是确保组织内部沟通畅通的重要基础设施。传统的信息发布方式往往存在时效性差、覆盖面窄、管理混乱等问题。RuoYi框架的通知公告模块正是为了解决这些痛点而设计,为企业提供了一个集中化、规范化、权限可控的信息发布平台。
通过本文,您将深入了解RuoYi通知公告系统的:
- 🎯 核心架构设计与技术实现
- 🔐 完善的权限控制机制
- 📊 高效的数据存储与检索方案
- 🛡️ 安全防护与数据验证策略
- 🚀 实际应用场景与最佳实践
系统架构设计
整体架构概览
RuoYi通知公告系统采用经典的三层架构设计,确保系统的高可用性和可扩展性:
数据库设计
系统采用MySQL作为数据存储,sys_notice表结构设计如下:
| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 注释 |
|---|---|---|---|---|---|
| notice_id | int | 4 | NOT NULL | AUTO_INCREMENT | 公告ID |
| notice_title | varchar | 50 | NOT NULL | - | 公告标题 |
| notice_type | char | 1 | NOT NULL | - | 公告类型(1通知 2公告) |
| notice_content | longblob | - | DEFAULT NULL | - | 公告内容 |
| status | char | 1 | DEFAULT '0' | '0' | 公告状态(0正常 1关闭) |
| create_by | varchar | 64 | DEFAULT '' | '' | 创建者 |
| create_time | datetime | - | - | - | 创建时间 |
| update_by | varchar | 64 | DEFAULT '' | '' | 更新者 |
| update_time | datetime | - | - | - | 更新时间 |
| remark | varchar | 255 | DEFAULT NULL | - | 备注 |
SQL建表语句:
CREATE TABLE sys_notice (
notice_id INT(4) NOT NULL AUTO_INCREMENT COMMENT '公告ID',
notice_title VARCHAR(50) NOT NULL COMMENT '公告标题',
notice_type CHAR(1) NOT NULL COMMENT '公告类型(1通知 2公告)',
notice_content LONGBLOB DEFAULT NULL COMMENT '公告内容',
status CHAR(1) DEFAULT '0' COMMENT '公告状态(0正常 1关闭)',
create_by VARCHAR(64) DEFAULT '' COMMENT '创建者',
create_time DATETIME COMMENT '创建时间',
update_by VARCHAR(64) DEFAULT '' COMMENT '更新者',
update_time DATETIME COMMENT '更新时间',
remark VARCHAR(255) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (notice_id)
) ENGINE=INNODB AUTO_INCREMENT=10 COMMENT='通知公告表';
核心功能实现
1. 实体层设计(Domain Layer)
public class SysNotice extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 公告ID */
private Long noticeId;
/** 公告标题 */
private String noticeTitle;
/** 公告类型(1通知 2公告) */
private String noticeType;
/** 公告内容 */
private String noticeContent;
/** 公告状态(0正常 1关闭) */
private String status;
// 严格的输入验证和XSS防护
@Xss(message = "公告标题不能包含脚本字符")
@NotBlank(message = "公告标题不能为空")
@Size(min = 0, max = 50, message = "公告标题不能超过50个字符")
public String getNoticeTitle() {
return noticeTitle;
}
// Getter和Setter方法...
}
2. 数据访问层(Mapper Layer)
public interface SysNoticeMapper {
/**
* 查询公告信息
*/
SysNotice selectNoticeById(Long noticeId);
/**
* 查询公告列表
*/
List<SysNotice> selectNoticeList(SysNotice notice);
/**
* 新增公告
*/
int insertNotice(SysNotice notice);
/**
* 修改公告
*/
int updateNotice(SysNotice notice);
/**
* 批量删除公告
*/
int deleteNoticeByIds(String[] noticeIds);
}
3. 业务逻辑层(Service Layer)
@Service
public class SysNoticeServiceImpl implements ISysNoticeService {
@Autowired
private SysNoticeMapper noticeMapper;
@Override
public SysNotice selectNoticeById(Long noticeId) {
return noticeMapper.selectNoticeById(noticeId);
}
@Override
public List<SysNotice> selectNoticeList(SysNotice notice) {
return noticeMapper.selectNoticeList(notice);
}
@Override
public int insertNotice(SysNotice notice) {
return noticeMapper.insertNotice(notice);
}
@Override
public int updateNotice(SysNotice notice) {
return noticeMapper.updateNotice(notice);
}
@Override
public int deleteNoticeByIds(String ids) {
return noticeMapper.deleteNoticeByIds(Convert.toStrArray(ids));
}
}
4. 控制层(Controller Layer)
@Controller
@RequestMapping("/system/notice")
public class SysNoticeController extends BaseController {
private String prefix = "system/notice";
@Autowired
private ISysNoticeService noticeService;
// 权限控制:需要system:notice:view权限才能访问
@RequiresPermissions("system:notice:view")
@GetMapping()
public String notice() {
return prefix + "/notice";
}
// 查询公告列表(分页支持)
@RequiresPermissions("system:notice:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysNotice notice) {
startPage();
List<SysNotice> list = noticeService.selectNoticeList(notice);
return getDataTable(list);
}
// 新增公告(业务日志记录)
@RequiresPermissions("system:notice:add")
@Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysNotice notice) {
notice.setCreateBy(getLoginName());
return toAjax(noticeService.insertNotice(notice));
}
}
权限控制机制
RuoYi通知公告系统采用Apache Shiro进行细粒度的权限控制:
权限标识定义
| 操作 | 权限标识 | 描述 |
|---|---|---|
| 查看公告页面 | system:notice:view | 访问公告管理界面 |
| 查询公告列表 | system:notice:list | 获取公告列表数据 |
| 新增公告 | system:notice:add | 创建新的公告 |
| 修改公告 | system:notice:edit | 编辑现有公告 |
| 删除公告 | system:notice:remove | 删除公告记录 |
Shiro权限注解使用
// 在Controller方法上使用权限控制注解
@RequiresPermissions("system:notice:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysNotice notice) {
// 业务逻辑
}
@RequiresPermissions("system:notice:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysNotice notice) {
// 业务逻辑
}
安全防护策略
1. XSS跨站脚本防护
// 使用@Xss注解进行XSS过滤
@Xss(message = "公告标题不能包含脚本字符")
@NotBlank(message = "公告标题不能为空")
@Size(min = 0, max = 50, message = "公告标题不能超过50个字符")
public String getNoticeTitle() {
return noticeTitle;
}
2. 输入验证机制
// 使用Bean Validation进行数据验证
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysNotice notice) {
// 自动进行参数验证
if (bindingResult.hasErrors()) {
return AjaxResult.error(bindingResult.getFieldError().getDefaultMessage());
}
// 业务逻辑
}
3. 业务操作日志
// 使用@Log注解记录操作日志
@Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysNotice notice) {
// 业务逻辑
}
数据字典管理
系统使用统一的数据字典管理公告类型和状态:
公告类型字典(sys_notice_type)
| 值 | 标签 | 样式 | 默认 | 状态 | 描述 |
|---|---|---|---|---|---|
| 1 | 通知 | warning | Y | 0 | 通知类型 |
| 2 | 公告 | success | N | 0 | 公告类型 |
公告状态字典(sys_notice_status)
| 值 | 标签 | 样式 | 默认 | 状态 | 描述 |
|---|---|---|---|---|---|
| 0 | 正常 | primary | Y | 0 | 正常状态 |
| 1 | 关闭 | danger | N | 0 | 关闭状态 |
性能优化策略
1. 分页查询优化
// 使用TableSupport进行分页处理
startPage();
List<SysNotice> list = noticeService.selectNoticeList(notice);
return getDataTable(list);
2. 数据库索引优化
建议为常用查询字段创建索引:
-- 创建公告类型索引
CREATE INDEX idx_notice_type ON sys_notice(notice_type);
-- 创建状态索引
CREATE INDEX idx_status ON sys_notice(status);
-- 创建时间范围查询索引
CREATE INDEX idx_create_time ON sys_notice(create_time);
3. 缓存策略
对于频繁访问的公告数据,可以采用Redis缓存:
// 伪代码:公告缓存示例
@Cacheable(value = "notice", key = "#noticeId")
public SysNotice getNoticeById(Long noticeId) {
return noticeMapper.selectNoticeById(noticeId);
}
// 更新时清除缓存
@CacheEvict(value = "notice", key = "#notice.noticeId")
public int updateNotice(SysNotice notice) {
return noticeMapper.updateNotice(notice);
}
实际应用场景
场景一:企业日常通知发布
场景二:公告状态管理
// 公告状态变更示例
public int changeNoticeStatus(Long noticeId, String status) {
SysNotice notice = new SysNotice();
notice.setNoticeId(noticeId);
notice.setStatus(status);
notice.setUpdateBy(getLoginName());
notice.setUpdateTime(new Date());
return noticeMapper.updateNotice(notice);
}
场景三:批量操作处理
// 批量删除公告
@RequiresPermissions("system:notice:remove")
@Log(title = "通知公告", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids) {
try {
return toAjax(noticeService.deleteNoticeByIds(ids));
} catch (Exception e) {
return error("删除公告失败");
}
}
扩展功能建议
1. 公告推送机制
// 集成消息推送服务
public void pushNoticeToUsers(SysNotice notice, List<Long> userIds) {
// 推送到消息中心
messageService.pushNotice(notice, userIds);
// 发送邮件通知
emailService.sendNoticeEmail(notice, userIds);
// 移动端推送
pushService.sendMobilePush(notice, userIds);
}
2. 公告阅读状态跟踪
-- 新增公告阅读记录表
CREATE TABLE sys_notice_read (
read_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '阅读ID',
notice_id BIGINT(20) NOT NULL COMMENT '公告ID',
user_id BIGINT(20) NOT NULL COMMENT '用户ID',
read_time DATETIME COMMENT '阅读时间',
PRIMARY KEY (read_id),
INDEX idx_notice_user (notice_id, user_id)
) COMMENT='公告阅读记录表';
3. 公告有效期管理
// 增加有效期字段
public class SysNotice extends BaseEntity {
// 新增字段
private Date startTime; // 生效时间
private Date endTime; // 失效时间
// 校验有效期
public boolean isValid() {
Date now = new Date();
return now.after(startTime) && now.before(endTime);
}
}
最佳实践指南
1. 代码规范
// 良好的代码注释习惯
/**
* 根据条件查询公告列表
*
* @param notice 公告查询条件
* @return 公告列表
* @throws ServiceException 业务异常
*/
@Override
public List<SysNotice> selectNoticeList(SysNotice notice) {
try {
return noticeMapper.selectNoticeList(notice);
} catch (Exception e) {
throw new ServiceException("查询公告失败", e);
}
}
2. 异常处理
// 统一的异常处理机制
@ExceptionHandler(Exception.class)
public AjaxResult handleException(Exception e) {
log.error("公告操作异常", e);
return AjaxResult.error("操作失败,请稍后重试");
}
3. 日志管理
// 详细的日志记录
@Log(title = "通知公告", businessType = BusinessType.INSERT)
public int addNotice(SysNotice notice) {
log.info("开始新增公告,标题:{}", notice.getNoticeTitle());
int result = noticeMapper.insertNotice(notice);
log.info("新增公告完成,影响行数:{}", result);
return result;
}
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



