index.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import Taro, { useReachBottom } from "@tarojs/taro";
  2. import { View, Text } from "@tarojs/components";
  3. import EmptyData from "@/components/empty-data";
  4. import NavBarNormal from "@/components/NavBarNormal/index";
  5. import SearchBar from "@/components/search-bar/index";
  6. import style from "./index.module.less";
  7. import { useEffect, useState } from "react";
  8. import ContactCard from "./components/contact-card/index";
  9. import { getContactList, setContactToTop } from "@/service/contact";
  10. import { useLoadMore } from "@/utils/loadMore";
  11. import PageCustom from "@/components/page-custom/index";
  12. import { TContactItem } from "@/types/contact";
  13. import { isSuccess } from "@/utils";
  14. import useSWRInfinite from "swr/infinite";
  15. export default function Index() {
  16. const [searchValue, setSearchValue] = useState("");
  17. const fetcher = async ([_url, params, keyword]) => {
  18. params = params || {};
  19. console.log("fetcher", _url, params);
  20. const res = await getContactList({
  21. startId: params.nextId,
  22. pageSize: params.pageSize,
  23. keyword: keyword,
  24. });
  25. return res.data;
  26. };
  27. const getKey = (pageIndex:number, previousPageData) => {
  28. if (pageIndex === 0)
  29. return [
  30. "/my/contacts",
  31. { nextId: undefined, pageSize: 2, keyword: "" },
  32. searchValue,
  33. ];
  34. if (previousPageData && previousPageData.nextId) {
  35. return [
  36. "/my/contacts",
  37. { pageSize: 2, nextId: previousPageData.nextId },
  38. searchValue,
  39. ];
  40. }
  41. return null;
  42. };
  43. const { data, setSize } = useSWRInfinite(getKey, fetcher, {
  44. revalidateIfStale: false,
  45. onErrorRetry(err, key, config, revalidate, revalidateOpts) {
  46. if(err.status === 404) return
  47. if(err.status === 401) return
  48. if(revalidateOpts.retryCount >=3 )return
  49. },
  50. });
  51. const list = data?.flatMap((page) => page?.data || []) || [];
  52. const resetFetchList = () => {
  53. setSize(1);
  54. };
  55. const handleSearchBarChanged = (v: string) => {
  56. setSearchValue(v);
  57. };
  58. const handleClear = () => {
  59. setSearchValue("");
  60. };
  61. useReachBottom(() => {
  62. // 加载更多数据
  63. // 如果搜索框中有数据由不加载更多数据
  64. if (searchValue.length) {
  65. return;
  66. }
  67. setSize((prevSize) => prevSize + 1);
  68. });
  69. const handleHello = async (e: any) => {
  70. const detail = e.detail as { type: string; id: string };
  71. console.log(detail);
  72. // 置顶与取消置顶
  73. if (detail.type === "pin" || detail.type === "unpin") {
  74. const reseponse = await setContactToTop({
  75. isTop: detail.type === "pin",
  76. contactId: detail.id,
  77. });
  78. if (isSuccess(reseponse.status)) {
  79. resetFetchList();
  80. return;
  81. }
  82. }
  83. };
  84. const renderContent = () => {
  85. if (list?.length) {
  86. return list.map((item) => (
  87. // @ts-ignore
  88. <slide-delete
  89. pid={item.contactId}
  90. pinned={item.isTop}
  91. onAction={handleHello}
  92. >
  93. <View className={`${item.isTop ? "bg-gray" : "bg-white"}`}>
  94. <ContactCard
  95. refresh={resetFetchList}
  96. deleteable={!item.isEnt}
  97. key={item.contactId}
  98. data={item}
  99. fromContact
  100. ></ContactCard>
  101. </View>
  102. </slide-delete>
  103. ));
  104. }
  105. return <EmptyData type={2} />;
  106. };
  107. return (
  108. <PageCustom>
  109. <NavBarNormal
  110. scrollFadeIn
  111. leftColumn={() => <Text className="text-16 font-medium">联系人</Text>}
  112. ></NavBarNormal>
  113. <View className="flex flex-col w-full">
  114. <View className="px-16 pb-12">
  115. <SearchBar
  116. value={searchValue}
  117. onChange={(e) => handleSearchBarChanged(e)}
  118. onClear={() => handleClear()}
  119. ></SearchBar>
  120. </View>
  121. <View className={style.contactContent}>{renderContent()}</View>
  122. </View>
  123. </PageCustom>
  124. );
  125. }