|
561 | 561 | :label="$t('navbar.onlyUnread')" |
562 | 562 | size="large" /> |
563 | 563 | </div> |
| 564 | + <div class="flex items-center justify-between"> |
| 565 | + <div class="flex items-center gap-[12px] py-[12px]"> |
| 566 | + <el-checkbox |
| 567 | + class="unreadCheckbox" |
| 568 | + v-model="selectAll" |
| 569 | + @change="handleSelectAllChange" |
| 570 | + /> |
| 571 | + <span class="text-md text-gray-700">{{ $t('navbar.checkAll') }}</span> |
| 572 | + </div> |
| 573 | + <div class="flex items-center justify-end gap-[16px]"> |
| 574 | + <CsgButton |
| 575 | + class="btn btn-link-color btn-md" |
| 576 | + @click="allRead()" |
| 577 | + :name="$t('navbar.allRead')" /> |
| 578 | + <CsgButton |
| 579 | + class="btn btn-link-color btn-md" |
| 580 | + @click="allClear()" |
| 581 | + :name="$t('navbar.allClear')" /> |
| 582 | + </div> |
| 583 | + </div> |
564 | 584 | </div> |
565 | 585 | <div |
566 | 586 | class="msg-list-container h-[calc(100vh-200px)] overflow-y-auto" |
|
569 | 589 | <div |
570 | 590 | v-for="(item, index) in msgList" |
571 | 591 | :key="index" |
572 | | - @click="newMsgShowInfo(2, item, index)" |
573 | | - class="p-4 border-b border-gray-200 hover:bg-gray-50 cursor-pointer"> |
574 | | - <div class="flex items-start justify-between"> |
575 | | - <div class="flex items-center justify-start gap-[12px]"> |
576 | | - <span |
577 | | - class="block w-[8px] h-[8px] rounded-full" |
578 | | - :class="item.is_read ? '' : 'bg-brand-500'"></span> |
579 | | - <SvgIcon |
580 | | - :name="`${item.notification_type}-message`" |
581 | | - class="w-[40px] h-[40px]" /> |
582 | | - <div class="text-sm"> |
583 | | - <p class="text-gray-700 font-medium">{{ item.title }}</p> |
584 | | - <p class="text-gray-600 font-light"> |
585 | | - {{ item.click_action_url }} |
586 | | - </p> |
| 592 | + class="p-4 border-b border-gray-200 hover:bg-gray-50 cursor-pointer flex items-start gap-[12px]"> |
| 593 | + <el-checkbox |
| 594 | + v-model="item.checked" |
| 595 | + @change="handleItemCheckChange(item)" |
| 596 | + class="mt-1 unreadCheckbox" |
| 597 | + /> |
| 598 | + <div @click="newMsgShowInfo(2, item, index)" class="flex-1"> |
| 599 | + <div class="flex items-start justify-between gap-[16px]"> |
| 600 | + <div class="flex items-center justify-start gap-[12px]"> |
| 601 | + <span |
| 602 | + class="block w-[8px] h-[8px] rounded-full flex-shrink-0" |
| 603 | + :class="item.is_read ? '' : 'bg-brand-500'"></span> |
| 604 | + <SvgIcon |
| 605 | + :name="`${item.notification_type}-message`" |
| 606 | + class="w-[40px] h-[40px]" /> |
| 607 | + <div class="text-sm"> |
| 608 | + <p class="text-gray-700 font-medium">{{ item.title }}</p> |
| 609 | + <p class="text-gray-600 font-light line-clamp-1"> |
| 610 | + {{ item.click_action_url }} |
| 611 | + </p> |
| 612 | + </div> |
587 | 613 | </div> |
| 614 | + <p class="text-sm text-gray-600 font-light whitespace-nowrap"> |
| 615 | + {{ `${formatTime(item.created_at * 1000)}` }} |
| 616 | + </p> |
588 | 617 | </div> |
589 | | - <p class="text-sm text-gray-600 font-light"> |
590 | | - {{ `${formatTime(item.created_at * 1000)}` }} |
| 618 | + <p class="mt-[16px] text-gray-600 text-sm line-clamp-2"> |
| 619 | + {{ item.content }} |
591 | 620 | </p> |
592 | 621 | </div> |
593 | | - <p class="mt-[16px] text-gray-600 text-sm line-clamp-2"> |
594 | | - {{ item.content }} |
595 | | - </p> |
596 | 622 | </div> |
597 | 623 | <div |
598 | 624 | v-if="loading" |
|
757 | 783 | const { cookies } = useCookies() |
758 | 784 |
|
759 | 785 | return { |
| 786 | + selectAll: false, |
| 787 | + selectedItems: [], |
760 | 788 | showUserSet: false, |
761 | 789 | showSettings: false, |
762 | 790 | showMsgList: false, |
|
875 | 903 | showDialog() { |
876 | 904 | this.$refs.child.showDialog() |
877 | 905 | }, |
| 906 | + handleSelectAllChange(val) { |
| 907 | + this.msgList.forEach(item => { |
| 908 | + item.checked = val |
| 909 | + }) |
| 910 | + this.updateSelectedItems() |
| 911 | + }, |
| 912 | + handleItemCheckChange(item) { |
| 913 | + this.updateSelectedItems() |
| 914 | + this.selectAll = this.msgList.every(item => item.checked) |
| 915 | + }, |
| 916 | + updateSelectedItems() { |
| 917 | + this.selectedItems = this.msgList.filter(item => item.checked) |
| 918 | + }, |
| 919 | + async allRead() { |
| 920 | + let params = {} |
| 921 | + if(this.selectAll){ |
| 922 | + params = { |
| 923 | + mark_all:true |
| 924 | + } |
| 925 | + }else { |
| 926 | + params = { |
| 927 | + ids: this.selectedItems.map(item => item.id) |
| 928 | + } |
| 929 | + } |
| 930 | + const options = { body: JSON.stringify(params) } |
| 931 | + const { data, error } = await useFetchApi( |
| 932 | + `/notifications/read`, |
| 933 | + options |
| 934 | + ) |
| 935 | + .put() |
| 936 | + .json() |
| 937 | + if (data.value) { |
| 938 | + this.resetList() |
| 939 | + this.getMsgNum() |
| 940 | + } else { |
| 941 | + ElMessage.warning(error.value.msg) |
| 942 | + } |
| 943 | + }, |
| 944 | + async allClear() { |
| 945 | + let params = {} |
| 946 | + if(this.selectAll){ |
| 947 | + params = { |
| 948 | + mark_all:true |
| 949 | + } |
| 950 | + }else { |
| 951 | + params = { |
| 952 | + ids: this.selectedItems.map(item => item.id) |
| 953 | + } |
| 954 | + } |
| 955 | + const options = { body: JSON.stringify(params) } |
| 956 | + const { data, error } = await useFetchApi( |
| 957 | + `/notifications`, |
| 958 | + options |
| 959 | + ) |
| 960 | + .delete() |
| 961 | + .json() |
| 962 | + if (data.value) { |
| 963 | + this.resetList() |
| 964 | + this.getMsgNum() |
| 965 | + } else { |
| 966 | + ElMessage.warning(error.value.msg) |
| 967 | + } |
| 968 | + }, |
878 | 969 | handleLocaleChange(locale) { |
879 | 970 | location.href = `/${locale}/settings/locale` |
880 | 971 | }, |
|
1071 | 1162 |
|
1072 | 1163 | if (data.value?.data) { |
1073 | 1164 | this.msgNum = data.value.data.unread_count |
1074 | | - this.msgList = [...this.msgList, ...data.value.data.messages] |
| 1165 | + const newMessages = data.value.data.messages.map(msg => ({ |
| 1166 | + ...msg, |
| 1167 | + checked: false |
| 1168 | + })) |
| 1169 | + this.msgList = [...this.msgList, ...newMessages] |
1075 | 1170 | this.currentPage++ |
1076 | 1171 |
|
1077 | 1172 | if (data.value.data.messages.length < this.pageSize) { |
|
1107 | 1202 | this.msgList = [] |
1108 | 1203 | this.currentPage = 1 |
1109 | 1204 | this.noMore = false |
| 1205 | + this.selectAll = false |
1110 | 1206 | this.getMsgList() |
1111 | 1207 | }, |
1112 | 1208 |
|
|
1152 | 1248 | } |
1153 | 1249 | }, |
1154 | 1250 | watch: { |
| 1251 | + msgList(newVal) { |
| 1252 | + if (newVal.length > this.selectedItems.length) { |
| 1253 | + this.selectAll = false |
| 1254 | + } |
| 1255 | + }, |
1155 | 1256 | onlyUnread(newVal) { |
1156 | 1257 | this.resetList() |
1157 | 1258 | }, |
|
0 commit comments