list.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <template>
  2. <div class="tab6_list">
  3. <div class="left">
  4. <ul>
  5. <li
  6. :class="{ active: formData.type === item.type }"
  7. v-for="item in listData"
  8. :key="item.id"
  9. @click="cutTab(item)"
  10. >
  11. <p v-if="formData.type === item.type">
  12. ◆&emsp;{{ item.name }}&emsp;◆
  13. </p>
  14. <p v-else>{{ item.name }}</p>
  15. <span> {{ item.biaoshi }} </span>
  16. </li>
  17. </ul>
  18. </div>
  19. <!-- 下部内容 -->
  20. <div class="conten">
  21. <h1>
  22. 公告/置顶
  23. <div class="con_tit_post" @click="rollBottom">发帖</div>
  24. </h1>
  25. <div class="con_list">
  26. <div class="con_tit">
  27. <div class="con_tit_one">标题</div>
  28. <div class="con_tit_tow">作者</div>
  29. <div class="con_tit_three">回复数</div>
  30. <div class="con_tit_four">最后发表</div>
  31. </div>
  32. <div class="hint" v-if="data.length===0">暂 无 数 据</div>
  33. <template v-else>
  34. <div
  35. class="con_tit con_tit2"
  36. v-for="item in data"
  37. :key="item.id"
  38. @click="skip(item)"
  39. >
  40. <div class="con_tit_one" :title="item.title">
  41. {{ item.title }}
  42. </div>
  43. <div class="con_tit_tow" :title="item.creatorName">
  44. {{ item.creatorName }}
  45. </div>
  46. <div class="con_tit_three" :title="item.reply">
  47. {{ item.reply ? item.reply : 0 }}
  48. </div>
  49. <div
  50. class="con_tit_four"
  51. :title="`${item.replyName ? item.replyName : item.creatorName} ${
  52. item.replyTime ? item.replyTime : item.updateTime
  53. }`"
  54. >
  55. {{
  56. item.replyName
  57. ? item.replyName.length > 5
  58. ? item.replyName.substring(0, 5) + "..."
  59. : item.replyName
  60. : item.creatorName.length > 5
  61. ? item.creatorName.substring(0, 5) + "..."
  62. : item.creatorName
  63. }}
  64. {{
  65. item.replyTime
  66. ? item.replyTime.substring(0, 10)
  67. : item.updateTime.substring(0, 10)
  68. }}
  69. </div>
  70. </div>
  71. </template>
  72. </div>
  73. <!-- 分页 -->
  74. <div class="paging">
  75. <el-pagination
  76. layout="prev,pager,next,jumper"
  77. :total="total"
  78. :page-size="5"
  79. :current-page="formData.pageNum"
  80. @current-change="currentChange"
  81. @size-change="sizeChange"
  82. >
  83. </el-pagination>
  84. </div>
  85. <!-- 底部富文本盒子 -->
  86. <div class="rickText">
  87. <div class="txtTit">发表新帖</div>
  88. <div class="inputR">
  89. <el-select
  90. v-model="selectType"
  91. placeholder="请选择主题分类"
  92. style="width: 400px"
  93. >
  94. <el-option label="点赞箱" value="scene"></el-option>
  95. <el-option label="战友情" value="school"></el-option>
  96. <el-option label="敢为先" value="goods"></el-option>
  97. </el-select>
  98. <el-input
  99. style="margin-left: 20px"
  100. type="text"
  101. placeholder="标题不能超过30字"
  102. v-model="title"
  103. maxlength="30"
  104. show-word-limit
  105. >
  106. </el-input>
  107. <!-- 上传图片 -->
  108. <el-upload
  109. accept=".png,.jpg,.jpeg,.gif"
  110. title="上传图片"
  111. class="upload-demo imgUplod"
  112. :action="baseURL + '/web/bbs/upload'"
  113. multiple
  114. :before-upload="beforethumbUploadImg"
  115. :on-success="upload_thumb_successImg"
  116. >
  117. <i class="w-e-icon-image"></i>
  118. </el-upload>
  119. </div>
  120. <!-- 富文本 -->
  121. <div id="div1" style="z-index: 1"></div>
  122. <!-- 按钮 -->
  123. <div class="txtBtn">
  124. <div>
  125. <span class="txtBtn_tit">请填写您的姓名</span>
  126. <el-input
  127. style="width: 300px"
  128. type="text"
  129. placeholder="请输入姓名"
  130. v-model="creatorName"
  131. maxlength="8"
  132. show-word-limit
  133. >
  134. </el-input>
  135. </div>
  136. <el-button type="primary" style="width: 120px" @click="publish"
  137. >发 表</el-button
  138. >
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. </template>
  144. <script>
  145. import { webBbsSave, webBbsList } from "@/utils/api";
  146. import E from "wangeditor";
  147. import axios from "@/utils/request";
  148. export default {
  149. name: "tab6_list",
  150. components: {},
  151. data() {
  152. //这里存放数据
  153. return {
  154. data: [],
  155. total: 0,
  156. listData: [
  157. { biaoshi: "/", id: 1, name: "点赞箱", type: "scene" },
  158. { biaoshi: "/", id: 2, name: "战友情", type: "school" },
  159. { biaoshi: "", id: 3, name: "敢为先", type: "goods" },
  160. ],
  161. formData: {
  162. bbsType: "topic",
  163. status: 2,
  164. pageNum: 1,
  165. pageSize: 5,
  166. type: "scene",
  167. },
  168. // 有关富文本
  169. selectType: "scene",
  170. title: "",
  171. creatorName: "",
  172. };
  173. },
  174. //监听属性 类似于data概念
  175. computed: {},
  176. //监控data中的数据变化
  177. watch: {},
  178. //方法集合
  179. methods: {
  180. // 点击上部的发帖滚动到底部
  181. rollBottom() {
  182. window.scrollTo({ top: 1000, behavior: "smooth" });
  183. },
  184. // 点击通知父组件切换 动态组件is的值,并且把数据传过去
  185. async skip(item) {
  186. this.$emit("cutComFn", item);
  187. },
  188. // 点击发表
  189. async publish() {
  190. if (this.creatorName.trim() === "") {
  191. return this.$message.warning("名字不能为空!");
  192. }
  193. if (this.title.trim() === "") {
  194. return this.$message.warning("标题不能为空!");
  195. }
  196. if (this.editor.txt.html() === "") {
  197. return this.$message.warning("内容不能为空");
  198. }
  199. let obj = {
  200. bbsType: "topic",
  201. content: this.editor.txt.html(),
  202. creatorName: this.creatorName,
  203. title: this.title,
  204. type: this.selectType,
  205. };
  206. let res = await webBbsSave(obj);
  207. if (res.code === 0) {
  208. this.title = this.creatorName = "";
  209. this.editor.txt.html("");
  210. this.$message.success("发帖成功,等待审核.");
  211. } else this.$message.warning(res.msg);
  212. },
  213. // 切换顶部tab栏
  214. cutTab(val) {
  215. if (this.formData.type === val.type) return;
  216. this.formData.pageNum = 1;
  217. this.formData.type = val.type;
  218. this.selectType = val.type;
  219. this.webBbsList(this.formData);
  220. },
  221. // 分页器方法
  222. currentChange(val) {
  223. // console.log('当前页改变了', val)
  224. this.formData.pageNum = val;
  225. this.webBbsList(this.formData);
  226. },
  227. sizeChange(val) {
  228. // console.log('条数改变了', val)
  229. this.formData.pageNum = 1;
  230. this.formData.pageSize = val;
  231. this.webBbsList(this.formData);
  232. },
  233. // 上传图片
  234. beforethumbUploadImg(file) {
  235. // console.log(998, file)
  236. // 限制图片大小和格式
  237. const sizeOk = file.size / 1024 / 1024 < 5;
  238. const typeOk =
  239. file.type === "image/png" ||
  240. (file.type === "image/jpeg" && !file.name.includes(".jfif")) ||
  241. file.type === "image/gif";
  242. return new Promise((resolve, reject) => {
  243. if (!typeOk) {
  244. this.$message.error("图片格式有误!");
  245. reject(file);
  246. } else if (!sizeOk) {
  247. this.$message.error("图片大小超过5M!");
  248. reject(file);
  249. } else if (file.name.length > 32) {
  250. this.$message.error("图片名字不能超过32个字!");
  251. reject(file);
  252. } else {
  253. resolve(file);
  254. }
  255. });
  256. },
  257. upload_thumb_successImg(data) {
  258. this.$message.success("上传成功");
  259. this.editor.txt.append(
  260. `<img src="${this.baseURL}${data.data.filePath}" style="max-width:100%;display: block;margin: 10px auto;"/><p>&emsp;&emsp;</p>`
  261. );
  262. },
  263. // 封装一个获取列表的方法
  264. async webBbsList(data) {
  265. let res = await webBbsList(data);
  266. this.total = res.data.total;
  267. this.data = res.data.records;
  268. },
  269. },
  270. //生命周期 - 创建完成(可以访问当前this实例)
  271. created() {
  272. // 获取服务器前缀地址
  273. this.baseURL = axios.defaults.baseURL;
  274. this.webBbsList(this.formData);
  275. },
  276. //生命周期 - 挂载完成(可以访问DOM元素)
  277. mounted() {
  278. // 初始化富文本
  279. // 富文本
  280. this.editor = new E("#div1");
  281. // 配置字体
  282. this.editor.config.fontNames = [
  283. "黑体",
  284. "仿宋",
  285. "楷体",
  286. "标楷体",
  287. "华文仿宋",
  288. "华文楷体",
  289. "宋体",
  290. "微软雅黑",
  291. "Arial",
  292. "Tahoma",
  293. "Verdana",
  294. "Times New Roman",
  295. ];
  296. this.editor.config.showLinkVideo = false;
  297. this.editor.create();
  298. },
  299. beforeCreate() {}, //生命周期 - 创建之前
  300. beforeMount() {}, //生命周期 - 挂载之前
  301. beforeUpdate() {}, //生命周期 - 更新之前
  302. updated() {}, //生命周期 - 更新之后
  303. beforeDestroy() {}, //生命周期 - 销毁之前
  304. destroyed() {}, //生命周期 - 销毁完成
  305. activated() {
  306. window.scrollTo({ top: 0 });
  307. }, //如果页面有keep-alive缓存功能,这个函数会触发
  308. };
  309. </script>
  310. <style lang='less' scoped>
  311. .tab6_list {
  312. width: 100%;
  313. height: 100%;
  314. display: flex;
  315. flex-direction: column;
  316. color: #3e3e3e;
  317. .left {
  318. position: relative;
  319. width: 100%;
  320. height: 200px;
  321. background: url("../../assets/img/tab6Tab.png");
  322. background-size: 100% 100%;
  323. ul {
  324. padding-left: 40px;
  325. display: flex;
  326. height: 100%;
  327. align-items: center;
  328. justify-content: center;
  329. li {
  330. display: flex;
  331. justify-content: center;
  332. font-size: 20px;
  333. color: #fff;
  334. width: 240px;
  335. cursor: pointer;
  336. &:hover {
  337. color: #f2cd83;
  338. }
  339. & > span {
  340. margin-left: 50px;
  341. color: #fff !important;
  342. }
  343. & > p {
  344. text-align: center;
  345. width: 145px;
  346. }
  347. }
  348. .active {
  349. color: #f2cd83;
  350. }
  351. }
  352. }
  353. .conten {
  354. flex: 1;
  355. width: 100%;
  356. padding: 20px 300px;
  357. background: url("../../assets/img/tabBg.png");
  358. background-size: 100% 100%;
  359. & > h1 {
  360. position: relative;
  361. color: #be1220;
  362. font-size: 24px;
  363. margin-bottom: 35px;
  364. .con_tit_post {
  365. font-weight: 400;
  366. font-size: 22px;
  367. text-align: center;
  368. line-height: 40px;
  369. width: 120px;
  370. height: 40px;
  371. background-color: #be1220;
  372. color: #fff;
  373. cursor: pointer;
  374. position: absolute;
  375. right: 10px;
  376. top: 0;
  377. }
  378. }
  379. .con_list {
  380. .hint {
  381. text-align: center;
  382. font-size: 36px;
  383. width: 100%;
  384. height: 100px;
  385. line-height: 100px;
  386. }
  387. .con_tit {
  388. display: flex;
  389. font-weight: 700;
  390. font-size: 26px;
  391. color: #3a3a3a;
  392. & > div {
  393. padding-right: 20px;
  394. text-align: center;
  395. overflow: hidden;
  396. text-overflow: ellipsis;
  397. white-space: nowrap;
  398. }
  399. .con_tit_one {
  400. padding-left: 10px;
  401. text-align: left;
  402. flex: 1;
  403. }
  404. .con_tit_tow {
  405. width: 150px;
  406. }
  407. .con_tit_three {
  408. width: 150px;
  409. }
  410. .con_tit_four {
  411. text-align: right;
  412. padding-right: 50px;
  413. width: 300px;
  414. }
  415. }
  416. .con_tit2 {
  417. font-weight: 400;
  418. & > div {
  419. cursor: pointer;
  420. height: 70px;
  421. line-height: 70px;
  422. font-size: 22px;
  423. border-bottom: 1px dashed #d5a6a6;
  424. }
  425. .con_tit_four {
  426. padding-right: 10px;
  427. }
  428. }
  429. }
  430. .paging {
  431. /deep/.el-input__inner {
  432. width: 30px;
  433. height: 30px !important;
  434. background-color: transparent;
  435. border-radius: 50%;
  436. }
  437. margin: 30px 0;
  438. }
  439. .rickText {
  440. width: 100%;
  441. background-color: #fcf7f4;
  442. padding: 20px;
  443. .txtTit {
  444. color: #3a3a3a;
  445. font-weight: 700;
  446. font-size: 20px;
  447. margin-bottom: 20px;
  448. }
  449. .inputR {
  450. display: flex;
  451. margin-bottom: 20px;
  452. position: relative;
  453. .imgUplod {
  454. /deep/.w-e-icon-image {
  455. color: #999;
  456. display: inline-block;
  457. width: 40px;
  458. height: 40px;
  459. line-height: 40px;
  460. }
  461. /deep/.el-upload-list {
  462. display: none !important;
  463. }
  464. display: flex;
  465. justify-content: center;
  466. align-items: center;
  467. cursor: pointer;
  468. position: absolute;
  469. z-index: 9999;
  470. top: 61px;
  471. right: 0px;
  472. width: 40px;
  473. height: 40px;
  474. &:hover {
  475. background-color: #f6f6f6;
  476. /deep/.w-e-icon-image {
  477. color: black;
  478. }
  479. }
  480. }
  481. }
  482. .txtBtn {
  483. color: #9c9c9c;
  484. display: flex;
  485. justify-content: space-between;
  486. margin-top: 20px;
  487. .txtBtn_tit {
  488. margin-right: 15px;
  489. position: relative;
  490. &::after {
  491. content: "*";
  492. position: absolute;
  493. right: -10px;
  494. top: -6px;
  495. color: red;
  496. }
  497. }
  498. }
  499. }
  500. }
  501. }
  502. </style>