gaoluyang
2026-06-24 712aa51536236d43e87273e4ce45ac5691dffad8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { SystemNotifyMessageApi } from '#/api/system/notify/message';
 
import { ref } from 'vue';
 
import { DocAlert, Page, useVbenModal } from '..\..\..\..\packages\effects\common-ui\src';
import { isEmpty } from '..\..\..\..\packages\utils\src';
 
import { message } from 'ant-design-vue';
 
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import {
  getMyNotifyMessagePage,
  updateAllNotifyMessageRead,
  updateNotifyMessageRead,
} from '#/api/system/notify/message';
 
import { useGridColumns, useGridFormSchema } from './data';
import Detail from './modules/detail.vue';
 
const [DetailModal, detailModalApi] = useVbenModal({
  connectedComponent: Detail,
  destroyOnClose: true,
});
 
/** 刷新表格 */
function handleRefresh() {
  gridApi.query();
}
 
/** 查看站内信详情 */
function handleDetail(row: SystemNotifyMessageApi.NotifyMessage) {
  detailModalApi.setData(row).open();
}
 
/** 标记一条站内信已读 */
async function handleRead(row: SystemNotifyMessageApi.NotifyMessage) {
  const hideLoading = message.loading({
    content: '正在标记已读...',
    duration: 0,
  });
  try {
    await updateNotifyMessageRead([row.id]);
    message.success('标记已读成功');
    handleRefresh();
    // 打开详情
    handleDetail(row);
  } finally {
    hideLoading();
  }
}
 
/** 标记选中的站内信为已读 */
async function handleMarkRead() {
  const rows = gridApi.grid.getCheckboxRecords();
  if (!rows || rows.length === 0) {
    message.warning('请选择需要标记的站内信');
    return;
  }
 
  const ids = rows.map((row: SystemNotifyMessageApi.NotifyMessage) => row.id);
  const hideLoading = message.loading({
    content: '正在标记已读...',
    duration: 0,
  });
  try {
    await updateNotifyMessageRead(ids);
    checkedIds.value = [];
    message.success('标记已读成功');
    await gridApi.grid.setAllCheckboxRow(false);
    handleRefresh();
  } finally {
    hideLoading();
  }
}
 
const checkedIds = ref<number[]>([]);
function handleRowCheckboxChange({
  records,
}: {
  records: SystemNotifyMessageApi.NotifyMessage[];
}) {
  checkedIds.value = records.map((item) => item.id);
}
 
/** 标记所有站内信为已读 */
async function handleMarkAllRead() {
  const hideLoading = message.loading({
    content: '正在标记全部已读...',
    duration: 0,
  });
  try {
    await updateAllNotifyMessageRead();
    message.success('全部标记已读成功');
    checkedIds.value = [];
    await gridApi.grid.setAllCheckboxRow(false);
    handleRefresh();
  } finally {
    hideLoading();
  }
}
 
const [Grid, gridApi] = useVbenVxeGrid({
  formOptions: {
    schema: useGridFormSchema(),
  },
  gridOptions: {
    columns: useGridColumns(),
    height: 'auto',
    keepSource: true,
    proxyConfig: {
      ajax: {
        query: async ({ page }, formValues) => {
          return await getMyNotifyMessagePage({
            pageNo: page.currentPage,
            pageSize: page.pageSize,
            ...formValues,
          });
        },
      },
    },
    rowConfig: {
      keyField: 'id',
      isHover: true,
    },
    toolbarConfig: {
      refresh: true,
      search: true,
    },
    checkboxConfig: {
      checkMethod: (params: { row: SystemNotifyMessageApi.NotifyMessage }) =>
        !params.row.readStatus,
      highlight: true,
    },
  } as VxeTableGridOptions<SystemNotifyMessageApi.NotifyMessage>,
  gridEvents: {
    checkboxAll: handleRowCheckboxChange,
    checkboxChange: handleRowCheckboxChange,
  },
});
</script>
<template>
  <Page auto-content-height>
    <template #doc>
      <DocAlert title="站内信配置" url="https://doc.iocoder.cn/notify/" />
    </template>
 
    <DetailModal @success="handleRefresh" />
    <Grid table-title="我的站内信">
      <template #toolbar-tools>
        <TableAction
          :actions="[
            {
              label: '标记已读',
              type: 'primary',
              icon: ACTION_ICON.ADD,
              disabled: isEmpty(checkedIds),
              onClick: handleMarkRead,
            },
            {
              label: '全部已读',
              type: 'primary',
              icon: ACTION_ICON.ADD,
              onClick: handleMarkAllRead,
            },
          ]"
        />
      </template>
      <template #actions="{ row }">
        <TableAction
          :actions="[
            {
              label: '查看',
              type: 'link',
              ifShow: row.readStatus,
              icon: ACTION_ICON.VIEW,
              onClick: handleDetail.bind(null, row),
            },
            {
              label: '已读',
              type: 'link',
              ifShow: !row.readStatus,
              icon: ACTION_ICON.ADD,
              onClick: handleRead.bind(null, row),
            },
          ]"
        />
      </template>
    </Grid>
  </Page>
</template>