23 changed files with 1748 additions and 141 deletions
-
90chenhai-admin/src/main/java/com/chenhai/web/controller/vet/CertificateTestController.java
-
56chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetCertificateController.java
-
103chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetNotificationController.java
-
21chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetPersonalInfoController.java
-
2chenhai-admin/src/main/resources/application.yml
-
55chenhai-system/src/main/java/com/chenhai/vet/CertificateRemindTask.java
-
8chenhai-system/src/main/java/com/chenhai/vet/domain/VetCertificate.java
-
161chenhai-system/src/main/java/com/chenhai/vet/domain/VetNotification.java
-
14chenhai-system/src/main/java/com/chenhai/vet/domain/VetPersonalInfo.java
-
120chenhai-system/src/main/java/com/chenhai/vet/mapper/VetNotificationMapper.java
-
1chenhai-system/src/main/java/com/chenhai/vet/mapper/VetPersonalInfoMapper.java
-
60chenhai-system/src/main/java/com/chenhai/vet/service/IVetCertificateService.java
-
1chenhai-system/src/main/java/com/chenhai/vet/service/IVetPersonalInfoService.java
-
64chenhai-system/src/main/java/com/chenhai/vet/service/VetNotificationService.java
-
328chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetCertificateServiceImpl.java
-
178chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetNotificationServiceImpl.java
-
5chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetPersonalInfoServiceImpl.java
-
182chenhai-system/src/main/resources/mapper/vet/VetNotificationMapper.xml
-
44chenhai-system/src/main/resources/mapper/vet/VetPersonalInfoMapper.xml
-
44chenhai-ui/src/api/vet/notification.js
-
4chenhai-ui/src/views/vet/certificate/index.vue
-
340chenhai-ui/src/views/vet/notification/index.vue
-
2chenhai-ui/vue.config.js
@ -0,0 +1,90 @@ |
|||||
|
/* |
||||
|
package com.chenhai.vet.controller; |
||||
|
|
||||
|
import com.chenhai.common.core.controller.BaseController; |
||||
|
import com.chenhai.common.core.domain.AjaxResult; |
||||
|
import com.chenhai.vet.domain.VetCertificate; |
||||
|
import com.chenhai.vet.service.IVetCertificateService; |
||||
|
import com.chenhai.vet.service.VetNotificationService; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
|
||||
|
*/ |
||||
|
/** |
||||
|
* 证书提醒测试控制器 |
||||
|
*//* |
||||
|
|
||||
|
@RestController |
||||
|
@RequestMapping("/test/certificate") |
||||
|
public class CertificateTestController extends BaseController { |
||||
|
|
||||
|
@Autowired |
||||
|
private IVetCertificateService vetCertificateService; |
||||
|
|
||||
|
@Autowired |
||||
|
private VetNotificationService vetNotificationService; |
||||
|
|
||||
|
*/ |
||||
|
/** |
||||
|
* 测试单个证书提醒 |
||||
|
*//* |
||||
|
|
||||
|
@GetMapping("/test-notify/{certId}") |
||||
|
public AjaxResult testNotify(@PathVariable Long certId) { |
||||
|
try { |
||||
|
logger.info("🎯 测试证书提醒,证书ID: {}", certId); |
||||
|
|
||||
|
// 1. 获取证书 |
||||
|
VetCertificate cert = vetCertificateService.selectVetCertificateById(certId); |
||||
|
if (cert == null) { |
||||
|
return error("证书不存在: " + certId); |
||||
|
} |
||||
|
|
||||
|
// 2. 直接调用通知服务 |
||||
|
logger.info("📨 调用通知服务,证书: {}", cert.getCertName()); |
||||
|
vetNotificationService.sendCertificateExpireRemind(cert); |
||||
|
logger.info("✅ 通知服务调用完成"); |
||||
|
|
||||
|
// 3. 返回结果 |
||||
|
return success("测试完成,证书ID: " + certId + |
||||
|
",证书名称: " + cert.getCertName() + |
||||
|
",请检查数据库通知表"); |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
logger.error("测试失败", e); |
||||
|
return error("测试失败: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
*/ |
||||
|
/** |
||||
|
* 手动触发定时任务 |
||||
|
*//* |
||||
|
|
||||
|
@GetMapping("/trigger-task") |
||||
|
public AjaxResult triggerTask() { |
||||
|
try { |
||||
|
logger.info("🚀 手动触发证书检查任务"); |
||||
|
vetCertificateService.checkAndSendCertificateReminders(); |
||||
|
return success("定时任务已手动触发,请查看控制台日志"); |
||||
|
} catch (Exception e) { |
||||
|
logger.error("触发定时任务失败", e); |
||||
|
return error("触发失败: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
*/ |
||||
|
/** |
||||
|
* 检查通知表数据 |
||||
|
*//* |
||||
|
|
||||
|
@GetMapping("/check-notifications") |
||||
|
public AjaxResult checkNotifications() { |
||||
|
try { |
||||
|
// 这里需要查询通知表,暂时返回简单信息 |
||||
|
return success("请通过SQL查询通知表: SELECT * FROM vet_notification ORDER BY create_time DESC LIMIT 10"); |
||||
|
} catch (Exception e) { |
||||
|
return error("检查失败: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
}*/ |
||||
@ -0,0 +1,103 @@ |
|||||
|
package com.chenhai.web.controller.vet; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import org.springframework.security.access.prepost.PreAuthorize; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
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.chenhai.common.annotation.Log; |
||||
|
import com.chenhai.common.core.controller.BaseController; |
||||
|
import com.chenhai.common.core.domain.AjaxResult; |
||||
|
import com.chenhai.common.enums.BusinessType; |
||||
|
import com.chenhai.vet.domain.VetNotification; |
||||
|
import com.chenhai.vet.service.VetNotificationService; |
||||
|
import com.chenhai.common.utils.poi.ExcelUtil; |
||||
|
import com.chenhai.common.core.page.TableDataInfo; |
||||
|
|
||||
|
/** |
||||
|
* 兽医通知Controller |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2025-12-29 |
||||
|
*/ |
||||
|
@RestController |
||||
|
@RequestMapping("/vet/notification") |
||||
|
public class VetNotificationController extends BaseController |
||||
|
{ |
||||
|
@Autowired |
||||
|
private VetNotificationService vetNotificationService; |
||||
|
|
||||
|
/** |
||||
|
* 查询兽医通知列表 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('vet:notification:list')") |
||||
|
@GetMapping("/list") |
||||
|
public TableDataInfo list(VetNotification vetNotification) |
||||
|
{ |
||||
|
startPage(); |
||||
|
List<VetNotification> list = vetNotificationService.selectVetNotificationList(vetNotification); |
||||
|
return getDataTable(list); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导出兽医通知列表 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('vet:notification:export')") |
||||
|
@Log(title = "兽医通知", businessType = BusinessType.EXPORT) |
||||
|
@GetMapping("/export") |
||||
|
public AjaxResult export(VetNotification vetNotification) |
||||
|
{ |
||||
|
List<VetNotification> list = vetNotificationService.selectVetNotificationList(vetNotification); |
||||
|
ExcelUtil<VetNotification> util = new ExcelUtil<VetNotification>(VetNotification.class); |
||||
|
return util.exportExcel(list, "兽医通知数据"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取兽医通知详细信息 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('vet:notification:query')") |
||||
|
@GetMapping(value = "/{id}") |
||||
|
public AjaxResult getInfo(@PathVariable("id") Long id) |
||||
|
{ |
||||
|
return success(vetNotificationService.selectVetNotificationById(id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增兽医通知 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('vet:notification:add')") |
||||
|
@Log(title = "兽医通知", businessType = BusinessType.INSERT) |
||||
|
@PostMapping |
||||
|
public AjaxResult add(@RequestBody VetNotification vetNotification) |
||||
|
{ |
||||
|
return toAjax(vetNotificationService.insertVetNotification(vetNotification)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改兽医通知 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('vet:notification:edit')") |
||||
|
@Log(title = "兽医通知", businessType = BusinessType.UPDATE) |
||||
|
@PutMapping |
||||
|
public AjaxResult edit(@RequestBody VetNotification vetNotification) |
||||
|
{ |
||||
|
return toAjax(vetNotificationService.updateVetNotification(vetNotification)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除兽医通知 |
||||
|
*/ |
||||
|
@PreAuthorize("@ss.hasPermi('vet:notification:remove')") |
||||
|
@Log(title = "兽医通知", businessType = BusinessType.DELETE) |
||||
|
@DeleteMapping("/{ids}") |
||||
|
public AjaxResult remove(@PathVariable Long[] ids) |
||||
|
{ |
||||
|
return toAjax(vetNotificationService.deleteVetNotificationByIds(ids)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
package com.chenhai.vet; |
||||
|
|
||||
|
import com.chenhai.vet.domain.VetCertificate; |
||||
|
import com.chenhai.vet.service.IVetCertificateService; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.scheduling.annotation.EnableScheduling; |
||||
|
import org.springframework.scheduling.annotation.Scheduled; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 证书提醒定时任务 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
*/ |
||||
|
@Component |
||||
|
@EnableScheduling |
||||
|
@Slf4j |
||||
|
public class CertificateRemindTask { |
||||
|
|
||||
|
@Autowired |
||||
|
private IVetCertificateService vetCertificateService; |
||||
|
|
||||
|
/** |
||||
|
* 每天凌晨2点检查证书过期情况 |
||||
|
*/ |
||||
|
/* @Scheduled(cron = "0 0 2 * * ?")*/ |
||||
|
@Scheduled(cron = "0 */1 * * * ?") |
||||
|
public void dailyCertificateCheck() { |
||||
|
log.info("开始执行每日证书检查任务..."); |
||||
|
try { |
||||
|
vetCertificateService.checkAndSendCertificateReminders(); |
||||
|
log.info("每日证书检查任务执行完成"); |
||||
|
} catch (Exception e) { |
||||
|
log.error("每日证书检查任务执行失败", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* *//** |
||||
|
* 每小时检查一次(可选,用于及时更新状态) |
||||
|
*//* |
||||
|
@Scheduled(cron = "0 0 * * * ?") |
||||
|
public void hourlyCertificateCheck() { |
||||
|
log.debug("执行每小时证书状态检查..."); |
||||
|
try { |
||||
|
// 更新所有证书状态 |
||||
|
vetCertificateService.selectVetCertificateList(new VetCertificate()) |
||||
|
.forEach(cert -> { |
||||
|
// 这里可以调用更新状态的方法 |
||||
|
}); |
||||
|
} catch (Exception e) { |
||||
|
log.error("每小时证书检查失败", e); |
||||
|
} |
||||
|
}*/ |
||||
|
} |
||||
@ -0,0 +1,161 @@ |
|||||
|
package com.chenhai.vet.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.chenhai.common.annotation.Excel; |
||||
|
import com.chenhai.common.core.domain.BaseEntity; |
||||
|
|
||||
|
/** |
||||
|
* 兽医通知对象 vet_notification |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2026-01-04 |
||||
|
*/ |
||||
|
public class VetNotification extends BaseEntity |
||||
|
{ |
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** 主键ID */ |
||||
|
private Long id; |
||||
|
|
||||
|
/** 接收用户ID */ |
||||
|
@Excel(name = "接收用户ID") |
||||
|
private Long userId; |
||||
|
|
||||
|
/** 通知标题 */ |
||||
|
@Excel(name = "通知标题") |
||||
|
private String title; |
||||
|
|
||||
|
/** 通知内容 */ |
||||
|
@Excel(name = "通知内容") |
||||
|
private String content; |
||||
|
|
||||
|
/** 通知类型 */ |
||||
|
@Excel(name = "通知类型") |
||||
|
private String type; |
||||
|
|
||||
|
/** 关联ID */ |
||||
|
@Excel(name = "关联ID") |
||||
|
private String relatedId; |
||||
|
|
||||
|
/** 是否已读 0:未读 1:已读 */ |
||||
|
@Excel(name = "是否已读 0:未读 1:已读") |
||||
|
private Integer isRead; |
||||
|
|
||||
|
/** 提醒级别 1:低 2:中 3:高 */ |
||||
|
@Excel(name = "提醒级别 1:低 2:中 3:高") |
||||
|
private Integer remindLevel; |
||||
|
|
||||
|
/** 阅读时间 */ |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd") |
||||
|
@Excel(name = "阅读时间", width = 30, dateFormat = "yyyy-MM-dd") |
||||
|
private Date readTime; |
||||
|
|
||||
|
public void setId(Long id) |
||||
|
{ |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public Long getId() |
||||
|
{ |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setUserId(Long userId) |
||||
|
{ |
||||
|
this.userId = userId; |
||||
|
} |
||||
|
|
||||
|
public Long getUserId() |
||||
|
{ |
||||
|
return userId; |
||||
|
} |
||||
|
|
||||
|
public void setTitle(String title) |
||||
|
{ |
||||
|
this.title = title; |
||||
|
} |
||||
|
|
||||
|
public String getTitle() |
||||
|
{ |
||||
|
return title; |
||||
|
} |
||||
|
|
||||
|
public void setContent(String content) |
||||
|
{ |
||||
|
this.content = content; |
||||
|
} |
||||
|
|
||||
|
public String getContent() |
||||
|
{ |
||||
|
return content; |
||||
|
} |
||||
|
|
||||
|
public void setType(String type) |
||||
|
{ |
||||
|
this.type = type; |
||||
|
} |
||||
|
|
||||
|
public String getType() |
||||
|
{ |
||||
|
return type; |
||||
|
} |
||||
|
|
||||
|
public void setRelatedId(String relatedId) |
||||
|
{ |
||||
|
this.relatedId = relatedId; |
||||
|
} |
||||
|
|
||||
|
public String getRelatedId() |
||||
|
{ |
||||
|
return relatedId; |
||||
|
} |
||||
|
|
||||
|
public void setIsRead(Integer isRead) |
||||
|
{ |
||||
|
this.isRead = isRead; |
||||
|
} |
||||
|
|
||||
|
public Integer getIsRead() |
||||
|
{ |
||||
|
return isRead; |
||||
|
} |
||||
|
|
||||
|
public void setRemindLevel(Integer remindLevel) |
||||
|
{ |
||||
|
this.remindLevel = remindLevel; |
||||
|
} |
||||
|
|
||||
|
public Integer getRemindLevel() |
||||
|
{ |
||||
|
return remindLevel; |
||||
|
} |
||||
|
|
||||
|
public void setReadTime(Date readTime) |
||||
|
{ |
||||
|
this.readTime = readTime; |
||||
|
} |
||||
|
|
||||
|
public Date getReadTime() |
||||
|
{ |
||||
|
return readTime; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String toString() { |
||||
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) |
||||
|
.append("id", getId()) |
||||
|
.append("userId", getUserId()) |
||||
|
.append("title", getTitle()) |
||||
|
.append("content", getContent()) |
||||
|
.append("type", getType()) |
||||
|
.append("relatedId", getRelatedId()) |
||||
|
.append("isRead", getIsRead()) |
||||
|
.append("remindLevel", getRemindLevel()) |
||||
|
.append("createTime", getCreateTime()) |
||||
|
.append("readTime", getReadTime()) |
||||
|
.toString(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,120 @@ |
|||||
|
|
||||
|
// VetNotificationMapper.java |
||||
|
package com.chenhai.vet.mapper; |
||||
|
|
||||
|
import com.chenhai.vet.domain.VetNotification; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 兽医通知Mapper接口 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2025-12-29 |
||||
|
*/ |
||||
|
public interface VetNotificationMapper |
||||
|
{ |
||||
|
/** |
||||
|
* 查询兽医通知 |
||||
|
* |
||||
|
* @param id 兽医通知主键 |
||||
|
* @return 兽医通知 |
||||
|
*/ |
||||
|
public VetNotification selectVetNotificationById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 查询兽医通知列表 |
||||
|
* |
||||
|
* @param vetNotification 兽医通知 |
||||
|
* @return 兽医通知集合 |
||||
|
*/ |
||||
|
public List<VetNotification> selectVetNotificationList(VetNotification vetNotification); |
||||
|
|
||||
|
/** |
||||
|
* 新增兽医通知 |
||||
|
* |
||||
|
* @param vetNotification 兽医通知 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int insertVetNotification(VetNotification vetNotification); |
||||
|
|
||||
|
/** |
||||
|
* 修改兽医通知 |
||||
|
* |
||||
|
* @param vetNotification 兽医通知 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int updateVetNotification(VetNotification vetNotification); |
||||
|
|
||||
|
/** |
||||
|
* 删除兽医通知 |
||||
|
* |
||||
|
* @param id 兽医通知主键 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int deleteVetNotificationById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 批量删除兽医通知 |
||||
|
* |
||||
|
* @param ids 需要删除的数据主键集合 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int deleteVetNotificationByIds(Long[] ids); |
||||
|
|
||||
|
/** |
||||
|
* 根据用户ID查询未读通知列表 |
||||
|
* |
||||
|
* @param userId 用户ID |
||||
|
* @return 通知列表 |
||||
|
*/ |
||||
|
public List<VetNotification> selectUnreadNotificationsByUserId(Long userId); |
||||
|
|
||||
|
/** |
||||
|
* 根据用户ID查询证书相关通知列表 |
||||
|
* |
||||
|
* @param userId 用户ID |
||||
|
* @return 通知列表 |
||||
|
*/ |
||||
|
public List<VetNotification> selectCertificateNotificationsByUserId(Long userId); |
||||
|
|
||||
|
/** |
||||
|
* 标记通知为已读 |
||||
|
* |
||||
|
* @param id 通知ID |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int markNotificationAsRead(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 标记用户所有通知为已读 |
||||
|
* |
||||
|
* @param userId 用户ID |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int markAllNotificationsAsRead(Long userId); |
||||
|
|
||||
|
/** |
||||
|
* 查询用户未读通知数量 |
||||
|
* |
||||
|
* @param userId 用户ID |
||||
|
* @return 未读通知数量 |
||||
|
*/ |
||||
|
public Integer countUnreadNotificationsByUserId(Long userId); |
||||
|
|
||||
|
/** |
||||
|
* 批量插入通知 |
||||
|
* |
||||
|
* @param notifications 通知列表 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
public int batchInsertVetNotifications(@Param("list") List<VetNotification> notifications); |
||||
|
|
||||
|
/** |
||||
|
* 清理过期通知 |
||||
|
* |
||||
|
* @param days 过期天数 |
||||
|
* @return 清理数量 |
||||
|
*/ |
||||
|
public int cleanExpiredNotifications(@Param("days") Integer days); |
||||
|
} |
||||
@ -1,62 +1,66 @@ |
|||||
package com.chenhai.vet.service; |
package com.chenhai.vet.service; |
||||
|
|
||||
import com.chenhai.vet.domain.VetCertificate; |
import com.chenhai.vet.domain.VetCertificate; |
||||
|
|
||||
import java.util.List; |
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
/** |
/** |
||||
* 兽医执业证书Service接口 |
* 兽医执业证书Service接口 |
||||
* |
|
||||
* @author ruoyi |
|
||||
* @date 2025-12-29 |
|
||||
*/ |
*/ |
||||
public interface IVetCertificateService |
public interface IVetCertificateService |
||||
{ |
{ |
||||
/** |
/** |
||||
* 查询兽医执业证书 |
* 查询兽医执业证书 |
||||
* |
|
||||
* @param id 兽医执业证书主键 |
|
||||
* @return 兽医执业证书 |
|
||||
*/ |
*/ |
||||
public VetCertificate selectVetCertificateById(Long id); |
|
||||
|
VetCertificate selectVetCertificateById(Long id); |
||||
|
|
||||
/** |
/** |
||||
* 查询兽医执业证书列表 |
* 查询兽医执业证书列表 |
||||
* |
|
||||
* @param vetCertificate 兽医执业证书 |
|
||||
* @return 兽医执业证书集合 |
|
||||
*/ |
*/ |
||||
public List<VetCertificate> selectVetCertificateList(VetCertificate vetCertificate); |
|
||||
|
List<VetCertificate> selectVetCertificateList(VetCertificate vetCertificate); |
||||
|
|
||||
/** |
/** |
||||
* 新增兽医执业证书 |
* 新增兽医执业证书 |
||||
* |
|
||||
* @param vetCertificate 兽医执业证书 |
|
||||
* @return 结果 |
|
||||
*/ |
*/ |
||||
public int insertVetCertificate(VetCertificate vetCertificate); |
|
||||
|
int insertVetCertificate(VetCertificate vetCertificate); |
||||
|
|
||||
/** |
/** |
||||
* 修改兽医执业证书 |
* 修改兽医执业证书 |
||||
* |
|
||||
* @param vetCertificate 兽医执业证书 |
|
||||
* @return 结果 |
|
||||
*/ |
*/ |
||||
public int updateVetCertificate(VetCertificate vetCertificate); |
|
||||
|
int updateVetCertificate(VetCertificate vetCertificate); |
||||
|
|
||||
/** |
/** |
||||
* 批量删除兽医执业证书 |
* 批量删除兽医执业证书 |
||||
* |
|
||||
* @param ids 需要删除的兽医执业证书主键集合 |
|
||||
* @return 结果 |
|
||||
*/ |
*/ |
||||
public int deleteVetCertificateByIds(Long[] ids); |
|
||||
|
int deleteVetCertificateByIds(Long[] ids); |
||||
|
|
||||
/** |
/** |
||||
* 删除兽医执业证书信息 |
* 删除兽医执业证书信息 |
||||
* |
|
||||
* @param id 兽医执业证书主键 |
|
||||
* @return 结果 |
|
||||
*/ |
*/ |
||||
public int deleteVetCertificateById(Long id); |
|
||||
|
int deleteVetCertificateById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 根据用户ID查询证书列表 |
||||
|
*/ |
||||
|
List<VetCertificate> selectCertificatesByUserId(Long userId); |
||||
|
|
||||
|
/** |
||||
|
* 获取即将过期的证书(30天内) |
||||
|
*/ |
||||
|
List<VetCertificate> selectExpiringCertificates(Long userId); |
||||
|
|
||||
|
/** |
||||
|
* 检查并发送证书过期提醒 |
||||
|
*/ |
||||
|
void checkAndSendCertificateReminders(); |
||||
|
|
||||
|
/** |
||||
|
* 手动触发证书检查 |
||||
|
*/ |
||||
|
void manualCheckCertificates(Long userId); |
||||
|
|
||||
|
/** |
||||
|
* 获取证书统计信息 |
||||
|
*/ |
||||
|
Map<String, Object> getCertificateStatistics(Long userId); |
||||
} |
} |
||||
@ -0,0 +1,64 @@ |
|||||
|
// VetNotificationService.java |
||||
|
package com.chenhai.vet.service; |
||||
|
|
||||
|
import com.chenhai.vet.domain.VetCertificate; |
||||
|
import com.chenhai.vet.domain.VetNotification; |
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface VetNotificationService { |
||||
|
|
||||
|
/** |
||||
|
* 根据ID查询通知 |
||||
|
*/ |
||||
|
VetNotification selectVetNotificationById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 查询通知列表 |
||||
|
*/ |
||||
|
List<VetNotification> selectVetNotificationList(VetNotification vetNotification); |
||||
|
|
||||
|
/** |
||||
|
* 新增通知 |
||||
|
*/ |
||||
|
int insertVetNotification(VetNotification vetNotification); |
||||
|
|
||||
|
/** |
||||
|
* 修改通知 |
||||
|
*/ |
||||
|
int updateVetNotification(VetNotification vetNotification); |
||||
|
|
||||
|
/** |
||||
|
* 删除通知 |
||||
|
*/ |
||||
|
int deleteVetNotificationById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 批量删除通知 |
||||
|
*/ |
||||
|
int deleteVetNotificationByIds(Long[] ids); |
||||
|
|
||||
|
/** |
||||
|
* 获取用户通知列表 |
||||
|
*/ |
||||
|
List<VetNotification> getNotificationsByUserId(Long userId); |
||||
|
|
||||
|
/** |
||||
|
* 获取未读通知数量 |
||||
|
*/ |
||||
|
int getUnreadCount(Long userId); |
||||
|
|
||||
|
/** |
||||
|
* 发送证书过期提醒通知 |
||||
|
*/ |
||||
|
void sendCertificateExpireRemind(VetCertificate certificate); |
||||
|
|
||||
|
/** |
||||
|
* 标记通知为已读 |
||||
|
*/ |
||||
|
boolean markAsRead(Long notificationId); |
||||
|
|
||||
|
/** |
||||
|
* 标记所有通知为已读 |
||||
|
*/ |
||||
|
boolean markAllAsRead(Long userId); |
||||
|
} |
||||
@ -0,0 +1,178 @@ |
|||||
|
// 更简单的版本,完全使用 Date |
||||
|
package com.chenhai.vet.service.impl; |
||||
|
|
||||
|
import com.chenhai.vet.domain.VetCertificate; |
||||
|
import com.chenhai.vet.domain.VetNotification; |
||||
|
import com.chenhai.vet.mapper.VetNotificationMapper; |
||||
|
import com.chenhai.vet.service.VetNotificationService; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.text.SimpleDateFormat; |
||||
|
import java.util.Calendar; |
||||
|
import java.util.Date; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Service |
||||
|
@RequiredArgsConstructor |
||||
|
@Slf4j |
||||
|
public class VetNotificationServiceImpl implements VetNotificationService { |
||||
|
|
||||
|
private final VetNotificationMapper vetNotificationMapper; |
||||
|
|
||||
|
@Override |
||||
|
public VetNotification selectVetNotificationById(Long id) { |
||||
|
return vetNotificationMapper.selectVetNotificationById(id); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<VetNotification> selectVetNotificationList(VetNotification vetNotification) { |
||||
|
return vetNotificationMapper.selectVetNotificationList(vetNotification); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int insertVetNotification(VetNotification vetNotification) { |
||||
|
return vetNotificationMapper.insertVetNotification(vetNotification); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int updateVetNotification(VetNotification vetNotification) { |
||||
|
return vetNotificationMapper.updateVetNotification(vetNotification); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int deleteVetNotificationById(Long id) { |
||||
|
return vetNotificationMapper.deleteVetNotificationById(id); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int deleteVetNotificationByIds(Long[] ids) { |
||||
|
return vetNotificationMapper.deleteVetNotificationByIds(ids); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<VetNotification> getNotificationsByUserId(Long userId) { |
||||
|
VetNotification query = new VetNotification(); |
||||
|
query.setUserId(userId); |
||||
|
return vetNotificationMapper.selectVetNotificationList(query); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getUnreadCount(Long userId) { |
||||
|
VetNotification query = new VetNotification(); |
||||
|
query.setUserId(userId); |
||||
|
query.setIsRead(0); |
||||
|
List<VetNotification> list = vetNotificationMapper.selectVetNotificationList(query); |
||||
|
return list != null ? list.size() : 0; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void sendCertificateExpireRemind(VetCertificate certificate) { |
||||
|
if (certificate == null || certificate.getExpireDate() == null) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
Date now = new Date(); |
||||
|
Date expireDate = certificate.getExpireDate(); |
||||
|
|
||||
|
// 计算距离过期的天数 |
||||
|
long daysBetween = calculateDayDifference(now, expireDate); |
||||
|
|
||||
|
VetNotification notification = new VetNotification(); |
||||
|
notification.setUserId(certificate.getUserId()); |
||||
|
notification.setRelatedId(certificate.getId().toString()); |
||||
|
notification.setType("CERT_EXPIRE_REMIND"); |
||||
|
notification.setIsRead(0); |
||||
|
notification.setCreateTime(now); // 直接使用 Date |
||||
|
|
||||
|
if (daysBetween <= 0) { |
||||
|
notification.setTitle("🔴 证书已过期"); |
||||
|
notification.setContent(String.format("您的《%s》证书已于%s过期!请立即更新证书以继续提供服务。", |
||||
|
certificate.getCertName(), formatDate(expireDate))); |
||||
|
notification.setRemindLevel(3); |
||||
|
} else if (daysBetween <= 7) { |
||||
|
notification.setTitle("⚠️ 证书即将过期(7天内)"); |
||||
|
notification.setContent(String.format("您的《%s》证书将在%d天后过期,请尽快完成更新!", |
||||
|
certificate.getCertName(), daysBetween)); |
||||
|
notification.setRemindLevel(3); |
||||
|
} else if (daysBetween <= 30) { |
||||
|
notification.setTitle("⚠️ 证书即将过期(30天内)"); |
||||
|
notification.setContent(String.format("您的《%s》证书将在%d天后过期,请及时安排更新。", |
||||
|
certificate.getCertName(), daysBetween)); |
||||
|
notification.setRemindLevel(2); |
||||
|
} else { |
||||
|
// 超过30天,不发送常规提醒 |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
vetNotificationMapper.insertVetNotification(notification); |
||||
|
log.info("发送证书提醒通知:用户ID={}, 证书ID={}, 天数={}", |
||||
|
certificate.getUserId(), certificate.getId(), daysBetween); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean markAsRead(Long notificationId) { |
||||
|
VetNotification notification = vetNotificationMapper.selectVetNotificationById(notificationId); |
||||
|
if (notification != null && notification.getIsRead() == 0) { |
||||
|
notification.setIsRead(1); |
||||
|
notification.setReadTime(new Date()); |
||||
|
int result = vetNotificationMapper.updateVetNotification(notification); |
||||
|
return result > 0; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean markAllAsRead(Long userId) { |
||||
|
List<VetNotification> unreadNotifications = getNotificationsByUserId(userId); |
||||
|
int count = 0; |
||||
|
for (VetNotification notification : unreadNotifications) { |
||||
|
if (notification.getIsRead() == 0) { |
||||
|
notification.setIsRead(1); |
||||
|
notification.setReadTime(new Date()); |
||||
|
vetNotificationMapper.updateVetNotification(notification); |
||||
|
count++; |
||||
|
} |
||||
|
} |
||||
|
log.info("标记所有通知为已读:用户ID={}, 标记数量={}", userId, count); |
||||
|
return count > 0; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 计算两个日期之间的天数差(忽略时间部分) |
||||
|
*/ |
||||
|
private long calculateDayDifference(Date startDate, Date endDate) { |
||||
|
if (startDate == null || endDate == null) { |
||||
|
return 0L; |
||||
|
} |
||||
|
|
||||
|
Calendar startCal = Calendar.getInstance(); |
||||
|
startCal.setTime(startDate); |
||||
|
startCal.set(Calendar.HOUR_OF_DAY, 0); |
||||
|
startCal.set(Calendar.MINUTE, 0); |
||||
|
startCal.set(Calendar.SECOND, 0); |
||||
|
startCal.set(Calendar.MILLISECOND, 0); |
||||
|
|
||||
|
Calendar endCal = Calendar.getInstance(); |
||||
|
endCal.setTime(endDate); |
||||
|
endCal.set(Calendar.HOUR_OF_DAY, 0); |
||||
|
endCal.set(Calendar.MINUTE, 0); |
||||
|
endCal.set(Calendar.SECOND, 0); |
||||
|
endCal.set(Calendar.MILLISECOND, 0); |
||||
|
|
||||
|
long diff = endCal.getTimeInMillis() - startCal.getTimeInMillis(); |
||||
|
return diff / (1000 * 60 * 60 * 24); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 格式化日期为字符串 |
||||
|
*/ |
||||
|
private String formatDate(Date date) { |
||||
|
if (date == null) { |
||||
|
return ""; |
||||
|
} |
||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
||||
|
return sdf.format(date); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,182 @@ |
|||||
|
<?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.chenhai.vet.mapper.VetNotificationMapper"> |
||||
|
|
||||
|
<resultMap type="VetNotification" id="VetNotificationResult"> |
||||
|
<id property="id" column="id"/> |
||||
|
<result property="userId" column="user_id"/> |
||||
|
<result property="title" column="title"/> |
||||
|
<result property="content" column="content"/> |
||||
|
<result property="type" column="type"/> |
||||
|
<result property="relatedId" column="related_id"/> |
||||
|
<result property="isRead" column="is_read"/> |
||||
|
<result property="remindLevel" column="remind_level"/> |
||||
|
<result property="createTime" column="create_time"/> |
||||
|
<result property="readTime" column="read_time"/> |
||||
|
</resultMap> |
||||
|
|
||||
|
<sql id="selectVetNotificationVo"> |
||||
|
select id, user_id, title, content, type, related_id, is_read, remind_level, create_time, read_time |
||||
|
from vet_notification |
||||
|
</sql> |
||||
|
|
||||
|
<select id="selectVetNotificationById" parameterType="Long" resultMap="VetNotificationResult"> |
||||
|
<include refid="selectVetNotificationVo"/> |
||||
|
where id = #{id} |
||||
|
<!-- 已删除 is_deleted = 0 --> |
||||
|
</select> |
||||
|
|
||||
|
<select id="selectVetNotificationList" parameterType="VetNotification" resultMap="VetNotificationResult"> |
||||
|
<include refid="selectVetNotificationVo"/> |
||||
|
<where> |
||||
|
<!-- 已删除 is_deleted = 0 --> |
||||
|
<if test="userId != null"> and user_id = #{userId}</if> |
||||
|
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if> |
||||
|
<if test="content != null and content != ''"> and content like concat('%', #{content}, '%')</if> |
||||
|
<if test="type != null and type != ''"> and type = #{type}</if> |
||||
|
<if test="relatedId != null and relatedId != ''"> and related_id = #{relatedId}</if> |
||||
|
<if test="isRead != null"> and is_read = #{isRead}</if> |
||||
|
<if test="remindLevel != null"> and remind_level = #{remindLevel}</if> |
||||
|
<if test="createTime != null"> and create_time = #{createTime}</if> |
||||
|
<if test="readTime != null"> and read_time = #{readTime}</if> |
||||
|
</where> |
||||
|
order by create_time desc |
||||
|
</select> |
||||
|
|
||||
|
<select id="selectUnreadNotificationsByUserId" parameterType="Long" resultMap="VetNotificationResult"> |
||||
|
<include refid="selectVetNotificationVo"/> |
||||
|
where user_id = #{userId} |
||||
|
and is_read = 0 |
||||
|
<!-- 已删除 and is_deleted = 0 --> |
||||
|
order by create_time desc |
||||
|
</select> |
||||
|
|
||||
|
<select id="selectCertificateNotificationsByUserId" parameterType="Long" resultMap="VetNotificationResult"> |
||||
|
<include refid="selectVetNotificationVo"/> |
||||
|
where user_id = #{userId} |
||||
|
and type like 'CERT%' |
||||
|
<!-- 已删除 and is_deleted = 0 --> |
||||
|
order by create_time desc |
||||
|
</select> |
||||
|
|
||||
|
<select id="countUnreadNotificationsByUserId" parameterType="Long" resultType="Integer"> |
||||
|
select count(*) from vet_notification |
||||
|
where user_id = #{userId} |
||||
|
and is_read = 0 |
||||
|
<!-- 已删除 and is_deleted = 0 --> |
||||
|
</select> |
||||
|
|
||||
|
<insert id="insertVetNotification" parameterType="VetNotification" useGeneratedKeys="true" keyProperty="id"> |
||||
|
insert into vet_notification |
||||
|
<trim prefix="(" suffix=")" suffixOverrides=","> |
||||
|
<if test="userId != null">user_id,</if> |
||||
|
<if test="title != null and title != ''">title,</if> |
||||
|
<if test="content != null and content != ''">content,</if> |
||||
|
<if test="type != null and type != ''">type,</if> |
||||
|
<if test="relatedId != null and relatedId != ''">related_id,</if> |
||||
|
<if test="isRead != null">is_read,</if> |
||||
|
<if test="remindLevel != null">remind_level,</if> |
||||
|
<if test="createTime != null">create_time,</if> |
||||
|
<if test="readTime != null">read_time,</if> |
||||
|
</trim> |
||||
|
<trim prefix="values (" suffix=")" suffixOverrides=","> |
||||
|
<if test="userId != null">#{userId},</if> |
||||
|
<if test="title != null and title != ''">#{title},</if> |
||||
|
<if test="content != null and content != ''">#{content},</if> |
||||
|
<if test="type != null and type != ''">#{type},</if> |
||||
|
<if test="relatedId != null and relatedId != ''">#{relatedId},</if> |
||||
|
<if test="isRead != null">#{isRead},</if> |
||||
|
<if test="remindLevel != null">#{remindLevel},</if> |
||||
|
<if test="createTime != null">#{createTime},</if> |
||||
|
<if test="readTime != null">#{readTime},</if> |
||||
|
</trim> |
||||
|
</insert> |
||||
|
|
||||
|
<insert id="batchInsertVetNotifications" parameterType="java.util.List"> |
||||
|
insert into vet_notification (user_id, title, content, type, related_id, is_read, remind_level, create_time) |
||||
|
values |
||||
|
<foreach collection="list" item="item" separator=","> |
||||
|
( |
||||
|
#{item.userId}, |
||||
|
#{item.title}, |
||||
|
#{item.content}, |
||||
|
#{item.type}, |
||||
|
#{item.relatedId}, |
||||
|
#{item.isRead}, |
||||
|
#{item.remindLevel}, |
||||
|
#{item.createTime} |
||||
|
) |
||||
|
</foreach> |
||||
|
</insert> |
||||
|
|
||||
|
<update id="updateVetNotification" parameterType="VetNotification"> |
||||
|
update vet_notification |
||||
|
<trim prefix="SET" suffixOverrides=","> |
||||
|
<if test="userId != null">user_id = #{userId},</if> |
||||
|
<if test="title != null and title != ''">title = #{title},</if> |
||||
|
<if test="content != null and content != ''">content = #{content},</if> |
||||
|
<if test="type != null and type != ''">type = #{type},</if> |
||||
|
<if test="relatedId != null and relatedId != ''">related_id = #{relatedId},</if> |
||||
|
<if test="isRead != null">is_read = #{isRead},</if> |
||||
|
<if test="remindLevel != null">remind_level = #{remindLevel},</if> |
||||
|
<if test="createTime != null">create_time = #{createTime},</if> |
||||
|
<if test="readTime != null">read_time = #{readTime},</if> |
||||
|
</trim> |
||||
|
where id = #{id} |
||||
|
</update> |
||||
|
|
||||
|
<update id="markNotificationAsRead" parameterType="Long"> |
||||
|
update vet_notification |
||||
|
set is_read = 1, |
||||
|
read_time = now() |
||||
|
where id = #{id} |
||||
|
and is_read = 0 |
||||
|
</update> |
||||
|
|
||||
|
<update id="markAllNotificationsAsRead" parameterType="Long"> |
||||
|
update vet_notification |
||||
|
set is_read = 1, |
||||
|
read_time = now() |
||||
|
where user_id = #{userId} |
||||
|
and is_read = 0 |
||||
|
</update> |
||||
|
|
||||
|
<!-- 删除这个cleanExpiredNotifications方法,因为没有is_deleted字段 --> |
||||
|
<!-- <update id="cleanExpiredNotifications" parameterType="Integer"> |
||||
|
update vet_notification |
||||
|
set is_deleted = 1 |
||||
|
where create_time < date_sub(now(), interval #{days} day) |
||||
|
and is_deleted = 0 |
||||
|
</update> --> |
||||
|
|
||||
|
<!-- 删除这个deleteVetNotificationById方法,因为没有is_deleted字段 --> |
||||
|
<!-- <update id="deleteVetNotificationById" parameterType="Long"> |
||||
|
update vet_notification |
||||
|
set is_deleted = 1 |
||||
|
where id = #{id} |
||||
|
</update> --> |
||||
|
|
||||
|
<!-- 删除这个deleteVetNotificationByIds方法,因为没有is_deleted字段 --> |
||||
|
<!-- <update id="deleteVetNotificationByIds" parameterType="Long"> |
||||
|
update vet_notification |
||||
|
set is_deleted = 1 |
||||
|
where id in |
||||
|
<foreach item="id" collection="array" open="(" separator="," close=")"> |
||||
|
#{id} |
||||
|
</foreach> |
||||
|
</update> --> |
||||
|
|
||||
|
<!-- 如果需要硬删除,可以添加以下方法 --> |
||||
|
<delete id="deleteVetNotificationById" parameterType="Long"> |
||||
|
delete from vet_notification where id = #{id} |
||||
|
</delete> |
||||
|
|
||||
|
<delete id="deleteVetNotificationByIds" parameterType="Long"> |
||||
|
delete from vet_notification where id in |
||||
|
<foreach item="id" collection="array" open="(" separator="," close=")"> |
||||
|
#{id} |
||||
|
</foreach> |
||||
|
</delete> |
||||
|
</mapper> |
||||
@ -0,0 +1,44 @@ |
|||||
|
import request from '@/utils/request' |
||||
|
|
||||
|
// 查询兽医通知列表
|
||||
|
export function listNotification(query) { |
||||
|
return request({ |
||||
|
url: '/vet/notification/list', |
||||
|
method: 'get', |
||||
|
params: query |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 查询兽医通知详细
|
||||
|
export function getNotification(id) { |
||||
|
return request({ |
||||
|
url: '/vet/notification/' + id, |
||||
|
method: 'get' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 新增兽医通知
|
||||
|
export function addNotification(data) { |
||||
|
return request({ |
||||
|
url: '/vet/notification', |
||||
|
method: 'post', |
||||
|
data: data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 修改兽医通知
|
||||
|
export function updateNotification(data) { |
||||
|
return request({ |
||||
|
url: '/vet/notification', |
||||
|
method: 'put', |
||||
|
data: data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 删除兽医通知
|
||||
|
export function delNotification(id) { |
||||
|
return request({ |
||||
|
url: '/vet/notification/' + id, |
||||
|
method: 'delete' |
||||
|
}) |
||||
|
} |
||||
@ -0,0 +1,340 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
||||
|
<el-form-item label="接收用户ID" prop="userId"> |
||||
|
<el-input |
||||
|
v-model="queryParams.userId" |
||||
|
placeholder="请输入接收用户ID" |
||||
|
clearable |
||||
|
@keyup.enter.native="handleQuery" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="通知标题" prop="title"> |
||||
|
<el-input |
||||
|
v-model="queryParams.title" |
||||
|
placeholder="请输入通知标题" |
||||
|
clearable |
||||
|
@keyup.enter.native="handleQuery" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="关联ID" prop="relatedId"> |
||||
|
<el-input |
||||
|
v-model="queryParams.relatedId" |
||||
|
placeholder="请输入关联ID" |
||||
|
clearable |
||||
|
@keyup.enter.native="handleQuery" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="是否已读 0:未读 1:已读" prop="isRead"> |
||||
|
<el-input |
||||
|
v-model="queryParams.isRead" |
||||
|
placeholder="请输入是否已读 0:未读 1:已读" |
||||
|
clearable |
||||
|
@keyup.enter.native="handleQuery" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="提醒级别 1:低 2:中 3:高" prop="remindLevel"> |
||||
|
<el-input |
||||
|
v-model="queryParams.remindLevel" |
||||
|
placeholder="请输入提醒级别 1:低 2:中 3:高" |
||||
|
clearable |
||||
|
@keyup.enter.native="handleQuery" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="阅读时间" prop="readTime"> |
||||
|
<el-date-picker clearable |
||||
|
v-model="queryParams.readTime" |
||||
|
type="date" |
||||
|
value-format="yyyy-MM-dd" |
||||
|
placeholder="请选择阅读时间"> |
||||
|
</el-date-picker> |
||||
|
</el-form-item> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
||||
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
|
||||
|
<el-row :gutter="10" class="mb8"> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button |
||||
|
type="primary" |
||||
|
plain |
||||
|
icon="el-icon-plus" |
||||
|
size="mini" |
||||
|
@click="handleAdd" |
||||
|
v-hasPermi="['vet:notification:add']" |
||||
|
>新增</el-button> |
||||
|
</el-col> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button |
||||
|
type="success" |
||||
|
plain |
||||
|
icon="el-icon-edit" |
||||
|
size="mini" |
||||
|
:disabled="single" |
||||
|
@click="handleUpdate" |
||||
|
v-hasPermi="['vet:notification:edit']" |
||||
|
>修改</el-button> |
||||
|
</el-col> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button |
||||
|
type="danger" |
||||
|
plain |
||||
|
icon="el-icon-delete" |
||||
|
size="mini" |
||||
|
:disabled="multiple" |
||||
|
@click="handleDelete" |
||||
|
v-hasPermi="['vet:notification:remove']" |
||||
|
>删除</el-button> |
||||
|
</el-col> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button |
||||
|
type="warning" |
||||
|
plain |
||||
|
icon="el-icon-download" |
||||
|
size="mini" |
||||
|
@click="handleExport" |
||||
|
v-hasPermi="['system:notification:export']" |
||||
|
>导出</el-button> |
||||
|
</el-col> |
||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
||||
|
</el-row> |
||||
|
|
||||
|
<el-table v-loading="loading" :data="notificationList" @selection-change="handleSelectionChange"> |
||||
|
<el-table-column type="selection" width="55" align="center" /> |
||||
|
<el-table-column label="主键ID" align="center" prop="id" /> |
||||
|
<el-table-column label="接收用户ID" align="center" prop="userId" /> |
||||
|
<el-table-column label="通知标题" align="center" prop="title" /> |
||||
|
<el-table-column label="通知内容" align="center" prop="content" /> |
||||
|
<el-table-column label="通知类型" align="center" prop="type" /> |
||||
|
<el-table-column label="关联ID" align="center" prop="relatedId" /> |
||||
|
<el-table-column label="是否已读 0:未读 1:已读" align="center" prop="isRead" /> |
||||
|
<el-table-column label="提醒级别 1:低 2:中 3:高" align="center" prop="remindLevel" /> |
||||
|
<el-table-column label="阅读时间" align="center" prop="readTime" width="180"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span>{{ parseTime(scope.row.readTime, '{y}-{m}-{d}') }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-button |
||||
|
size="mini" |
||||
|
type="text" |
||||
|
icon="el-icon-edit" |
||||
|
@click="handleUpdate(scope.row)" |
||||
|
v-hasPermi="['vet:notification:edit']" |
||||
|
>修改</el-button> |
||||
|
<el-button |
||||
|
size="mini" |
||||
|
type="text" |
||||
|
icon="el-icon-delete" |
||||
|
@click="handleDelete(scope.row)" |
||||
|
v-hasPermi="['vet:notification:remove']" |
||||
|
>删除</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
|
||||
|
<pagination |
||||
|
v-show="total>0" |
||||
|
:total="total" |
||||
|
:page.sync="queryParams.pageNum" |
||||
|
:limit.sync="queryParams.pageSize" |
||||
|
@pagination="getList" |
||||
|
/> |
||||
|
|
||||
|
<!-- 添加或修改兽医通知对话框 --> |
||||
|
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> |
||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
||||
|
<el-form-item label="接收用户ID" prop="userId"> |
||||
|
<el-input v-model="form.userId" placeholder="请输入接收用户ID" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="通知标题" prop="title"> |
||||
|
<el-input v-model="form.title" placeholder="请输入通知标题" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="通知内容"> |
||||
|
<editor v-model="form.content" :min-height="192"/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="关联ID" prop="relatedId"> |
||||
|
<el-input v-model="form.relatedId" placeholder="请输入关联ID" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="是否已读 0:未读 1:已读" prop="isRead"> |
||||
|
<el-input v-model="form.isRead" placeholder="请输入是否已读 0:未读 1:已读" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="提醒级别 1:低 2:中 3:高" prop="remindLevel"> |
||||
|
<el-input v-model="form.remindLevel" placeholder="请输入提醒级别 1:低 2:中 3:高" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="阅读时间" prop="readTime"> |
||||
|
<el-date-picker clearable |
||||
|
v-model="form.readTime" |
||||
|
type="date" |
||||
|
value-format="yyyy-MM-dd" |
||||
|
placeholder="请选择阅读时间"> |
||||
|
</el-date-picker> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="primary" @click="submitForm">确 定</el-button> |
||||
|
<el-button @click="cancel">取 消</el-button> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { listNotification, getNotification, delNotification, addNotification, updateNotification } from "@/api/vet/notification" |
||||
|
|
||||
|
export default { |
||||
|
name: "Notification", |
||||
|
data() { |
||||
|
return { |
||||
|
// 遮罩层 |
||||
|
loading: true, |
||||
|
// 选中数组 |
||||
|
ids: [], |
||||
|
// 非单个禁用 |
||||
|
single: true, |
||||
|
// 非多个禁用 |
||||
|
multiple: true, |
||||
|
// 显示搜索条件 |
||||
|
showSearch: true, |
||||
|
// 总条数 |
||||
|
total: 0, |
||||
|
// 兽医通知表格数据 |
||||
|
notificationList: [], |
||||
|
// 弹出层标题 |
||||
|
title: "", |
||||
|
// 是否显示弹出层 |
||||
|
open: false, |
||||
|
// 查询参数 |
||||
|
queryParams: { |
||||
|
pageNum: 1, |
||||
|
pageSize: 10, |
||||
|
userId: null, |
||||
|
title: null, |
||||
|
content: null, |
||||
|
type: null, |
||||
|
relatedId: null, |
||||
|
isRead: null, |
||||
|
remindLevel: null, |
||||
|
readTime: null |
||||
|
}, |
||||
|
// 表单参数 |
||||
|
form: {}, |
||||
|
// 表单校验 |
||||
|
rules: { |
||||
|
userId: [ |
||||
|
{ required: true, message: "接收用户ID不能为空", trigger: "blur" } |
||||
|
], |
||||
|
title: [ |
||||
|
{ required: true, message: "通知标题不能为空", trigger: "blur" } |
||||
|
], |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
this.getList() |
||||
|
}, |
||||
|
methods: { |
||||
|
/** 查询兽医通知列表 */ |
||||
|
getList() { |
||||
|
this.loading = true |
||||
|
listNotification(this.queryParams).then(response => { |
||||
|
this.notificationList = response.rows |
||||
|
this.total = response.total |
||||
|
this.loading = false |
||||
|
}) |
||||
|
}, |
||||
|
// 取消按钮 |
||||
|
cancel() { |
||||
|
this.open = false |
||||
|
this.reset() |
||||
|
}, |
||||
|
// 表单重置 |
||||
|
reset() { |
||||
|
this.form = { |
||||
|
id: null, |
||||
|
userId: null, |
||||
|
title: null, |
||||
|
content: null, |
||||
|
type: null, |
||||
|
relatedId: null, |
||||
|
isRead: null, |
||||
|
remindLevel: null, |
||||
|
createTime: null, |
||||
|
readTime: null |
||||
|
} |
||||
|
this.resetForm("form") |
||||
|
}, |
||||
|
/** 搜索按钮操作 */ |
||||
|
handleQuery() { |
||||
|
this.queryParams.pageNum = 1 |
||||
|
this.getList() |
||||
|
}, |
||||
|
/** 重置按钮操作 */ |
||||
|
resetQuery() { |
||||
|
this.resetForm("queryForm") |
||||
|
this.handleQuery() |
||||
|
}, |
||||
|
// 多选框选中数据 |
||||
|
handleSelectionChange(selection) { |
||||
|
this.ids = selection.map(item => item.id) |
||||
|
this.single = selection.length!==1 |
||||
|
this.multiple = !selection.length |
||||
|
}, |
||||
|
/** 新增按钮操作 */ |
||||
|
handleAdd() { |
||||
|
this.reset() |
||||
|
this.open = true |
||||
|
this.title = "添加兽医通知" |
||||
|
}, |
||||
|
/** 修改按钮操作 */ |
||||
|
handleUpdate(row) { |
||||
|
this.reset() |
||||
|
const id = row.id || this.ids |
||||
|
getNotification(id).then(response => { |
||||
|
this.form = response.data |
||||
|
this.open = true |
||||
|
this.title = "修改兽医通知" |
||||
|
}) |
||||
|
}, |
||||
|
/** 提交按钮 */ |
||||
|
submitForm() { |
||||
|
this.$refs["form"].validate(valid => { |
||||
|
if (valid) { |
||||
|
if (this.form.id != null) { |
||||
|
updateNotification(this.form).then(response => { |
||||
|
this.$modal.msgSuccess("修改成功") |
||||
|
this.open = false |
||||
|
this.getList() |
||||
|
}) |
||||
|
} else { |
||||
|
addNotification(this.form).then(response => { |
||||
|
this.$modal.msgSuccess("新增成功") |
||||
|
this.open = false |
||||
|
this.getList() |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
/** 删除按钮操作 */ |
||||
|
handleDelete(row) { |
||||
|
const ids = row.id || this.ids |
||||
|
this.$modal.confirm('是否确认删除兽医通知编号为"' + ids + '"的数据项?').then(function() { |
||||
|
return delNotification(ids) |
||||
|
}).then(() => { |
||||
|
this.getList() |
||||
|
this.$modal.msgSuccess("删除成功") |
||||
|
}).catch(() => {}) |
||||
|
}, |
||||
|
/** 导出按钮操作 */ |
||||
|
handleExport() { |
||||
|
this.download('vet/notification/export', { |
||||
|
...this.queryParams |
||||
|
}, `notification_${new Date().getTime()}.xlsx`) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue