yyb
11 小时以前 d7f9fc20b91f72f52cb76e699858458d995c6c76
src/views/officeProcessAutomation/NoticeAnnouncement/notice-manage/index.vue
@@ -1,253 +1,12 @@
<!--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>