notice.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <template>
  2. <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
  3. <cwg-header :title="t('News.Notice')" />
  4. <view class="info-card">
  5. <view class="search-bar">
  6. <cwg-combox v-model:value="search.read" :options="readOptions"
  7. :placeholder="t('Custom.PaymentHistory.StatusPlaceholder')" />
  8. </view>
  9. <cwg-tabel ref="tableRef" :columns="columns" :mobilePrimaryFields="mobilePrimaryFields"
  10. :queryParams="search" :api="listApi" @go-pages="goPages" :isPages="true">
  11. <template #status="{ row }">
  12. <text class="status-tag" :class="getStatusColor(row.read)">{{readOptions.find(item => item.value === row.read)?.text}}</text>
  13. </template>
  14. </cwg-tabel>
  15. </view>
  16. </cwg-page-wrapper>
  17. </template>
  18. <script setup lang="ts">
  19. import { computed, ref, watch } from 'vue';
  20. import { useI18n } from 'vue-i18n';
  21. const { t, locale } = useI18n();
  22. import { newsApi } from '@/service/news';
  23. import useRouter from "@/hooks/useRouter";
  24. const router = useRouter();
  25. const search = ref({
  26. read: null,
  27. lang: locale.value
  28. })
  29. const readOptions = computed(() => [
  30. { value: null, text: t('State.All') },
  31. { value: 0, text: t('News.Unread') },
  32. { value: 1, text: t('News.Read') }
  33. ]);
  34. const tableRef = ref(null)
  35. watch(locale, () => {
  36. search.value.lang = locale.value
  37. tableRef.value?.reload()
  38. })
  39. watch(search, (newVal) => {
  40. tableRef.value?.reload()
  41. }, { immediate: true, deep: true })
  42. // 表格列配置(支持插槽和格式化)
  43. const columns = computed(() => [
  44. {
  45. prop: 'subject',
  46. label: t('News.Title'),
  47. align: 'left',
  48. slot: 'subject' // 使用插槽自定义标题点击
  49. },
  50. {
  51. prop: 'addTime',
  52. label: t('Drawer.Label.Date'),
  53. align: 'center',
  54. formatter: ({ row }) => row.addTime || '--'
  55. },
  56. {
  57. prop: 'read',
  58. label: t('Custom.Recording.Status'),
  59. align: 'right',
  60. slot: 'status' // 使用插槽显示未读/已读状态
  61. },
  62. {
  63. prop: 'more',
  64. type: 'more',
  65. width: 20,
  66. align: 'right'
  67. },
  68. ])
  69. const mobilePrimaryFields = ref([
  70. {
  71. prop: 'subject',
  72. label: t('News.Title'),
  73. align: 'left',
  74. slot: 'subject' // 使用插槽自定义标题点击
  75. },
  76. {
  77. prop: 'addTime',
  78. label: t('Drawer.Label.Date'),
  79. align: 'center',
  80. formatter: ({ row }) => row.addTime || '--'
  81. },
  82. {
  83. prop: 'read',
  84. label: t('Custom.Recording.Status'),
  85. align: 'right',
  86. slot: 'status' // 使用插槽显示未读/已读状态
  87. },
  88. {
  89. prop: 'more',
  90. type: 'more',
  91. width: 20,
  92. align: 'right'
  93. },
  94. ])
  95. const getStatusColor = (value) => {
  96. const classMap= {
  97. 0: 'status-pending',
  98. 1: 'status-cancelled',
  99. }
  100. return classMap[value] || ''
  101. }
  102. const goPages = (e) => {
  103. router.push({
  104. path: '/pages/analytics/detail',
  105. query: {
  106. id: e.id,
  107. type: 7
  108. }
  109. })
  110. tableRef.value?.reload()
  111. }
  112. const listApi = ref(null)
  113. listApi.value = newsApi.newsNoticeList
  114. </script>
  115. <style scoped lang="scss">
  116. @import "@/uni.scss";
  117. .avatar {
  118. width: px2rpx(60);
  119. height: px2rpx(60);
  120. border-radius: 4px;
  121. }
  122. .content-title {
  123. display: flex;
  124. justify-content: space-between;
  125. align-items: center;
  126. font-size: px2rpx(20);
  127. font-weight: 500;
  128. .content-title-btns {
  129. margin: px2rpx(8) 0;
  130. display: flex;
  131. align-items: center;
  132. justify-content: center;
  133. gap: px2rpx(12);
  134. .btn-primary {
  135. min-width: px2rpx(120);
  136. background-color: var(--color-error);
  137. color: white;
  138. padding: 0 px2rpx(12);
  139. border: none;
  140. font-size: px2rpx(14);
  141. text-align: center;
  142. cursor: pointer;
  143. display: flex;
  144. align-items: center;
  145. justify-content: center;
  146. gap: px2rpx(8);
  147. }
  148. .btn-primary:active {
  149. background-color: #cf1322;
  150. ;
  151. }
  152. }
  153. }
  154. .operation-btn {
  155. :deep(span) {
  156. display: flex;
  157. align-items: center;
  158. justify-content: center;
  159. gap: px2rpx(4);
  160. cursor: pointer;
  161. background-color: var(--color-slate-150);
  162. padding: px2rpx(8) 0;
  163. }
  164. }
  165. .operation-btn.disabled {
  166. cursor: not-allowed;
  167. opacity: 0.5;
  168. }
  169. .search-bar {
  170. display: flex;
  171. align-items: center;
  172. justify-content: flex-start;
  173. flex-wrap: wrap;
  174. gap: px2rpx(16);
  175. margin: px2rpx(16) 0;
  176. .cwg-combox,
  177. .uni-easyinput,
  178. .uni-date {
  179. width: px2rpx(240) !important;
  180. flex: none;
  181. }
  182. }
  183. </style>