index.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <template>
  2. <div class="p-4">
  3. <!-- <GrowCard :loading="loading" class="enter-y" /> -->
  4. <BasicTable @register="registerTable">
  5. <template #headerTop>
  6. <div class="md:flex enter-y">
  7. <div class="md:w-1/2 enter-y">
  8. <Card class="w-full">
  9. <VisitAnalysisBar :loading="loading" />
  10. </Card>
  11. </div>
  12. <div class="!md:mx-2"></div>
  13. <Card class="md:w-1/2 enter-y">
  14. <!-- <VisitAnalysis :loading="loading" /> -->
  15. <VisitAnalysis :loading="loading" />
  16. </Card>
  17. </div>
  18. </template>
  19. <template #toolbar>
  20. <a-button type="primary" @click="handleExport">导出数据</a-button>
  21. </template>
  22. </BasicTable>
  23. <!-- <div class="md:flex enter-y">
  24. <div class="md:w-1/2 enter-y">
  25. <Card class="w-full">
  26. <VisitAnalysisBar :loading="loading" />
  27. </Card>
  28. </div>
  29. <div class="!md:mx-2"></div>
  30. <Card class="md:w-1/2 enter-y">
  31. <VisitAnalysis :loading="loading" />
  32. </Card>
  33. </div>
  34. <div class="md:flex enter-y mt-4">
  35. <Card class="md:w-1/2 md:w-full"> </Card>
  36. </div> -->
  37. </div>
  38. </template>
  39. <script lang="ts" setup>
  40. import { onMounted, reactive, ref } from 'vue';
  41. import { BasicTable, useTable, BasicColumn, FormProps } from '/@/components/Table';
  42. // import { useI18n } from '/@/hooks/web/useI18n';
  43. // import GrowCard from './components/GrowCard.vue';
  44. import { Card } from 'ant-design-vue';
  45. import VisitAnalysis from './components/VisitAnalysis.vue';
  46. import VisitAnalysisBar from './components/VisitAnalysisBar.vue';
  47. import {
  48. // bulletChatApi,
  49. userStaticsApi,
  50. bulletChatStaticsApi,
  51. bulletChatExportApi,
  52. } from '/@/api/dashboard/analysis';
  53. import { listRoomsApi } from '/@/api/scene/list';
  54. import { dateUtil, formatToDate } from '/@/utils/dateUtil';
  55. const today = formatToDate(dateUtil(new Date()));
  56. const priorDate = formatToDate(dateUtil(new Date().setDate(new Date().getDate() - 30)));
  57. const loading = ref(true);
  58. // const { t } = useI18n();
  59. const columns: BasicColumn[] = [
  60. {
  61. title: '微信昵称',
  62. dataIndex: 'nickName',
  63. width: 120,
  64. },
  65. {
  66. title: '手机号',
  67. dataIndex: 'userName',
  68. width: 120,
  69. },
  70. {
  71. title: '房间名称',
  72. dataIndex: 'liveRoomName',
  73. width: 120,
  74. },
  75. {
  76. title: '在线时长(min)',
  77. dataIndex: 'duration',
  78. width: 120,
  79. },
  80. {
  81. title: '留言条数',
  82. dataIndex: 'bulletChatAmount',
  83. width: 120,
  84. },
  85. {
  86. title: '留言内容',
  87. dataIndex: 'bulletChatContents',
  88. width: 320,
  89. },
  90. ];
  91. const searchForm: Partial<FormProps> = {
  92. labelWidth: 100,
  93. schemas: [
  94. {
  95. field: 'liveRoomId',
  96. label: '全部房间',
  97. component: 'ApiSelect',
  98. colProps: {
  99. xl: 5,
  100. xxl: 5,
  101. },
  102. componentProps: {
  103. api: listRoomsApi,
  104. labelField: 'name',
  105. resultField: 'list',
  106. valueField: 'id',
  107. immediate: false,
  108. showSearch: true,
  109. optionFilterProp: 'label',
  110. params: {
  111. page: 1,
  112. limit: 1000,
  113. },
  114. },
  115. },
  116. {
  117. field: 'time',
  118. label: '时间段',
  119. component: 'RangePicker',
  120. // defaultValue: [priorDate, today],
  121. colProps: {
  122. xl: 16,
  123. xxl: 16,
  124. },
  125. componentProps: {
  126. format: 'YYYY-MM-DD',
  127. disabledDate(current) {
  128. // console.log('current', current, date);
  129. return current && current > dateUtil().endOf('day');
  130. },
  131. // onChange: (value) => {
  132. // console.log('onchange', value);
  133. // },
  134. },
  135. },
  136. ],
  137. };
  138. const searchInfo = reactive({
  139. liveRoomId: '',
  140. limit: 20,
  141. page: 1,
  142. time: [priorDate, today],
  143. });
  144. const [registerTable] = useTable({
  145. title: '房间留言状态',
  146. columns: columns,
  147. useSearchForm: true,
  148. formConfig: searchForm,
  149. api: bulletChatStaticsApi,
  150. afterFetch: function (data) {
  151. console.log('data', data);
  152. return data;
  153. },
  154. searchInfo: searchInfo,
  155. });
  156. onMounted(async () => {
  157. await userStaticsApi(searchInfo);
  158. });
  159. async function handleExport() {
  160. const data = await bulletChatExportApi(searchInfo);
  161. const downloadBlob = new Blob([data], {
  162. type: 'application/msexcel',
  163. });
  164. const url = URL.createObjectURL(downloadBlob);
  165. const a: HTMLAnchorElement = document.createElement('a');
  166. document.body.appendChild(a);
  167. a.style.display = 'none';
  168. a.href = url;
  169. const name = new Date().getTime();
  170. a.download = `${name}.csv`;
  171. a.click();
  172. window.URL.revokeObjectURL(url);
  173. }
  174. setTimeout(() => {
  175. loading.value = false;
  176. }, 1500);
  177. </script>