msg_board.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. <template>
  2. <view class="board">
  3. <view class="tab flexS">
  4. <view @click="choose(0)" :class="tabType == 0 ? 'active' : ''" style="margin-right:30rpx;">精选留言</view>
  5. <view @click="choose(1)" :class="tabType == 1 ? 'active' : ''">{{ userInfo.type == 1 ? '全部留言' : '个人留言' }}</view>
  6. </view>
  7. <view class="board_list" v-for="(item, index) in msgList" :key="item.id">
  8. <view class="top">
  9. <view class="flexS">
  10. <image :src="item.get_user.avatar ? item.get_user.avatar : userInfo.avatar"></image>
  11. <view>
  12. <view class="nickname flexS">
  13. <text>{{ item.get_user.nickname ? item.get_user.nickname : userInfo.nickname | getName }}</text>
  14. <view v-if="item.is_wonderful == 1" class="best">精选</view>
  15. <view v-if="item.is_top == 1" class="best">置顶</view>
  16. </view>
  17. <view class="time">{{ item.created_at | timeFormat }}</view>
  18. </view>
  19. </view>
  20. <view class="del" @click="userInfo.type == 1 ? setMsg(item.$orig) : delMsg(item.$orig.id)">
  21. <text v-if="userInfo.type == 1">设置</text>
  22. <text v-if="userInfo.type == 0">{{ tabType == 1 ? '删除' : '' }}</text>
  23. </view>
  24. </view>
  25. <view class="con">{{ item.content }}</view>
  26. <view class="reply_btn flexB" v-if="!item.get_message_reply && userInfo.type == 1">
  27. <input type="text" placeholder="回复一句吧~" v-model="item.replayCon" />
  28. <view @click="replyMsg(item.id, item.replayCon)">回复</view>
  29. </view>
  30. <view class="bottom" v-if="item.get_message_reply">
  31. <image src="../../static/imgs/logo.png"></image>
  32. <view>
  33. <view class="nickname" style="color:#F44545;">大卫博士</view>
  34. <view>
  35. <view class="time">{{ item.get_message_reply.created_at | timeFormat }}</view>
  36. <view class="con">{{ item.get_message_reply.content }}</view>
  37. </view>
  38. </view>
  39. </view>
  40. </view>
  41. <view class="no_msg" v-if="noMsg">
  42. <image src="../../static/no_msg.png"></image>
  43. <view>目前还没有留言哦~</view>
  44. <view class="go_msg" @click="goMsg" v-if="userInfo.type == 0">去留言</view>
  45. </view>
  46. <view class="msg_btn flexC" v-if="!noMsg && userInfo.type == 0"><view @click="goMsg" class="go_msg">去留言</view></view>
  47. </view>
  48. </template>
  49. <script>
  50. import { lookMsg, putMsg, replyMsg, manageMsg, deleteMsg, wonderfulMsg, isWonderful, isTop, cancelWonderful, cancelTop } from '../../api/msg.js';
  51. export default {
  52. data() {
  53. return {
  54. noMsg: false, //没有留言状态显示
  55. replyCon: '', //回复留言内容
  56. msgList: '', //留言列表
  57. userInfo: {},
  58. tabType: '', // 个人留言,精选留言切换
  59. timer: null, //toast定时器
  60. page: 1, //当前页面
  61. totalPage: '' //总页数
  62. };
  63. },
  64. onLoad(options) {
  65. if (options.tabType) {
  66. this.tabType = options.tabType;
  67. }
  68. },
  69. onShow() {
  70. this.userInfo = uni.getStorageSync('userInfo');
  71. this.page = 1;
  72. this.msgState();
  73. this.goTop();
  74. },
  75. filters: {
  76. timeFormat(times) {
  77. var timearr = times
  78. .replace(' ', ':')
  79. .replace(/\:/g, '-')
  80. .split('-');
  81. let time = '';
  82. if (new Date(times).toDateString() === new Date().toDateString()) {
  83. time = '今天' + ' ' + timearr[3] + ':' + timearr[4];
  84. } else {
  85. time = timearr[0] + '/' + timearr[1] + '/' + timearr[2] + ' ' + timearr[3] + ':' + timearr[4];
  86. }
  87. return time;
  88. },
  89. getName(name) {
  90. if (name) {
  91. return name.length > 10 ? name.slice(0, 10) + '...' : name;
  92. }
  93. return '';
  94. }
  95. },
  96. beforeDestroy() {
  97. clearInterval(this.timer);
  98. this.timer = null;
  99. },
  100. onReachBottom() {
  101. this.getMore();
  102. },
  103. methods: {
  104. goTop() {
  105. // 一键回到顶部
  106. if (uni.pageScrollTo) {
  107. uni.pageScrollTo({
  108. scrollTop: 0
  109. });
  110. }
  111. },
  112. //管理员设置留言
  113. setMsg(item) {
  114. let item1 = '';
  115. let item2 = '';
  116. if (item.is_wonderful == 1) {
  117. item1 = '取消精选(对所有人不可见)';
  118. } else {
  119. item1 = '设为精选(对所与人可见)';
  120. }
  121. if (item.is_top == 1) {
  122. item2 = '取消置顶';
  123. } else {
  124. item2 = '置顶';
  125. }
  126. uni.showActionSheet({
  127. itemList: [item1, item2, '删除'],
  128. success: res => {
  129. if (res.tapIndex == 0) {
  130. let http = '';
  131. let hint = '';
  132. if (item1 == '取消精选(对所有人不可见)') {
  133. http = cancelWonderful;
  134. hint = '取消精选成功';
  135. } else {
  136. http = isWonderful;
  137. hint = '设为精选成功';
  138. }
  139. http({ id: item.id }).then(res => {
  140. console.log(res);
  141. if (res.code == 200) {
  142. uni.showToast({
  143. title: hint,
  144. icon: 'none',
  145. duration: 2000,
  146. mask: true,
  147. success: res => {
  148. this.timer = setTimeout(res => {
  149. this.tabType = 0;
  150. this.getMsg();
  151. }, 2000);
  152. }
  153. });
  154. } else {
  155. console.log(res);
  156. uni.showModal({
  157. content: res.message,
  158. showCancel: false
  159. });
  160. }
  161. });
  162. return false;
  163. }
  164. if (res.tapIndex == 1) {
  165. let topHttp = '';
  166. let hint1 = '';
  167. if (item2 == '取消置顶') {
  168. topHttp = cancelTop;
  169. hint1 = '取消置顶成功';
  170. } else {
  171. topHttp = isTop;
  172. hint1 = '留言置顶成功';
  173. }
  174. topHttp({ id: item.id }).then(res => {
  175. if (res.code == 200) {
  176. uni.showToast({
  177. title: hint1,
  178. icon: 'none'
  179. });
  180. } else {
  181. uni.showModal({
  182. content: res.message || '留言置顶失败',
  183. showCancel: false
  184. });
  185. }
  186. });
  187. return false;
  188. }
  189. if (res.tapIndex == 2) {
  190. this.delMsg(item.id);
  191. }
  192. },
  193. fail: function(res) {
  194. console.log(res.errMsg);
  195. }
  196. });
  197. },
  198. //用户删除留言
  199. delMsg(id) {
  200. uni.showModal({
  201. title: '删除留言',
  202. content: '您确定要删除此条留言吗?',
  203. success: res => {
  204. if (res.confirm) {
  205. deleteMsg({ id }).then(res => {
  206. if (res.code == 200) {
  207. uni.showToast({
  208. title: '删除留言成功',
  209. icon: 'none',
  210. duration: 2000,
  211. mask: true,
  212. success: res => {
  213. this.timer = setTimeout(res => {
  214. uni.hideToast();
  215. this.msgState();
  216. }, 2000);
  217. }
  218. });
  219. } else {
  220. uni.showModal({
  221. content: res.message || '删除留言失败',
  222. showCancel: false
  223. });
  224. }
  225. });
  226. }
  227. }
  228. });
  229. },
  230. msgState(isMore) {
  231. if (this.tabType == 0) {
  232. this.getMsg(isMore);
  233. return false;
  234. }
  235. if (this.tabType == 1 && this.userInfo.type == 1) {
  236. this.getManagMsg(isMore);
  237. } else {
  238. this.getUserMsg(isMore);
  239. }
  240. },
  241. getMsg(isMore) {
  242. wonderfulMsg({ page: this.page }).then(res => {
  243. if (res.code == 200) {
  244. this.totalPage = Math.ceil(res.data.total / 20);
  245. if (isMore) {
  246. this.msgList = this.msgList.concat(res.data.list);
  247. } else {
  248. if (res.data.list.length == 0) {
  249. this.msgList = '';
  250. this.noMsg = true;
  251. return false;
  252. }
  253. this.noMsg = false;
  254. this.msgList = res.data.list;
  255. }
  256. } else {
  257. uni.showModal({
  258. content: res.message || '获取留言失败',
  259. showCancel: false
  260. });
  261. }
  262. });
  263. },
  264. //用户看到的留言列表
  265. getUserMsg(isMore) {
  266. lookMsg({ page: this.page }).then(res => {
  267. if (res.code == 200) {
  268. this.totalPage = Math.ceil(res.data.total / 20);
  269. if (isMore) {
  270. this.msgList = this.msgList.concat(res.data.list);
  271. } else {
  272. if (res.data.list.length == 0) {
  273. this.msgList = '';
  274. this.noMsg = true;
  275. return false;
  276. }
  277. this.noMsg = false;
  278. this.msgList = res.data.list;
  279. }
  280. } else {
  281. uni.showModal({
  282. content: res.message || '获取留言失败',
  283. showCancel: false
  284. });
  285. }
  286. });
  287. },
  288. //管理员看到的留言列表
  289. getManagMsg(isMore) {
  290. manageMsg({ page: this.page }).then(res => {
  291. if (res.code == 200) {
  292. this.noMsg = false;
  293. this.totalPage = Math.ceil(res.data.total / 20);
  294. let list = res.data.list;
  295. if (isMore) {
  296. list = this.msgList.concat(res.data.list);
  297. } else {
  298. if (res.data.list.length == 0) {
  299. this.msgList = '';
  300. this.noMsg = true;
  301. return false;
  302. }
  303. this.noMsg = false;
  304. list = res.data.list;
  305. }
  306. list.map(i => {
  307. this.$set(i, 'inpVal', '');
  308. });
  309. this.msgList = list;
  310. } else {
  311. uni.showModal({
  312. content: res.message || '获取留言失败',
  313. showCancel: false
  314. });
  315. }
  316. });
  317. },
  318. //获取更多留言列表
  319. getMore() {
  320. if (this.page > this.totalPage) {
  321. uni.showToast({
  322. title: '没有更多啦~',
  323. icon: 'none'
  324. });
  325. return false;
  326. }
  327. this.page++;
  328. this.msgState(true);
  329. },
  330. /*
  331. * 精选 和 个人(全部)切换
  332. * type 0 精选 1 个人(全部)
  333. */
  334. choose(cur) {
  335. this.msgList = [];
  336. this.tabType = cur;
  337. this.page = 1;
  338. let { type } = this.userInfo;
  339. if (cur == 0) {
  340. //精选接口
  341. this.getMsg();
  342. return false;
  343. }
  344. if (cur == 1 && type == 1) {
  345. this.getManagMsg();
  346. return false;
  347. }
  348. if (cur == 1 && type == 0) {
  349. this.getUserMsg();
  350. }
  351. },
  352. goMsg() {
  353. uni.navigateTo({
  354. url: '../message/message'
  355. });
  356. },
  357. //回复留言
  358. replyMsg(id, content) {
  359. console.log(content);
  360. if (!content) {
  361. uni.showModal({
  362. content: '请先输入回复内容',
  363. showCancel: false
  364. });
  365. return false;
  366. }
  367. replyMsg({
  368. id,
  369. content
  370. }).then(res => {
  371. if (res.code == 200) {
  372. uni.showToast({
  373. title: '回复留言成功',
  374. showCancel: false,
  375. duration: 2000,
  376. mask: true,
  377. success: res => {
  378. this.timer = setTimeout(res => {
  379. uni.hideToast();
  380. this.msgState();
  381. }, 2000);
  382. }
  383. });
  384. this.replyCon = '';
  385. } else {
  386. uni.showModal({
  387. content: res.message || '回复留言失败',
  388. showCancel: false
  389. });
  390. }
  391. });
  392. }
  393. }
  394. };
  395. </script>
  396. <style lang="scss" scoped>
  397. .board {
  398. width: 100%;
  399. min-height: 100%;
  400. position: relative;
  401. padding-bottom: 150rpx;
  402. .tab {
  403. width: 690rpx;
  404. margin: 30rpx auto;
  405. view {
  406. font-size: 28rpx;
  407. color: #999;
  408. }
  409. .active {
  410. font-size: 32rpx;
  411. color: #333;
  412. font-weight: bold;
  413. &::after {
  414. content: '';
  415. display: block;
  416. margin-top: 5rpx;
  417. width: 42rpx;
  418. height: 8rpx;
  419. background: linear-gradient(90deg, #f97c55 0%, #f44545 100%);
  420. opacity: 1;
  421. border-radius: 4rpx;
  422. }
  423. }
  424. }
  425. .board_list {
  426. width: 690rpx;
  427. margin: 30rpx auto 0;
  428. padding: 30rpx;
  429. box-sizing: border-box;
  430. background-color: #fff;
  431. border-radius: 24rpx;
  432. .nickname {
  433. font-size: 28rpx;
  434. color: #333;
  435. }
  436. .time {
  437. font-size: 24rpx;
  438. color: #999;
  439. margin-top: 5rpx;
  440. }
  441. .con {
  442. margin: 20rpx 0;
  443. font-size: 28rpx;
  444. color: #333;
  445. }
  446. .top {
  447. display: flex;
  448. align-items: flex-start;
  449. justify-content: space-between;
  450. .best {
  451. width: 60rpx;
  452. text-align: center;
  453. height: 32rpx;
  454. line-height: 32rpx;
  455. font-size: 20rpx;
  456. border: 1rpx solid #f44545;
  457. margin-left: 15rpx;
  458. color: #f44545;
  459. border-radius: 4rpx;
  460. }
  461. image {
  462. width: 72rpx;
  463. height: 72rpx;
  464. margin-right: 15rpx;
  465. border-radius: 50%;
  466. }
  467. .del {
  468. font-size: 28rpx;
  469. color: #999;
  470. }
  471. }
  472. .reply_btn {
  473. height: 70rpx;
  474. margin: 30rpx 0;
  475. input {
  476. width: 80%;
  477. height: 100%;
  478. background: #f8f8f8;
  479. border-radius: 36rpx;
  480. padding-left: 25rpx;
  481. }
  482. view {
  483. width: 120rpx;
  484. text-align: center;
  485. height: 62rpx;
  486. line-height: 62rpx;
  487. background: linear-gradient(141deg, #f97c55 0%, #f44545 100%);
  488. opacity: 1;
  489. border-radius: 34rpx;
  490. color: #fff;
  491. }
  492. }
  493. .bottom {
  494. display: flex;
  495. justify-content: flex-start;
  496. align-items: flex-start;
  497. image {
  498. width: 48rpx;
  499. height: 48rpx;
  500. flex-shrink: 0;
  501. margin-right: 15rpx;
  502. }
  503. .reply {
  504. font-size: 28rpx;
  505. color: #999;
  506. }
  507. }
  508. }
  509. .no_msg {
  510. width: 100%;
  511. text-align: center;
  512. margin-top: 116rpx;
  513. image {
  514. width: 484rpx;
  515. height: 350rpx;
  516. }
  517. view:nth-child(2) {
  518. font-size: 28rpx;
  519. color: #333;
  520. margin: 30rpx 0 80rpx;
  521. }
  522. }
  523. .go_msg {
  524. width: 460rpx;
  525. margin: 0 auto;
  526. text-align: center;
  527. height: 88rpx;
  528. line-height: 88rpx;
  529. background: linear-gradient(93deg, #f97c55 0%, #f44545 100%);
  530. opacity: 1;
  531. border-radius: 44rpx;
  532. color: #fff;
  533. font-size: 32rpx;
  534. }
  535. .msg_btn {
  536. position: fixed;
  537. left: 0;
  538. bottom: 0;
  539. width: 100%;
  540. height: 108rpx;
  541. background-color: #fff;
  542. z-index: 999;
  543. }
  544. }
  545. </style>