index.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. <template>
  2. <view class="page_mine">
  3. <notice-header title="我的通知" :showSearch="true" :showFilter="true" :showTabs="true" :tabs="tabs"
  4. :activeTab="activeTab" tabMode="index" @tabChange="handleTabChange" @typeChange="handleTypeChange" @timeChange="handleTimeChange" @searchChange="handleSearchChange"></notice-header>
  5. <view class="notice_content">
  6. <view class="notice_list">
  7. <scroll-view scroll-y v-for="item in noticeList" :key="item.id" class="notice_item">
  8. <view class="item_content">
  9. <view class="notice_title_row">
  10. <image class="notice_icon" :src="item.icon" mode="aspectFit"></image>
  11. <text class="notice_title">{{ item.title }}</text>
  12. </view>
  13. <view class="notice_meta">
  14. <view class="status_tag" :class="item.statusClass">
  15. <text>{{ item.status }}</text>
  16. </view>
  17. <text class="meta_text">{{ item.category }}</text>
  18. <text class="meta_text">{{ item.department }}</text>
  19. <text class="meta_text">{{ item.time }}</text>
  20. </view>
  21. </view>
  22. <view class="item_bottom">
  23. <view class="notice_stats">
  24. <text class="stats_text">已读: {{ item.readCount }}人</text>
  25. <text class="stats_text">未读: {{ item.unreadCount }}人</text>
  26. </view>
  27. <view class="notice_actions">
  28. <view class="action_btn" :class="getDeleteClass(item)" @click="handleDelete(item.id)">
  29. <text>删除</text>
  30. </view>
  31. <view class="action_btn edit" @click="handleEdit(item.id)">
  32. <text>编辑</text>
  33. </view>
  34. <view class="action_btn detail" @click="handleDetail(item.id)">
  35. <text>详情</text>
  36. </view>
  37. </view>
  38. </view>
  39. </scroll-view>
  40. <no-data v-if="noticeList.length === 0" text="暂无通知" />
  41. </view>
  42. </view>
  43. <common-tabbar></common-tabbar>
  44. </view>
  45. </template>
  46. <script setup>
  47. import { ref } from 'vue';
  48. import NoticeHeader from '@/components/notice-header.vue';
  49. import NoData from '@/components/no-data.vue';
  50. const tabs = ['未读', '已读', '全部'];
  51. const activeTab = ref(0);
  52. const noticeList = ref([
  53. {
  54. id: '1',
  55. title: '25-26学年第一学期初一期中考试安排通知',
  56. status: '已发布',
  57. statusClass: 'status-published',
  58. category: '教学教务',
  59. department: '教务处',
  60. time: '2024-06-03 18:00:00',
  61. readCount: 1500,
  62. unreadCount: 50,
  63. icon: '/static/image/todo/xiaoxi.png'
  64. },
  65. {
  66. id: '2',
  67. title: '关于开展教师培训的通知',
  68. status: '已发布',
  69. statusClass: 'status-published',
  70. category: '教师培训',
  71. department: '人事处',
  72. time: '2024-06-02 10:00:00',
  73. readCount: 280,
  74. unreadCount: 15,
  75. icon: '/static/image/todo/xiaoxi.png'
  76. },
  77. {
  78. id: '3',
  79. title: '暑期放假安排通知',
  80. status: '待发布',
  81. statusClass: 'status-pending',
  82. category: '学校通知',
  83. department: '校长办公室',
  84. time: '2024-06-01 09:00:00',
  85. readCount: 0,
  86. unreadCount: 0,
  87. icon: '/static/image/todo/xiaoxi.png'
  88. }
  89. ]);
  90. const getDeleteClass = (item) => {
  91. if (item.noticeStatus !== 2) {
  92. return 'delete disabled';
  93. }
  94. return 'delete';
  95. };
  96. const goBack = () => {
  97. uni.navigateBack();
  98. };
  99. const handleTabChange = (idx) => {
  100. activeTab.value = idx;
  101. };
  102. const handleTypeChange = () => {};
  103. const handleTimeChange = () => {};
  104. const handleSearchChange = () => {};
  105. const handleDelete = (id) => {
  106. uni.showModal({
  107. title: '确认删除',
  108. content: '确定要删除这条通知吗?',
  109. success: (res) => {
  110. if (res.confirm) {
  111. noticeList.value = noticeList.value.filter(item => item.id !== id);
  112. uni.showToast({ title: '删除成功', icon: 'success' });
  113. }
  114. }
  115. });
  116. };
  117. const handleEdit = (id) => {
  118. uni.navigateTo({ url: `/pages/notice/publish/index?id=${id}` });
  119. };
  120. const handleDetail = (id) => {
  121. const item = noticeList.value.find(item => item.id === id);
  122. if (item && item.status === '待发布') {
  123. uni.showToast({ title: '待发布通知暂无法查看详情', icon: 'none' });
  124. return;
  125. }
  126. uni.showToast({ title: `查看详情: ${id}`, icon: 'none' });
  127. };
  128. </script>
  129. <style lang="scss">
  130. .page_mine {
  131. }
  132. .notice_content {
  133. padding-top: 325rpx;
  134. padding-bottom: 104px;
  135. }
  136. .notice_list {
  137. padding: 0rpx 24rpx;
  138. box-sizing: border-box;
  139. }
  140. .notice_item {
  141. background-color: #F9FAFF;
  142. border-radius: 20rpx;
  143. margin-bottom: 24rpx;
  144. border: 2rpx solid #E4E7ED;
  145. .item_content {
  146. padding: 24rpx;
  147. .notice_title_row {
  148. display: flex;
  149. align-items: center;
  150. margin-bottom: 16rpx;
  151. .notice_icon {
  152. width: 32rpx;
  153. height: 32rpx;
  154. margin-right: 16rpx;
  155. }
  156. .notice_title {
  157. flex: 1;
  158. font-weight: 500;
  159. font-size: 28rpx;
  160. color: #333333;
  161. overflow: hidden;
  162. text-overflow: ellipsis;
  163. white-space: nowrap;
  164. }
  165. }
  166. .notice_meta {
  167. display: flex;
  168. align-items: center;
  169. flex-wrap: wrap;
  170. gap: 16rpx;
  171. .status_tag {
  172. font-size: 24rpx;
  173. height: 48rpx;
  174. width: 96rpx;
  175. text-align: center;
  176. line-height: 48rpx;
  177. border-radius: 8rpx;
  178. font-weight: 400;
  179. &.status-pending {
  180. background: rgba(46, 100, 250, 0.1);
  181. color: #2E64FA;
  182. }
  183. &.status-published {
  184. background: rgba(82, 196, 26, 0.1);
  185. color: #2BC644;
  186. }
  187. &.status-closed {
  188. background: rgba(245, 108, 108, 0.1);
  189. color: #F56C6C;
  190. }
  191. }
  192. .meta_text {
  193. font-size: 24rpx;
  194. color: #999999;
  195. line-height: 48rpx;
  196. }
  197. }
  198. }
  199. .item_bottom {
  200. border-top: 2rpx solid #E4E7ED;
  201. display: flex;
  202. flex-direction: row;
  203. justify-content: space-between;
  204. align-items: center;
  205. padding: 24rpx 16rpx;
  206. .notice_stats {
  207. display: flex;
  208. .stats_text {
  209. font-size: 24rpx;
  210. color: #999999;
  211. &:first-child {
  212. margin-right: 32rpx;
  213. }
  214. }
  215. }
  216. .notice_actions {
  217. display: flex;
  218. justify-content: flex-end;
  219. gap: 16rpx;
  220. .action_btn {
  221. font-size: 24rpx;
  222. padding: 12rpx 24rpx;
  223. border-radius: 8rpx;
  224. border: 2rpx solid transparent;
  225. &.delete {
  226. border-color: #F56C6C;
  227. color: #F56C6C;
  228. background-color: #FFFFFF;
  229. &.disabled {
  230. border-color: #C0C4CC;
  231. color: #C0C4CC;
  232. background-color: #FFFFFF;
  233. }
  234. }
  235. &.edit {
  236. border-color: #2E64FA;
  237. color: #2E64FA;
  238. background-color: #FFFFFF;
  239. &.disabled {
  240. border-color: #C0C4CC;
  241. color: #C0C4CC;
  242. background-color: #FFFFFF;
  243. }
  244. }
  245. &.detail {
  246. background-color: #2E64FA;
  247. color: #FFFFFF;
  248. &.disabled {
  249. border-color: #C0C4CC;
  250. color: #C0C4CC;
  251. background-color: #FFFFFF;
  252. }
  253. }
  254. }
  255. }
  256. }
  257. &:last-child {
  258. margin-bottom: 0;
  259. }
  260. }
  261. </style>