index.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <template>
  2. <view class="page-container">
  3. <nav-bar title="我要留言"></nav-bar>
  4. <view class="content">
  5. <scroll-view
  6. :scroll-y="true"
  7. class="scroll-view"
  8. :refresher-threshold="80"
  9. :refresher-enabled="true"
  10. :refresher-triggered="isRefreshing"
  11. scroll-with-animation="true"
  12. @refresherrefresh="handleRefresh"
  13. @scrolltolower="loadMore">
  14. <view class="list" v-if="list.length">
  15. <view class="item-card" v-for="item in list" :key="item.messageId">
  16. <view class="text">{{ item.content }}</view>
  17. <view class="time">{{ item.createTime }}</view>
  18. <view>
  19. <view class="tag" :class="{ 'tag-danger': item.status == 2 }" v-if="setStatusText(item.status)">{{ setStatusText(item.status) }}</view>
  20. <view v-if="item.auditContent" class="audit-content">{{ item.auditContent }}</view>
  21. </view>
  22. <view class="buttons">
  23. <view class="button" @click="handleDelete(item)">删除</view>
  24. </view>
  25. </view>
  26. </view>
  27. <view class="empty" v-else>暂无留言内容</view>
  28. </scroll-view>
  29. </view>
  30. <c-modal :value="showConfirmModal" title="提示" @cancel="showConfirmModal = false" @confirm="deleteMessage">
  31. 您是否确定删除该留言?
  32. </c-modal>
  33. <c-modal :value="showModal" title="请留言" @cancel="showModal = false" @confirm="handleSubmit">
  34. <textarea
  35. v-model="message"
  36. placeholder="请提交您想要反馈的留言"
  37. class="textarea"
  38. placeholder-class="placeholder-class"
  39. maxlength="1000">
  40. </textarea>
  41. </c-modal>
  42. <view class="button-section">
  43. <view class="submit-btn" @click="showModal = true">我要留言</view>
  44. </view>
  45. </view>
  46. </template>
  47. <script>
  48. import navBar from '@/components/nav-bar/index.vue'
  49. import cModal from '@/components/c-modal.vue'
  50. export default {
  51. components: {
  52. navBar,
  53. cModal
  54. },
  55. data() {
  56. return {
  57. showConfirmModal: false,
  58. showModal: false,
  59. loading: false,
  60. updating: false,
  61. message: '',
  62. list: [],
  63. deleteMessageId: '',
  64. total: 0,
  65. page: 1,
  66. limit: 10,
  67. isRefreshing: false,
  68. }
  69. },
  70. watch: {
  71. showModal(value) {
  72. if (!value) {
  73. this.message = ''
  74. }
  75. }
  76. },
  77. onLoad() {
  78. if (this.$queue.getData('token')) {
  79. this.getList()
  80. }
  81. },
  82. methods: {
  83. // 设置状态文案
  84. setStatusText(value) {
  85. switch (value) {
  86. case 0:
  87. return '已留言'
  88. case 1:
  89. return '已采纳'
  90. case 2:
  91. return '不采纳'
  92. }
  93. return ''
  94. },
  95. // 获取留言数据
  96. getList() {
  97. if (this.loading) return
  98. this.loading = true
  99. uni.showLoading({ title: '加载中' })
  100. this.$Request
  101. .getT('/app/messageBoard/selectMessageBoardList', {
  102. page: this.page,
  103. limit: this.limit
  104. })
  105. .then(res => {
  106. if (res.code === 0) {
  107. this.list = this.page == 1 ? res.data.records : [...this.list, ...res.data.records],
  108. this.total = res.data.total
  109. }
  110. })
  111. .finally(() => {
  112. this.isRefreshing = false
  113. this.loading = false
  114. uni.hideLoading()
  115. })
  116. },
  117. handleDelete(item) {
  118. this.deleteMessageId = item.messageId
  119. this.showConfirmModal = true
  120. },
  121. // 删除留言
  122. deleteMessage() {
  123. if (this.updating) return
  124. this.updating = true
  125. uni.showLoading({ title: '删除中' })
  126. this.$Request
  127. .getT('/app/messageBoard/deleteMessageBoard', {
  128. messageBoardId: this.deleteMessageId
  129. })
  130. .then(res => {
  131. if (res.code === 0) {
  132. this.$queue.showToast('删除成功')
  133. this.showConfirmModal = false
  134. this.page = 1
  135. this.getList()
  136. }
  137. })
  138. .finally(() => {
  139. this.updating = false
  140. uni.hideLoading()
  141. })
  142. },
  143. // 提交留言
  144. handleSubmit() {
  145. if (this.updating) return
  146. if (!this.message) {
  147. this.$queue.showToast('请输入留言内容')
  148. return
  149. }
  150. this.updating = true
  151. uni.showLoading({ title: '留言中' })
  152. this.$Request
  153. .postJson('/app/messageBoard/updateMessageBoard', {
  154. messageId: '',
  155. content: this.message
  156. })
  157. .then(res => {
  158. if (res.code == 0) {
  159. this.$queue.showToast('留言成功')
  160. this.showModal = false
  161. this.page = 1
  162. this.getList()
  163. }
  164. })
  165. .finally(() => {
  166. this.updating = false
  167. uni.hideLoading()
  168. })
  169. },
  170. // 刷新
  171. handleRefresh() {
  172. if (this.isRefreshing) return
  173. this.isRefreshing = true
  174. this.page = 1
  175. this.getList()
  176. },
  177. // 加载更多
  178. loadMore() {
  179. if (this.loading || this.list.length >= this.total) return
  180. this.page++
  181. this.getList()
  182. }
  183. }
  184. }
  185. </script>
  186. <style lang="scss" scoped>
  187. @import '@/common.scss';
  188. .page-container {
  189. display: flex;
  190. flex-direction: column;
  191. justify-content: space-between;
  192. height: 100vh;
  193. font-family: DM Sans;
  194. font-style: Regular;
  195. .content {
  196. flex: 1;
  197. padding: 0 40rpx;
  198. overflow: hidden;
  199. .scroll-view {
  200. width: 100%;
  201. height: 100%;
  202. }
  203. .list {
  204. padding: 20rpx 0;
  205. }
  206. .item-card {
  207. padding: 16rpx 36rpx;
  208. box-sizing: border-box;
  209. border: 1px solid rgba(227, 231, 236, 1);
  210. border-radius: 6px;
  211. background: rgba(255, 255, 255, 1);
  212. margin-bottom: 20rpx;
  213. .text {
  214. color: rgba(23, 23, 37, 1);
  215. font-size: 28rpx;
  216. font-weight: 400;
  217. line-height: 44rpx;
  218. margin-bottom: 8rpx;
  219. word-break: break-all;
  220. }
  221. .time {
  222. color: rgba(156, 164, 171, 1);
  223. font-size: 20rpx;
  224. font-weight: 400;
  225. line-height: 40rpx;
  226. }
  227. .tag {
  228. display: inline-block;
  229. padding: 8rpx;
  230. border-radius: 8rpx;
  231. background: rgba(1, 107, 246, 0.1);
  232. color: rgba(1, 107, 246, 1);
  233. font-size: 20rpx;
  234. font-weight: 400;
  235. line-height: 1;
  236. margin: 8rpx 0;
  237. }
  238. .tag-danger {
  239. color: rgba(237, 66, 69, 1);
  240. background: rgba(255, 246, 247, 1);
  241. }
  242. .audit-content {
  243. color: #999;
  244. font-size: 24rpx;
  245. margin-bottom: 12rpx;
  246. word-wrap: break-word;
  247. }
  248. .button {
  249. width: 190rpx;
  250. height: 60rpx;
  251. border: 1px solid rgba(232, 232, 232, 1);
  252. border-radius: 60rpx;
  253. text-align: center;
  254. line-height: 58rpx;
  255. color: rgba(153, 153, 153, 1);
  256. font-size: 24rpx;
  257. font-weight: 500;
  258. }
  259. }
  260. .empty {
  261. padding: 50rpx;
  262. text-align: center;
  263. color: #999;
  264. }
  265. }
  266. .textarea {
  267. width: 100%;
  268. box-sizing: border-box;
  269. border: 1px solid rgba(242, 242, 242, 1);
  270. border-radius: 6px;
  271. background: rgba(250, 250, 250, 1);
  272. padding: 26rpx 20rpx;
  273. font-size: 28rpx;
  274. line-height: 40rpx;
  275. color: rgba(158, 161, 168, 1);
  276. }
  277. .placeholder-class {
  278. color: rgba(158, 161, 168, 1);
  279. }
  280. }
  281. </style>