index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <template>
  2. <div class="auxiliary-notice-container layout-pd">
  3. <el-card shadow="never">
  4. <el-tabs v-model="listType" @tab-change="queryList">
  5. <el-tab-pane name="0" label="通知"></el-tab-pane>
  6. <el-tab-pane name="1" label="公告"></el-tab-pane>
  7. </el-tabs>
  8. <el-form :model="state.queryParams" ref="ruleFormRef" :inline="true" @submit.native.prevent class="mt10">
  9. <el-form-item label="标题" prop="Title">
  10. <el-input v-model="state.queryParams.Title" placeholder="标题" clearable @keyup.enter="queryList" style="width: 250px" />
  11. </el-form-item>
  12. <template v-if="listType === '0'">
  13. <el-form-item label="通知类型" prop="CircularTypeId">
  14. <el-select v-model="state.queryParams.CircularTypeId" placeholder="请选择通知类型">
  15. <el-option v-for="item in circularType" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
  16. </el-select>
  17. </el-form-item>
  18. <el-form-item label="通知时间" prop="exTime">
  19. <el-date-picker
  20. v-model="state.queryParams.exTime"
  21. type="datetimerange"
  22. unlink-panels
  23. range-separator="至"
  24. start-placeholder="开始时间"
  25. end-placeholder="结束时间"
  26. :shortcuts="shortcuts"
  27. @change="timeStartChangeCr"
  28. value-format="YYYY-MM-DD[T]HH:mm:ss"
  29. />
  30. </el-form-item>
  31. </template>
  32. <template v-else>
  33. <el-form-item label="公告类型" prop="BulletinTypeId">
  34. <el-select v-model="state.queryParams.BulletinTypeId" placeholder="请选择公告类型">
  35. <el-option v-for="item in bulletinType" :value="item.dicDataValue" :key="item.dicDataValue" :label="item.dicDataName" />
  36. </el-select>
  37. </el-form-item>
  38. <el-form-item label="公告时间" prop="Time">
  39. <el-date-picker
  40. v-model="state.queryParams.Time"
  41. type="datetimerange"
  42. unlink-panels
  43. range-separator="至"
  44. start-placeholder="开始时间"
  45. end-placeholder="结束时间"
  46. :shortcuts="shortcuts"
  47. @change="timeStartChange"
  48. value-format="YYYY-MM-DD[T]HH:mm:ss"
  49. />
  50. </el-form-item>
  51. </template>
  52. <el-form-item>
  53. <el-button type="primary" @click="queryList" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
  54. <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
  55. </el-form-item>
  56. </el-form>
  57. <div class="mb20">
  58. <el-button type="primary" @click="onNoticeAdd('0')" v-if="listType === '0'" v-auth="'auxiliary:notice:add'" title="新增通知">
  59. <SvgIcon name="ele-Plus" class="mr5" />新增
  60. </el-button>
  61. <el-button type="primary" @click="onNoticeAdd('1')" v-else v-auth="'auxiliary:bulletin:add'" title="新增公告">
  62. <SvgIcon name="ele-Plus" class="mr5" />新增
  63. </el-button>
  64. </div>
  65. <!-- 表格 -->
  66. <el-table :data="state.tableData" v-loading="state.loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
  67. <el-table-column type="selection" width="55" />
  68. <!-- 通知 -->
  69. <template v-if="listType === '0'">
  70. <el-table-column prop="circularTypeName" label="通知类型" show-overflow-tooltip width="120"></el-table-column>
  71. <el-table-column prop="circularStateText" label="通知状态" show-overflow-tooltip width="120"></el-table-column>
  72. <el-table-column prop="title" label="通知标题" show-overflow-tooltip width="150"></el-table-column>
  73. <el-table-column prop="commonTypeText" label="必须阅读" show-overflow-tooltip>
  74. <template #default="{ row }">
  75. {{ row.isMustRead ? '是' : '否' }}
  76. </template>
  77. </el-table-column>
  78. <el-table-column label="已阅读数" show-overflow-tooltip>
  79. <template #default="{ row }">
  80. <el-popover placement="right" :width="450" trigger="click" popper-class="notice-container" v-if="[2].includes(row.circularState)">
  81. <template #reference>
  82. <el-button link type="primary">{{ row.readedNum + '/' + row.needReadNum }}</el-button>
  83. </template>
  84. <div class="notice-container-box">
  85. <div class="notice-container-box-inner">
  86. 已读:{{ row.readedNum }}
  87. <el-scrollbar class="mt5" v-if="row.circularReadGroups?.length">
  88. <el-tag v-for="item in row.circularReadGroups.filter((i) => i.isRead)">{{
  89. row.circularType === 1 ? item.userName : item.orgName
  90. }} <span v-if="item.isTimeOut" class="color-danger">(超时阅读)</span> </el-tag>
  91. </el-scrollbar>
  92. </div>
  93. <div class="notice-container-box-inner">
  94. 未读:{{ row.needReadNum - row.readedNum }}
  95. <el-scrollbar class="mt5 mb10" v-if="row.circularReadGroups?.length">
  96. <el-tag v-for="item in row.circularReadGroups.filter((i) => !i.isRead)">{{
  97. row.circularType === 1 ? item.userName : item.orgName
  98. }}</el-tag>
  99. </el-scrollbar>
  100. </div>
  101. </div>
  102. </el-popover>
  103. </template>
  104. </el-table-column>
  105. <el-table-column prop="circularTypeText" label="通知对象" show-overflow-tooltip></el-table-column>
  106. <el-table-column prop="commonTypeText" label="通知时间" show-overflow-tooltip width="170">
  107. <template #default="{ row }">
  108. <span>{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
  109. </template>
  110. </el-table-column>
  111. <el-table-column label="失效时间" show-overflow-tooltip width="170">
  112. <template #default="{ row }">
  113. <span>{{ formatDate(row.lostEfficacyTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
  114. </template>
  115. </el-table-column>
  116. <el-table-column prop="sourceOrgName" label="来源单位" show-overflow-tooltip width="120"></el-table-column>
  117. <el-table-column prop="circularStateText" label="审核状态" show-overflow-tooltip width="120"></el-table-column>
  118. </template>
  119. <!-- 公告 -->
  120. <template v-if="listType === '1'">
  121. <el-table-column prop="bulletinTypeName" label="公告类型" show-overflow-tooltip width="120"></el-table-column>
  122. <el-table-column prop="bulletinStateText" label="公告状态" show-overflow-toolti width="120"></el-table-column>
  123. <el-table-column prop="title" label="公告标题" show-overflow-tooltip width="150"></el-table-column>
  124. <el-table-column prop="readedNum" label="已阅次数" show-overflow-tooltip></el-table-column>
  125. <el-table-column prop="pushRangesText" label="公告范围" show-overflow-tooltip width="300"></el-table-column>
  126. <el-table-column prop="commonTypeText" label="通知时间" show-overflow-tooltip width="170">
  127. <template #default="{ row }">
  128. <span>{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
  129. </template>
  130. </el-table-column>
  131. <el-table-column label="失效时间" show-overflow-tooltip width="170">
  132. <template #default="{ row }">
  133. <span>{{ formatDate(row.loseEfficacyTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
  134. </template>
  135. </el-table-column>
  136. <el-table-column prop="creatorOrgName" label="来源单位" show-overflow-tooltip width="120"></el-table-column>
  137. <el-table-column prop="bulletinStateText" label="审核状态" show-overflow-tooltip width="120"></el-table-column>
  138. </template>
  139. <el-table-column prop="examinOpinion" label="审核理由" show-overflow-tooltip width="150"></el-table-column>
  140. <el-table-column prop="examinMan" label="审核人" show-overflow-tooltip></el-table-column>
  141. <el-table-column prop="examinOpinion" label="审核时间" show-overflow-tooltip width="170">
  142. <template #default="{ row }">
  143. <span>{{ formatDate(row.examinTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
  144. </template>
  145. </el-table-column>
  146. <el-table-column label="操作" width="200" fixed="right" align="center">
  147. <template #default="{ row }">
  148. <template v-if="listType === '0'">
  149. <el-button link type="primary" @click="onEdit(row, '0')" v-if="[0, 3].includes(row.circularState)" v-auth="'auxiliary:notice:edit'">
  150. 编辑
  151. </el-button>
  152. <el-button link type="danger" @click="onDelete(row, '0')" v-if="[0].includes(row.circularState)" v-auth="'auxiliary:notice:delete'">
  153. 删除
  154. </el-button>
  155. <el-button
  156. link
  157. type="primary"
  158. @click="onCommit(row, '0')"
  159. v-if="[0, 3].includes(row.circularState)"
  160. title="提交审批"
  161. v-auth="'auxiliary:notice:commit'"
  162. >
  163. 提交
  164. </el-button>
  165. <el-button link type="primary" @click="onDetail(row, '0')" v-auth="'auxiliary:notice:detail'" v-if="[1, 2].includes(row.circularState)">
  166. 查看详情
  167. </el-button>
  168. </template>
  169. <template v-if="listType === '1'">
  170. <el-button link type="primary" @click="onEdit(row, '1')" v-if="[0, 3].includes(row.bulletinState)" v-auth="'auxiliary:notice:edit'">
  171. 编辑
  172. </el-button>
  173. <el-button link type="danger" @click="onDelete(row, '1')" v-if="[0].includes(row.bulletinState)" v-auth="'auxiliary:notice:delete'">
  174. 删除
  175. </el-button>
  176. <el-button
  177. link
  178. type="primary"
  179. @click="onCommit(row, '1')"
  180. v-if="[0, 3].includes(row.bulletinState)"
  181. title="提交审批"
  182. v-auth="'auxiliary:notice:commit'"
  183. >
  184. 提交
  185. </el-button>
  186. <el-button link type="primary" @click="onDetail(row, '1')" v-auth="'auxiliary:notice:detail'" v-if="[1, 2].includes(row.bulletinState)">
  187. 查看详情
  188. </el-button>
  189. </template>
  190. </template>
  191. </el-table-column>
  192. <template #empty>
  193. <Empty />
  194. </template>
  195. </el-table>
  196. <!-- 分页 -->
  197. <pagination
  198. :total="state.total"
  199. v-model:page="state.queryParams.PageIndex"
  200. v-model:limit="state.queryParams.PageSize"
  201. @pagination="queryList"
  202. />
  203. </el-card>
  204. <!-- 流程审批 -->
  205. <process-audit ref="processAuditRef" @orderProcessSuccess="queryList" />
  206. <!-- 新增通知公告 -->
  207. <notice-add ref="noticeAddRef" @updateList="queryList" />
  208. <!-- 编辑通知公告 -->
  209. <notice-edit ref="noticeEditRef" @updateList="queryList" />
  210. </div>
  211. </template>
  212. <script lang="ts" setup name="auxiliaryNotice">
  213. import { defineAsyncComponent, onActivated, onMounted, reactive, ref } from 'vue';
  214. import { useRouter } from 'vue-router';
  215. import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
  216. import { shortcuts } from '/@/utils/constants';
  217. import { formatDate } from '/@/utils/formatTime';
  218. import { auth } from '/@/utils/authFunction';
  219. import {
  220. bulletinBaseData,
  221. bulletinCommit,
  222. bulletinDelete,
  223. bulletinList,
  224. circularBaseData,
  225. circularCommit,
  226. circularDelete,
  227. circularList,
  228. } from '/@/api/auxiliary/notice';
  229. import { businessTagDelete } from '/@/api/auxiliary/businessTag';
  230. // 引入组件
  231. const ProcessAudit = defineAsyncComponent(() => import('/@/components/ProcessAudit/index.vue')); // 流程审批
  232. const NoticeAdd = defineAsyncComponent(() => import('/@/views/auxiliary/notice/component/Notice-add.vue')); // 通知公告新增
  233. const NoticeEdit = defineAsyncComponent(() => import('/@/views/auxiliary/notice/component/Notice-edit.vue')); // 通知公告编辑
  234. // 定义变量内容
  235. const state = reactive<any>({
  236. loading: false, // 加载状态
  237. queryParams: {
  238. // 查询参数
  239. PageIndex: 1,
  240. PageSize: 10,
  241. Title: null,
  242. BulletinTimeStart: null, // 创建时间 开始
  243. BulletinTimeEnd: null, // 创建时间 结束
  244. CircularTimeStart: null,
  245. CircularTimeEnd: null,
  246. exTime: [],
  247. Time: [],
  248. BulletinTypeId: null, //通知类型
  249. CircularTypeId: null,
  250. },
  251. total: 0, // 总条数
  252. tableData: [], // 表格数据
  253. });
  254. const ruleFormRef = ref<RefType>(null); // 表单ref
  255. const bulletinType = ref<EmptyArrayType>([]); // 通知类型
  256. const circularType = ref<EmptyArrayType>([]); // 通知类型
  257. const listType = ref<string>('0'); // 列表类型
  258. const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
  259. if (val) {
  260. state.queryParams[startKey] = val[0];
  261. state.queryParams[endKey] = val[1];
  262. } else {
  263. state.queryParams[startKey] = '';
  264. state.queryParams[endKey] = '';
  265. }
  266. queryList();
  267. };
  268. // 甄别时间
  269. const timeStartChangeCr = (val: string[]) => {
  270. handleTimeChange(val, 'CircularTimeStart', 'CircularTimeEnd');
  271. };
  272. const timeStartChange = (val: string[]) => {
  273. handleTimeChange(val, 'BulletinTimeStart', 'BulletinTimeEnd');
  274. };
  275. const getBaseData = async () => {
  276. try {
  277. const resCircularType = await circularBaseData();
  278. circularType.value = resCircularType.result?.circularType ?? [];
  279. const res = await bulletinBaseData();
  280. bulletinType.value = res.result.bulletinType ?? [];
  281. } catch (error) {
  282. console.log(error);
  283. }
  284. };
  285. // 获取参数列表
  286. const queryList = () => {
  287. state.loading = true;
  288. switch (listType.value) {
  289. case '0': //通知
  290. if (!auth('auxiliary:notice:query')) ElMessage.error('抱歉,您没有权限获取通知公告列表!');
  291. else {
  292. const requestCircular = {
  293. title: state.queryParams.Title,
  294. CircularTypeId: state.queryParams.CircularTypeId,
  295. CircularTimeStart: state.queryParams.CircularTimeStart,
  296. CircularTimeEnd: state.queryParams.CircularTimeEnd,
  297. PageIndex: state.queryParams.PageIndex,
  298. PageSize: state.queryParams.PageSize,
  299. };
  300. circularList(requestCircular)
  301. .then((res) => {
  302. state.loading = false;
  303. state.tableData = res.result.items ?? [];
  304. state.total = res.result.total ?? 0;
  305. })
  306. .finally(() => {
  307. state.loading = false;
  308. });
  309. }
  310. break;
  311. case '1': // 公告
  312. if (!auth('auxiliary:bulletin:query')) ElMessage.error('抱歉,您没有权限获取通知公告列表!');
  313. else {
  314. const requestBulletin = {
  315. title: state.queryParams.Title,
  316. BulletinTypeId: state.queryParams.BulletinTypeId,
  317. BulletinTimeStart: state.queryParams.BulletinTimeStart,
  318. BulletinTimeEnd: state.queryParams.BulletinTimeEnd,
  319. PageIndex: state.queryParams.PageIndex,
  320. PageSize: state.queryParams.PageSize,
  321. };
  322. bulletinList(requestBulletin)
  323. .then((res) => {
  324. state.loading = false;
  325. state.tableData = res.result.items ?? [];
  326. state.total = res.result.total ?? 0;
  327. })
  328. .finally(() => {
  329. state.loading = false;
  330. });
  331. }
  332. break;
  333. }
  334. };
  335. // 重置表单
  336. const resetQuery = (formEl: FormInstance | undefined) => {
  337. if (!formEl) return;
  338. formEl.resetFields();
  339. state.queryParams.BulletinTimeStart = null;
  340. state.queryParams.BulletinTimeEnd = null;
  341. state.queryParams.CircularTimeStart = null;
  342. state.queryParams.CircularTimeEnd = null;
  343. queryList();
  344. };
  345. // 通知公告新增
  346. const processAuditRef = ref<RefType>(); // 处理流程
  347. const noticeAddRef = ref<RefType>(); // 通知公告新增
  348. const onNoticeAdd = (type: string) => {
  349. const processType = type === '0' ? '新增通知' : '新增公告';
  350. noticeAddRef.value.openDialog(processType);
  351. };
  352. // 查看详情
  353. const router = useRouter();
  354. const onDetail = (row: any, type: string) => {
  355. const tagsViewName = type === '0' ? '通知详情' : '公告详情';
  356. router.push({
  357. name: 'auxiliaryNoticeDetail',
  358. params: {
  359. id: row.id,
  360. isRead: 0,
  361. tagsViewName,
  362. },
  363. });
  364. };
  365. // 编辑
  366. const noticeEditRef = ref<RefType>(); // 通知公告编辑
  367. const onEdit = (row: any, type: string) => {
  368. noticeEditRef.value.openDialog(row, type === '0' ? '编辑通知' : '编辑公告');
  369. };
  370. // 删除
  371. const onDelete = (row: any, type: string) => {
  372. ElMessageBox.confirm(`您确定要删除:【${row.title}】,是否继续?`, '提示', {
  373. confirmButtonText: '确认',
  374. cancelButtonText: '取消',
  375. type: 'warning',
  376. draggable: true,
  377. cancelButtonClass: 'default-button',
  378. autofocus: false,
  379. })
  380. .then(() => {
  381. if (type === '0') {
  382. circularDelete(row.id).then(() => {
  383. ElMessage.success('操作成功!');
  384. queryList();
  385. });
  386. } else {
  387. bulletinDelete(row.id).then(() => {
  388. ElMessage.success('操作成功!');
  389. queryList();
  390. });
  391. }
  392. })
  393. .catch(() => {});
  394. };
  395. // 提交
  396. const onCommit = (row: any, type: string) => {
  397. ElMessageBox.confirm(`您确定要提交:【${row.title}】,是否继续?`, '提示', {
  398. confirmButtonText: '确认',
  399. cancelButtonText: '取消',
  400. type: 'warning',
  401. draggable: true,
  402. cancelButtonClass: 'default-button',
  403. autofocus: false,
  404. })
  405. .then(() => {
  406. if (type === '0') {
  407. circularCommit(row.id).then(() => {
  408. ElMessage.success('操作成功!');
  409. queryList();
  410. });
  411. } else {
  412. bulletinCommit(row.id).then(() => {
  413. ElMessage.success('操作成功!');
  414. queryList();
  415. });
  416. }
  417. })
  418. .catch(() => {});
  419. };
  420. // 表格多选
  421. const multipleTableRef = ref<RefType>();
  422. const multipleSelection = ref<any>([]);
  423. const handleSelectionChange = (val: any[]) => {
  424. multipleSelection.value = val;
  425. };
  426. const params = history.state;
  427. // 页面加载时
  428. onMounted(() => {
  429. getBaseData();
  430. if (params.index) {
  431. listType.value = params.index as string;
  432. }
  433. queryList();
  434. });
  435. onActivated(() => {
  436. if (params.index) {
  437. listType.value = params.index as string;
  438. }
  439. });
  440. </script>
  441. <style lang="scss">
  442. .notice-container {
  443. &-box {
  444. display: flex;
  445. padding: 10px;
  446. max-height: 300px;
  447. &-inner {
  448. flex: 1;
  449. padding: 10px 0 10px 10px;
  450. &:last-child {
  451. border-left: var(--el-border);
  452. }
  453. .el-tag {
  454. margin: 0 5px 5px 0;
  455. }
  456. }
  457. }
  458. }
  459. </style>