diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm
index 3e6be024..5387f784 100644
--- a/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm
+++ b/ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/domain.java.vm
@@ -40,8 +40,8 @@ public class ${ClassName} extends ${Entity}
#if($parentheseIndex != -1)
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
#elseif($column.javaType == 'Date')
- @JsonFormat(pattern = "yyyy-MM-dd")
- @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
#else
@Excel(name = "${comment}")
#end
@@ -62,11 +62,18 @@ public class ${ClassName} extends ${Entity}
#else
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#end
+ /**
+ * 设置 ${AttrName}
+ * @param $column.columnComment
+ */
public void set${AttrName}($column.javaType $column.javaField)
{
this.$column.javaField = $column.javaField;
}
-
+ /**
+ * 获取 $column.columnComment
+ * @return
+ */
public $column.javaType get${AttrName}()
{
return $column.javaField;
diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml
index 46baaddb..f9ddcb00 100644
--- a/ruoyi-modules/ruoyi-system/pom.xml
+++ b/ruoyi-modules/ruoyi-system/pom.xml
@@ -77,6 +77,12 @@
com.ruoyi
ruoyi-common-swagger
+
+
+ org.nutz
+ nutz
+ 1.r.69.20210929
+
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/BulletinInfoController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/BulletinInfoController.java
new file mode 100644
index 00000000..31833b0d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/BulletinInfoController.java
@@ -0,0 +1,173 @@
+package com.ruoyi.system.controller;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.log.annotation.Log;
+import com.ruoyi.common.log.enums.BusinessType;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.domain.BulletinRecive;
+import com.ruoyi.system.service.IBulletinInfoService;
+import com.ruoyi.system.service.IBulletinReciveService;
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+
+/**
+ * 公告栏Controller
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+@RestController
+@RequestMapping("/bulletin")
+public class BulletinInfoController extends BaseController
+{
+ @Autowired
+ private IBulletinInfoService bulletinInfoService;
+
+ @Autowired
+ private IBulletinReciveService bulletinReciveService;
+
+ /**
+ * 查询公告栏列表
+ */
+ @RequiresPermissions("system:bulletin:list")
+ @GetMapping("/list")
+ public TableDataInfo list(BulletinInfo bulletinInfo)
+ {
+ startPage();
+ List list = bulletinInfoService.selectBulletinInfoList(bulletinInfo);
+ return getDataTable(list);
+ }
+
+ /**
+ * 获取公告栏详细信息
+ */
+ @RequiresPermissions("system:bulletin:query")
+ @GetMapping(value = "/{bulletinId}")
+ public AjaxResult getInfo(@PathVariable("bulletinId") String bulletinId)
+ {
+ return success(bulletinInfoService.selectBulletinInfoByBulletinId(bulletinId));
+ }
+
+ /**
+ * 发送公告栏
+ */
+ @RequiresPermissions("system:bulletin:add")
+ @Log(title = "公告栏", businessType = BusinessType.OTHER)
+ @PostMapping("/batchSend/{bulletinIds}")
+ public AjaxResult batchSend(@PathVariable String[] bulletinIds)
+ {
+ return toAjax(bulletinInfoService.sendBulletinInfo(bulletinIds));
+ }
+
+ /**
+ * 新增或发送 公告栏
+ */
+ @RequiresPermissions("system:bulletin:add")
+ @Log(title = "公告栏", businessType = BusinessType.INSERT)
+ @PostMapping
+ public AjaxResult add(@Validated @RequestBody BulletinInfo bulletinInfo)
+ {
+ return toAjax(bulletinInfoService.insertBulletinInfo(bulletinInfo));
+ }
+
+
+
+ /**
+ * 修改公告栏
+ */
+ @RequiresPermissions("system:bulletin:edit")
+ @Log(title = "公告栏", businessType = BusinessType.UPDATE)
+ @PutMapping
+ public AjaxResult edit(@RequestBody BulletinInfo bulletinInfo)
+ {
+ return toAjax(bulletinInfoService.updateBulletinInfo(bulletinInfo));
+ }
+
+ /**
+ * 物理删除公告栏
+ */
+ @RequiresPermissions("system:bulletin:remove")
+ @Log(title = "公告栏", businessType = BusinessType.DELETE)
+ @DeleteMapping("/delete/{bulletinIds}")
+ public AjaxResult removePysical(@PathVariable String[] bulletinIds)
+ {
+ return toAjax(bulletinInfoService.deleteBulletinInfoByBulletinIds(bulletinIds,"D"));
+ }
+
+ /**
+ * 逻辑删除公告栏
+ */
+ @RequiresPermissions("system:bulletin:remove")
+ @Log(title = "公告栏", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{bulletinIds}")
+ public AjaxResult remove(@PathVariable String[] bulletinIds)
+ {
+ return toAjax(bulletinInfoService.deleteBulletinInfoByBulletinIds(bulletinIds,"B"));
+ }
+
+ /**
+ * 批量阅读成功
+ */
+ @RequiresPermissions("system:bulletin:edit")
+ @PutMapping("/recive/batchRead/{reciveIds}")
+ public AjaxResult batchRead(@PathVariable String[] reciveIds)
+ {
+ return toAjax(bulletinReciveService.batchRead(reciveIds));
+ }
+
+ /**
+ * 查询公告接收者列表
+ */
+ @RequiresPermissions("system:bulletin:list")
+ @GetMapping("/recive/list")
+ public TableDataInfo reciveList(BulletinRecive bulletinRecive)
+ {
+ startPage();
+ List list = bulletinReciveService.selectBulletinReciveList(bulletinRecive);
+ return getDataTable(list);
+ }
+
+ /**
+ * 逻辑删除公告接收者
+ */
+ @RequiresPermissions("system:bulletin:remove")
+ @Log(title = "公告接收者", businessType = BusinessType.DELETE)
+ @DeleteMapping("/recive/{reciveIds}")
+ public AjaxResult reciveRemove(@PathVariable String[] reciveIds)
+ {
+ return toAjax(bulletinReciveService.deleteBulletinReciveByReciveIds(reciveIds));
+ }
+
+ /**
+ * 物理删除公告接收者
+ */
+ @RequiresPermissions("system:bulletin:remove")
+ @Log(title = "公告接收者", businessType = BusinessType.DELETE)
+ @DeleteMapping("/recive/delete/{reciveIds}")
+ public AjaxResult recivePhysicalRemove(@PathVariable String[] reciveIds)
+ {
+ return toAjax(bulletinReciveService.deletePhysicalBulletinReciveByReciveIds(reciveIds));
+ }
+
+ /**
+ * 获取公告接收者详细信息
+ */
+ @RequiresPermissions("system:bulletin:query")
+ @GetMapping(value = "/recive/{reciveId}")
+ public AjaxResult getReciveInfo(@PathVariable("reciveId") String reciveId)
+ {
+ return success(bulletinReciveService.selectBulletinReciveByReciveId(reciveId));
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinInfo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinInfo.java
new file mode 100644
index 00000000..b43b1ef6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinInfo.java
@@ -0,0 +1,242 @@
+package com.ruoyi.system.domain;
+
+import java.util.List;
+
+import javax.validation.constraints.NotEmpty;
+
+import java.util.Collections;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+
+/**
+ * 公告栏对象 t_bulletin_info
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public class BulletinInfo extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 公告ID */
+ private String bulletinId;
+
+ /** 公告标题 */
+ @Excel(name = "公告标题")
+ @NotEmpty(message = "公告标题不允许为空")
+ private String title;
+
+ /** 公告内容 */
+ @Excel(name = "公告内容")
+ private String content;
+
+ /** 已读人数 */
+ @Excel(name = "已读人数")
+ private Long readNum;
+
+ /** 公告的发送时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "公告的发送时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date sendTime;
+
+ /** 员工ID */
+ @Excel(name = "员工ID")
+ private Long createUserId;
+
+ /** 更新员工 */
+ @Excel(name = "更新员工")
+ private Long updateUserId;
+
+ /** 状态 */
+ @Excel(name = "状态")
+ @NotEmpty(message = "状态不允许为空")
+ private String sts;
+
+ /** 公告接收者信息 */
+ private List bulletinReciveList;
+ /**
+ * 给前端过渡,用于生成BulletinRecive
+ */
+ private List receiveStaffIds;
+ /**
+ * 接收人员,以逗号分隔
+ */
+ private String reciveStaffNames;
+
+
+ public String getReciveStaffNames() {
+ return reciveStaffNames;
+ }
+ public void setReciveStaffNames(String reciveStaffNames) {
+ this.reciveStaffNames = reciveStaffNames;
+ }
+ public List getReceiveStaffIds() {
+ if(receiveStaffIds==null) {
+ receiveStaffIds=Collections.emptyList();
+ }
+ return receiveStaffIds;
+ }
+ public void setReceiveStaffIds(List receiveStaffIds) {
+ this.receiveStaffIds = receiveStaffIds;
+ }
+ /**
+ * 设置 BulletinId
+ * @param 公告ID
+ */
+ public void setBulletinId(String bulletinId)
+ {
+ this.bulletinId = bulletinId;
+ }
+ /**
+ * 获取 公告ID
+ * @return
+ */
+ public String getBulletinId()
+ {
+ return bulletinId;
+ }
+ /**
+ * 设置 Title
+ * @param 公告标题
+ */
+ public void setTitle(String title)
+ {
+ this.title = title;
+ }
+ /**
+ * 获取 公告标题
+ * @return
+ */
+ public String getTitle()
+ {
+ return title;
+ }
+ /**
+ * 设置 Content
+ * @param 公告内容
+ */
+ public void setContent(String content)
+ {
+ this.content = content;
+ }
+ /**
+ * 获取 公告内容
+ * @return
+ */
+ public String getContent()
+ {
+ return content;
+ }
+ /**
+ * 设置 ReadNum
+ * @param 已读人数
+ */
+ public void setReadNum(Long readNum)
+ {
+ this.readNum = readNum;
+ }
+ /**
+ * 获取 已读人数
+ * @return
+ */
+ public Long getReadNum()
+ {
+ return readNum;
+ }
+ /**
+ * 设置 SendTime
+ * @param 公告的发送时间
+ */
+ public void setSendTime(Date sendTime)
+ {
+ this.sendTime = sendTime;
+ }
+ /**
+ * 获取 公告的发送时间
+ * @return
+ */
+ public Date getSendTime()
+ {
+ return sendTime;
+ }
+ /**
+ * 设置 CreateUserId
+ * @param 员工ID
+ */
+ public void setCreateUserId(Long createUserId)
+ {
+ this.createUserId = createUserId;
+ }
+ /**
+ * 获取 员工ID
+ * @return
+ */
+ public Long getCreateUserId()
+ {
+ return createUserId;
+ }
+ /**
+ * 设置 UpdateUserId
+ * @param 更新员工
+ */
+ public void setUpdateUserId(Long updateUserId)
+ {
+ this.updateUserId = updateUserId;
+ }
+ /**
+ * 获取 更新员工
+ * @return
+ */
+ public Long getUpdateUserId()
+ {
+ return updateUserId;
+ }
+ /**
+ * 设置 Sts
+ * @param 状态
+ */
+ public void setSts(String sts)
+ {
+ this.sts = sts;
+ }
+ /**
+ * 获取 状态
+ * @return
+ */
+ public String getSts()
+ {
+ return sts;
+ }
+
+ public List getBulletinReciveList()
+ {
+ return bulletinReciveList;
+ }
+
+ public void setBulletinReciveList(List bulletinReciveList)
+ {
+ this.bulletinReciveList = bulletinReciveList;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("bulletinId", getBulletinId())
+ .append("title", getTitle())
+ .append("content", getContent())
+ .append("createTime", getCreateTime())
+ .append("readNum", getReadNum())
+ .append("sendTime", getSendTime())
+ .append("createUserId", getCreateUserId())
+ .append("updateUserId", getUpdateUserId())
+ .append("updateTime", getUpdateTime())
+ .append("remark", getRemark())
+ .append("sts", getSts())
+ .append("bulletinReciveList", getBulletinReciveList())
+ .toString();
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinRecive.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinRecive.java
new file mode 100644
index 00000000..3765f550
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/BulletinRecive.java
@@ -0,0 +1,197 @@
+package com.ruoyi.system.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+
+/**
+ * 公告接收者对象 t_bulletin_recive
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public class BulletinRecive extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 接收ID */
+ private String reciveId;
+
+ /** 接收员工ID */
+ @Excel(name = "接收员工ID")
+ private Long reciveUserId;
+
+ /** 阅读时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "阅读时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date readTime;
+
+ /** 阅读次数 */
+ @Excel(name = "阅读次数")
+ private Long readNum;
+
+ /** 员工ID */
+ @Excel(name = "员工ID")
+ private Long createUserId;
+
+ /** 更新员工 */
+ @Excel(name = "更新员工")
+ private Long updateUserId;
+
+ /** 公告ID */
+ @Excel(name = "公告ID")
+ private String bulletinId;
+
+ /** A:已阅读,B:已删除 C:未阅读 */
+ @Excel(name = "A:已阅读,B:已删除 C:未阅读")
+ private String sts;
+
+ /**
+ * 设置 ReciveId
+ * @param 接收ID
+ */
+ public void setReciveId(String reciveId)
+ {
+ this.reciveId = reciveId;
+ }
+ /**
+ * 获取 接收ID
+ * @return
+ */
+ public String getReciveId()
+ {
+ return reciveId;
+ }
+ /**
+ * 设置 ReciveUserId
+ * @param 接收员工ID
+ */
+ public void setReciveUserId(Long reciveUserId)
+ {
+ this.reciveUserId = reciveUserId;
+ }
+ /**
+ * 获取 接收员工ID
+ * @return
+ */
+ public Long getReciveUserId()
+ {
+ return reciveUserId;
+ }
+ /**
+ * 设置 ReadTime
+ * @param 阅读时间
+ */
+ public void setReadTime(Date readTime)
+ {
+ this.readTime = readTime;
+ }
+ /**
+ * 获取 阅读时间
+ * @return
+ */
+ public Date getReadTime()
+ {
+ return readTime;
+ }
+ /**
+ * 设置 ReadNum
+ * @param 阅读次数
+ */
+ public void setReadNum(Long readNum)
+ {
+ this.readNum = readNum;
+ }
+ /**
+ * 获取 阅读次数
+ * @return
+ */
+ public Long getReadNum()
+ {
+ return readNum;
+ }
+ /**
+ * 设置 CreateUserId
+ * @param 员工ID
+ */
+ public void setCreateUserId(Long createUserId)
+ {
+ this.createUserId = createUserId;
+ }
+ /**
+ * 获取 员工ID
+ * @return
+ */
+ public Long getCreateUserId()
+ {
+ return createUserId;
+ }
+ /**
+ * 设置 UpdateUserId
+ * @param 更新员工
+ */
+ public void setUpdateUserId(Long updateUserId)
+ {
+ this.updateUserId = updateUserId;
+ }
+ /**
+ * 获取 更新员工
+ * @return
+ */
+ public Long getUpdateUserId()
+ {
+ return updateUserId;
+ }
+ /**
+ * 设置 BulletinId
+ * @param 公告ID
+ */
+ public void setBulletinId(String bulletinId)
+ {
+ this.bulletinId = bulletinId;
+ }
+ /**
+ * 获取 公告ID
+ * @return
+ */
+ public String getBulletinId()
+ {
+ return bulletinId;
+ }
+ /**
+ * 设置 Sts
+ * @param A:已阅读,B:已删除 C:未阅读
+ */
+ public void setSts(String sts)
+ {
+ this.sts = sts;
+ }
+ /**
+ * 获取 A:已阅读,B:已删除 C:未阅读
+ * @return
+ */
+ public String getSts()
+ {
+ return sts;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("reciveId", getReciveId())
+ .append("reciveUserId", getReciveUserId())
+ .append("readTime", getReadTime())
+ .append("readNum", getReadNum())
+ .append("createTime", getCreateTime())
+ .append("createUserId", getCreateUserId())
+ .append("updateUserId", getUpdateUserId())
+ .append("updateTime", getUpdateTime())
+ .append("remark", getRemark())
+ .append("bulletinId", getBulletinId())
+ .append("sts", getSts())
+ .toString();
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinInfoMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinInfoMapper.java
new file mode 100644
index 00000000..cd8a16dd
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinInfoMapper.java
@@ -0,0 +1,95 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+
+
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.domain.BulletinRecive;
+
+/**
+ * 公告栏Mapper接口
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public interface BulletinInfoMapper
+{
+ /**
+ * 查询公告栏
+ *
+ * @param bulletinId 公告栏主键
+ * @return 公告栏
+ */
+ public BulletinInfo selectBulletinInfoByBulletinId(String bulletinId);
+
+ /**
+ * 查询公告栏列表
+ *
+ * @param bulletinInfo 公告栏
+ * @return 公告栏集合
+ */
+ public List selectBulletinInfoList(BulletinInfo bulletinInfo);
+
+ /**
+ * 根据bulletinId查询公告栏列表
+ * @param bulletinIds
+ * @return
+ */
+ public List selectBulletinInfoListbyBulletinIds(String[] bulletinIds);
+ /**
+ * 新增公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ public int insertBulletinInfo(BulletinInfo bulletinInfo);
+
+ /**
+ * 修改公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ public int updateBulletinInfo(BulletinInfo bulletinInfo);
+
+ /**
+ * 删除公告栏
+ *
+ * @param bulletinId 公告栏主键
+ * @return 结果
+ */
+ public int deleteBulletinInfoByBulletinId(String bulletinId);
+
+ /**
+ * 批量删除公告栏
+ *
+ * @param bulletinIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteBulletinInfoByBulletinIds(String[] bulletinIds);
+
+ /**
+ * 批量删除公告接收者
+ *
+ * @param bulletinIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteBulletinReciveByBulletinIds(String[] bulletinIds);
+
+ /**
+ * 批量新增公告接收者
+ *
+ * @param bulletinReciveList 公告接收者列表
+ * @return 结果
+ */
+ public int batchBulletinRecive(List bulletinReciveList);
+
+
+ /**
+ * 通过公告栏主键删除公告接收者信息
+ *
+ * @param bulletinId 公告栏ID
+ * @return 结果
+ */
+ public int deleteBulletinReciveByBulletinId(String bulletinId);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinReciveMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinReciveMapper.java
new file mode 100644
index 00000000..207cfe61
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/BulletinReciveMapper.java
@@ -0,0 +1,74 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+import com.ruoyi.system.domain.BulletinRecive;
+
+/**
+ * 公告接收者Mapper接口
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public interface BulletinReciveMapper
+{
+
+ /**
+ * 批量更新已阅读
+ * @param bulletinRecive
+ * @return
+ */
+ public int batchUpdateRead(String[] reciveIds);
+ /**
+ * 只查询出bulletinId和接收的reciveUserId
+ * @param bulletinIds
+ * @return
+ */
+ public List selectBulletinReciveUserIdByBulletinIds(String[] bulletinIds);
+ /**
+ * 查询公告接收者
+ *
+ * @param reciveId 公告接收者主键
+ * @return 公告接收者
+ */
+ public BulletinRecive selectBulletinReciveByReciveId(String reciveId);
+
+ /**
+ * 查询公告接收者列表
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 公告接收者集合
+ */
+ public List selectBulletinReciveList(BulletinRecive bulletinRecive);
+
+ /**
+ * 新增公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ public int insertBulletinRecive(BulletinRecive bulletinRecive);
+
+ /**
+ * 修改公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ public int updateBulletinRecive(BulletinRecive bulletinRecive);
+
+ /**
+ * 删除公告接收者
+ *
+ * @param reciveId 公告接收者主键
+ * @return 结果
+ */
+ public int deleteBulletinReciveByReciveId(String reciveId);
+
+ /**
+ * 批量删除公告接收者
+ *
+ * @param reciveIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteBulletinReciveByReciveIds(String[] reciveIds);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinInfoService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinInfoService.java
new file mode 100644
index 00000000..c383c6b7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinInfoService.java
@@ -0,0 +1,69 @@
+package com.ruoyi.system.service;
+
+import java.util.List;
+import com.ruoyi.system.domain.BulletinInfo;
+
+/**
+ * 公告栏Service接口
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public interface IBulletinInfoService
+{
+ /**
+ * 查询公告栏
+ *
+ * @param bulletinId 公告栏主键
+ * @return 公告栏
+ */
+ public BulletinInfo selectBulletinInfoByBulletinId(String bulletinId);
+
+ /**
+ * 查询公告栏列表
+ *
+ * @param bulletinInfo 公告栏
+ * @return 公告栏集合
+ */
+ public List selectBulletinInfoList(BulletinInfo bulletinInfo);
+
+ /**
+ * 新增公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ public int insertBulletinInfo(BulletinInfo bulletinInfo);
+
+ /**
+ * 修改公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ public int updateBulletinInfo(BulletinInfo bulletinInfo);
+
+ /**
+ * 批量删除公告栏
+ *
+ * @param bulletinIds 需要删除的公告栏主键集合
+ * @param sts B:逻辑删除,D:物理删除
+ * @return 结果
+ */
+ public int deleteBulletinInfoByBulletinIds(String[] bulletinIds,String sts);
+
+ /**
+ * 删除公告栏信息
+ *
+ * @param bulletinId 公告栏主键
+ * @return 结果
+ */
+ public int deleteBulletinInfoByBulletinId(String bulletinId);
+
+ /**
+ * 批量发送公告
+ * @param bulletinIds
+ * @return
+ */
+ int sendBulletinInfo(String[] bulletinIds);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinReciveService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinReciveService.java
new file mode 100644
index 00000000..b2ca63f6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/IBulletinReciveService.java
@@ -0,0 +1,78 @@
+package com.ruoyi.system.service;
+
+import java.util.List;
+
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.domain.BulletinRecive;
+
+/**
+ * 公告接收者Service接口
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+public interface IBulletinReciveService
+{
+ /**
+ * 查询公告接收者
+ *
+ * @param reciveId 公告接收者主键
+ * @return 公告接收者
+ */
+ public BulletinRecive selectBulletinReciveByReciveId(String reciveId);
+
+ /**
+ * 查询公告接收者列表
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 公告接收者集合
+ */
+ public List selectBulletinReciveList(BulletinRecive bulletinRecive);
+
+ /**
+ * 新增公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ public int insertBulletinRecive(BulletinRecive bulletinRecive);
+
+ /**
+ * 修改公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ public int updateBulletinRecive(BulletinRecive bulletinRecive);
+
+ /**
+ * 批量删除公告接收者
+ *
+ * @param reciveIds 需要删除的公告接收者主键集合
+ * @return 结果
+ */
+ public int deleteBulletinReciveByReciveIds(String[] reciveIds);
+
+ /**
+ * 删除公告接收者信息
+ *
+ * @param reciveId 公告接收者主键
+ * @return 结果
+ */
+ public int deleteBulletinReciveByReciveId(String reciveId);
+
+ /**
+ * 批量更新已阅读
+ * @param reciveIds
+ * @return
+ */
+ int batchRead(String[] reciveIds);
+
+ /**
+ * 批量物理删除公告接收者
+ *
+ * @param reciveIds 需要删除的公告接收者主键
+ * @return 结果
+ */
+ int deletePhysicalBulletinReciveByReciveIds(String[] reciveIds);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinInfoServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinInfoServiceImpl.java
new file mode 100644
index 00000000..db2b7972
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinInfoServiceImpl.java
@@ -0,0 +1,237 @@
+package com.ruoyi.system.service.impl;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.ruoyi.common.core.utils.DateUtils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.nutz.lang.util.NutMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+
+import com.ruoyi.common.security.utils.SecurityUtils;
+
+import org.springframework.transaction.annotation.Transactional;
+import com.ruoyi.system.domain.BulletinRecive;
+import com.ruoyi.system.mapper.BulletinInfoMapper;
+import com.ruoyi.system.mapper.BulletinReciveMapper;
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.service.IBulletinInfoService;
+
+import ecc.c3.util.IDUtil;
+
+/**
+ * 公告栏Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+@Service
+public class BulletinInfoServiceImpl implements IBulletinInfoService
+{
+ private Logger log=LoggerFactory.getLogger(BulletinInfoServiceImpl.class);
+ @Autowired
+ private BulletinInfoMapper bulletinInfoMapper;
+ @Autowired
+ private BulletinReciveMapper bulletinReciveMapper;
+
+ /**
+ * 查询公告栏
+ *
+ * @param bulletinId 公告栏主键
+ * @return 公告栏
+ */
+ @Override
+ public BulletinInfo selectBulletinInfoByBulletinId(String bulletinId)
+ {
+ List reciveUserIdAndbulletinId=bulletinReciveMapper.selectBulletinReciveUserIdByBulletinIds(new String[] {bulletinId});
+ BulletinInfo info= bulletinInfoMapper.selectBulletinInfoByBulletinId(bulletinId);
+ //TODO 把员工换算成名称
+ info.setCreateBy(info.getCreateUserId()+"");
+ info.setUpdateBy(info.getUpdateUserId()+"");
+ List reciveUserIdList=reciveUserIdAndbulletinId.stream().map(userId->userId.getReciveUserId()).collect(Collectors.toList());
+ info.setReceiveStaffIds(reciveUserIdList);
+ info.setReciveStaffNames(StringUtils.join(reciveUserIdList.iterator(), ","));
+ return info;
+ }
+
+ /**
+ * 查询公告栏列表
+ *
+ * @param bulletinInfo 公告栏
+ * @return 公告栏
+ */
+ @Override
+ public List selectBulletinInfoList(BulletinInfo bulletinInfo)
+ {
+ bulletinInfo.setCreateUserId(SecurityUtils.getUserId());
+ List list=bulletinInfoMapper.selectBulletinInfoList(bulletinInfo);
+ String[] bulletinIds=list.stream().map(info->info.getBulletinId()).toArray(String[]::new);
+ if(bulletinIds.length>0) {
+ final NutMap reciveUserNameMap=NutMap.NEW();
+ final NutMap reciveBulletinReciveMap=NutMap.NEW();
+ List reciveUserIdAndbulletinIdList=bulletinReciveMapper.selectBulletinReciveUserIdByBulletinIds(bulletinIds);
+ reciveUserIdAndbulletinIdList.forEach(reciveUserIdAndBulletinId->{
+ //TODO 这里要把reciveUserId换算成用户名
+ reciveUserNameMap.addv2(reciveUserIdAndBulletinId.getBulletinId(), reciveUserIdAndBulletinId.getReciveUserId()+"");
+ reciveBulletinReciveMap.addv2(reciveUserIdAndBulletinId.getBulletinId(), reciveUserIdAndBulletinId);
+ });
+ list.forEach(info->{
+ String reciveStaffNames=String.join(",", reciveUserNameMap.getList(info.getBulletinId(), String.class, Collections.emptyList()));
+ info.setReciveStaffNames(reciveStaffNames);
+ info.setBulletinReciveList(reciveBulletinReciveMap.getList(info.getBulletinId(), BulletinRecive.class,Collections.emptyList()));
+ });
+ }
+ return list;
+ }
+
+ /**
+ * 批量发送公告
+ * @param bulletinIds
+ * @return
+ */
+ @Override
+ public int sendBulletinInfo(String[] bulletinIds) {
+ int updateCount=0;
+ for (String bulletinId : bulletinIds) {
+ log.info("发送公告,bulletinId:{}",bulletinId);
+ BulletinInfo info=new BulletinInfo();
+ info.setBulletinId(bulletinId);
+ info.setSendTime(DateUtils.getNowDate());
+ info.setUpdateUserId(SecurityUtils.getUserId());
+ info.setUpdateTime(info.getSendTime());
+ info.setSts("A");
+
+ updateCount+=bulletinInfoMapper.updateBulletinInfo(info);
+ }
+ return updateCount;
+ }
+ /**
+ * 推送公告给客户端
+ * @param bulletinId
+ * @return
+ */
+ private boolean pushBulletinToClient(String bulletinId) {
+ //TODO 发送公告的业务逻辑还没做,需要获取在线用户,推送给对方
+ log.info("发送公告,bulletinId:{} 业务逻辑还是空的",bulletinId);
+ return true;
+ }
+ /**
+ * 新增公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ @Transactional
+ @Override
+ public int insertBulletinInfo(BulletinInfo bulletinInfo)
+ {
+ bulletinInfo.setBulletinId(IDUtil.getStrId());
+ Long userId=SecurityUtils.getUserId();
+ bulletinInfo.setCreateUserId(userId);
+ Date currDate=DateUtils.getNowDate();
+ bulletinInfo.setCreateTime(currDate);
+ bulletinInfo.setUpdateTime(currDate);
+ bulletinInfo.setUpdateUserId(userId);
+ if("A".equals(bulletinInfo.getSts())) {
+ bulletinInfo.setSendTime(bulletinInfo.getCreateTime());
+ }
+ bulletinInfo.setReadNum(0L);
+ int rows = bulletinInfoMapper.insertBulletinInfo(bulletinInfo);
+ insertBulletinRecive(bulletinInfo);
+ pushBulletinToClient(bulletinInfo.getBulletinId());
+ return rows;
+ }
+
+ /**
+ * 修改公告栏
+ *
+ * @param bulletinInfo 公告栏
+ * @return 结果
+ */
+ @Transactional
+ @Override
+ public int updateBulletinInfo(BulletinInfo bulletinInfo)
+ {
+ bulletinInfo.setUpdateTime(DateUtils.getNowDate());
+ bulletinInfo.setUpdateUserId(SecurityUtils.getUserId());
+ if(!bulletinInfo.getReceiveStaffIds().isEmpty()) {
+ bulletinInfoMapper.deleteBulletinReciveByBulletinId(bulletinInfo.getBulletinId());
+ insertBulletinRecive(bulletinInfo);
+ }
+ return bulletinInfoMapper.updateBulletinInfo(bulletinInfo);
+ }
+
+ /**
+ * 批量逻辑删除公告栏
+ *
+ * @param bulletinIds 需要删除的公告栏主键
+ * @return 结果
+ */
+ @Transactional
+ @Override
+ public int deleteBulletinInfoByBulletinIds(String[] bulletinIds,String sts)
+ {
+ int iCount=0;
+ for (String bulletinId : bulletinIds) {
+ BulletinInfo bulletinInfo=new BulletinInfo();
+ bulletinInfo.setBulletinId(bulletinId);
+ bulletinInfo.setUpdateTime(DateUtils.getNowDate());
+ bulletinInfo.setUpdateUserId(SecurityUtils.getUserId());
+ bulletinInfo.setSts(sts);
+ iCount+=bulletinInfoMapper.updateBulletinInfo(bulletinInfo);
+ }
+ return iCount;
+ }
+
+ /**
+ * 逻辑删除公告栏信息
+ *
+ * @param bulletinId 公告栏主键
+ * @return 结果
+ */
+ @Transactional
+ @Override
+ public int deleteBulletinInfoByBulletinId(String bulletinId)
+ {
+ return deleteBulletinInfoByBulletinIds(new String[] {bulletinId},"B");
+ }
+
+ /**
+ * 新增公告接收者信息
+ *
+ * @param bulletinInfo 公告栏对象
+ */
+ public void insertBulletinRecive(BulletinInfo bulletinInfo)
+ {
+ List reciveUserIdList=bulletinInfo.getReceiveStaffIds();
+ String bulletinId = bulletinInfo.getBulletinId();
+ List reciveList=new ArrayList<>(reciveUserIdList.size());
+ Date now=DateUtils.getNowDate();
+ bulletinInfo.setBulletinReciveList(reciveList);
+ Long userId=SecurityUtils.getUserId();
+ for (Long reciveUserId : reciveUserIdList) {
+ BulletinRecive bulletinRecive=new BulletinRecive();
+ bulletinRecive.setBulletinId(bulletinId);
+ bulletinRecive.setCreateTime(now);
+ bulletinRecive.setCreateUserId(userId);
+ bulletinRecive.setUpdateTime(now);
+ bulletinRecive.setUpdateUserId(userId);
+ bulletinRecive.setReadNum(0L);
+ bulletinRecive.setSts("C");
+ bulletinRecive.setReciveUserId(reciveUserId);
+ bulletinRecive.setReciveId(IDUtil.getStrId());
+ reciveList.add(bulletinRecive);
+ }
+ if (reciveList.size() > 0)
+ {
+ bulletinInfoMapper.batchBulletinRecive(reciveList);
+ }
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinReciveServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinReciveServiceImpl.java
new file mode 100644
index 00000000..c11abc89
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BulletinReciveServiceImpl.java
@@ -0,0 +1,157 @@
+package com.ruoyi.system.service.impl;
+
+import java.util.Collections;
+import java.util.List;
+
+import com.ruoyi.common.core.utils.DateUtils;
+import com.ruoyi.common.security.utils.SecurityUtils;
+
+import org.nutz.lang.util.NutMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.ruoyi.system.mapper.BulletinInfoMapper;
+import com.ruoyi.system.mapper.BulletinReciveMapper;
+import com.ruoyi.system.domain.BulletinInfo;
+import com.ruoyi.system.domain.BulletinRecive;
+import com.ruoyi.system.service.IBulletinReciveService;
+
+/**
+ * 公告接收者Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2023-03-09
+ */
+@Service
+public class BulletinReciveServiceImpl implements IBulletinReciveService
+{
+ @Autowired
+ private BulletinReciveMapper bulletinReciveMapper;
+ @Autowired
+ private BulletinInfoMapper bulletinInfoMapper;
+
+ @Transactional
+ /**
+ * 批量更新已阅读
+ * @param reciveIds
+ * @return
+ */
+ @Override
+ public int batchRead(String[] reciveIds) {
+ return bulletinReciveMapper.batchUpdateRead(reciveIds);
+ }
+ /**
+ * 查询公告接收者
+ *
+ * @param reciveId 公告接收者主键
+ * @return 公告接收者
+ */
+ @Override
+ public BulletinRecive selectBulletinReciveByReciveId(String reciveId)
+ {
+ return bulletinReciveMapper.selectBulletinReciveByReciveId(reciveId);
+ }
+
+ /**
+ * 查询公告接收者列表
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 公告接收者
+ */
+ @Override
+ public List selectBulletinReciveList(BulletinRecive bulletinRecive)
+ {
+ bulletinRecive.setReciveUserId(SecurityUtils.getUserId());
+ List reciveList= bulletinReciveMapper.selectBulletinReciveList(bulletinRecive);
+ if(reciveList.isEmpty()) {
+ return Collections.emptyList();
+ }
+ NutMap map=NutMap.NEW();
+ String[] bulletinIds=new String[reciveList.size()];
+ for (int i = 0; i < bulletinIds.length; i++) {
+ BulletinRecive recive=reciveList.get(i);
+ map.addv2(recive.getBulletinId(), recive);
+ bulletinIds[i]=recive.getBulletinId();
+ }
+ List infoList=bulletinInfoMapper.selectBulletinInfoListbyBulletinIds(bulletinIds);
+ infoList.forEach(info->{
+ info.setBulletinReciveList(map.getList(info.getBulletinId(), BulletinRecive.class,Collections.emptyList()));
+ });
+ return infoList;
+ }
+
+ /**
+ * 新增公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ @Override
+ public int insertBulletinRecive(BulletinRecive bulletinRecive)
+ {
+ bulletinRecive.setCreateTime(DateUtils.getNowDate());
+ return bulletinReciveMapper.insertBulletinRecive(bulletinRecive);
+ }
+
+ /**
+ * 修改公告接收者
+ *
+ * @param bulletinRecive 公告接收者
+ * @return 结果
+ */
+ @Override
+ public int updateBulletinRecive(BulletinRecive bulletinRecive)
+ {
+ bulletinRecive.setUpdateTime(DateUtils.getNowDate());
+ bulletinRecive.setUpdateUserId(SecurityUtils.getUserId());
+ return bulletinReciveMapper.updateBulletinRecive(bulletinRecive);
+ }
+
+ /**
+ * 批量物理删除公告接收者
+ *
+ * @param reciveIds 需要删除的公告接收者主键
+ * @return 结果
+ */
+ @Override
+ public int deletePhysicalBulletinReciveByReciveIds(String[] reciveIds)
+ {
+ return bulletinReciveMapper.deleteBulletinReciveByReciveIds(reciveIds);
+ }
+
+
+ /**
+ * 批量逻辑删除公告接收者
+ *
+ * @param reciveIds 需要删除的公告接收者主键
+ * @return 结果
+ */
+ @Override
+ @Transactional
+ public int deleteBulletinReciveByReciveIds(String[] reciveIds)
+ {
+ int iCount=0;
+ for (String reciveId : reciveIds) {
+ BulletinRecive bulletinRecive=new BulletinRecive();
+ bulletinRecive.setReciveId(reciveId);
+ bulletinRecive.setSts("B");
+ bulletinRecive.setUpdateTime(DateUtils.getNowDate());
+ bulletinRecive.setUpdateUserId(SecurityUtils.getUserId());
+ iCount+=bulletinReciveMapper.updateBulletinRecive(bulletinRecive);
+ }
+ return iCount;
+ }
+
+ /**
+ * 删除公告接收者信息
+ *
+ * @param reciveId 公告接收者主键
+ * @return 结果
+ */
+ @Override
+ public int deleteBulletinReciveByReciveId(String reciveId)
+ {
+ return bulletinReciveMapper.deleteBulletinReciveByReciveId(reciveId);
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/ecc/c3/util/IDUtil.java b/ruoyi-modules/ruoyi-system/src/main/java/ecc/c3/util/IDUtil.java
new file mode 100644
index 00000000..591ae387
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/ecc/c3/util/IDUtil.java
@@ -0,0 +1,45 @@
+package ecc.c3.util;
+
+import java.util.Random;
+
+/**
+ * 自动生成ID的工具类
+ * @author Condy
+ *
+ */
+public class IDUtil {
+ static private SnowflakeIdWorker id;
+ static {
+ Random random=new Random();
+ int workId=random.nextInt(32);
+ int datacenterId=random.nextInt(32);
+ id=new SnowflakeIdWorker(workId,datacenterId);
+ }
+ /**
+ * 获取18位的唯一主键
+ * @return
+ */
+ static public long getId(){
+ try {
+ return id.nextId();
+ }catch(RuntimeException e) {
+ //时间被调整回去了,可能是时间同步引起的
+ if(e.toString().contains("Clock moved backwards")) {
+ try {Thread.sleep(50);} catch (InterruptedException e1) {}
+ return id.nextId();
+ } else {
+ throw e;
+ }
+ }
+
+ }
+
+ /**
+ * 返回18位字符串的唯一ID
+ * @return
+ */
+ static public String getStrId(){
+ return id.nextId()+"";
+ }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/ecc/c3/util/SnowflakeIdWorker.java b/ruoyi-modules/ruoyi-system/src/main/java/ecc/c3/util/SnowflakeIdWorker.java
new file mode 100644
index 00000000..adf0e2b9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/ecc/c3/util/SnowflakeIdWorker.java
@@ -0,0 +1,146 @@
+package ecc.c3.util;
+
+/**
+ * Twitter_Snowflake
+ * SnowFlake的结构如下(每部分用-分开):
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号
+ * 加起来刚好64位,为一个Long型。
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+public class SnowflakeIdWorker {
+
+ // ==============================Fields===========================================
+ /** 开始时间截 (2015-01-01) */
+ private final long twepoch = 1420041600000L;
+
+ /** 机器id所占的位数 */
+ private final long workerIdBits = 5L;
+
+ /** 数据标识id所占的位数 */
+ private final long datacenterIdBits = 5L;
+
+ /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+ private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+ /** 支持的最大数据标识id,结果是31 */
+ private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+ /** 序列在id中占的位数 */
+ private final long sequenceBits = 12L;
+
+ /** 机器ID向左移12位 */
+ private final long workerIdShift = sequenceBits;
+
+ /** 数据标识id向左移17位(12+5) */
+ private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+ /** 时间截向左移22位(5+5+12) */
+ private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+ /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+ private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+ /** 工作机器ID(0~31) */
+ private long workerId;
+
+ /** 数据中心ID(0~31) */
+ private long datacenterId;
+
+ /** 毫秒内序列(0~4095) */
+ private long sequence = 0L;
+
+ /** 上次生成ID的时间截 */
+ private long lastTimestamp = -1L;
+
+ //==============================Constructors=====================================
+ /**
+ * 构造函数
+ * @param workerId 工作ID (0~31)
+ * @param datacenterId 数据中心ID (0~31)
+ */
+ public SnowflakeIdWorker(long workerId, long datacenterId) {
+ if (workerId > maxWorkerId || workerId < 0) {
+ throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+ }
+ if (datacenterId > maxDatacenterId || datacenterId < 0) {
+ throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+ }
+ this.workerId = workerId;
+ this.datacenterId = datacenterId;
+ }
+
+ // ==============================Methods==========================================
+ /**
+ * 获得下一个ID (该方法是线程安全的)
+ * @return SnowflakeId
+ */
+ public synchronized long nextId() {
+ long timestamp = timeGen();
+
+ //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+ if (timestamp < lastTimestamp) {
+ throw new RuntimeException(
+ String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+ }
+
+ //如果是同一时间生成的,则进行毫秒内序列
+ if (lastTimestamp == timestamp) {
+ sequence = (sequence + 1) & sequenceMask;
+ //毫秒内序列溢出
+ if (sequence == 0) {
+ //阻塞到下一个毫秒,获得新的时间戳
+ timestamp = tilNextMillis(lastTimestamp);
+ }
+ }
+ //时间戳改变,毫秒内序列重置
+ else {
+ sequence = 0L;
+ }
+
+ //上次生成ID的时间截
+ lastTimestamp = timestamp;
+
+ //移位并通过或运算拼到一起组成64位的ID
+ return ((timestamp - twepoch) << timestampLeftShift) //
+ | (datacenterId << datacenterIdShift) //
+ | (workerId << workerIdShift) //
+ | sequence;
+ }
+
+ /**
+ * 阻塞到下一个毫秒,直到获得新的时间戳
+ * @param lastTimestamp 上次生成ID的时间截
+ * @return 当前时间戳
+ */
+ protected long tilNextMillis(long lastTimestamp) {
+ long timestamp = timeGen();
+ while (timestamp <= lastTimestamp) {
+ timestamp = timeGen();
+ }
+ return timestamp;
+ }
+
+ /**
+ * 返回以毫秒为单位的当前时间
+ * @return 当前时间(毫秒)
+ */
+ protected long timeGen() {
+ return System.currentTimeMillis();
+ }
+
+ //==============================Test=============================================
+ /** 测试 */
+ public static void main(String[] args) {
+ SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
+ for (int i = 0; i < 1000; i++) {
+ long id = idWorker.nextId();
+ System.out.println(Long.toBinaryString(id));
+ System.out.println(id);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml b/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml
index 96bc0bbe..50435feb 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/logback.xml
@@ -3,7 +3,10 @@
-
+
+
@@ -11,6 +14,29 @@
${log.pattern}
+
+
+
+ ${log.path}/debug.log
+
+
+
+ ${log.path}/debug.%d{yyyy-MM-dd}.log
+
+ 4
+
+
+ ${log.pattern}
+
+
+
+ DEBUG
+
+ ACCEPT
+
+ DENY
+
+
@@ -61,14 +87,24 @@
+
+
+
+
+
+
+
+
+
-
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinInfoMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinInfoMapper.xml
new file mode 100644
index 00000000..e70c6be2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinInfoMapper.xml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select BULLETIN_ID, TITLE, CONTENT, CREATE_TIME, READ_NUM, SEND_TIME, CREATE_USER_ID, UPDATE_USER_ID, UPDATE_TIME, REMARK, STS from t_bulletin_info
+
+
+
+
+
+
+
+
+
+
+
+ insert into t_bulletin_info
+
+ BULLETIN_ID,
+ TITLE,
+ CONTENT,
+ CREATE_TIME,
+ READ_NUM,
+ SEND_TIME,
+ CREATE_USER_ID,
+ UPDATE_USER_ID,
+ UPDATE_TIME,
+ REMARK,
+ STS,
+
+
+ #{bulletinId},
+ #{title},
+ #{content},
+ #{createTime},
+ #{readNum},
+ #{sendTime},
+ #{createUserId},
+ #{updateUserId},
+ #{updateTime},
+ #{remark},
+ #{sts},
+
+
+
+
+ update t_bulletin_info
+
+ TITLE = #{title},
+ CONTENT = #{content},
+ CREATE_TIME = #{createTime},
+ READ_NUM = #{readNum},
+ SEND_TIME = #{sendTime},
+ CREATE_USER_ID = #{createUserId},
+ UPDATE_USER_ID = #{updateUserId},
+ UPDATE_TIME = #{updateTime},
+ REMARK = #{remark},
+ STS = #{sts},
+
+ where BULLETIN_ID = #{bulletinId}
+
+
+
+ delete from t_bulletin_info where BULLETIN_ID = #{bulletinId}
+
+
+
+ delete from t_bulletin_info where BULLETIN_ID in
+
+ #{bulletinId}
+
+
+
+
+ delete from t_bulletin_recive where BULLETIN_ID in
+
+ #{bulletinId}
+
+
+
+
+ delete from t_bulletin_recive where BULLETIN_ID = #{bulletinId}
+
+
+
+ insert into t_bulletin_recive( RECIVE_ID, RECIVE_USER_ID, READ_TIME, READ_NUM, CREATE_TIME, CREATE_USER_ID, UPDATE_USER_ID, UPDATE_TIME, REMARK, BULLETIN_ID, STS) values
+
+ ( #{item.reciveId}, #{item.reciveUserId}, #{item.readTime}, #{item.readNum}, #{item.createTime}, #{item.createUserId}, #{item.updateUserId}, #{item.updateTime}, #{item.remark}, #{item.bulletinId}, #{item.sts})
+
+
+
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinReciveMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinReciveMapper.xml
new file mode 100644
index 00000000..4c697327
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/BulletinReciveMapper.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select RECIVE_ID, RECIVE_USER_ID, READ_TIME, READ_NUM, CREATE_TIME, CREATE_USER_ID, UPDATE_USER_ID, UPDATE_TIME, REMARK, BULLETIN_ID, STS from t_bulletin_recive
+
+
+
+
+
+
+
+
+
+ insert into t_bulletin_recive
+
+ RECIVE_ID,
+ RECIVE_USER_ID,
+ READ_TIME,
+ READ_NUM,
+ CREATE_TIME,
+ CREATE_USER_ID,
+ UPDATE_USER_ID,
+ UPDATE_TIME,
+ REMARK,
+ BULLETIN_ID,
+ STS,
+
+
+ #{reciveId},
+ #{reciveUserId},
+ #{readTime},
+ #{readNum},
+ #{createTime},
+ #{createUserId},
+ #{updateUserId},
+ #{updateTime},
+ #{remark},
+ #{bulletinId},
+ #{sts},
+
+
+
+
+ update t_bulletin_recive
+
+ RECIVE_USER_ID = #{reciveUserId},
+ READ_TIME = #{readTime},
+ READ_NUM = #{readNum},
+ CREATE_TIME = #{createTime},
+ CREATE_USER_ID = #{createUserId},
+ UPDATE_USER_ID = #{updateUserId},
+ UPDATE_TIME = #{updateTime},
+ REMARK = #{remark},
+ BULLETIN_ID = #{bulletinId},
+ STS = #{sts},
+
+ where RECIVE_ID = #{reciveId}
+
+
+
+ update t_bulletin_recive set
+ READ_TIME = sysdate() ,
+ READ_NUM = READ_NUM+1,
+ sts ='A',
+ UPDATE_TIME=sysdate(),
+ UPDATE_USER_ID = RECIVE_USER_ID
+ where RECIVE_ID in
+
+ #{reciveId}
+
+
+
+
+ delete from t_bulletin_recive where RECIVE_ID = #{reciveId}
+
+
+
+ delete from t_bulletin_recive where RECIVE_ID in
+
+ #{reciveId}
+
+
+
\ No newline at end of file