| | |
| | | <div class="search_form"> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">新增公告</el-button> |
| | | <el-button type="danger" plain @click="handleDelete" :disabled="!selectedIds.length">删除</el-button> |
| | | <el-button type="info" @click="openNoticeTypeDialog">公告类型配置</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 通知公告板 --> |
| | | <div class="notice-board"> |
| | | <!-- 放假通知区域 --> |
| | | <div class="notice-section" v-if="holidayNoticeCount > 0"> |
| | | <div class="section-header"> |
| | | <h3>📅 放假通知</h3> |
| | | <span class="section-count">{{ holidayNoticeCount }}条</span> |
| | | </div> |
| | | <div class="notice-cards"> |
| | | <div |
| | | v-for="notice in holidayNotices" |
| | | :key="notice.id" |
| | | class="notice-card holiday-card" |
| | | :class="{ 'urgent': notice.priority === '3' }" |
| | | > |
| | | <div class="card-header"> |
| | | <div class="card-title"> |
| | | <el-icon class="holiday-icon"> |
| | | <Calendar/> |
| | | </el-icon> |
| | | {{ notice.title }} |
| | | </div> |
| | | <div class="card-actions"> |
| | | <el-button link type="primary" @click="handleEdit(notice)" :disabled="isNoticeExpired(notice)">编辑</el-button> |
| | | <el-button link type="danger" @click="handleDelete(notice.id)">删除</el-button> |
| | | <el-tabs v-model="activeNoticeTypeTab" @tab-change="handleNoticeTypeTabChange"> |
| | | <el-tab-pane |
| | | v-for="noticeType in noticeTypeList" |
| | | :key="noticeType.id" |
| | | :label="noticeType.noticeType" |
| | | :name="String(noticeType.id)" |
| | | > |
| | | <template #label> |
| | | <span>{{ noticeType.noticeType }} |
| | | <span class="tab-count" v-if="getNoticeCountByType(noticeType.id) > 0"> |
| | | ({{ getNoticeCountByType(noticeType.id) }}) |
| | | </span> |
| | | </span> |
| | | </template> |
| | | |
| | | <div class="notice-section"> |
| | | <div class="notice-cards"> |
| | | <div |
| | | v-for="notice in getNoticesByType(noticeType.id)" |
| | | :key="notice.id" |
| | | class="notice-card" |
| | | :class="{ 'urgent': notice.priority === '3' }" |
| | | > |
| | | <div class="card-header"> |
| | | <div class="card-title"> |
| | | <el-icon class="notice-icon"> |
| | | <Calendar/> |
| | | </el-icon> |
| | | {{ notice.title }} |
| | | </div> |
| | | <div class="card-actions"> |
| | | <el-button link type="primary" @click="handleEdit(notice)" :disabled="isNoticeExpired(notice)" v-if="notice.status !== 1">编辑</el-button> |
| | | <el-button link type="success" @click="handlePublish(notice)" v-if="notice.status === 0">发布</el-button> |
| | | <el-button link type="danger" @click="handleDelete(notice.id)" v-if="notice.status !== 1">删除</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="card-content"> |
| | | <p>{{ notice.content }}</p> |
| | | </div> |
| | | <div class="card-footer"> |
| | | <div class="card-meta"> |
| | | <span class="priority" :class="'priority-' + notice.priority"> |
| | | {{ getPriorityText(notice.priority) }} |
| | | </span> |
| | | <span class="status" :class="'status-' + getNoticeStatus(notice)"> |
| | | {{ getStatusText(getNoticeStatus(notice)) }} |
| | | </span> |
| | | </div> |
| | | <div class="card-info"> |
| | | <span class="creator">{{ notice.createUserName }}</span> |
| | | <span class="expiration" v-if="notice.expirationDate">截止日期:{{ notice.expirationDate }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="card-remark" v-if="notice.remark"> |
| | | <el-icon> |
| | | <InfoFilled/> |
| | | </el-icon> |
| | | <span>{{ notice.remark }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="card-content"> |
| | | <p>{{ notice.content }}</p> |
| | | </div> |
| | | <div class="card-footer"> |
| | | <div class="card-meta"> |
| | | <span class="priority" :class="'priority-' + notice.priority"> |
| | | {{ getPriorityText(notice.priority) }} |
| | | </span> |
| | | <span class="status" :class="'status-' + getNoticeStatus(notice)"> |
| | | {{ getStatusText(getNoticeStatus(notice)) }} |
| | | </span> |
| | | </div> |
| | | <div class="card-info"> |
| | | <span class="creator">{{ notice.createUserName }}</span> |
| | | <span class="expiration" v-if="notice.expirationDate">截止日期:{{ notice.expirationDate }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="card-remark" v-if="notice.remark"> |
| | | <el-icon> |
| | | <InfoFilled/> |
| | | </el-icon> |
| | | <span>{{ notice.remark }}</span> |
| | | |
| | | <pagination |
| | | v-if="getNoticePageByType(noticeType.id).total > 0" |
| | | :total="getNoticePageByType(noticeType.id).total" |
| | | :page="getNoticePageByType(noticeType.id).current" |
| | | :limit="getNoticePageByType(noticeType.id).size" |
| | | @pagination="(val) => handleNoticeCurrentChange(noticeType.id, val)" |
| | | /> |
| | | |
| | | <!-- 空状态 --> |
| | | <div class="empty-state" v-if="getNoticesByType(noticeType.id).length === 0"> |
| | | <el-empty description="暂无通知公告"/> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <pagination |
| | | v-if="holidayNoticePage.total > 0" |
| | | :total="holidayNoticePage.total" |
| | | :page="holidayNoticePage.current" |
| | | :limit="holidayNoticePage.size" |
| | | @pagination="handleHolidayNoticeCurrentChange" |
| | | /> |
| | | |
| | | <!-- 设备维修通知区域 --> |
| | | <div class="notice-section" v-if="maintenanceNoticeCount > 0"> |
| | | <div class="section-header"> |
| | | <h3>🔧 设备维修通知</h3> |
| | | <span class="section-count">{{ maintenanceNoticeCount }}条</span> |
| | | </div> |
| | | <div class="notice-cards"> |
| | | <div |
| | | v-for="notice in maintenanceNotices" |
| | | :key="notice.id" |
| | | class="notice-card maintenance-card" |
| | | :class="{ 'urgent': notice.priority === '3' }" |
| | | > |
| | | <div class="card-header"> |
| | | <div class="card-title"> |
| | | <el-icon class="maintenance-icon"> |
| | | <Tools/> |
| | | </el-icon> |
| | | {{ notice.title }} |
| | | </div> |
| | | <div class="card-actions"> |
| | | <el-button link type="primary" @click="handleEdit(notice)" :disabled="isNoticeExpired(notice)">编辑</el-button> |
| | | <el-button link type="danger" @click="handleDelete(notice.id)">删除</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="card-content"> |
| | | <p>{{ notice.content }}</p> |
| | | </div> |
| | | <div class="card-footer"> |
| | | <div class="card-meta"> |
| | | <span class="priority" :class="'priority-' + notice.priority"> |
| | | {{ getPriorityText(notice.priority) }} |
| | | </span> |
| | | <span class="status" :class="'status-' + getNoticeStatus(notice)"> |
| | | {{ getStatusText(getNoticeStatus(notice)) }} |
| | | </span> |
| | | </div> |
| | | <div class="card-info"> |
| | | <span class="creator">{{ notice.createUserName }}</span> |
| | | <span class="expiration" v-if="notice.expirationDate">截止日期:{{ notice.expirationDate }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="card-remark" v-if="notice.remark"> |
| | | <el-icon> |
| | | <InfoFilled/> |
| | | </el-icon> |
| | | <span>{{ notice.remark }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <pagination |
| | | v-if="maintenanceNoticePage.total > 0" |
| | | :total="maintenanceNoticePage.total" |
| | | :page="maintenanceNoticePage.current" |
| | | :limit="maintenanceNoticePage.size" |
| | | @pagination="handleMaintenanceNoticeCurrentChange" |
| | | /> |
| | | |
| | | <!-- 空状态 --> |
| | | <div class="empty-state" v-if="holidayNotices.length === 0 && maintenanceNotices.length === 0"> |
| | | <el-empty description="暂无通知公告"/> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | |
| | | <!-- 新增/编辑对话框 --> |
| | |
| | | <el-col :span="12"> |
| | | <el-form-item label="公告类型" prop="type"> |
| | | <el-select v-model="form.type" placeholder="请选择公告类型" style="width: 100%"> |
| | | <el-option label="放假通知" :value="1"/> |
| | | <el-option label="设备维修通知" :value="2"/> |
| | | <el-option |
| | | v-for="item in noticeTypeList" |
| | | :key="item.id" |
| | | :label="item.noticeType" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 公告类型配置弹框 --> |
| | | <el-dialog |
| | | v-model="noticeTypeDialogVisible" |
| | | title="公告类型配置" |
| | | width="800px" |
| | | @close="handleNoticeTypeDialogClose" |
| | | > |
| | | <div class="notice-type-container"> |
| | | <div class="notice-type-header"> |
| | | <el-button type="primary" @click="handleAddNoticeType">新增类型</el-button> |
| | | </div> |
| | | <el-table :data="noticeTypeList" border style="width: 100%"> |
| | | <el-table-column prop="id" label="ID" width="80" align="center"/> |
| | | <el-table-column prop="noticeType" label="公告类型" align="center"> |
| | | <template #default="scope"> |
| | | <el-input |
| | | v-if="scope.row.editing" |
| | | v-model="scope.row.noticeType" |
| | | placeholder="请输入公告类型" |
| | | /> |
| | | <span v-else>{{ scope.row.noticeType }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="200" align="center"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | v-if="scope.row.editing" |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="handleSaveNoticeType(scope.row)" |
| | | > |
| | | 保存 |
| | | </el-button> |
| | | <el-button |
| | | v-if="scope.row.editing" |
| | | link |
| | | type="info" |
| | | size="small" |
| | | @click="handleCancelEdit(scope.row)" |
| | | > |
| | | 取消 |
| | | </el-button> |
| | | <el-button |
| | | v-if="!scope.row.editing" |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="handleEditNoticeType(scope.row)" |
| | | > |
| | | 编辑 |
| | | </el-button> |
| | | <el-button |
| | | v-if="!scope.row.editing" |
| | | link |
| | | type="danger" |
| | | size="small" |
| | | @click="handleDeleteNoticeType(scope.row)" |
| | | > |
| | | 删除 |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {Search, Calendar, Tools, InfoFilled} from "@element-plus/icons-vue"; |
| | | import {Calendar, InfoFilled} from "@element-plus/icons-vue"; |
| | | import {onMounted, ref, reactive, toRefs, computed} from "vue"; |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import {useRoute} from "vue-router"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { |
| | | addNotice, |
| | | delNotice, |
| | | getCount, |
| | | listNotice, |
| | | updateNotice |
| | | updateNotice, |
| | | listNoticeType, |
| | | addNoticeType, |
| | | delNoticeType |
| | | } from "../../../api/collaborativeApproval/noticeManagement.js"; |
| | | import pagination from "../../../components/PIMTable/Pagination.vue"; |
| | | |
| | | const userStore = useUserStore(); |
| | | const route = useRoute(); |
| | | |
| | | // 响应式数据 |
| | | const data = reactive({ |
| | |
| | | // 页面状态 |
| | | const dialogVisible = ref(false); |
| | | const dialogTitle = ref(""); |
| | | const selectedIds = ref([]); |
| | | const formRef = ref(); |
| | | |
| | | // 公告类型配置相关 |
| | | const noticeTypeDialogVisible = ref(false); |
| | | const noticeTypeList = ref([]); |
| | | const activeNoticeTypeTab = ref(''); |
| | | |
| | | // 通知数据 - 使用 Map 存储,key 为类型 id |
| | | const noticesMap = ref({}); |
| | | const noticePagesMap = ref({}); |
| | | |
| | | |
| | | // 计算属性 |
| | |
| | | }); |
| | | }; |
| | | |
| | | const handlePublish = (notice) => { |
| | | ElMessageBox.confirm( |
| | | "确认发布这条公告吗?", |
| | | "提示", |
| | | { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "info" |
| | | } |
| | | ).then(() => { |
| | | updateNotice({ |
| | | ...notice, |
| | | status: 1 |
| | | }).then(res => { |
| | | if (res.code === 200) { |
| | | ElMessage.success("发布成功"); |
| | | resetTable() |
| | | } |
| | | }) |
| | | }); |
| | | }; |
| | | |
| | | const submitForm = () => { |
| | | formRef.value.validate((valid) => { |
| | | if (valid) { |
| | |
| | | }); |
| | | }; |
| | | |
| | | const holidayNoticeCount = ref() |
| | | const maintenanceNoticeCount = ref() |
| | | const fetchCount = () => { |
| | | getCount().then(res => { |
| | | holidayNoticeCount.value = res.data.filter(item => { |
| | | return item.type === 1 |
| | | })[0].count; |
| | | maintenanceNoticeCount.value = res.data.filter(item => { |
| | | return item.type === 2 |
| | | })[0].count; |
| | | }); |
| | | } |
| | | // 初始化某个类型的分页数据 |
| | | const initNoticePage = (typeId) => { |
| | | if (!noticePagesMap.value[typeId]) { |
| | | noticePagesMap.value[typeId] = { |
| | | total: 0, |
| | | current: 1, |
| | | size: 10 |
| | | }; |
| | | } |
| | | if (!noticesMap.value[typeId]) { |
| | | noticesMap.value[typeId] = []; |
| | | } |
| | | }; |
| | | |
| | | const holidayNotices = ref([]) |
| | | const maintenanceNotices = ref([]) |
| | | const holidayNoticePage = ref({ |
| | | total: 0, |
| | | current: 1, |
| | | size: 9 |
| | | }) |
| | | // 获取某个类型的通知列表 |
| | | const getNoticesByType = (typeId) => { |
| | | return noticesMap.value[typeId] || []; |
| | | }; |
| | | |
| | | const maintenanceNoticePage = ref({ |
| | | total: 0, |
| | | current: 1, |
| | | size: 9 |
| | | }) |
| | | // 获取某个类型的分页数据 |
| | | const getNoticePageByType = (typeId) => { |
| | | return noticePagesMap.value[typeId] || { total: 0, current: 1, size: 10 }; |
| | | }; |
| | | |
| | | const fetchHolidayNotices = () => { |
| | | listNotice({...holidayNoticePage.value, type: 1}).then(res => { |
| | | holidayNotices.value = res.data.records |
| | | holidayNoticePage.value.total = res.data.total |
| | | // 获取某个类型的数量 |
| | | const getNoticeCountByType = (typeId) => { |
| | | return getNoticePageByType(typeId).total || 0; |
| | | }; |
| | | |
| | | // 获取某个类型的通知数据 |
| | | const fetchNoticesByType = (typeId) => { |
| | | initNoticePage(typeId); |
| | | const pageData = noticePagesMap.value[typeId]; |
| | | listNotice({...pageData, type: typeId}).then(res => { |
| | | if (res.code === 200) { |
| | | noticesMap.value[typeId] = res.data.records || []; |
| | | noticePagesMap.value[typeId].total = res.data.total || 0; |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const fetchMaintenanceNotices = () => { |
| | | listNotice({...holidayNoticePage.value, type: 2}).then(res => { |
| | | maintenanceNotices.value = res.data.records |
| | | maintenanceNoticePage.value.total = res.data.total |
| | | }); |
| | | // 处理分页变化 |
| | | const handleNoticeCurrentChange = (typeId, val) => { |
| | | initNoticePage(typeId); |
| | | noticePagesMap.value[typeId].size = val.limit; |
| | | noticePagesMap.value[typeId].current = val.page; |
| | | fetchNoticesByType(typeId); |
| | | }; |
| | | |
| | | const handleHolidayNoticeCurrentChange = (val) => { |
| | | holidayNoticePage.value.size = val.limit |
| | | holidayNoticePage.value.current = val.page |
| | | fetchHolidayNotices() |
| | | }; |
| | | |
| | | const handleMaintenanceNoticeCurrentChange = (val) => { |
| | | maintenanceNoticePage.value.size = val.limit |
| | | maintenanceNoticePage.value.current = val.page |
| | | fetchMaintenanceNotices() |
| | | // 处理 tab 切换 |
| | | const handleNoticeTypeTabChange = (tabName) => { |
| | | activeNoticeTypeTab.value = tabName; |
| | | const typeId = Number(tabName); |
| | | fetchNoticesByType(typeId); |
| | | }; |
| | | |
| | | const resetTable = () => { |
| | | holidayNoticePage.value.current = 1 |
| | | holidayNoticePage.value.size = 9 |
| | | maintenanceNoticePage.value.current = 1 |
| | | maintenanceNoticePage.value.size = 9 |
| | | fetchHolidayNotices() |
| | | fetchMaintenanceNotices() |
| | | fetchCount() |
| | | // 重置所有类型的分页并重新获取数据 |
| | | noticeTypeList.value.forEach(type => { |
| | | initNoticePage(type.id); |
| | | noticePagesMap.value[type.id].current = 1; |
| | | noticePagesMap.value[type.id].size = 10; |
| | | fetchNoticesByType(type.id); |
| | | }); |
| | | }; |
| | | |
| | | const resetForm = () => { |
| | | formRef.value?.resetFields(); |
| | | }; |
| | | |
| | | // 公告类型配置相关方法 |
| | | const openNoticeTypeDialog = () => { |
| | | noticeTypeDialogVisible.value = true; |
| | | fetchNoticeTypeList(); |
| | | }; |
| | | |
| | | const fetchNoticeTypeList = () => { |
| | | return listNoticeType().then(res => { |
| | | if (res.code === 200) { |
| | | noticeTypeList.value = res.data.map(item => ({ |
| | | ...item, |
| | | editing: false |
| | | })); |
| | | |
| | | // 检查路由参数中的 type |
| | | const routeType = route.query.type; |
| | | let targetTypeId = null; |
| | | |
| | | if (routeType) { |
| | | // 如果路由参数中有 type,查找对应的类型 |
| | | const typeId = Number(routeType); |
| | | const foundType = noticeTypeList.value.find(item => item.id === typeId); |
| | | if (foundType) { |
| | | targetTypeId = typeId; |
| | | } |
| | | } |
| | | |
| | | // 如果有类型数据 |
| | | if (noticeTypeList.value.length > 0) { |
| | | // 如果路由参数指定了类型且存在,使用路由参数的类型 |
| | | // 否则如果没有选中 tab,默认选中第一个 |
| | | if (targetTypeId !== null) { |
| | | activeNoticeTypeTab.value = String(targetTypeId); |
| | | fetchNoticesByType(targetTypeId); |
| | | } else if (!activeNoticeTypeTab.value) { |
| | | activeNoticeTypeTab.value = String(noticeTypeList.value[0].id); |
| | | fetchNoticesByType(noticeTypeList.value[0].id); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const handleAddNoticeType = () => { |
| | | const newItem = { |
| | | id: undefined, |
| | | noticeType: '', |
| | | editing: true |
| | | }; |
| | | noticeTypeList.value.push(newItem); |
| | | }; |
| | | |
| | | const handleEditNoticeType = (row) => { |
| | | // 保存原始值 |
| | | row.originalNoticeType = row.noticeType; |
| | | row.editing = true; |
| | | }; |
| | | |
| | | const handleSaveNoticeType = (row) => { |
| | | if (!row.noticeType || row.noticeType.trim() === '') { |
| | | ElMessage.warning('公告类型不能为空'); |
| | | return; |
| | | } |
| | | |
| | | const data = { |
| | | noticeType: row.noticeType.trim() |
| | | }; |
| | | |
| | | if (row.id) { |
| | | // 编辑模式 - 先删除再添加(因为只有 add 和 del 接口) |
| | | delNoticeType(row.id).then(res => { |
| | | if (res.code === 200) { |
| | | addNoticeType(data).then(addRes => { |
| | | if (addRes.code === 200) { |
| | | ElMessage.success('编辑成功'); |
| | | row.editing = false; |
| | | delete row.originalNoticeType; |
| | | fetchNoticeTypeList().then(() => { |
| | | // 如果当前选中的类型被编辑,需要重新获取数据 |
| | | if (activeNoticeTypeTab.value === String(row.id)) { |
| | | fetchNoticesByType(addRes.data?.id || row.id); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } else { |
| | | // 新增模式 |
| | | addNoticeType(data).then(res => { |
| | | if (res.code === 200) { |
| | | ElMessage.success('新增成功'); |
| | | row.editing = false; |
| | | fetchNoticeTypeList(); |
| | | } |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | const handleDeleteNoticeType = (row) => { |
| | | // 如果没有id,说明是新增但未保存的行,直接从前端删除 |
| | | if (!row.id) { |
| | | const index = noticeTypeList.value.indexOf(row); |
| | | if (index > -1) { |
| | | noticeTypeList.value.splice(index, 1); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | // 如果有id,调用后端接口删除 |
| | | ElMessageBox.confirm( |
| | | "确认删除这个公告类型吗?", |
| | | "提示", |
| | | { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning" |
| | | } |
| | | ).then(() => { |
| | | delNoticeType(row.id).then(res => { |
| | | if (res.code === 200) { |
| | | ElMessage.success("删除成功"); |
| | | // 如果删除的是当前选中的类型,切换到第一个类型 |
| | | if (activeNoticeTypeTab.value === String(row.id)) { |
| | | fetchNoticeTypeList().then(() => { |
| | | if (noticeTypeList.value.length > 0) { |
| | | activeNoticeTypeTab.value = String(noticeTypeList.value[0].id); |
| | | fetchNoticesByType(noticeTypeList.value[0].id); |
| | | } else { |
| | | activeNoticeTypeTab.value = ''; |
| | | } |
| | | }); |
| | | } else { |
| | | fetchNoticeTypeList(); |
| | | } |
| | | } |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | const handleCancelEdit = (row) => { |
| | | if (!row.id) { |
| | | // 如果是新增但未保存的行,移除它 |
| | | const index = noticeTypeList.value.indexOf(row); |
| | | if (index > -1) { |
| | | noticeTypeList.value.splice(index, 1); |
| | | } |
| | | } else { |
| | | // 如果是编辑中的行,取消编辑状态并恢复原值 |
| | | row.editing = false; |
| | | if (row.originalNoticeType !== undefined) { |
| | | row.noticeType = row.originalNoticeType; |
| | | delete row.originalNoticeType; |
| | | } |
| | | } |
| | | }; |
| | | |
| | | const handleNoticeTypeDialogClose = () => { |
| | | // 关闭弹框时,取消所有编辑状态 |
| | | noticeTypeList.value.forEach(item => { |
| | | if (item.editing && !item.id) { |
| | | // 如果是新增但未保存的行,移除它 |
| | | const index = noticeTypeList.value.indexOf(item); |
| | | if (index > -1) { |
| | | noticeTypeList.value.splice(index, 1); |
| | | } |
| | | } else if (item.editing) { |
| | | // 如果是编辑中的行,取消编辑状态并恢复原值 |
| | | item.editing = false; |
| | | if (item.originalNoticeType !== undefined) { |
| | | item.noticeType = item.originalNoticeType; |
| | | delete item.originalNoticeType; |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 生命周期 |
| | | onMounted(() => { |
| | | fetchCount() |
| | | fetchHolidayNotices() |
| | | fetchMaintenanceNotices() |
| | | // 先获取公告类型列表,然后根据类型获取通知数据 |
| | | fetchNoticeTypeList(); |
| | | }); |
| | | </script> |
| | | |
| | |
| | | box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | .holiday-card { |
| | | border-left-color: #67c23a; |
| | | .notice-icon { |
| | | color: #409eff; |
| | | margin-right: 8px; |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .maintenance-card { |
| | | border-left-color: #e6a23c; |
| | | .tab-count { |
| | | color: #909399; |
| | | font-size: 12px; |
| | | margin-left: 4px; |
| | | } |
| | | |
| | | .urgent { |
| | |
| | | flex: 1; |
| | | } |
| | | |
| | | .holiday-icon { |
| | | color: #67c23a; |
| | | margin-right: 8px; |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .maintenance-icon { |
| | | color: #e6a23c; |
| | | margin-right: 8px; |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .card-actions { |
| | | display: flex; |
| | |
| | | text-align: right; |
| | | } |
| | | |
| | | .notice-type-container { |
| | | padding: 10px 0; |
| | | } |
| | | |
| | | .notice-type-header { |
| | | margin-bottom: 15px; |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | } |
| | | |
| | | /* 响应式设计 */ |
| | | @media (max-width: 768px) { |
| | | .notice-cards { |