index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. <template>
  2. <div class="common-box">
  3. <!--条件-->
  4. <el-form :model="listQuery" ref="queryForm" :inline="true">
  5. <el-form-item label="公告标题">
  6. <el-input
  7. v-model="listQuery.msgTitle"
  8. placeholder="请输入公告标题"
  9. ></el-input>
  10. </el-form-item>
  11. <el-form-item label="公告类型">
  12. <el-select v-model="listQuery.msgType" placeholder="请选择公告类型">
  13. <el-option
  14. v-for="item in typeList"
  15. :key="item.dicCode"
  16. :label="item.dicVal"
  17. :value="item.dicCode"
  18. >
  19. </el-option>
  20. </el-select>
  21. </el-form-item>
  22. <el-form-item>
  23. <el-button type="primary" @click="getData('search')"> 查询 </el-button>
  24. <el-button @click="reset()">重置</el-button>
  25. </el-form-item>
  26. <el-form-item>
  27. <el-button
  28. type="primary"
  29. class="lake-Blue"
  30. icon="el-icon-plus"
  31. @click="handleAddOrEdit(0, null, 'create')"
  32. >
  33. 新增
  34. </el-button>
  35. </el-form-item>
  36. </el-form>
  37. <el-tabs v-model="activeName" @tab-click="handleClick">
  38. <el-tab-pane
  39. :label="item.label"
  40. :name="item.id"
  41. v-for="item in tabs"
  42. :key="item.id"
  43. >
  44. <el-table
  45. v-loading="listLoading"
  46. :data="list"
  47. element-loading-text="加载中"
  48. fit
  49. stripe
  50. >
  51. <template slot="empty">
  52. <img src="@/assets/nopage.png" alt />
  53. <p>暂无数据</p>
  54. </template>
  55. <el-table-column
  56. fixed
  57. type="index"
  58. label="序号"
  59. width="60"
  60. ></el-table-column>
  61. <el-table-column label="公告标题" prop="msgTitle" />
  62. <el-table-column label="公告类型" width="200">
  63. <template slot-scope="scope">{{
  64. reversedMessage(scope.row.msgType)
  65. }}</template>
  66. </el-table-column>
  67. <el-table-column label="发布者" width="200" prop="msgPubdUser" />
  68. <el-table-column
  69. v-if="activeName == '1'"
  70. label="发布时间"
  71. width="200"
  72. >
  73. <template slot-scope="scope">
  74. <span>{{ scope.row.msgPubdTime | formatDate }}</span>
  75. </template>
  76. </el-table-column>
  77. <el-table-column fixed="right" label="操作" width="180">
  78. <template slot-scope="scope">
  79. <el-button
  80. v-if="activeName == '0'"
  81. icon="el-icon-edit"
  82. style="color: #52C8CC;"
  83. :disabled="scope.row.state === 'deleted'"
  84. type="text"
  85. @click="handleAddOrEdit(scope.$index, scope.row, 'update')"
  86. >编辑
  87. </el-button>
  88. <el-button
  89. icon="el-icon-delete"
  90. style="color: #CE4745;"
  91. :disabled="scope.row.state === 'deleted'"
  92. type="text"
  93. @click="handleDelete(scope.row, 'deleted')"
  94. >删除
  95. </el-button>
  96. </template>
  97. </el-table-column>
  98. </el-table>
  99. <!--分页-->
  100. <yl-pagination
  101. v-show="total > 0"
  102. :total="total"
  103. :page.sync="listQuery.current"
  104. :limit.sync="listQuery.size"
  105. @pagination="getData"
  106. />
  107. </el-tab-pane>
  108. </el-tabs>
  109. <!--添加/修改-->
  110. <el-dialog
  111. v-if="dialogFormVisible"
  112. :title="textMap[dialogStatus]"
  113. :visible.sync="dialogFormVisible"
  114. width="1300px"
  115. :close-on-click-modal="false"
  116. >
  117. <el-form
  118. ref="dataForm"
  119. :rules="rules"
  120. :model="temp"
  121. label-position="right"
  122. label-width="80px"
  123. >
  124. <el-row>
  125. <el-col :span="12">
  126. <el-form-item label="标题" prop="msgTitle">
  127. <el-input v-model.trim="temp.msgTitle" />
  128. </el-form-item>
  129. </el-col>
  130. <el-col :span="6">
  131. <el-form-item label="分类" prop="msgType">
  132. <el-select
  133. v-model="temp.msgType"
  134. placeholder="请选择分类"
  135. style="width: 100%"
  136. >
  137. <el-option
  138. v-for="item in typeList"
  139. :key="item.dicCode"
  140. :label="item.dicVal"
  141. :value="item.dicCode"
  142. >
  143. </el-option>
  144. </el-select>
  145. </el-form-item>
  146. </el-col>
  147. <el-col :span="6">
  148. <el-form-item label="发布者">
  149. <el-input v-model.trim="temp.msgPubder" />
  150. </el-form-item>
  151. </el-col>
  152. </el-row>
  153. <el-form-item label="发送给">
  154. <!-- :disabled="noticeDetail.msgStas == 1" -->
  155. <el-radio-group v-model="temp.forAll">
  156. <el-radio label="1">全部用户</el-radio>
  157. <el-radio label="0">部分用户</el-radio>
  158. </el-radio-group>
  159. </el-form-item>
  160. <el-form-item label="接收用户" v-if="temp.forAll == 0">
  161. <div class="textarea-box">
  162. <el-tooltip
  163. :content="tag.id"
  164. placement="bottom"
  165. effect="light"
  166. :key="tag.id"
  167. v-for="tag in temp.receiveUser"
  168. popper-class="notice-testtooltip"
  169. open-delay="500"
  170. >
  171. <!-- :closable="noticeDetail.msgStas != 1" -->
  172. <el-tag
  173. closable
  174. @close="handleUsersClose(tag)"
  175. style="margin-right: 5px"
  176. >
  177. {{ tag.name }}
  178. </el-tag>
  179. </el-tooltip>
  180. </div>
  181. <!-- :disabled="noticeDetail.msgStas == 1" -->
  182. <el-button type="primary" icon="el-icon-plus" @click="chooseUsers"
  183. >选择</el-button
  184. >
  185. </el-form-item>
  186. <el-form-item label="接收角色" v-if="temp.forAll == 0">
  187. <div class="textarea-box">
  188. <el-tooltip
  189. :content="tag.id"
  190. placement="bottom"
  191. effect="light"
  192. :key="tag.id"
  193. v-for="tag in temp.receiveRole"
  194. popper-class="notice-testtooltip"
  195. open-delay="500"
  196. >
  197. <!-- :closable="noticeDetail.msgStas != 1" -->
  198. <el-tag
  199. closable
  200. @close="handleRolesClose(tag)"
  201. style="margin-right: 5px"
  202. >
  203. {{ tag.name }}
  204. </el-tag>
  205. </el-tooltip>
  206. </div>
  207. <!-- :disabled="noticeDetail.msgStas == 1" -->
  208. <el-button type="primary" icon="el-icon-plus" @click="chooseRoles"
  209. >选择</el-button
  210. >
  211. </el-form-item>
  212. <el-form-item label="内容">
  213. <div class="editor-css" style="border: 1px solid #ccc">
  214. <Toolbar
  215. style="border-bottom: 1px solid #ccc"
  216. :editor="editor"
  217. :defaultConfig="toolbarConfig"
  218. :mode="mode"
  219. />
  220. <Editor
  221. style="height: 500px; overflow-y: hidden"
  222. v-model="temp.mainText"
  223. :defaultConfig="editorConfig"
  224. :mode="mode"
  225. @onCreated="onCreated"
  226. />
  227. </div>
  228. </el-form-item>
  229. </el-form>
  230. <div slot="footer" class="dialog-footer">
  231. <el-button
  232. type="success"
  233. @click="commitData(0)"
  234. v-if="
  235. (dialogStatus == 'update' && noticeDetail.msgStas == 0) ||
  236. dialogStatus == 'create'
  237. "
  238. >保存</el-button
  239. >
  240. <el-button type="primary" @click="commitData(1)">发布</el-button>
  241. </div>
  242. </el-dialog>
  243. <!--添加接收用户-->
  244. <el-dialog
  245. v-if="dialogUsersFormVisible"
  246. title="选择接收用户"
  247. :visible.sync="dialogUsersFormVisible"
  248. width="1300px"
  249. :close-on-click-modal="false"
  250. >
  251. <users
  252. :checkUser="temp.receiveUser"
  253. @usersClose="usersClose"
  254. @usersSubmit="usersSubmit"
  255. ></users>
  256. </el-dialog>
  257. <!--添加接收角色-->
  258. <el-dialog
  259. v-if="dialogRolesFormVisible"
  260. title="选择接收角色"
  261. :visible.sync="dialogRolesFormVisible"
  262. width="1300px"
  263. :close-on-click-modal="false"
  264. >
  265. <roles
  266. :checkRole="temp.receiveRole"
  267. @rolesClose="rolesClose"
  268. @rolesSubmit="rolesSubmit"
  269. ></roles>
  270. </el-dialog>
  271. </div>
  272. </template>
  273. <script>
  274. import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
  275. import {
  276. addNotice,
  277. getNotice,
  278. delNotice,
  279. editNotice,
  280. getNoticeDetail
  281. } from "@/api/system/notice";
  282. import { getQueryDic } from "@/api/system/dic";
  283. import users from "@/views/page/system/notice/components/users";
  284. import roles from "@/views/page/system/notice/components/roles";
  285. import ylPagination from "@/components/yl-pagination";
  286. import moment from "moment";
  287. export default {
  288. components: { Editor, Toolbar, ylPagination, users, roles },
  289. data() {
  290. return {
  291. // 公告详情
  292. noticeDetail: {},
  293. dialogUsersFormVisible: false,
  294. dialogRolesFormVisible: false,
  295. // 公告分类
  296. typeList: [],
  297. activeName: "0",
  298. listLoading: false,
  299. list: null, //列表
  300. total: 0, //分页
  301. listQuery: {
  302. //条件查询
  303. current: 1,
  304. size: 10,
  305. msgTitle: "",
  306. msgType: "",
  307. msgStas: 0
  308. },
  309. textMap: {
  310. update: "编辑",
  311. create: "添加"
  312. },
  313. // tab栏
  314. tabs: [
  315. {
  316. id: "0",
  317. label: "未发布"
  318. },
  319. {
  320. id: "1",
  321. label: "已发布"
  322. }
  323. ],
  324. dialogFormVisible: false, //是否对话框
  325. dialogStatus: "",
  326. temp: {},
  327. rules: {
  328. msgType: [
  329. {
  330. required: true,
  331. message: "请选择分类",
  332. trigger: "change"
  333. }
  334. ],
  335. msgTitle: [
  336. {
  337. required: true,
  338. message: "标题不能为空",
  339. trigger: "blur"
  340. }
  341. ]
  342. },
  343. // 富文本编辑器
  344. editor: null,
  345. toolbarConfig: {
  346. excludeKeys: ["group-video", "codeBlock", "undo", "redo", "emotion"]
  347. },
  348. editorConfig: {
  349. placeholder: "请输入内容...",
  350. // 所有的菜单配置,都要在 MENU_CONF 属性下
  351. MENU_CONF: {
  352. // 配置上传图片
  353. uploadImage: {
  354. customUpload: this.update,
  355. base64LimitSize: 1024 * 1024 // 5*1024 = 5kb
  356. }
  357. // 继续其他菜单配置...
  358. }
  359. },
  360. mode: "default" // or 'simple'
  361. };
  362. },
  363. filters: {
  364. formatDate(status) {
  365. if (status) {
  366. var time = moment(time).format("YYYY-MM-DD HH:mm:ss");
  367. }
  368. return time;
  369. }
  370. },
  371. created() {
  372. this.getNoticeType();
  373. this.getData();
  374. },
  375. mounted() {},
  376. beforeDestroy() {
  377. const editor = this.editor;
  378. if (editor == null) return;
  379. editor.destroy(); // 组件销毁时,及时销毁编辑器
  380. },
  381. methods: {
  382. reversedMessage(val) {
  383. let newVal = this.typeList.find((item) => {
  384. return item.dicCode == val;
  385. });
  386. if (newVal) {
  387. return newVal.dicVal;
  388. }
  389. },
  390. // 删除用户标签
  391. handleUsersClose(tag) {
  392. this.temp.receiveUser.splice(this.temp.receiveUser.indexOf(tag), 1);
  393. },
  394. // 删除角色标签
  395. handleRolesClose(tag) {
  396. this.temp.receiveRole.splice(this.temp.receiveRole.indexOf(tag), 1);
  397. },
  398. // 获取到选中的用户
  399. usersSubmit(item) {
  400. this.temp.receiveUser = item;
  401. this.dialogUsersFormVisible = false;
  402. },
  403. // 获取到选中的用户
  404. rolesSubmit(item) {
  405. this.temp.receiveRole = item;
  406. this.dialogRolesFormVisible = false;
  407. },
  408. // 关闭用户对话框
  409. usersClose() {
  410. this.dialogUsersFormVisible = false;
  411. },
  412. // 关闭角色对话框
  413. rolesClose() {
  414. this.dialogRolesFormVisible = false;
  415. },
  416. // 选择用户对话框
  417. chooseUsers() {
  418. this.dialogUsersFormVisible = true;
  419. },
  420. // 选择角色对话框
  421. chooseRoles() {
  422. this.dialogRolesFormVisible = true;
  423. },
  424. // 获取公告分类
  425. getNoticeType() {
  426. getQueryDic({ dicCode: "noticeType" }).then((response) => {
  427. this.typeList = response.data;
  428. });
  429. },
  430. // 上传图片
  431. update(file, insertFn) {
  432. this.$message({
  433. message: "上传图片不能超过1MB!",
  434. type: "info"
  435. });
  436. // file 即选中的文件
  437. // 自己实现上传,并得到图片 url alt href
  438. // let name = md5(file.name);
  439. // let suffix = file.type.split("/")[1];
  440. // name = name + "." + suffix;
  441. // uploadFile(name, file).then((res) => {
  442. // if (res.statusCode == 200) {
  443. // // 最后插入图片
  444. // insertFn(
  445. // "http://" + res.Location,
  446. // file.name,
  447. // "http://" + res.Location
  448. // );
  449. // } else {
  450. // }
  451. // });
  452. },
  453. // 富文本编辑器
  454. onCreated(editor) {
  455. this.editor = Object.seal(editor); // 一定要用 Object.seal() ,否则会报错
  456. },
  457. // tab栏跳转
  458. handleClick(tab, event) {
  459. this.activeName = tab.name;
  460. this.listQuery.current = 1;
  461. this.list = [];
  462. if (this.activeName == 0) {
  463. this.listQuery.msgStas = 0;
  464. } else {
  465. this.listQuery.msgStas = 1;
  466. }
  467. this.getData();
  468. },
  469. // 重置页面
  470. reset() {
  471. this.listQuery.msgType = "";
  472. this.listQuery.msgTitle = "";
  473. this.getData();
  474. },
  475. //获取列表数据
  476. getData(type) {
  477. if (type == "search") {
  478. this.listQuery.current = 1;
  479. }
  480. this.listLoading = true;
  481. getNotice(this.listQuery)
  482. .then((response) => {
  483. this.list = response.data.records;
  484. this.total = response.data.total;
  485. this.listLoading = false;
  486. })
  487. .catch((err) => {
  488. this.listLoading = false;
  489. });
  490. },
  491. //提交表单数据
  492. commitData(type) {
  493. if (this.temp.forAll == "1") {
  494. delete this.temp.receiveUser;
  495. delete this.temp.receiveRole;
  496. } else {
  497. if (this.temp.receiveUser.length == 0 && this.temp.receiveRole == 0) {
  498. this.$message({
  499. message: "请选择接收用户或者角色",
  500. type: "info"
  501. });
  502. return false;
  503. }
  504. }
  505. this.$refs["dataForm"].validate((valid) => {
  506. if (valid) {
  507. this.$confirm("确认提交", "提示", {
  508. confirmButtonText: "确定",
  509. cancelButtonText: "取消",
  510. type: "warning"
  511. }).then(() => {
  512. this.temp.msgStas = type;
  513. if (this.dialogStatus === "create") {
  514. addNotice(this.temp).then((response) => {
  515. this.$message({
  516. message: "操作成功",
  517. type: "success"
  518. });
  519. this.dialogFormVisible = false;
  520. this.getData();
  521. });
  522. } else {
  523. editNotice(this.temp).then((response) => {
  524. this.$message({
  525. message: "操作成功",
  526. type: "success"
  527. });
  528. this.dialogFormVisible = false;
  529. this.getData();
  530. });
  531. }
  532. });
  533. }
  534. });
  535. },
  536. // 打开添加/修改对话框
  537. handleAddOrEdit(index, row, type) {
  538. this.temp = {};
  539. this.noticeDetail = {};
  540. //修改对话框
  541. if (type === "update") {
  542. getNoticeDetail({ id: row.id })
  543. .then((response) => {
  544. this.noticeDetail = response.data;
  545. this.temp = {
  546. id: row.id,
  547. msgTitle: this.noticeDetail.msgTitle,
  548. mainText: this.noticeDetail.mainText,
  549. msgType: this.noticeDetail.msgType,
  550. msgPubder: this.noticeDetail.msgPubdUser,
  551. forAll: this.noticeDetail.forAll + "",
  552. receiveUser: this.noticeDetail.receiveUser,
  553. receiveRole: this.noticeDetail.receiveRole
  554. };
  555. })
  556. .catch((err) => {});
  557. } else {
  558. this.temp = {
  559. id: "",
  560. msgTitle: "",
  561. msgType: "",
  562. msgPubder: "",
  563. mainText: "",
  564. receiveUser: [],
  565. receiveRole: [],
  566. forAll: "1"
  567. };
  568. }
  569. this.dialogStatus = type;
  570. this.dialogFormVisible = true;
  571. this.$nextTick(() => {
  572. this.$refs["dataForm"].clearValidate();
  573. });
  574. },
  575. //删除
  576. handleDelete(row, status) {
  577. this.$confirm("确认删除", "提示", {
  578. confirmButtonText: "确定",
  579. cancelButtonText: "取消",
  580. type: "warning"
  581. }).then(() => {
  582. this.temp = {
  583. msgIds: [row.id]
  584. };
  585. delNotice(this.temp).then((response) => {
  586. this.$message({
  587. message: "操作成功",
  588. type: "success"
  589. });
  590. // 解决element el-pagination分页最后一页数据清空了页码显示正确,但是列表为空
  591. const totalPage = Math.ceil((this.total - 1) / this.listQuery.size);
  592. const currentPage =
  593. this.listQuery.current > totalPage
  594. ? totalPage
  595. : this.listQuery.current;
  596. this.listQuery.current = currentPage < 1 ? 1 : currentPage;
  597. this.getData();
  598. });
  599. });
  600. }
  601. }
  602. };
  603. </script>
  604. <style src="@wangeditor/editor/dist/css/style.css"></style>
  605. <style scoped type="scss">
  606. .textarea-box {
  607. float: left;
  608. box-sizing: border-box;
  609. border-radius: 4px;
  610. background-color: #f5f7fa;
  611. border: 1px solid #dfe4ed;
  612. color: #c0c4cc;
  613. padding: 0px 15px;
  614. width: 1100px;
  615. min-height: 30px;
  616. margin-right: 5px;
  617. }
  618. </style>