Files
mini-programs/src/components/NTRPTestEntryCard/index.tsx
2026-02-07 18:07:33 +08:00

226 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect, useCallback, memo } from "react";
import { View, Image, Text } from "@tarojs/components";
import { requireLoginWithPhone } from "@/utils/helper";
import Taro from "@tarojs/taro";
import {
useUserInfo,
useUserActions,
useLastTestResult,
} from "@/store/userStore";
// import { getCurrentFullPath } from "@/utils";
import { OSS_BASE } from "@/config/api";
import { StageType } from "@/services/evaluateService";
import { waitForAuthInit } from "@/utils/authInit";
import DocCopy from "@/static/ntrp/ntrp_doc_copy.svg";
import ArrowRight from "@/static/ntrp/ntrp_arrow_right_color.svg";
import {
EvaluateScene,
useEvaluate,
EvaluateCallback,
} from "@/store/evaluateStore";
import styles from "./index.module.scss";
function NTRPTestEntryCard(props: {
type: EvaluateScene;
evaluateCallback?: EvaluateCallback;
}) {
const { type, evaluateCallback } = props;
const userInfo = useUserInfo();
const { setCallback } = useEvaluate();
const { fetchUserInfo, fetchLastTestResult } = useUserActions();
// 使用全局状态中的测试结果,避免重复调用接口
const lastTestResult = useLastTestResult();
// 从全局状态中获取测试结果,如果不存在则调用接口(使用请求锁避免重复调用)
useEffect(() => {
const init = async () => {
// 先等待静默登录完成
await waitForAuthInit();
// 然后再获取用户信息
if (!userInfo.id) {
await fetchUserInfo();
}
// 如果全局状态中没有测试结果,则调用接口(使用请求锁,多个组件同时调用时只会请求一次)
if (!lastTestResult) {
await fetchLastTestResult();
}
};
init();
}, [userInfo.id, fetchUserInfo, fetchLastTestResult, lastTestResult]);
// 从全局状态中计算标志位
const testFlag = lastTestResult?.has_test_record || false;
const hasTestInLastMonth = lastTestResult?.has_test_in_last_month || false;
const handleTest = useCallback(
function () {
// 没有绑定手机号,线条转登陆
// if (!requireLoginWithPhone()) {
// return;
// }
switch (type) {
case EvaluateScene.list:
setCallback({
type,
next: () => {
Taro.redirectTo({ url: "/main_pages/index" });
},
onCancel: () => {
Taro.navigateBack();
},
});
break;
case EvaluateScene.share:
setCallback({
type,
next: () => {
Taro.redirectTo({ url: "/main_pages/index" });
},
onCancel: () => {
Taro.redirectTo({ url: "/main_pages/index" });
},
});
break;
case EvaluateScene.detail:
case EvaluateScene.publish:
setCallback(evaluateCallback as EvaluateCallback);
break;
case EvaluateScene.user:
setCallback({
type,
next: () => {
Taro.redirectTo({ url: "/main_pages/index" });
},
onCancel: () => {
// Taro.redirectTo({ url: "/user_pages/myself/index" });
Taro.navigateBack();
},
});
break;
case EvaluateScene.userEdit:
setCallback({
type,
next: () => {
Taro.redirectTo({ url: "/main_pages/index" });
},
onCancel: () => {
// Taro.redirectTo({ url: "/user_pages/edit/index" });
Taro.navigateBack();
},
});
break;
default:
setCallback({
type,
next: () => {
Taro.redirectTo({ url: "/main_pages/index" });
},
onCancel: () => {
Taro.redirectTo({ url: "/main_pages/index" });
},
});
}
if (!testFlag && !userInfo.phone) {
Taro.navigateTo({
url: `/login_pages/index/index?redirect=${encodeURIComponent(
`/other_pages/ntrp-evaluate/index?stage=${StageType.INTRO}`,
)}`,
});
return false;
}
Taro.navigateTo({
url: `/other_pages/ntrp-evaluate/index?stage=${
testFlag ? StageType.INTRO : StageType.TEST
}`,
});
},
[setCallback, testFlag, type, evaluateCallback, userInfo.phone],
);
// 如果最近一个月有测试记录,则不展示
if (hasTestInLastMonth && type === EvaluateScene.list) {
return null;
}
return type === EvaluateScene.list ? (
<View className={styles.higher} onClick={handleTest}>
<View
className={styles.lines}
style={{
backgroundImage: `url(${OSS_BASE}/front/ball/images/215f1ce1-be52-4a92-8250-5a4a69e7f2b3.png)`,
}}
/>
<View className={styles.desc}>
<View>
<View className={styles.title}>
<Text></Text>
</View>
<View className={styles.title}>
<Text></Text>
<Text className={styles.colorTip}> (</Text>
<Text className={styles.strongTip}>NTRP</Text>
<Text className={styles.colorTip}>) </Text>
<Text>?</Text>
</View>
</View>
<View className={styles.entry}>
<Text></Text>
<Image className={styles.entryIcon} src={ArrowRight} />
</View>
</View>
<View className={styles.avatarWrap}>
<View className={styles.avatar}>
<Image
className={styles.avatarUrl}
src={userInfo.avatar_url}
mode="aspectFill"
/>
</View>
{/* avatar side */}
<View className={styles.addonImage}>
<Image className={styles.docImage} src={DocCopy} mode="aspectFill" />
</View>
</View>
</View>
) : (
<View className={styles.lower} onClick={handleTest}>
<View
className={styles.lines}
style={{
backgroundImage: `url(${OSS_BASE}/front/ball/images/215f1ce1-be52-4a92-8250-5a4a69e7f2b3.png)`,
}}
/>
<View className={styles.desc}>
<View className={styles.title}>
<Text></Text>
<Text className={styles.colorTip}> (</Text>
<Text className={styles.strongTip}>NTRP</Text>
<Text className={styles.colorTip}>) </Text>
<Text>?</Text>
</View>
<View className={styles.entry}>
<Text></Text>
<Image className={styles.entryIcon} src={ArrowRight} />
</View>
</View>
<View className={styles.avatarWrap}>
<View className={styles.avatar}>
<Image
className={styles.avatarUrl}
src={userInfo.avatar_url}
mode="aspectFill"
/>
</View>
{/* avatar side */}
<View className={styles.addonImage}>
<Image className={styles.docImage} src={DocCopy} mode="aspectFill" />
</View>
</View>
</View>
);
}
export default memo(NTRPTestEntryCard);
// export default NTRPTestEntryCard;