From a73b804437779a01887cd729446ef4ef22c68027 Mon Sep 17 00:00:00 2001 From: al Date: Wed, 10 Jul 2024 16:50:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AD=98=E5=9C=A8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/public.js | 83 +++++++++++- app/bill/page.js | 2 +- app/login/page.js | 14 -- app/my/editUserProfile/editUserName/page.js | 63 ++++++++- .../selectUserProfileItem/page.js | 23 +--- app/my/page.js | 8 +- app/my/wallet/page.js | 2 +- app/page.js | 1 + app/pay/page.js | 5 +- app/share/[mid]/page.js | 113 ++++++++++++++++ app/space/[id]/page.js | 122 ++++++++++-------- app/space/page.js | 114 ++++++++++------ .../person_space_introduce/[mid]/page.js | 4 +- components/PaySpacePost/index.js | 27 +++- components/Photos/index.js | 4 +- components/PostItem/index.js | 6 +- package-lock.json | 27 ++++ package.json | 1 + public/icons/magnifier.png | Bin 0 -> 1738 bytes public/icons/rightarrow_border.png | Bin 0 -> 463 bytes utils/upload.js | 2 + 21 files changed, 463 insertions(+), 158 deletions(-) create mode 100644 app/share/[mid]/page.js create mode 100644 public/icons/magnifier.png create mode 100644 public/icons/rightarrow_border.png diff --git a/api/public.js b/api/public.js index 42133ee..9423225 100644 --- a/api/public.js +++ b/api/public.js @@ -86,7 +86,7 @@ export const zoneThumbsUp = async (id, times = 1, callback) => { console.error(error); } }; - +// 查看关系 export async function checkRelation(subMid, objMid, predicate) { try { const data = @@ -110,6 +110,7 @@ export async function checkRelation(subMid, objMid, predicate) { console.error(error); } } +// 获取用户信息 export async function getUserInfo() { try { const data = @@ -127,3 +128,83 @@ export async function getUserInfo() { console.error(error); } } + +// 创建订单 +export const createOrder = async (type = "alipay_h5") => { + if (!selectedPrice.id && !customCoin.selected) { + Toast.show({ + content: "请选择充值档位", + }); + return; + } + if (customCoin.selected && customCoin.num < 10) { + Toast.show({ + content: "最低充值1元哦~", + }); + return; + } + + const base = webviewBaseRequest(); + const body = { + ...base, + product_id: customCoin.selected ? "h5_custom_coin" : selectedPrice.id, + custom_coins: customCoin.selected ? customCoin.num : 0, + pay_type: type, + redirect_url: type === "yeepay_wxpay_h5" ? window.location.href : "", + from: "app", + }; + + //如果是微信jsapi支付直接跳转到中间页 + if (type === "wxpay_jsapi") { + router.push(`/pay/${encodeURIComponent(JSON.stringify(body))}`); + return; + } + + setIsLoading(true); + + const signature = generateSignature(body); + try { + const response = await fetch( + `/api/vas/create_order?signature=${signature}`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + } + ); + const data = await response.json(); + if (data.ret === -1) { + Toast.show({ + content: data.msg, + }); + return; + } + switch (type) { + case "yeepay_alipay_h5": + router.push(`${data.data.yeepay_alipay_h5_param_str}`); + break; + case "yeepay_wxpay_h5": + router.push(`${data.data.yeepay_wxpay_h5_param_str}`); + break; + case "alipay_h5": + router.push(`${data.data.alipay_h5_param_str}`); + break; + case "wxpay_h5": + router.push( + `https://shop.tiefen.fun/pay/wxpay_h5/${encodeURIComponent( + data.data.wxpay_h5_param_str + )}` + ); + break; + default: + router.push(`${data.data.alipay_h5_param_str}`); + break; + } + } catch (error) { + console.error(error); + } finally { + setIsLoading(false); + } +}; \ No newline at end of file diff --git a/app/bill/page.js b/app/bill/page.js index 653552a..f30fcba 100644 --- a/app/bill/page.js +++ b/app/bill/page.js @@ -19,7 +19,7 @@ export default function Recharge() { icon={faAngleLeft} size="xl" onClick={() => { - router.back(); + router.push("/my/wallet"); }} /> diff --git a/app/login/page.js b/app/login/page.js index 5f0f1e9..96b8540 100644 --- a/app/login/page.js +++ b/app/login/page.js @@ -247,20 +247,6 @@ function Login({ handleLogin }) { /> -
-

- 密码 -

- setLoginInfo({ ...loginInfo, password: value})} - value={loginInfo.password} - type="password" - style={{ "--color": "#FFFFFF", "--font-size": "16px" }} - /> -
-

验证码 diff --git a/app/my/editUserProfile/editUserName/page.js b/app/my/editUserProfile/editUserName/page.js index 7494bac..844f30f 100644 --- a/app/my/editUserProfile/editUserName/page.js +++ b/app/my/editUserProfile/editUserName/page.js @@ -1,13 +1,68 @@ "use client"; -import React, { useState } from "react"; -import { Input, Button } from "antd-mobile"; +import React, { useState,useEffect } from "react"; +import { Input, Button, Toast } from "antd-mobile"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faAngleLeft, faAngleRight } from "@fortawesome/free-solid-svg-icons"; import { useRouter } from "next/navigation"; +import {getUserInfo} from "@/api/public"; +import {get,save} from "@/utils/storeInfo"; +import require from "@/utils/require"; +const account = get("account"); export default function EditUserName() { const router = useRouter(); const [name, setName] = useState(); + + useEffect(() => { + const getName = async () => { + + setName(account.name); + }; + getName(); + }, []); + + const handleSubmit = async () => { + if (!name) { + Toast.show({ + icon: "fail", + content: "昵称不得为空", + position: "top", + }); + return; + } else if (name.length > 10) { + Toast.show({ + icon: "fail", + content: "昵称不得超过10个字", + position: "top", + }); + return; + } else if (name === account.name) { + router.back(); + return; + } + + try { + const data = await require("POST", "/api/account/update", { + body: { + name: name, + }, + },true); + if (data.ret === -1) { + Toast.show({ + icon: "fail", + content: data.msg, + position: "top", + }); + return; + } + //向服务器请求新的账号信息并保存到本地 + const account = await getUserInfo() + save("account", JSON.stringify(account)); + } catch (error) { + console.error(error); + } + router.back(); + }; return (

@@ -29,7 +84,7 @@ export default function EditUserName() { placeholder="请输入新昵称" max={8} onChange={(value) => setName(value)} - value={"铁粉空间"} + value={name} style={{ "--placeholder-color": "#FFFFFF80" }} />
@@ -39,7 +94,7 @@ export default function EditUserName() { size="middle" block - // onClick={handleSubmit} + onClick={handleSubmit} style={{"--background-color": "#FF669E","color": "#FFFFFF"}} > 确认 diff --git a/app/my/editUserProfile/selectUserProfileItem/page.js b/app/my/editUserProfile/selectUserProfileItem/page.js index ed609e6..5911505 100644 --- a/app/my/editUserProfile/selectUserProfileItem/page.js +++ b/app/my/editUserProfile/selectUserProfileItem/page.js @@ -1,7 +1,7 @@ "use client"; import React, { useEffect, useState } from "react"; -import { Avatar, Divider, Input } from "antd-mobile"; +import { Avatar, Divider, Toast } from "antd-mobile"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faAngleLeft, faAngleRight } from "@fortawesome/free-solid-svg-icons"; import { useRouter } from "next/navigation"; @@ -18,23 +18,8 @@ export default function SelectUserProfileItem() { setUserInfo(userInfo); } }, []); - const uploadImg = async (e) => { - console.log(e.target.files[0]); - const file = e.target.files[0]; - var reader = new FileReader(); - reader.readAsDataURL(file); - if (file) { - reader.onload = (e) => { - uploadHead(); - }; - } - - // return { - // url: URL.createObjectURL(file), - // }; - }; - const uploadHead = async () => { - const avatarId = await uploadImage(userInfo?.avatar?.images[0]?.urls[0]); + const uploadHead = async (e) => { + const avatarId = await uploadImage(e.target.files[0]); try { const data = await require("POST", "/api/account/update", { body: { avatar: { image_ids: [avatarId] } }, @@ -97,7 +82,7 @@ export default function SelectUserProfileItem() { style={{ display: "none" }} accept="image/png, image/jpeg" capture="camera" - onChange={uploadImg} + onChange={uploadHead} />
diff --git a/app/my/page.js b/app/my/page.js index 557d658..214536b 100644 --- a/app/my/page.js +++ b/app/my/page.js @@ -101,22 +101,22 @@ const My = () => { className="text-center" onClick={() => router.push("my/relationship?key=follow")} > -

{userInfo?.follow_count}

+

{userInfo?.follow_count || 0}

关注

  • router.push("my/relationship?key=fans")} > -

    {userInfo?.is_followed_count}

    +

    {userInfo?.is_followed_count || 0}

    粉丝

  • router.push("my/wallet")}> -

    {userInfo.gold_num}

    +

    {userInfo.gold_num || 0}

    金币

  • router.push("my/wallet")}> -

    {userInfo.diamond_num}

    +

    {userInfo.diamond_num || 0}

    钻石

  • diff --git a/app/my/wallet/page.js b/app/my/wallet/page.js index 73ce94f..0116882 100644 --- a/app/my/wallet/page.js +++ b/app/my/wallet/page.js @@ -25,7 +25,7 @@ export default function Wallet() { icon={faAngleLeft} size="xl" onClick={() => { - router.back(); + router.push("/my"); }} />
    diff --git a/app/page.js b/app/page.js index b677475..7740cd2 100644 --- a/app/page.js +++ b/app/page.js @@ -144,6 +144,7 @@ const RecommPostList = forwardRef(({ scrollHeight }, ref) => { // throw new Error("刷新失败"); const list = await getRecommPostList(1); setCommenPostList(list); + setHasMore(true) } async function loadMore() { const list = await getRecommPostList(0); diff --git a/app/pay/page.js b/app/pay/page.js index f5f5c4f..a6c42fa 100644 --- a/app/pay/page.js +++ b/app/pay/page.js @@ -5,6 +5,7 @@ import { Mask, Divider } from "antd-mobile"; import { useRouter } from "next/navigation"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faAngleLeft } from "@fortawesome/free-solid-svg-icons"; +import {createOrder} from "@/api/public" export default function Pay() { const router = useRouter(); const [visible, setVisible] = useState(false); @@ -64,9 +65,7 @@ export default function Pay() { {/* */}
    { - router.push("/pay"); - }} + onClick={createOrder} > 支付宝支付
    diff --git a/app/share/[mid]/page.js b/app/share/[mid]/page.js new file mode 100644 index 0000000..49d1dd9 --- /dev/null +++ b/app/share/[mid]/page.js @@ -0,0 +1,113 @@ +"use client"; + +import React, { useEffect, useState } from "react"; +import { Divider, Toast } from "antd-mobile"; +import { useRouter, useParams, useSearchParams } from "next/navigation"; +import clipboard from "copy-to-clipboard"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + faAngleLeft, + faAngleRight, + faWallet, + faPrint, + faDollar, +} from "@fortawesome/free-solid-svg-icons"; +import { getStreamerInfo } from "@/api/space"; +export default function ShareSpace({ data }) { + const router = useRouter(); + const { mid } = useParams(); + const searchParams = useSearchParams(); + const webUrl = process.env.NEXT_PUBLIC_WEB_URL; + const [streamerInfo, setStreamerInfo] = useState(null); + useEffect(() => { + getStreamerInfo(Number(mid)).then((res) => { + setStreamerInfo(res); + }); + }, []); + //保存内容到剪贴板 + const copy = (_data) => { + console.log("_data",_data) + clipboard(_data); + Toast.show({ + icon: "success", + content: "已复制到剪贴板", + position: "top", + }); + }; + + //复制口令 + const copyShareCode = () => { + const shareCode = `【${streamerInfo?.streamer_ext?.name}】『ID:${streamerInfo?.streamer_ext?.user_id}』,复制此条消息,打开铁粉空间APP,查看详情${webUrl}/zone/${streamerInfo?.streamer_ext?.user_id}`; + + copy(shareCode); + }; + + //复制邀请链接 + const copyShareUrl = () => { + const shareCode = `${webUrl}/zone/${streamerInfo?.streamer_ext?.user_id}`; + console.log("shareCode", shareCode); + copy(shareCode); + }; + + return ( +
    +
    +
    + { + router.back(); + }} + /> +
    +

    分享空间

    +
    +
    +
    + 复制口令 + { + router.push("/my"); + }} + /> +
    + +
    + 复制邀请链接 + { + router.push("/my"); + }} + /> +
    + +
    { + // router.push("WebWithoutHeader", { + // uri: webUrl + "/zone/share/" + data?.streamer_ext?.user_id, + // }) + }} + className="flex justify-between pt-4 pb-2" + > + 生成分享卡片 + { + router.push("/my"); + }} + /> +
    + +
    +
    + ); +} diff --git a/app/space/[id]/page.js b/app/space/[id]/page.js index 1a29e2b..99b4da2 100644 --- a/app/space/[id]/page.js +++ b/app/space/[id]/page.js @@ -27,11 +27,7 @@ const anchors = [ window.innerHeight - 280, window.innerHeight - 60, ]; -const tabItems = [ - { label: "全部", key: "all" }, - { label: "铁粉专享", key: "ironFan" }, - { label: "超粉专享", key: "chaofen" }, -]; + export default function PersonSpace() { const router = useRouter(); const { id } = useParams(); @@ -39,6 +35,7 @@ export default function PersonSpace() { const [hasMore, setHasMore] = useState(true); const [scrollHeight, setScrollHeight] = useState(0); const [postList, setPostList] = useState([]); + const [tabItems, setTabItems] = useState([]); const [offset, setOffset] = useState(0); const [maskVisible, setMaskVisible] = useState({ visible: false, type: "" }); const [currentKey, setCurrentKey] = useState("all"); @@ -62,6 +59,17 @@ export default function PersonSpace() { // debugger } getStreamerInfo(Number(id)).then((res) => { + let tabitems = res.is_superfanship_enabled + ? [ + { label: "全部", key: "all" }, + { label: "铁粉专享", key: "ironFan" }, + { label: "超粉专享", key: "chaofen" }, + ] + : [ + { label: "全部", key: "all" }, + { label: "铁粉专享", key: "ironFan" }, + ]; + setTabItems(tabitems); setStreamerInfo(res); }); getCurrentTime(); @@ -174,10 +182,9 @@ export default function PersonSpace() { {/* 内容 */}
    @@ -220,7 +227,7 @@ export default function PersonSpace() {
    setMaskVisible(true)} + onClick={() => router.push("/share/"+streamerInfo?.streamer_ext?.mid)} >

    分享 @@ -270,29 +277,31 @@ export default function PersonSpace() { 10 )}/${parseInt(streamerInfo?.ironfanship_price / 100, 10)}`}

    -
  • { - streamerInfo?.is_superfanship_unlocked === 1 - ? setCurrentKey("chaofen") - : router.push("/pay"); - }} - > -
    - -
    -

    - {streamerInfo?.is_superfanship_unlocked === 1 - ? "尊贵超粉" - : "成为超粉"} -

    -
  • + {streamerInfo?.is_superfanship_enabled && ( +
  • { + streamerInfo?.is_superfanship_unlocked === 1 + ? setCurrentKey("chaofen") + : router.push("/pay"); + }} + > +
    + +
    +

    + {streamerInfo?.is_superfanship_unlocked === 1 + ? "尊贵超粉" + : "成为超粉"} +

    +
  • + )}
  • setMaskVisible(true)} @@ -308,7 +317,7 @@ export default function PersonSpace() {
  • 举报

    - {streamerInfo?.visitor_role === 3 && ( + {/* {streamerInfo?.visitor_role === 3 && (
  • router.push("VisibleToOneselfSpacePosts")} className="flex flex-col items-center" @@ -322,7 +331,7 @@ export default function PersonSpace() { />

    审核未通过

  • - )} + )} */}
    @@ -419,34 +428,35 @@ export default function PersonSpace() { />

    - {" "} {streamerInfo?.is_ironfanship_unlocked === 1 ? "已是铁粉" : "成为铁粉"}

    {/*

    0/299

    */} -
  • { - setCurrentKey("chaofen"); - }} - > -
    - -
    -

    - {streamerInfo?.is_superfanship_unlocked === 1 - ? "尊贵超粉" - : "成为超粉"} -

    -
  • + {streamerInfo?.is_superfanship_enabled && ( +
  • { + setCurrentKey("chaofen"); + }} + > +
    + +
    +

    + {streamerInfo?.is_superfanship_unlocked === 1 + ? "尊贵超粉" + : "成为超粉"} +

    +
  • + )} {maskVisible.type == "weChat" && ( { @@ -40,7 +41,7 @@ export default function Space() { // }; }, []); useEffect(() => { - firstRequest() + firstRequest(); }, [activeIndex]); const firstRequest = () => { resetOffset(); @@ -52,7 +53,7 @@ export default function Space() { setDataList(res); }); } - } + }; const resetOffset = () => { setOffset(0); // setDataList([]); @@ -72,7 +73,7 @@ export default function Space() { } //在末尾添加元素以展示查看更多卡片 if (data.data.list.length !== 0) { - const finalData = [...data.data.list, { id: 999999, last: true }]; + const finalData = [...data.data.list]; setDataList(finalData); return; } @@ -109,14 +110,16 @@ export default function Space() { async function loadMore() { if (!offset) return; const append = await getSpacePosts(offset); - if(append){ + if (append) { setDataList((val) => [...val, ...append]); setHasMore(append.length > 0); } - } return ( -
    +
    {!activeIndex && ( -
    + !loading ?
      - {dataList.map((item) => ( + {dataList?.map((item) => (
    • ))} +
    • router.push("/search")}> +
      navigation.navigate("Stream")} + // onClick={} + className="w-full h-52" + > +
      +
      +
      +
      +

      + 发现更多 +

      +

      + 缘分就在不经意间 +

      + + +
      +
      +
      +
    - {!dataList.length && ( + {!dataList?.length && (
    )} -
    +
    :
    )}
    - {activeIndex && -
    - + {!!activeIndex && ( +
    + {loading && ( <> @@ -206,10 +236,10 @@ export default function Space() { )} {dataList.map((item, index) => ( - - - - ))} + + + + ))} {!dataList.length && ( @@ -221,22 +251,24 @@ export default function Space() {
    )}
    - } + )}
    -
    - {scrollRef.current?.scrollTo(0, 0); firstRequest();}} - /> -
    + className={`fixed bottom-[78px] right-4 z-[999] w-10 h-10 flex items-center justify-center bg-[#1d1d1d71] rounded-full text-white ${ + loading && !offset ? "animate-spin" : "" + }`} + > + { + scrollRef.current?.scrollTo(0, 0); + firstRequest(); + }} + /> +
    ); } @@ -245,7 +277,7 @@ const VisitingCard = ({ data }) => { const router = useRouter(); return (
    router.push("/space/" + data?.streamer_ext?.mid)} > {data?.is_unread_zone_moment_exist === 1 && ( diff --git a/app/space/person_space_introduce/[mid]/page.js b/app/space/person_space_introduce/[mid]/page.js index bfaab08..2d1a6a8 100644 --- a/app/space/person_space_introduce/[mid]/page.js +++ b/app/space/person_space_introduce/[mid]/page.js @@ -92,9 +92,9 @@ export default function PersonSpaceIntroduce() { {/* 内容 */}
    diff --git a/components/PaySpacePost/index.js b/components/PaySpacePost/index.js index 0138a81..53a2945 100644 --- a/components/PaySpacePost/index.js +++ b/components/PaySpacePost/index.js @@ -3,7 +3,11 @@ import React, { useRef, useState } from "react"; import { Image } from "antd-mobile"; -export default function PaySpacePost({ type = "ironFan", status = 0,data={} }) { +export default function PaySpacePost({ + type = "ironFan", + status = 0, + data = {}, +}) { return (
    {!data.is_zone_moment_unlocked ? ( - - {status === 1 - ? "已付费解锁" - : `${type === "ironFan" ? "铁粉" : "超粉"}免费查看`} - - ) : ( {data.is_ironfan_visible === 1 ? "铁粉免费查看" @@ -44,6 +42,21 @@ export default function PaySpacePost({ type = "ironFan", status = 0,data={} }) { ? "超粉免费查看" : "付费解锁"} + ) : ( + + {data.is_ironfanship_unlocked === 1 && + data.is_ironfan_visible === 1 && + "已使用铁粉特权解锁"} + {data.is_superfanship_unlocked === 1 && + data.is_ironfan_visible === 0 && + "已使用超粉特权解锁"} + {data.is_superfanship_unlocked === 0 && + data.is_ironfan_visible === 0 && + "已付费解锁"} + {data.is_ironfanship_unlocked === 0 && + data.is_ironfan_visible === 1 && + "已付费解锁"} + )}
    } - width={"100%"} - height={"100%"} + width={currentPhotos.length>1 ? "25vw":"100%"} + height={currentPhotos.length>1 ? "25vw":"100%"} className={`rounded max-w-full`} fit="cover" src={item.url} diff --git a/components/PostItem/index.js b/components/PostItem/index.js index a98d5df..b754a32 100644 --- a/components/PostItem/index.js +++ b/components/PostItem/index.js @@ -30,7 +30,7 @@ export default function PostItem({ }, []); const getDays = useMemo(() => { const today = new Date(); - const days = Math.floor((today - date) / (1000 * 60 * 60 * 24)); + const days = Math.floor((today - data.ct) / (1000 * 60 * 60 * 24)); return days; }, []); return ( @@ -73,7 +73,7 @@ export default function PostItem({
    {data.media_component && } - {type == "space" && !isCreator && !!data.c_type && ( + {type == "space" && !isCreator && data.c_type && ( - 点赞 + {isThumbsUp == 1 ? "已赞" : "点赞"}
    ···
    diff --git a/package-lock.json b/package-lock.json index 0ace2f0..21a5692 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@reduxjs/toolkit": "^2.2.6", "antd-mobile": "^5.36.1", "cookies-next": "^4.0.0", + "copy-to-clipboard": "^3.3.3", "crypto-js": "^4.2.0", "jsencrypt": "^3.3.2", "next": "14.0.2", @@ -887,6 +888,14 @@ "url": "https://github.com/sponsors/mesqueeb" } }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2559,6 +2568,11 @@ "node": ">=8.0" } }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -3316,6 +3330,14 @@ "is-what": "^3.14.1" } }, + "copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "requires": { + "toggle-selection": "^1.0.6" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -4452,6 +4474,11 @@ "is-number": "^7.0.0" } }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, "ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", diff --git a/package.json b/package.json index c6f758e..da5d983 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@reduxjs/toolkit": "^2.2.6", "antd-mobile": "^5.36.1", "cookies-next": "^4.0.0", + "copy-to-clipboard": "^3.3.3", "crypto-js": "^4.2.0", "jsencrypt": "^3.3.2", "next": "14.0.2", diff --git a/public/icons/magnifier.png b/public/icons/magnifier.png new file mode 100644 index 0000000000000000000000000000000000000000..23b78b06195e6875f8903a8d3d725abc3e2a2b2c GIT binary patch literal 1738 zcmV;*1~vJKP)P)t-s0000e zC@v`{Eh#4~ARsU)CoC!^Eh#4~DJLu{CoL%`Ei5Q3DJCo^C@d%^EGZ`}D<~}~DJ&@` zEGZ@}Fd#4~C@m@`D=RB7DJLxTcZfp(000Kw$4+Ft1P$ z-=8qp1o~0{00tIGL_t(|+U=a#lH(u@MOls4cU~hG3h|}gg!QVE?Xt3Wikq#o0qUd~*gK?#_5=(8ZI;5m zSHrWj@sb5O{WipEiuheE(vl<=&hkp>&XOgX-!SV${HC9n6(i=uG@VT=ojlYBVUtTN zNfG&GvuNZMd-{}4WkzW;N+dDn{*M`}Gp1^-TNPy^K3bQma{18NGBSjywil{oU}_t# zkF7P!#JT!DO8B&!R*o?PQ@zC4gx1`fnLJNWli5VZ#IC}!qtp`vT8+#UK57ghG=V>$ z3dW7Yg@Z5R>LP@$YnC=>zP|MI1PFh{a5rvx=N?Q!n8)E4Y$~!K5zX%W$fYrHYP(?U z%u54BE*y+Z5aKaEQG5cQUBC)Zu*W2L4xs?xBC35oS~M)3}y zAed4pzq2Wflf{z!ukZocGRoOHS+Ai(DTi2RYr;eY^2;MK!gs)!sB4=|*vAYQ_+WT| z-w36HJTR+>s2N$94jU|~LgtSaM@@VgD&v+caEZ->$30-gIS5m75g0qXqpyFoag_My z4Poi0VG%mUS1H>dQ*x1_6F&MFN`;5z5R$DPX&M-uHr5bF3Zk=5P5LPVSE^bZw+iOS zjffZzdh!4C2djv9I_X=F-yhD|0z z;>Ca&nDPvron}ZeJiV40(2jI1R}wf6qiiQtI|6oWi-^+kz$5!v~2>Y5d-9 zSQ*L|PR`OF+nlARgrn-1eeu1z@iWLkWAwg!Zom&rs1}W?$u}albl%2QF?!DIiQyS| zJEi#S$kfo^o*`*iCatrB5jF3gKd%gmK0|hoz~e!OOsT7@?6?!Rsyb{FIU>ZihT@~{c?XvH-Ae4={6=7l0%blUWlbb5CYj!^tafmW^Z>@#%)c5a&kkmxu(^i#sev9%9O%0x0s6jJ^5a9PPQI@H{Q2% zb3Oj{zl-g`4vunK{2Q?rTT4Ed{x{;sT*(^;v{)c0(!j#SR zcHO=PQ*yA$a*{1XnSKv&{WE9Tr35e}3UGXunXU$$3j_h4VJ9Ww!KW#U7wN`& z#K9)ag015x>yh?X?_ics&)8YF1jqz{GAko~qz04)85^(`Ty9(rUPi&ePSIj9{;xcF?6Y6GAB?|8`8;QRyAbhJxF4E2H+`gL**^)$Io zV@5J%pY^W8L0YVad?r?M;{A(hC`G1=@A#Q_=#*UKxXN}o5erdT5qC4N+Rw3AkkWR| zK)8Rn1m$@j5c!sAOi91hQMNnx18NBfi7~#}V0E%J!>WFxTD`C zRb46U3s$tY5LKL(oc>2EDDC8J7Bdb=d;wifhifbxW- zlJ5E`$B#dZ_pv?ovSL0=$r6kI5TmNE<`B~*fr1W#FaxrlQqvH{bi4os>R zXJ^=FUvu(1W68-7=5KDFuG~DVC%xvxC6ic9HWuL5XqJ za&FEkmsy!}4l+a=91xc|@+