邮件API

This commit is contained in:
2025-11-16 20:46:32 +08:00
parent 3b3d6dea66
commit 74930dab46
9 changed files with 200 additions and 16 deletions

View File

@@ -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 {
}

View File

@@ -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;
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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 {
}

View File

@@ -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";
}

View File

@@ -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()

View 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>

View File

@@ -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'})