邮件API
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package com.mini.capi.biz.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* VIEW 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author gaoxq
|
||||
* @since 2025-11-16
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/biz/bizBaseNoticeView")
|
||||
public class BizBaseNoticeViewController {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.mini.capi.biz.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* VIEW
|
||||
* </p>
|
||||
*
|
||||
* @author gaoxq
|
||||
* @since 2025-11-16
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("biz_base_notice_view")
|
||||
public class BizBaseNoticeView implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
@TableField("notice_title")
|
||||
private String noticeTitle;
|
||||
|
||||
/**
|
||||
* 正文
|
||||
*/
|
||||
@TableField("notice_text")
|
||||
private String noticeText;
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
@TableField("expiration_time")
|
||||
private LocalDateTime expirationTime;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.mini.capi.biz.mapper;
|
||||
|
||||
import com.mini.capi.biz.domain.BizBaseNoticeView;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* VIEW Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author gaoxq
|
||||
* @since 2025-11-16
|
||||
*/
|
||||
public interface BizBaseNoticeViewMapper extends BaseMapper<BizBaseNoticeView> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.mini.capi.biz.service;
|
||||
|
||||
import com.mini.capi.biz.domain.BizBaseNoticeView;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* VIEW 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author gaoxq
|
||||
* @since 2025-11-16
|
||||
*/
|
||||
public interface BizBaseNoticeViewService extends IService<BizBaseNoticeView> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.mini.capi.biz.service.impl;
|
||||
|
||||
import com.mini.capi.biz.domain.BizBaseNoticeView;
|
||||
import com.mini.capi.biz.mapper.BizBaseNoticeViewMapper;
|
||||
import com.mini.capi.biz.service.BizBaseNoticeViewService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* VIEW 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author gaoxq
|
||||
* @since 2025-11-16
|
||||
*/
|
||||
@Service
|
||||
public class BizBaseNoticeViewServiceImpl extends ServiceImpl<BizBaseNoticeViewMapper, BizBaseNoticeView> implements BizBaseNoticeViewService {
|
||||
|
||||
}
|
||||
@@ -59,6 +59,9 @@ public class viewController {
|
||||
@Resource
|
||||
private BizTodoTaskViewService bizTodoTaskViewService;
|
||||
|
||||
@Resource
|
||||
private BizBaseNoticeViewService bizBaseNoticeViewService;
|
||||
|
||||
|
||||
@GetMapping("/login")
|
||||
public String showLoginPage() {
|
||||
@@ -82,10 +85,13 @@ public class viewController {
|
||||
taskViewQueryWrapper.notIn("ustatus", "CPT");
|
||||
List<BizTodoTaskView> todoViews = bizTodoTaskViewService.list(taskViewQueryWrapper);
|
||||
|
||||
List<BizBaseNoticeView> noticeViews = bizBaseNoticeViewService.list();
|
||||
|
||||
model.addAttribute("hosts", hosts);
|
||||
model.addAttribute("storages", storages);
|
||||
model.addAttribute("uname", user.getUname());
|
||||
model.addAttribute("todoViews", todoViews);
|
||||
model.addAttribute("noticeViews", noticeViews);
|
||||
model.addAttribute("times", vDate.getRunTimes(runInfo.getProcessInfo().getUptime()));
|
||||
return "index";
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class demo {
|
||||
.pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir") + "/src/main/resources/mapper"));
|
||||
})
|
||||
.strategyConfig(builder -> {
|
||||
builder.addInclude("biz_sub_task")
|
||||
builder.addInclude("biz_base_notice_view")
|
||||
.addTablePrefix("biz_,erp_")
|
||||
.entityBuilder()
|
||||
.enableLombok()
|
||||
|
||||
18
src/main/resources/mapper/BizBaseNoticeViewMapper.xml
Normal file
18
src/main/resources/mapper/BizBaseNoticeViewMapper.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?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.mini.capi.biz.mapper.BizBaseNoticeViewMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.mini.capi.biz.domain.BizBaseNoticeView">
|
||||
<result column="create_time" property="createTime" />
|
||||
<result column="notice_title" property="noticeTitle" />
|
||||
<result column="notice_text" property="noticeText" />
|
||||
<result column="expiration_time" property="expirationTime" />
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
create_time, notice_title, notice_text, expiration_time
|
||||
</sql>
|
||||
|
||||
</mapper>
|
||||
@@ -257,28 +257,46 @@
|
||||
</div>
|
||||
|
||||
<!-- 通知信息内容 (默认隐藏) -->
|
||||
<div id="notificationContent"
|
||||
class="bg-white/70 rounded-lg p-3 h-[calc(100%-50px)] overflow-y-auto scrollbar-thin hidden">
|
||||
<div class="space-y-4">
|
||||
<div class="p-3 border-b border-gray-100">
|
||||
<div id="notificationContent" class="bg-white/70 rounded-lg p-3 h-[calc(100%-50px)] overflow-y-auto scrollbar-thin hidden">
|
||||
<div class="space-y-4" th:each="notice : ${noticeViews}">
|
||||
<div class="p-3 border-b border-gray-100 cursor-pointer hover:bg-primary/30 transition-colors rounded-md"
|
||||
onclick="showNoticeDetail(this)"> <!-- 点击整个通知项触发弹窗 -->
|
||||
<div class="flex justify-between items-start">
|
||||
<h3 class="font-medium text-dark">数据库备份成功</h3>
|
||||
<span class="text-xs text-gray-500">今天 08:30</span>
|
||||
<h3 class="font-medium text-dark" th:text="${notice.getNoticeTitle}"></h3>
|
||||
<span class="text-xs text-gray-500" th:text="${notice.getCreateTime()}">今天 08:30</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mt-1">
|
||||
主数据库自动备份已完成,备份文件大小:2.4GB,存储路径:/backup/db/20251115/</p>
|
||||
</div>
|
||||
|
||||
<div class="p-3 border-b border-gray-100">
|
||||
<div class="flex justify-between items-start">
|
||||
<h3 class="font-medium text-dark">用户登录提醒</h3>
|
||||
<span class="text-xs text-gray-500">昨天 16:45</span>
|
||||
<!-- 省略显示的文本 -->
|
||||
<div class="text-sm text-gray-600 mt-1 line-clamp-2 notice-short-content">
|
||||
<span th:utext="${notice.getNoticeText()}"></span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mt-1">您的账号在新设备(Windows 10, Chrome
|
||||
120)登录,IP地址:113.25.XX.XX,如非本人操作,请及时修改密码。</p>
|
||||
|
||||
<!-- 存储完整内容的隐藏容器(避免DOM查找冲突) -->
|
||||
<div class="hidden notice-full-content" th:utext="${notice.getNoticeText()}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 全局居中弹窗容器 -->
|
||||
<div id="noticeDetailPopup" class="fixed inset-0 z-50 flex items-center justify-center hidden">
|
||||
<!-- 半透明遮罩 -->
|
||||
<div class="absolute inset-0 bg-black/50" onclick="hideNoticeDetail()"></div>
|
||||
<!-- 弹窗内容区 -->
|
||||
<div class="relative bg-white rounded-lg shadow-xl w-[1200px] max-h-[80vh] flex flex-col">
|
||||
<!-- 关闭按钮 -->
|
||||
<button class="absolute top-3 right-3 text-gray-500 hover:text-gray-700 z-10" onclick="hideNoticeDetail()">
|
||||
<i class="fa fa-times text-xl"></i>
|
||||
</button>
|
||||
<!-- 弹窗标题 - 居中+浅蓝色背景 -->
|
||||
<div class="bg-blue-50 border-b border-gray-200 px-6 py-4 text-center flex-shrink-0">
|
||||
<h3 class="text-lg font-medium text-dark" id="popupNoticeTitle"></h3>
|
||||
<p class="text-sm text-gray-500 mt-1" id="popupNoticeTime" style="text-align: end"></p>
|
||||
</div>
|
||||
<!-- 弹窗内容 - 确保滚动条可见 -->
|
||||
<div class="p-6 flex-grow overflow-y-auto scrollbar-thin" style="scrollbar-width: thin; scrollbar-color: #ccc #f5f5f5;" id="popupNoticeContent"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -691,6 +709,30 @@
|
||||
});
|
||||
});
|
||||
|
||||
// 显示通知完整内容(点击触发)
|
||||
function showNoticeDetail(noticeElement) {
|
||||
// 从点击的元素中获取信息(通过类名精准查找,避免冲突)
|
||||
const noticeTitle = noticeElement.querySelector('h3').textContent;
|
||||
const noticeTime = noticeElement.querySelector('.text-xs.text-gray-500').textContent;
|
||||
const fullContent = noticeElement.querySelector('.notice-full-content').innerHTML; // 从隐藏容器获取完整内容
|
||||
|
||||
// 填充弹窗内容
|
||||
document.getElementById('popupNoticeTitle').textContent = noticeTitle;
|
||||
document.getElementById('popupNoticeTime').textContent = noticeTime;
|
||||
document.getElementById('popupNoticeContent').innerHTML = fullContent;
|
||||
|
||||
// 显示弹窗
|
||||
document.getElementById('noticeDetailPopup').classList.remove('hidden');
|
||||
document.body.style.overflow = 'hidden'; // 禁止背景滚动
|
||||
}
|
||||
|
||||
// 隐藏通知完整内容
|
||||
function hideNoticeDetail() {
|
||||
const popup = document.getElementById('noticeDetailPopup');
|
||||
popup.classList.add('hidden');
|
||||
document.body.style.overflow = ''; // 恢复背景滚动
|
||||
}
|
||||
|
||||
// 确认退出(替换alert为弹窗)
|
||||
confirmLogout.addEventListener('click', () => {
|
||||
fetch('logout', {method: 'POST'})
|
||||
|
||||
Reference in New Issue
Block a user