初始化项目

This commit is contained in:
2026-03-25 22:34:17 +08:00
parent 39db00e022
commit c3e7288953
18 changed files with 214 additions and 93 deletions

View File

@@ -43,12 +43,27 @@ export interface TabItem {
unreadlist?: MyNoticeTodo[];
}
export interface MyFileList {
filePath: string;
fileName: string;
fileType?: number;
fileIcon?: string;
fileSize?: string;
}
export const tabListDataAll = (params?: MyNoticeTodo | any) =>
defHttp.get<TabItem[]>({ url: adminPath + '/biz/myNoticeTodo/tabListData', params});
export const myNoticeTodoList = (params?: MyNoticeTodo | any) =>
defHttp.get<MyNoticeTodo>({ url: adminPath + '/biz/myNoticeTodo/list', params });
export const myNoticeTodoFileList = (params?: MyNoticeTodo | any) =>
defHttp.get<MyFileList[]>({ url: adminPath + '/biz/myNoticeTodo/fileList', params });
export const myNoticeTodoListAll = (params?: MyNoticeTodo | any) =>
defHttp.get<MyNoticeTodo[]>({ url: adminPath + '/biz/myNoticeTodo/listAll', params });
export const myNoticeTodoListData = (params?: MyNoticeTodo | any) =>
defHttp.post<Page<MyNoticeTodo>>({ url: adminPath + '/biz/myNoticeTodo/listData', params });

View File

@@ -130,6 +130,7 @@
sorter: true,
width: 130,
align: 'center',
dictType: 'msg_type',
},
{
title: t('是否已读'),
@@ -138,6 +139,7 @@
sorter: true,
width: 130,
align: 'center',
dictType: 'read_flag',
},
{
title: t('是否关闭'),
@@ -146,6 +148,7 @@
sorter: true,
width: 130,
align: 'center',
dictType: 'click_close',
},
{
title: t('额外信息'),
@@ -186,6 +189,7 @@
sorter: true,
width: 130,
align: 'center',
dictType: 'notice_status',
},
];

View File

@@ -103,13 +103,13 @@ const tableProps: BasicTableProps = {
},
columns: tableColumns,
formConfig: searchForm,
rowKey: 'userCode',
rowKey: 'loginCode',
};
export default {
modalProps,
tableProps,
itemCode: 'userCode',
itemCode: 'loginCode',
itemName: 'userName',
isShowCode: true,
};

View File

@@ -7,7 +7,7 @@
v-for="item in tabs"
:key="item.key"
:class="['tab-item', { active: activeTab === item.key }]"
@click="activeTab = item.key"
@click="handleTabChange(item.key)"
>
{{ item.label }}
</button>
@@ -15,52 +15,56 @@
</div>
<div class="card-content">
<div ref="tableWrapRef" class="table-container">
<el-table :data="currentList" :height="tableHeight" :show-header="true" :border="false">
<el-table-column prop="title" label="标题" min-width="120">
<el-table :data="listData" :height="tableHeight" :show-header="true" :border="false">
<el-table-column prop="title" label="标题" min-width="120" show-overflow-tooltip="true" />
<el-table-column prop="datetime" label="到期时间" width="180" />
<el-table-column label="操作" width="90" align="center" fixed="right">
<template #default="{ row }">
<el-button class="notice-title-button" link type="primary" @click="openNoticeDialog(row)">
{{ row.title }}
<el-button class="notice-action-button" link type="primary" @click="openNoticeDialog(row)">
查看
</el-button>
</template>
</el-table-column>
<el-table-column prop="time" label="时间" width="180" />
<el-table-column prop="content" label="内容" min-width="200" show-overflow-tooltip="true" />
</el-table>
</div>
</div>
<el-dialog v-model="dialogVisible" class="notice-info-dialog" title="通知详情" width="60%" destroy-on-close>
<el-dialog v-model="dialogVisible" class="notice-info-dialog" title="通知详情" width="50%" destroy-on-close>
<template v-if="selectedNotice">
<div class="notice-dialog">
<div class="notice-dialog__header">
<div class="notice-dialog__title">{{ selectedNotice.title }}</div>
<div class="notice-dialog__header-divider"></div>
<div class="notice-dialog__time">{{ selectedNotice.time }}</div>
<div class="notice-dialog__time">
<div class="notice-dialog__time-left">
<span>发布时间{{ selectedNotice.createTime }}</span>
<span>发布人{{ selectedNotice.createUser }}</span>
</div>
<div class="notice-dialog__time-right">截至时间{{ selectedNotice.datetime }}</div>
</div>
</div>
<el-divider class="notice-dialog__divider" />
<div class="notice-dialog__content-panel">
<div class="notice-dialog__content" v-html="selectedNotice.content"></div>
<div class="notice-dialog__content" v-html="selectedNotice.description"></div>
</div>
<div v-if="selectedNotice.attachments?.length" class="notice-dialog__attachments-panel">
<div class="notice-dialog__attachments-title">附件区域</div>
<div v-if="fileData?.length" class="notice-dialog__attachments-panel">
<div class="notice-dialog__attachments-title">附件区域({{ fileData?.length }})</div>
<div class="notice-dialog__attachments-list">
<div
v-for="attachment in selectedNotice.attachments"
:key="attachment"
class="notice-dialog__attachment-item"
>
<div v-for="item in fileData" :key="item" class="notice-dialog__attachment-item">
<div class="notice-dialog__attachment-meta">
<el-icon class="notice-dialog__attachment-icon"><Document /></el-icon>
<span class="notice-dialog__attachment-name">{{ attachment }}</span>
<Icon :icon="item.fileIcon" class="icon-img" size="24" />
<el-tooltip :content="item.fileName" placement="top" :show-after="200">
<span class="notice-dialog__attachment-name">{{ item.fileName }}</span>
</el-tooltip>
</div>
<div class="notice-dialog__attachment-actions">
<span class="notice-dialog__attachment-size">{{ getAttachmentSize(attachment) }}</span>
<span class="notice-dialog__attachment-size">{{ item.fileSize }}</span>
<el-button
class="notice-dialog__attachment-download"
type="primary"
link
:icon="Download"
@click.stop="handleAttachmentDownload(attachment)"
@click.stop="handleDownload(item)"
>下载</el-button
>
</div>
@@ -75,15 +79,17 @@
<script setup lang="ts">
import { ElMessage } from 'element-plus';
import { Icon } from '@jeesite/core/components/Icon';
import { Document, Download } from '@element-plus/icons-vue';
import { useGlobSetting } from '@jeesite/core/hooks/setting';
import { downloadByUrl } from '@jeesite/core/utils/file/download';
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
interface NoticeItem {
title: string;
time: string;
content: string;
attachments?: string[];
}
import {
MyFileList,
myNoticeTodoFileList,
MyNoticeTodo,
myNoticeTodoListAll,
} from '@jeesite/biz/api/biz/myNoticeTodo';
const tabs = [
{ key: '0', label: '未读' },
@@ -91,74 +97,28 @@
];
const activeTab = ref('0');
const fileData = ref<MyFileList[]>([]);
const listData = ref<MyNoticeTodo[]>([]);
const noticeData: Record<string, NoticeItem[]> = {
0: [
{
title: '系统升级通知',
time: '2025-03-25 10:00',
content: '<p>系统将于今晚进行升级维护,请提前保存工作内容。</p><p><strong>维护时间:</strong>23:00 - 02:00</p>',
attachments: [
'升级说明.pdf',
'影响范围清单.xlsx',
'系统切换流程.docx',
'升级回退预案.pdf',
'服务影响通知单.xls',
'值班安排表.doc',
'数据库检查项.txt',
],
},
{
title: '安全检查提醒',
time: '2025-03-25 09:30',
content:
'<p>请及时完成本周安全检查任务,确保系统运行稳定。</p><ul><li>检查设备运行状态</li><li>确认日志采集是否正常</li></ul>',
attachments: ['安全检查模板.docx', '巡检项清单.pdf', '整改说明.docx', '告警记录.xlsx'],
},
{
title: '备份任务完成',
time: '2025-03-25 08:15',
content: '<p>数据库备份任务已完成,备份文件已存储至指定位置。</p>',
attachments: [],
},
],
1: [
{
title: '巡检报告提交',
time: '2025-03-24 16:20',
content: '<p>昨日巡检报告已提交并审核通过。</p><p>请相关负责人及时查看结果。</p>',
attachments: ['巡检报告-0324.pdf'],
},
{
title: '权限变更通知',
time: '2025-03-24 14:10',
content: '<p>用户权限调整已生效,请相关人员知悉。</p>',
attachments: [],
},
],
};
const currentList = computed(() => noticeData[activeTab.value] || []);
const tableWrapRef = ref<HTMLElement>();
const tableHeight = ref(0);
const dialogVisible = ref(false);
const selectedNotice = ref<NoticeItem | null>(null);
const selectedNotice = ref<MyNoticeTodo | null>(null);
let resizeObserver: ResizeObserver | null = null;
function openNoticeDialog(notice: NoticeItem) {
function openNoticeDialog(notice: MyNoticeTodo) {
getFileList(notice.id);
selectedNotice.value = notice;
dialogVisible.value = true;
}
function handleAttachmentDownload(attachment: string) {
ElMessage.info(`待接入下载地址:${attachment}`);
}
function getAttachmentSize(attachment: string) {
const seed = attachment.split('').reduce((total, char) => total + char.charCodeAt(0), 0);
return `${((seed % 9000) / 100 + 0.8).toFixed(2)} MB`;
async function handleDownload(item: MyFileList) {
const { ctxAdminPath } = useGlobSetting();
await downloadByUrl({
url: ctxAdminPath + '/biz/myNoticeTodo/downloadFile',
params: item,
});
}
function updateTableHeight() {
@@ -169,7 +129,42 @@
});
}
function handleTabChange(tabKey: string) {
if (activeTab.value === tabKey) return;
activeTab.value = tabKey;
getDataList();
}
const getDataList = async () => {
try {
const reqParams = {
type: '1',
clickClose: '0',
readFlag: activeTab.value,
};
const result = await myNoticeTodoListAll(reqParams);
listData.value = result || [];
} catch (error) {
listData.value = [];
}
};
const getFileList = async (bizId: string) => {
try {
const reqParams = {
id: bizId,
};
const result = await myNoticeTodoFileList(reqParams);
fileData.value = result || [];
console.log(fileData.value);
} catch (error) {
fileData.value = [];
}
};
onMounted(() => {
getDataList();
updateTableHeight();
if (tableWrapRef.value) {
resizeObserver = new ResizeObserver(() => {
@@ -296,12 +291,16 @@
line-height: 20px;
}
.notice-title-button {
.notice-action-button {
padding: 0;
font-weight: 500;
text-align: left;
white-space: normal;
word-break: break-all;
}
.notice-description {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: rgb(71 85 105);
}
}
}
@@ -352,8 +351,23 @@
}
&__time {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
font-size: 13px;
color: rgb(100 116 139);
}
&__time-left {
display: flex;
align-items: center;
gap: 16px;
min-width: 0;
}
&__time-right {
flex-shrink: 0;
text-align: right;
}