ConversationHistoryContainer.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <template>
  2. <div class="conversation-history-container">
  3. <HistoryName />
  4. <HistorySearchInput @search="handleHistorySearch" />
  5. <HistoryList
  6. v-if="list_history.length !== 0"
  7. :list="list_history"
  8. :can_loadmore="can_loadmore"
  9. @loadmore="handleListLoadMore"
  10. @active="handleListItemActive"
  11. />
  12. <template v-if="api_status === 2">
  13. <div class="infomations-container">
  14. <a-spin :size="32" />
  15. </div>
  16. </template>
  17. <template v-if="api_status === 3 && list_history.length === 0">
  18. <div class="infomations-container">
  19. <a-empty> {{ $t('conversation.history_empty') }} </a-empty>
  20. </div>
  21. <!-- <HistoryList
  22. v-if="list_history.length !== 0"
  23. :list="list_history"
  24. :can_loadmore="can_loadmore"
  25. @loadmore="handleListLoadMore"
  26. @active="handleListItemActive"
  27. /> -->
  28. </template>
  29. <template v-if="api_status === 4">
  30. <div class="infomations-container">
  31. <a-result status="warning" :title="api_message"> </a-result>
  32. </div>
  33. </template>
  34. <template v-if="api_status === 5">
  35. <div class="infomations-container">
  36. <a-result status="error" :title="api_message"> </a-result>
  37. </div>
  38. </template>
  39. <div class="conversation-history-placeholder"></div>
  40. </div>
  41. </template>
  42. <script setup>
  43. import { ref, onMounted } from 'vue';
  44. import HistoryName from '../../modules/conversation-history/HistoryName.vue';
  45. import HistorySearchInput from '../../modules/conversation-history/HistorySearchInput.vue';
  46. import HistoryList from '../../modules/conversation-history/HistoryList.vue';
  47. import { apiConversationHistoryList } from '../../modules/conversation-history/api-conversation-history';
  48. import { getTodayZeroTimestamp, ONE_DAY, ONE_MONTH } from '../../utils/datetime';
  49. const page_no = ref(1); // 当前页码
  50. const page_count = ref(50); // 每页显示的数量
  51. const search_text = ref(''); // 搜索字符串
  52. const can_loadmore = ref(true); // 是否可以加载更多
  53. // api请求的状态
  54. const api_status = ref(1); // api状态 1 请求未启动 2 请求进心中 3 请求已成功 4 请求失败(网络成功,但是code不等于200) 5 请求出错
  55. const api_message = ref(''); // 请求消息 与 api_status 对应的 message 消息内容
  56. // 历史记录列表数据
  57. const list_history = ref([]); // 历史记录的列表数据
  58. const count_today = ref(0); // 记录今天的数据量
  59. const count_month = ref(0); // 记录本月的数据量
  60. const count_earlier = ref(0); // 记录更早的数据量
  61. const today_zero = getTodayZeroTimestamp(); // 今天零点
  62. const yesterday_zero = today_zero - ONE_DAY; // 昨天零点
  63. const last_month_zero = yesterday_zero - ONE_MONTH; // 上个月(30天之前的)零点
  64. /**
  65. * 将数据进行分类
  66. * 依据时间戳,将列表数据分成三中类型:今天、本月、更早
  67. * 今天:从今天零点开始到现在
  68. * 本月:从今天零点之前,往前推30天
  69. * 更早:在30天之前的数据
  70. * @param res_list
  71. */
  72. function dropListByType(res_list) {
  73. res_list.forEach((item, index) => {
  74. // 获取每一项的内容
  75. const create_time = item.create_time; // 会话创建时间
  76. if (create_time >= today_zero) {
  77. if (count_today.value === 0) {
  78. // 第0个数据
  79. // 今天的数据
  80. list_history.value.push({
  81. client_field_content_type: 'label',
  82. client_field_timestamp_type: 'today'
  83. // content: '今天'
  84. // content: t('conversation.history_today')
  85. });
  86. }
  87. // 非第0个数据
  88. item.client_field_timestamp_type = 'today'; // 客户端自定义字段: 时间类型
  89. item.client_field_content_type = 'content'; // 内容类别
  90. // 今天的数据
  91. list_history.value.push(item);
  92. count_today.value = count_today.value + 1;
  93. } else if (create_time < today_zero && create_time > last_month_zero) {
  94. // 本月
  95. if (count_month.value === 0) {
  96. list_history.value.push({
  97. client_field_content_type: 'label',
  98. client_field_timestamp_type: 'month'
  99. // content: '本月'
  100. // content: t('conversation.history_month')
  101. });
  102. }
  103. item.client_field_timestamp_type = 'month'; // 客户端自定义字段: 时间类型
  104. item.client_field_content_type = 'content'; // 内容类别
  105. list_history.value.push(item);
  106. count_month.value = count_month.value + 1;
  107. } else {
  108. if (count_earlier.value === 0) {
  109. list_history.value.push({
  110. client_field_content_type: 'label',
  111. client_field_timestamp_type: 'earlier'
  112. // content: '更早以前'
  113. // content: t('conversation.history_earlier')
  114. });
  115. }
  116. item.client_field_timestamp_type = 'earlier'; // 客户端自定义字段: 时间类型
  117. item.client_field_content_type = 'content'; // 内容类别
  118. // 更早的数据
  119. list_history.value.push(item);
  120. count_earlier.value = count_earlier.value + 1;
  121. }
  122. });
  123. }
  124. /**
  125. * 处理请求参数
  126. */
  127. const formatListOptions = () => {
  128. return {
  129. search: search_text.value,
  130. page: page_no.value,
  131. per_page: page_count.value
  132. };
  133. };
  134. /**
  135. * 调用api请求
  136. */
  137. const handleApiRequest = () => {
  138. // 处理查询参数
  139. const opts = formatListOptions();
  140. // 进入加载状态
  141. api_status.value = 2;
  142. api_message.value = '';
  143. apiConversationHistoryList(opts)
  144. .then((res) => {
  145. if (res.code / 1 === 200) {
  146. // 成功
  147. const res_list = res.data; // 历史记录列表
  148. if (res_list.length === 0) {
  149. // 数据已经加载完成,不能加载更多了
  150. can_loadmore.value = false;
  151. } else {
  152. can_loadmore.value = true;
  153. dropListByType(res_list);
  154. }
  155. // api请求成功
  156. api_status.value = 3;
  157. api_message.value = 'success';
  158. } else {
  159. // api请求成功,但是业务失败
  160. api_status.value = 4;
  161. api_message.value = res.msg;
  162. }
  163. })
  164. .catch((err) => {
  165. console.log(err);
  166. // api请求出错
  167. api_status.value = 5;
  168. api_message.value = err.msg;
  169. });
  170. };
  171. /**
  172. * 请求更多数据
  173. */
  174. const handleListLoadMore = () => {
  175. if (!can_loadmore.value) {
  176. // 没有更多了
  177. return;
  178. }
  179. page_no.value = page_no.value + 1; // 页码加1
  180. // 调用api
  181. handleApiRequest();
  182. };
  183. /**
  184. * 点击某个历史记录触发的事件
  185. * @param history_id
  186. */
  187. const handleListItemActive = (history_id) => {};
  188. /**
  189. * 开始搜索
  190. * @param value
  191. */
  192. const handleHistorySearch = (value) => {
  193. search_text.value = value; // 搜索字符串
  194. page_no.value = 1; // 页码归位
  195. list_history.value = []; // 清空数据
  196. // 调用api
  197. handleApiRequest();
  198. };
  199. onMounted(() => {
  200. // 调用api
  201. handleApiRequest();
  202. });
  203. </script>
  204. <style lang="css" scoped>
  205. .conversation-history-container {
  206. width: 60%;
  207. height: 100%;
  208. margin-left: auto;
  209. margin-right: auto;
  210. display: flex;
  211. flex-direction: column;
  212. }
  213. /* 底部占位元素 */
  214. .conversation-history-placeholder {
  215. height: 50px;
  216. }
  217. .conversation-history-container .infomations-container {
  218. display: flex;
  219. justify-content: center;
  220. align-items: center;
  221. min-height: 200px;
  222. }
  223. </style>