| | |
| | | <!--OA模åï¼NoticeAnnouncement éç¥å
Œ--> |
| | | <!-- |
| | | 模å䏿åï¼éç¥å
Œ |
| | | ç®å½æ è¯ï¼NoticeAnnouncement/notice-manage |
| | | å¤ç¨é¡µé¢ï¼@/views/collaborativeApproval/noticeManagement/index.vueï¼åå审æ¹-éç¥å
¬åï¼ |
| | | --> |
| | | <template> |
| | | <div class="app-container notice-announcement-page"> |
| | | <div class="search_form mb20"> |
| | | <div class="search_fields"> |
| | | <span class="search_title">å
³é®è¯ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.keyword" |
| | | style="width: 200px" |
| | | placeholder="æ é¢ / ç¼å·" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | <span class="search_title" style="margin-left: 12px">ç±»åï¼</span> |
| | | <el-select v-model="searchForm.noticeType" placeholder="å
¨é¨" clearable style="width: 130px"> |
| | | <el-option v-for="opt in NOTICE_TYPE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" /> |
| | | </el-select> |
| | | <span class="search_title" style="margin-left: 12px">ä¼å
级ï¼</span> |
| | | <el-select v-model="searchForm.priority" placeholder="å
¨é¨" clearable style="width: 110px"> |
| | | <el-option v-for="opt in PRIORITY_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" /> |
| | | </el-select> |
| | | <span class="search_title" style="margin-left: 12px">ç¶æï¼</span> |
| | | <el-select v-model="searchForm.publishStatus" placeholder="å
¨é¨" clearable style="width: 110px"> |
| | | <el-option v-for="opt in PUBLISH_STATUS_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" /> |
| | | </el-select> |
| | | <span class="search_title" style="margin-left: 12px">å叿¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.publishDateRange" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§" |
| | | end-placeholder="ç»æ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | style="width: 260px" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" :icon="Search" class="ml10" @click="handleQuery">æç´¢</el-button> |
| | | <el-button :icon="RefreshRight" @click="resetSearch">éç½®</el-button> |
| | | </div> |
| | | <div class="search_actions"> |
| | | <el-button type="primary" :icon="Plus" @click="openFormDialog('add')">æ·»å å
Œ</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="false" |
| | | :tableLoading="tableLoading" |
| | | :total="page.total" |
| | | @pagination="pagination" |
| | | > |
| | | <template #noticeType="{ row }"> |
| | | <span class="notice-type-tag" :style="{ color: noticeTypeColor(row.noticeType) }"> |
| | | {{ noticeTypeLabel(row.noticeType) }} |
| | | </span> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <!-- æ·»å / ä¿®æ¹ --> |
| | | <el-dialog |
| | | v-model="formDialog.visible" |
| | | :title="formDialog.title" |
| | | width="800px" |
| | | append-to-body |
| | | destroy-on-close |
| | | class="notice-form-dialog" |
| | | @closed="formRef?.resetFields?.()" |
| | | > |
| | | <el-form |
| | | ref="formRef" |
| | | :model="form" |
| | | :rules="formRules" |
| | | label-width="100px" |
| | | :disabled="formDialog.readonly" |
| | | > |
| | | <el-form-item label="æ é¢" prop="title"> |
| | | <el-input v-model="form.title" placeholder="请è¾å
¥å
¬åæ é¢" maxlength="100" show-word-limit /> |
| | | </el-form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬åç±»å" prop="noticeType"> |
| | | <el-select v-model="form.noticeType" placeholder="è¯·éæ©" style="width: 100%" @change="onNoticeTypeChange"> |
| | | <el-option v-for="opt in NOTICE_TYPE_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¼å
级"> |
| | | <el-select v-model="form.priority" placeholder="è¯·éæ©" style="width: 100%"> |
| | | <el-option v-for="opt in PRIORITY_OPTIONS" :key="opt.value" :label="opt.label" :value="opt.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å叿¥æ" prop="publishDate"> |
| | | <el-date-picker |
| | | v-model="form.publishDate" |
| | | type="date" |
| | | placeholder="å叿¥æ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è¿ææ¥æ"> |
| | | <el-date-picker |
| | | v-model="form.expireDate" |
| | | type="date" |
| | | placeholder="å¯éï¼çç©ºä¸ºé¿æææ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | style="width: 100%" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="é
读èå´"> |
| | | <el-radio-group v-model="form.readScope"> |
| | | <el-radio v-for="opt in READ_SCOPE_OPTIONS" :key="opt.value" :value="opt.value"> |
| | | {{ opt.label }} |
| | | </el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="form.readScope === 'department'" label="å¯è§é¨é¨"> |
| | | <el-select v-model="form.targetDeptIds" multiple placeholder="éæ©é¨é¨" style="width: 100%"> |
| | | <el-option v-for="d in DEPT_OPTIONS" :key="d.value" :label="d.label" :value="d.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="form.noticeType === 'emergency'" label="å¿
读确认"> |
| | | <el-switch v-model="form.requireReadConfirm" active-text="ç´§æ¥éç¥éå工确认已读" /> |
| | | </el-form-item> |
| | | <el-form-item label="å
容" prop="contentHtml"> |
| | | <Editor v-model="form.contentHtml" :min-height="280" placeholder="请è¾å
¥å
容" /> |
| | | </el-form-item> |
| | | <el-form-item label="åå¸äºº"> |
| | | <el-input v-model="form.publisherName" placeholder="å¦ï¼è¡æ¿é¨" maxlength="50" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template v-if="!formDialog.readonly" #footer> |
| | | <el-button @click="formDialog.visible = false">å æ¶</el-button> |
| | | <el-button @click="onSave(false)">åè稿</el-button> |
| | | <el-button type="primary" @click="onSave(true)">ç¡® å®</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 详æ
--> |
| | | <el-dialog v-model="detailDialog.visible" title="å
¬å详æ
" width="800px" append-to-body destroy-on-close> |
| | | <NoticeDetailPanel :row="detailRow" /> |
| | | <template #footer> |
| | | <el-button @click="detailDialog.visible = false">å
³ é</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | <NoticeManagement /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { Plus, RefreshRight } from "@element-plus/icons-vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { onMounted } from "vue"; |
| | | import Editor from "@/components/Editor/index.vue"; |
| | | import { noticeTypeColor } from "./noticeAnnouncementUtils.js"; |
| | | import NoticeDetailPanel from "./components/NoticeDetailPanel.vue"; |
| | | import { useNoticeAnnouncement } from "./useNoticeAnnouncement.js"; |
| | | |
| | | const { |
| | | Search, |
| | | NOTICE_TYPE_OPTIONS, |
| | | PRIORITY_OPTIONS, |
| | | PUBLISH_STATUS_OPTIONS, |
| | | READ_SCOPE_OPTIONS, |
| | | DEPT_OPTIONS, |
| | | noticeTypeLabel, |
| | | searchForm, |
| | | tableLoading, |
| | | page, |
| | | tableData, |
| | | tableColumn, |
| | | formDialog, |
| | | form, |
| | | formRef, |
| | | formRules, |
| | | detailDialog, |
| | | detailRow, |
| | | handleQuery, |
| | | resetSearch, |
| | | pagination, |
| | | openFormDialog, |
| | | saveForm, |
| | | } = useNoticeAnnouncement(); |
| | | |
| | | function onNoticeTypeChange(type) { |
| | | if (type === "emergency") { |
| | | form.priority = "urgent"; |
| | | form.requireReadConfirm = true; |
| | | } |
| | | } |
| | | |
| | | function onSave(publish) { |
| | | const ret = saveForm(publish); |
| | | if (ret?.message) { |
| | | ElMessage.warning(ret.message); |
| | | return; |
| | | } |
| | | if (ret?.ok) { |
| | | ElMessage.success(publish ? "å
¬åå·²åå¸" : "å·²ä¿åè稿"); |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | handleQuery(); |
| | | }); |
| | | import NoticeManagement from "@/views/collaborativeApproval/noticeManagement/index.vue"; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .notice-announcement-page .search_form { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | justify-content: space-between; |
| | | align-items: flex-start; |
| | | gap: 12px; |
| | | } |
| | | .search_fields { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | align-items: center; |
| | | gap: 4px; |
| | | } |
| | | .search_actions { |
| | | flex-shrink: 0; |
| | | } |
| | | .notice-type-tag { |
| | | font-weight: 600; |
| | | font-size: 13px; |
| | | } |
| | | .ml10 { |
| | | margin-left: 10px; |
| | | } |
| | | .mb20 { |
| | | margin-bottom: 20px; |
| | | } |
| | | </style> |