notice.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. <template>
  2. <div
  3. class="pb_content"
  4. style="background: unset; height: 100%"
  5. v-loading="loading"
  6. >
  7. <div
  8. class="pb_content_body"
  9. style="
  10. background: #fff;
  11. padding: 0px 25px;
  12. box-sizing: border-box;
  13. border-radius: 5px;
  14. "
  15. >
  16. <div class="pb_head">
  17. <span>通知公告</span>
  18. <div class="student_button">
  19. <el-button
  20. type="primary"
  21. @click="dialogVisibleAdd = true"
  22. v-if="role == '1'"
  23. >新建通知</el-button
  24. >
  25. </div>
  26. </div>
  27. </div>
  28. <div class="pb_content_body" style="height: calc(100% - 100px)">
  29. <div class="noneBox" v-if="!tableData.length">
  30. <img src="../../../assets/icon/isNoMessage.png" />
  31. </div>
  32. <div class="n_noticeBox" v-else>
  33. <div class="left">
  34. <div class="title">通知内容</div>
  35. <div class="content">
  36. <div
  37. class="noticeContent"
  38. v-for="(item, index) in tableData"
  39. :key="index"
  40. @click="(res = item), (activeId = item.id)"
  41. :class="{ active: item.id == activeId }"
  42. >
  43. <div class="n_title">
  44. <span>{{ item.title }}</span>
  45. </div>
  46. <div class="n_content">{{ snippet(item.content) }}</div>
  47. <div class="n_time">{{ item.creatTime }}</div>
  48. </div>
  49. </div>
  50. </div>
  51. <div class="right">
  52. <div class="title">通知详情</div>
  53. <div class="content">
  54. <img src="../../../assets/icon/notice/noticeBg.png" alt="" />
  55. <div class="r_n_content">
  56. <div class="r_n_title">
  57. <div class="r_title">
  58. <span>{{ res.title }}</span>
  59. </div>
  60. <div class="r_time">
  61. <span></span><span>{{ res.creatTime }}</span>
  62. </div>
  63. </div>
  64. <div class="r_n_main">
  65. <div class="notice_content cont" v-html="res.content"></div>
  66. </div>
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. <el-dialog
  73. title="添加全站通知"
  74. :visible.sync="dialogVisibleAdd"
  75. width="700px"
  76. :before-close="handleClose"
  77. class="dialog_diy"
  78. center
  79. >
  80. <div>
  81. <div class="tian1">
  82. <span>通知标题</span>
  83. <el-input
  84. v-model="noticeTitle"
  85. style="width: 250px; margin: 15px 0px"
  86. placeholder="请输入通知标题"
  87. ></el-input>
  88. </div>
  89. <div class="tian1">
  90. <span>通知内容</span>
  91. <editor-bar v-model="detail" @change="change"></editor-bar>
  92. </div>
  93. </div>
  94. <span slot="footer" class="dialog-footer">
  95. <el-button type="primary" @click="addNotice">确认通知</el-button>
  96. <el-button @click="dialogVisibleAdd = false">取 消</el-button>
  97. </span>
  98. </el-dialog>
  99. </div>
  100. </template>
  101. <script>
  102. import EditorBar from "../../../components/tools/wangEnduit";
  103. export default {
  104. components: {
  105. EditorBar,
  106. },
  107. data() {
  108. return {
  109. tableHeight: "500px",
  110. page: 1,
  111. total: 0,
  112. loading: false,
  113. formLabelWidth: "100px",
  114. dialogVisible: false,
  115. dialogVisibleAdd: false,
  116. title: "",
  117. tableData: [],
  118. res: {},
  119. userid: this.$route.query.userid,
  120. oid: this.$route.query.oid,
  121. org: this.$route.query.org,
  122. role: this.$route.query.role,
  123. noticeTitle: "",
  124. detail: "",
  125. now: "",
  126. timer: null,
  127. activeId: "",
  128. };
  129. },
  130. mounted() {},
  131. beforeDestroy() {
  132. if (this.timer) {
  133. clearInterval(this.timer);
  134. this.timer = null;
  135. }
  136. },
  137. beforeRouteLeave(to, from, next) {
  138. if (this.timer) {
  139. clearInterval(this.timer);
  140. this.timer = null;
  141. }
  142. next();
  143. },
  144. methods: {
  145. tableRowClassName({ row, rowIndex }) {
  146. if ((rowIndex + 1) % 2 === 0) {
  147. return "even_row";
  148. } else {
  149. return "";
  150. }
  151. },
  152. snippet(str) {
  153. str = str.replace(/<\/?[^>]*>/g, ""); //去除HTML tag
  154. str = str.replace(/[ | ]*\n/g, "\n"); //去除行尾空白
  155. //str = str.replace(/\n[\s| | ]*\r/g,'\n'); //去除多余空行
  156. str = str.replace(/&nbsp;/gi, ""); //去掉&nbsp;
  157. return str;
  158. // return value.replace(/<[^>]*>/g, "");
  159. },
  160. tableRowClassName({ row, rowIndex }) {
  161. if ((rowIndex + 1) % 2 === 0) {
  162. return "even_row";
  163. } else {
  164. return "";
  165. }
  166. },
  167. handleCurrentChange(val) {
  168. this.page = val;
  169. this.getNews();
  170. },
  171. handleClose(done) {
  172. done();
  173. },
  174. getNewDetail(id) {
  175. this.dialogVisible = true;
  176. let params = { nid: id };
  177. this.ajax
  178. .get(this.$store.state.api + "selectNewDetail", params)
  179. .then((res) => {
  180. this.dialogVisible = true;
  181. this.res = res.data[0][0];
  182. })
  183. .catch((err) => {
  184. this.loading = false;
  185. });
  186. },
  187. getNews() {
  188. this.loading = true;
  189. let params = { uid: this.userid, oid: this.oid, org: this.org };
  190. this.ajax
  191. .get(this.$store.state.api + "selectNotice2", params)
  192. .then((res) => {
  193. this.loading = false;
  194. this.tableData = res.data[0];
  195. this.res = res.data[0][0];
  196. this.activeId = res.data[0][0].id;
  197. if (!this.timer) {
  198. this.timer = setInterval(() => {
  199. this.getNews2();
  200. }, 5000);
  201. }
  202. })
  203. .catch((err) => {
  204. this.loading = false;
  205. });
  206. },
  207. getNews2() {
  208. let params = { uid: this.userid, oid: this.oid, org: this.org };
  209. this.ajax
  210. .get(this.$store.state.api + "selectNotice2", params)
  211. .then((res) => {
  212. this.tableData = res.data[0];
  213. })
  214. .catch((err) => {
  215. this.loading = false;
  216. });
  217. },
  218. change(val) {
  219. console.log(val);
  220. },
  221. time() {
  222. if (!this.now) {
  223. this.now = new Date().getTime();
  224. return true;
  225. } else {
  226. let time = new Date().getTime();
  227. if (time - this.now > 3000) {
  228. this.now = time;
  229. return true;
  230. } else {
  231. return false;
  232. }
  233. }
  234. },
  235. //添加通知
  236. addNotice() {
  237. if (this.noticeTitle === "") {
  238. this.$message.error("请输入文章标题");
  239. return;
  240. } else if (this.detail === "") {
  241. this.$message.error("请输入文章内容");
  242. return;
  243. }
  244. if (this.time()) {
  245. let params = [
  246. {
  247. t: this.noticeTitle,
  248. nc: this.detail.replace(/%/g, "%25"),
  249. oid: this.oid,
  250. org: this.org,
  251. },
  252. ];
  253. this.ajax
  254. .post(this.$store.state.api + "addNotice", params)
  255. .then((res) => {
  256. this.$message({
  257. message: "添加成功",
  258. type: "success",
  259. });
  260. this.noticeTitle = "";
  261. this.detail = "";
  262. this.getNews();
  263. this.dialogVisibleAdd = false;
  264. })
  265. .catch((err) => {
  266. this.$message.error("添加失败");
  267. console.error(err);
  268. });
  269. }
  270. },
  271. },
  272. created() {
  273. this.getNews();
  274. },
  275. };
  276. </script>
  277. <style scoped>
  278. .pb_head {
  279. display: flex;
  280. justify-content: space-between;
  281. }
  282. .student_head {
  283. margin-bottom: 20px;
  284. }
  285. .student_search {
  286. display: flex;
  287. }
  288. .student_search > div:nth-child(1) {
  289. line-height: 35px;
  290. font-size: 14px;
  291. }
  292. .student_search >>> .el-input__inner {
  293. width: 190px;
  294. height: 35px;
  295. margin-left: 10px;
  296. }
  297. .student_table >>> .el-table--border td {
  298. border-right: 0px !important;
  299. }
  300. .header-title {
  301. display: flex;
  302. }
  303. .logoImg {
  304. width: 30px;
  305. }
  306. .logoImg > img {
  307. width: 100%;
  308. height: 100%;
  309. }
  310. .title_add_student {
  311. margin: 0 auto;
  312. color: #fff;
  313. }
  314. .dialog_diy >>> .el-dialog__header {
  315. background: #454545 !important;
  316. padding: 15px 20px;
  317. }
  318. .dialog_diy >>> .el-dialog__title {
  319. color: #fff;
  320. }
  321. .student_table >>> .el-table--border td {
  322. border-right: 0px !important;
  323. }
  324. .dialog_diy >>> .el-dialog__headerbtn {
  325. top: 19px;
  326. }
  327. .dialog_diy >>> .el-dialog__headerbtn .el-dialog__close {
  328. color: #fff;
  329. }
  330. .dialog_diy >>> .el-dialog__headerbtn .el-dialog__close:hover {
  331. color: #fff;
  332. }
  333. .notice_content {
  334. width: 100%;
  335. word-wrap: break-word;
  336. word-break: break-all;
  337. overflow: hidden;
  338. font-size: 16px;
  339. line-height: 31px;
  340. text-indent: 35px;
  341. }
  342. .close {
  343. width: 320px;
  344. height: 30px;
  345. line-height: 30px;
  346. font-size: 14px;
  347. background: #0e72e6;
  348. padding: 0 !important;
  349. }
  350. /* table 样式 */
  351. .cont >>> table {
  352. border-top: 1px solid #ccc;
  353. border-left: 1px solid #ccc;
  354. }
  355. .cont >>> table td,
  356. .cont >>> table th {
  357. border-bottom: 1px solid #ccc;
  358. border-right: 1px solid #ccc;
  359. padding: 3px 5px;
  360. }
  361. .cont >>> table th {
  362. border-bottom: 2px solid #ccc;
  363. text-align: center;
  364. }
  365. /* blockquote 样式 */
  366. .cont >>> blockquote {
  367. display: block;
  368. border-left: 8px solid #d0e5f2;
  369. padding: 5px 10px;
  370. margin: 10px 0;
  371. line-height: 1.4;
  372. font-size: 100%;
  373. background-color: #f1f1f1;
  374. }
  375. /* code 样式 */
  376. .cont >>> code {
  377. display: inline-block;
  378. *display: inline;
  379. *zoom: 1;
  380. background-color: #f1f1f1;
  381. border-radius: 3px;
  382. padding: 3px 5px;
  383. margin: 0 3px;
  384. }
  385. .cont >>> pre code {
  386. display: block;
  387. }
  388. /* ul ol 样式 */
  389. .cont >>> ul,
  390. ol {
  391. margin: 10px 0 10px 20px;
  392. }
  393. .el-table >>> .even_row {
  394. background-color: #f1f1f1;
  395. }
  396. .student_page {
  397. margin-top: 10px;
  398. }
  399. .pb_head {
  400. margin: 0 !important;
  401. width: 100% !important;
  402. }
  403. .student_table >>> .el-table,
  404. .student_table >>> .el-table__body-wrapper {
  405. height: auto !important;
  406. }
  407. .noneBox {
  408. height: 100%;
  409. width: 100%;
  410. background: rgb(242, 242, 242);
  411. display: flex;
  412. align-items: center;
  413. justify-content: center;
  414. }
  415. .noneBox img {
  416. width: 400px;
  417. }
  418. .n_noticeBox {
  419. height: 100%;
  420. width: 100%;
  421. display: flex;
  422. justify-content: space-between;
  423. }
  424. .n_noticeBox .left {
  425. width: 350px;
  426. height: 100%;
  427. }
  428. .n_noticeBox .left .title {
  429. background: rgb(241, 241, 241);
  430. width: 100%;
  431. font-weight: 700;
  432. color: rgb(153, 148, 143);
  433. text-align: center;
  434. height: 40px;
  435. line-height: 40px;
  436. border-radius: 5px;
  437. }
  438. .n_noticeBox .left .content {
  439. height: calc(100% - 50px);
  440. margin-top: 10px;
  441. background: #fff;
  442. border-radius: 5px;
  443. overflow: auto;
  444. }
  445. .n_noticeBox .right {
  446. width: calc(100% - 370px);
  447. }
  448. .n_noticeBox .right .title {
  449. background: rgb(241, 241, 241);
  450. width: 100%;
  451. font-weight: 700;
  452. color: rgb(153, 148, 143);
  453. text-align: center;
  454. height: 40px;
  455. line-height: 40px;
  456. border-top-left-radius: 5px;
  457. border-top-right-radius: 5px;
  458. }
  459. .n_noticeBox .right .content {
  460. height: calc(100% - 40px);
  461. background: #fff;
  462. border-bottom-left-radius: 5px;
  463. border-bottom-right-radius: 5px;
  464. position: relative;
  465. }
  466. .n_noticeBox .right .content > img {
  467. position: absolute;
  468. right: 20px;
  469. bottom: -30px;
  470. max-width: 100%;
  471. }
  472. .active {
  473. background: rgb(250, 250, 250) !important;
  474. }
  475. .noticeContent {
  476. padding: 15px 20px;
  477. cursor: pointer;
  478. }
  479. .noticeContent:hover {
  480. background: rgb(250, 250, 250) !important;
  481. }
  482. .noticeContent:nth-child(even) {
  483. background: rgb(247, 250, 255);
  484. }
  485. .n_title {
  486. width: 100%;
  487. display: flex;
  488. align-items: center;
  489. }
  490. .n_title span {
  491. overflow: hidden;
  492. text-overflow: ellipsis;
  493. word-break: break-all;
  494. white-space: nowrap;
  495. }
  496. .n_title::before {
  497. content: "";
  498. display: block;
  499. background-image: url(../../../assets/icon/notice/doi.png);
  500. min-width: 25px;
  501. height: 25px;
  502. background-size: 100% 100%;
  503. margin-right: 5px;
  504. margin-left: -5px;
  505. }
  506. .n_content {
  507. font-size: 14px;
  508. color: rgb(126, 126, 126);
  509. margin-top: 5px;
  510. line-height: 1.5;
  511. text-overflow: -o-ellipsis-lastline;
  512. overflow: hidden;
  513. text-overflow: ellipsis;
  514. display: -webkit-box;
  515. -webkit-line-clamp: 2;
  516. line-clamp: 2;
  517. -webkit-box-orient: vertical;
  518. }
  519. .n_time {
  520. font-size: 14px;
  521. color: rgb(61, 61, 61);
  522. margin-top: 5px;
  523. }
  524. .r_n_content {
  525. padding: 20px;
  526. height: 100%;
  527. width: 100%;
  528. box-sizing: border-box;
  529. }
  530. .r_n_title {
  531. }
  532. .r_title {
  533. font-size: 25px;
  534. display: flex;
  535. flex-direction: row;
  536. flex-wrap: nowrap;
  537. align-items: center;
  538. /* padding-bottom: 10px; */
  539. }
  540. .r_title::before {
  541. content: "";
  542. display: block;
  543. background-image: url(../../../assets/icon/notice/notice.png);
  544. min-width: 40px;
  545. height: 40px;
  546. background-size: 100% 100%;
  547. margin-right: 5px;
  548. margin-left: -5px;
  549. }
  550. .r_time {
  551. display: flex;
  552. font-size: 15px;
  553. align-items: center;
  554. color: rgb(61, 61, 61);
  555. }
  556. .r_time span:nth-child(1) {
  557. height: 1px;
  558. width: 100%;
  559. background: #eee;
  560. }
  561. .r_time span:nth-child(2) {
  562. min-width: fit-content;
  563. margin: 0 30px;
  564. }
  565. .r_n_main {
  566. height: calc(100% - 120px);
  567. width: 100%;
  568. overflow: auto;
  569. margin-top: 20px;
  570. padding: 0 20px;
  571. box-sizing: border-box;
  572. }
  573. </style>