财务门户设计
This commit is contained in:
@@ -37,57 +37,54 @@
|
||||
</span>
|
||||
<span class="trigger-time">{{ item.triggerTime }}</span>
|
||||
<span class="alert-type">{{ item.alertType }}</span>
|
||||
<span
|
||||
class="alert-title"
|
||||
@mouseenter="showFullContent(item.alertTitle || '', $event)"
|
||||
@mouseleave="hideFullContent"
|
||||
|
||||
<Tooltip
|
||||
:title="item.alertTitle || '--'"
|
||||
placement="top"
|
||||
trigger="hover"
|
||||
:mouseEnterDelay="0.1"
|
||||
class="alert-title-tooltip"
|
||||
>
|
||||
<a-button type="link" size="small" @click="openModal(true, item)">
|
||||
<span class="title-text">{{ item.alertTitle || '--' }}</span>
|
||||
</a-button>
|
||||
</span>
|
||||
<span class="alert-title"
|
||||
@mouseenter="showFullContent(item.alertContent || '', $event)"
|
||||
@mouseleave="hideFullContent"
|
||||
>
|
||||
{{ item.alertContent || '--' }}
|
||||
</span>
|
||||
<span class="alert-title" ref="titleRefs">
|
||||
<a-button type="link" size="small" @click="openModal(true, item)">
|
||||
<span class="title-text">{{ item.alertTitle || '--' }}</span>
|
||||
</a-button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip
|
||||
:title="item.alertContent || '--'"
|
||||
placement="top"
|
||||
trigger="hover"
|
||||
:mouseEnterDelay="0.1"
|
||||
class="alert-content-tooltip"
|
||||
>
|
||||
<span class="alert-title alert-content">
|
||||
{{ item.alertContent || '--' }}
|
||||
</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<!-- 新增:预警标题悬浮提示框 -->
|
||||
<div
|
||||
v-if="showContentTooltip"
|
||||
class="custom-tooltip"
|
||||
:style="{
|
||||
top: `${tooltipTop}px`,
|
||||
left: `${tooltipLeft}px`,
|
||||
zIndex: 9999
|
||||
}"
|
||||
>
|
||||
<pre class="tooltip-content">{{ fullContent }}</pre>
|
||||
<div class="tooltip-arrow"></div>
|
||||
</div>
|
||||
|
||||
<Modal @register="register" @modalClose="fetchAppList(currentStatus)" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { Card, Button } from 'ant-design-vue';
|
||||
import { ref, onMounted, nextTick } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useModal } from '@jeesite/core/components/Modal';
|
||||
import { Card, Tooltip, Button } from 'ant-design-vue';
|
||||
import { bizWarningAlertListAll, BizWarningAlert } from '@jeesite/biz/api/biz/warningAlert';
|
||||
import Modal from './info/WarningInfo.vue';
|
||||
|
||||
const [register, { openModal }] = useModal();
|
||||
const alertList = ref<BizWarningAlert[]>([]);
|
||||
const loading = ref<boolean>(false); // 新增加载状态
|
||||
const loading = ref<boolean>(false);
|
||||
const router = useRouter();
|
||||
const titleRefs = ref<HTMLElement[]>([]);
|
||||
|
||||
// 状态选项配置
|
||||
const statusOptions = ref([
|
||||
{ value: '0', label: '未处理' },
|
||||
{ value: '1', label: '处理中' },
|
||||
@@ -95,65 +92,33 @@ const statusOptions = ref([
|
||||
{ value: '3', label: '已忽略' },
|
||||
{ value: '4', label: '已关闭' },
|
||||
]);
|
||||
const currentStatus = ref<string>('0'); // 默认选中未处理
|
||||
const currentStatus = ref<string>('0');
|
||||
|
||||
// 新增:预警标题悬浮提示相关
|
||||
const showContentTooltip = ref(false);
|
||||
const fullContent = ref('');
|
||||
const tooltipTop = ref(0);
|
||||
const tooltipLeft = ref(0);
|
||||
|
||||
// 新增:显示完整标题
|
||||
const showFullContent = (content: string, event: MouseEvent) => {
|
||||
// 内容为空或无截断时不显示提示
|
||||
if (!content) return;
|
||||
|
||||
const target = event.target as HTMLElement;
|
||||
// 判断内容是否被截断(容器宽度 < 内容宽度)
|
||||
if (target.scrollWidth <= target.clientWidth) return;
|
||||
|
||||
// 直接赋值原始内容,不做任何格式化处理
|
||||
fullContent.value = content;
|
||||
// 定位提示框(鼠标位置偏移,避免遮挡鼠标)
|
||||
tooltipTop.value = event.clientY + 10;
|
||||
tooltipLeft.value = event.clientX + 10;
|
||||
showContentTooltip.value = true;
|
||||
};
|
||||
|
||||
// 新增:隐藏提示框
|
||||
const hideFullContent = () => {
|
||||
showContentTooltip.value = false;
|
||||
fullContent.value = '';
|
||||
};
|
||||
|
||||
// 处理状态切换(新增方法)
|
||||
const handleStatusChange = (status: string) => {
|
||||
if (currentStatus.value === status) return; // 避免重复请求
|
||||
if (currentStatus.value === status) return;
|
||||
currentStatus.value = status;
|
||||
fetchAppList(status); // 切换状态时传递参数
|
||||
fetchAppList(status);
|
||||
};
|
||||
|
||||
// 获取预警列表数据
|
||||
const fetchAppList = async (status: string) => {
|
||||
try {
|
||||
loading.value = true; // 开始加载
|
||||
const params = { alertStatus: status }; // 传递状态参数
|
||||
loading.value = true;
|
||||
const params = { alertStatus: status };
|
||||
const result = await bizWarningAlertListAll(params);
|
||||
alertList.value = result || [];
|
||||
await nextTick();
|
||||
} catch (error) {
|
||||
console.error('获取预警列表失败:', error);
|
||||
alertList.value = [];
|
||||
} finally {
|
||||
loading.value = false; // 结束加载
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 跳转到更多页面(优化:携带当前状态参数)
|
||||
const goToMorePage = () => {
|
||||
router.push('/biz/warningAlert/list');
|
||||
};
|
||||
|
||||
// 转换预警级别文本
|
||||
const getLevelText = (level: number | undefined) => {
|
||||
if (!level) return '未知';
|
||||
const levelMap = {
|
||||
@@ -165,30 +130,26 @@ const getLevelText = (level: number | undefined) => {
|
||||
return levelMap[level as keyof typeof levelMap] || '未知';
|
||||
};
|
||||
|
||||
// 初始化加载默认状态数据
|
||||
onMounted(() => {
|
||||
fetchAppList(currentStatus.value); // 初始化时传递默认状态(0)
|
||||
fetchAppList(currentStatus.value);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* extra插槽容器:状态标签 + 更多按钮 横向排列 */
|
||||
.status-filter-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
/* 状态筛选栏(非按钮样式) */
|
||||
.status-filter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px; /* 标签间距 */
|
||||
gap: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 状态项样式(纯文本标签) */
|
||||
.status-item {
|
||||
cursor: pointer;
|
||||
color: #666;
|
||||
@@ -198,13 +159,11 @@ onMounted(() => {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* 选中状态样式(下划线 + 高亮色) */
|
||||
.status-item.active {
|
||||
color: #1890ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 选中状态下划线 */
|
||||
.status-item.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
@@ -216,56 +175,50 @@ onMounted(() => {
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
/* 悬浮效果 */
|
||||
.status-item:not(.active):hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
|
||||
/* 列表外层容器:移除边框 + 滚动核心样式 + 极致紧凑 */
|
||||
.alert-list-container {
|
||||
width: 100%;
|
||||
height: 32vh; /* 限制最大高度,超出滚动 */
|
||||
overflow-y: auto; /* 垂直滚动 */
|
||||
overflow-x: hidden; /* 隐藏横向滚动 */
|
||||
padding: 0; /* 移除内边距 */
|
||||
margin: 0; /* 移除外边距 */
|
||||
height: 32vh;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* 空数据/加载提示 */
|
||||
.empty-tip {
|
||||
padding: 20px 0; /* 缩减空状态内边距,更紧凑 */
|
||||
padding: 20px 0;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 预警列表 */
|
||||
.alert-list {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 单个预警项:flex布局 + 紧凑排列(级别→时间→类型→标题) */
|
||||
.alert-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
font-size: 14px;
|
||||
gap: 10px; /* 统一控制元素间基础间距 */
|
||||
gap: 10px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 最后一项去掉底部边框 */
|
||||
.alert-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* 鼠标悬浮高亮 */
|
||||
.alert-item:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
/* 预警级别标签(固定宽度,不压缩) */
|
||||
.level-tag {
|
||||
display: inline-block;
|
||||
padding: 1px 6px;
|
||||
@@ -274,51 +227,55 @@ onMounted(() => {
|
||||
color: #fff;
|
||||
min-width: 40px;
|
||||
text-align: center;
|
||||
flex-shrink: 0; /* 固定宽度,不被压缩 */
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 级别颜色 */
|
||||
.level-1 { background-color: #f5222d; } /* 紧急 */
|
||||
.level-2 { background-color: #fa8c16; } /* 高 */
|
||||
.level-3 { background-color: #faad14; } /* 中 */
|
||||
.level-4 { background-color: #1890ff; } /* 低 */
|
||||
.level-undefined { background-color: #8c8c8c; } /* 未知 */
|
||||
.level-1 { background-color: #f5222d; }
|
||||
.level-2 { background-color: #fa8c16; }
|
||||
.level-3 { background-color: #faad14; }
|
||||
.level-4 { background-color: #1890ff; }
|
||||
.level-undefined { background-color: #8c8c8c; }
|
||||
|
||||
/* 预警触发时间(固定宽度,不压缩) */
|
||||
.trigger-time {
|
||||
width: 120px;
|
||||
color: #999;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0; /* 固定宽度,不被压缩 */
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* 预警类型(固定宽度,不压缩) */
|
||||
.alert-type {
|
||||
width: 60px;
|
||||
color: #666;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0; /* 固定宽度,不被压缩 */
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 预警标题(仅修改这部分样式) */
|
||||
.alert-title {
|
||||
width: 100px; /* 固定宽度,可根据需求调整(比如200px/400px) */
|
||||
flex-shrink: 0; /* 关键:禁止宽度被压缩,保证固定宽度生效 */
|
||||
width: 100px;
|
||||
flex-shrink: 0;
|
||||
color: #666;
|
||||
white-space: nowrap; /* 强制不换行 */
|
||||
overflow: hidden; /* 隐藏超出宽度的内容 */
|
||||
text-overflow: ellipsis; /* 超出显示省略号 */
|
||||
margin-left: 4px; /* 保留与类型的微小间距 */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-left: 4px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.alert-content {
|
||||
width: 200px;
|
||||
flex-grow: 1;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
/* 新增:标题文本样式 - 确保省略号生效 */
|
||||
.title-text {
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
@@ -326,71 +283,38 @@ onMounted(() => {
|
||||
text-overflow: ellipsis;
|
||||
display: inline-block;
|
||||
padding: 0 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 新增:自定义提示框样式 */
|
||||
.custom-tooltip {
|
||||
position: fixed;
|
||||
background: #1f2937;
|
||||
color: #ffffff;
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
max-width: 500px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
z-index: 9999;
|
||||
animation: fadeIn 0.2s ease-in-out;
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tooltip-content {
|
||||
font-family: "Consolas", "Monaco", "Courier New", monospace;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
color: #e5e7eb;
|
||||
margin: 0;
|
||||
:deep(.alert-title .ant-btn-link) {
|
||||
padding: 0;
|
||||
height: auto;
|
||||
line-height: 1;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.custom-tooltip::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
:deep(.ant-tooltip) {
|
||||
z-index: 1070 !important;
|
||||
}
|
||||
|
||||
.custom-tooltip::-webkit-scrollbar-track {
|
||||
background: #2d3748;
|
||||
border-radius: 2px;
|
||||
:deep(.ant-tooltip-inner) {
|
||||
max-width: 500px !important;
|
||||
padding: 12px 16px !important;
|
||||
font-size: 14px !important;
|
||||
line-height: 1.6 !important;
|
||||
white-space: pre-wrap !important;
|
||||
word-wrap: break-word !important;
|
||||
background: #1f2937 !important;
|
||||
color: #fff !important;
|
||||
border-radius: 8px !important;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
|
||||
}
|
||||
|
||||
.custom-tooltip::-webkit-scrollbar-thumb {
|
||||
background: #4a5568;
|
||||
border-radius: 2px;
|
||||
:deep(.ant-tooltip-arrow-content) {
|
||||
background: #1f2937 !important;
|
||||
}
|
||||
|
||||
.tooltip-arrow {
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 8px solid transparent;
|
||||
border-right: 8px solid transparent;
|
||||
border-bottom: 8px solid #1f2937;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 滚动条样式优化 */
|
||||
.alert-list-container::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
@@ -405,7 +329,6 @@ onMounted(() => {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 小屏幕适配 */
|
||||
@media (max-width: 768px) {
|
||||
.status-filter-container {
|
||||
gap: 8px;
|
||||
@@ -435,5 +358,11 @@ onMounted(() => {
|
||||
.alert-list-container {
|
||||
max-height: 200px;
|
||||
}
|
||||
.alert-title {
|
||||
width: 80px;
|
||||
}
|
||||
.alert-content {
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -11,6 +11,9 @@
|
||||
<TabPane key="3" tab="文件管理">
|
||||
<MyfileInfo />
|
||||
</TabPane>
|
||||
<TabPane key="4" tab="便签管理">
|
||||
<NoteTodo />
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
</template>
|
||||
@@ -18,6 +21,7 @@
|
||||
<script lang="ts" setup name="AboutPage">
|
||||
import { h, ref, onMounted } from 'vue';
|
||||
import { Tag, Tabs, TabPane } from 'ant-design-vue';
|
||||
import NoteTodo from './NoteTodo.vue';
|
||||
import MySchedule from './MySchedule.vue';
|
||||
import Calendar from './calendar/list.vue';
|
||||
import ItemsInfo from './listItem/list.vue';
|
||||
|
||||
Reference in New Issue
Block a user