NotifyManageRecord.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <script setup lang="ts">
  2. import type { NotifyRecordModel, NotifyRecordQuery } from '@/model/notify.model';
  3. import dayjs from 'dayjs';
  4. // 接口数据
  5. import { getNotifyRecordMethod } from '@/request/api/notify.api';
  6. import { usePagination } from 'alova/client';
  7. import { type VxeFormListeners, type VxeFormProps, type VxeGridInstance, type VxeGridListeners, type VxeGridProps, VxeUI } from 'vxe-pc-ui';
  8. const model = shallowRef<NotifyRecordQuery>();
  9. const searchFormProps = reactive<VxeFormProps<NotifyRecordQuery>>({
  10. titleWidth: 100,
  11. titleAlign: 'right',
  12. titleColon: true,
  13. data: {},
  14. items: [
  15. {
  16. field: 'noticeName',
  17. title: '名称',
  18. span: 6,
  19. itemRender: { name: 'VxeInput', props: { placeholder: '请输入通知名称' } },
  20. },
  21. {
  22. field: 'sendTime',
  23. title: '发送日期',
  24. span: 6,
  25. slots: {
  26. default: 'createTimes',
  27. },
  28. },
  29. {
  30. field: 'isRead',
  31. title: '查看状态',
  32. span: 6,
  33. itemRender: {
  34. name: 'VxeRadioGroup',
  35. props: {
  36. options: [
  37. { label: '已查看', value: 'Y' },
  38. { label: '未查看', value: 'N' },
  39. ],
  40. },
  41. },
  42. },
  43. {
  44. span: 6,
  45. itemRender: {
  46. name: 'VxeButtonGroup',
  47. options: [
  48. { name: 'submits', type: 'submit', content: '查询', status: 'primary' },
  49. { name: 'reset', type: 'reset', content: '重置', status: 'warning' },
  50. ],
  51. },
  52. },
  53. ],
  54. });
  55. const searchFormEmits: VxeFormListeners<NotifyRecordQuery> = {
  56. // 查询
  57. submit({ data }) {
  58. data.sendTimeStart = sendTimeStart.value ? dayjs(sendTimeStart.value).format('YYYY-MM-DD HH:mm') : '';
  59. data.sendTimeEnd = sendTimeEnd.value ? dayjs(sendTimeEnd.value).format('YYYY-MM-DD HH:mm') : '';
  60. onSearch(data);
  61. },
  62. // 重置
  63. reset({ data }) {
  64. sendTimeStart.value = '';
  65. sendTimeEnd.value = '';
  66. const resetData = { ...data };
  67. resetData.sendTimeStart = '';
  68. resetData.sendTimeEnd = '';
  69. onSearch(resetData);
  70. },
  71. };
  72. function onSearch(data: NotifyRecordQuery) {
  73. model.value = { ...data };
  74. nextTick(() => {
  75. (searchFormProps.data as any)! = { ...data };
  76. });
  77. }
  78. const gridRef = ref<VxeGridInstance<NotifyRecordModel>>();
  79. const gridOptions = reactive<VxeGridProps<NotifyRecordModel>>({
  80. id: 'tag-list',
  81. border: true,
  82. showOverflow: true,
  83. height: 'auto',
  84. autoResize: true,
  85. syncResize: true,
  86. scrollY: { enabled: true, gt: 0 },
  87. rowConfig: {
  88. isHover: true,
  89. isCurrent: true,
  90. },
  91. toolbarConfig: {
  92. custom: true,
  93. zoom: true,
  94. slots: {
  95. tools: 'toolbar-extra',
  96. },
  97. },
  98. columnConfig: {
  99. resizable: true,
  100. },
  101. customConfig: {
  102. storage: true,
  103. },
  104. columns: [
  105. { type: 'seq', width: 70, fixed: 'left' },
  106. { field: 'noticeName', title: '名称' },
  107. { field: 'patientName', title: '用户姓名' },
  108. { field: 'phone', title: '手机号码' },
  109. { field: 'sendTime', title: '发送时间' },
  110. { field: 'isRead', title: '发送状态', slots: { default: 'isReadCell' } },
  111. ],
  112. data: [],
  113. });
  114. const gridEvents: VxeGridListeners = {};
  115. const {
  116. loading,
  117. page,
  118. pageSize,
  119. total,
  120. onSuccess,
  121. refresh,
  122. send: sendRefresh,
  123. } = usePagination((page, size) => getNotifyRecordMethod(page, size, model.value), {
  124. initialData: { data: [], total: 0 },
  125. initialPage: 1,
  126. initialPageSize: 100,
  127. watchingStates: [model],
  128. immediate: true,
  129. });
  130. onSuccess((res: any) => {
  131. gridRef.value?.loadData(res?.data?.data ?? []);
  132. });
  133. onMounted(() => {
  134. onSearch(toRaw(searchFormProps.data) as any);
  135. });
  136. // 日期验证
  137. const sendTimeStart = ref<string>('');
  138. const sendTimeEnd = ref<string>('');
  139. // 禁用结束时间的日期(早于开始时间的日期)
  140. function disabledEndDate(current: any) {
  141. if (!sendTimeStart.value) return false;
  142. return current && current < dayjs(sendTimeStart.value);
  143. }
  144. defineExpose({
  145. send: sendRefresh,
  146. });
  147. </script>
  148. <template>
  149. <div class="page-container flex flex-col">
  150. <header class="flex-none mt-4">
  151. <vxe-form v-bind="searchFormProps" v-on="searchFormEmits">
  152. <template #createTimes>
  153. <div class="date-range-container">
  154. <a-date-picker v-model:value="sendTimeStart" placeholder="请选择开始日期" style="flex: 1" :show-time="{ format: 'HH:mm' }" />
  155. <span class="date-separator">至</span>
  156. <a-date-picker v-model:value="sendTimeEnd" placeholder="请选择结束日期" style="flex: 1" :disabledDate="disabledEndDate" :show-time="{ format: 'HH:mm' }" />
  157. </div>
  158. </template>
  159. </vxe-form>
  160. </header>
  161. <main class="flex-auto overflow-hidden">
  162. <vxe-grid ref="gridRef" v-bind="gridOptions" v-on="gridEvents" :loading="loading">
  163. <template #isReadCell="{ row }">
  164. <a-tag :color="row.isRead == 'Y' ? 'green' : 'red'">{{ row.isRead == 'Y' ? '已查看' : '未查看' }}</a-tag>
  165. </template>
  166. <template #toolbar-extra>
  167. <vxe-button style="margin-right: 12px" icon="vxe-icon-repeat" circle @click="refresh(page)"></vxe-button>
  168. </template>
  169. </vxe-grid>
  170. </main>
  171. <footer class="flex-none">
  172. <vxe-pager
  173. v-model:current-page="page"
  174. v-model:page-size="pageSize"
  175. :total="total"
  176. :layouts="['Home', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'End', 'Sizes', 'FullJump', 'Total']"
  177. />
  178. </footer>
  179. </div>
  180. </template>
  181. <style scoped lang="scss">
  182. .page-container {
  183. height: 100%;
  184. display: flex;
  185. flex-direction: column;
  186. }
  187. .date-range-container {
  188. display: flex;
  189. align-items: center;
  190. gap: 12px;
  191. width: 100%;
  192. .vxe-input {
  193. flex: 1;
  194. min-width: 0;
  195. }
  196. .date-separator {
  197. color: #666;
  198. font-size: 14px;
  199. font-weight: 500;
  200. white-space: nowrap;
  201. padding: 0 8px;
  202. }
  203. }
  204. </style>