Files
mini-programs/src/components/PublishMenu/PublishMenu.tsx
张成 969066591c 1
2026-02-05 23:23:21 +08:00

213 lines
6.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useRef, useEffect } from "react";
import { View, Text, Image } from "@tarojs/components";
import Taro from "@tarojs/taro";
import { useUserInfo } from "@/store/userStore";
import {
useEvaluate,
EvaluateCallback,
EvaluateScene,
} from "@/store/evaluateStore";
import { useListState } from "@/store/listStore";
import { navigateTo, redirectTo, navigateBack } from "@/utils/navigation";
import { requireLoginWithPhone } from "@/utils/helper";
import styles from "./index.module.scss";
import images from "@/config/images";
import AiImportPopup from "@/publish_pages/publishBall/components/AiImportPopup";
import NTRPEvaluatePopup from "../NTRPEvaluatePopup";
export interface PublishMenuProps {
onPersonalPublish?: () => void;
onActivityPublish?: () => void;
onVisibleChange?: (visible: boolean) => void; // 菜单显示/隐藏回调
}
const PublishMenu: React.FC<PublishMenuProps> = (props) => {
const { onVisibleChange } = props;
const [isVisible, setIsVisible] = useState(false);
const {
area
} = useListState();
// 使用 useEffect 监听 isVisible 变化,确保所有情况都能触发回调
useEffect(() => {
onVisibleChange?.(isVisible);
}, [isVisible, onVisibleChange]);
const [aiImportVisible, setAiImportVisible] = useState(false);
const userInfo = useUserInfo();
const ntrpRef = useRef<{
show: (evaluateCallback: EvaluateCallback) => void;
}>({ show: () => {} });
const handleIconClick = () => {
// 点击发布 icon 时先检查登录状态和手机号
if (!requireLoginWithPhone()) {
// 未登录或未绑定手机号,已跳转到登录页,不显示菜单
return;
}
// 已登录,显示/隐藏菜单
setIsVisible(!isVisible);
};
const handleOverlayClick = () => {
setIsVisible(false);
};
const handleMenuClick = (type: "individual" | "group" | "ai") => {
// 跳转到publishBall页面并传递type参数
console.log(type, "type");
setIsVisible(false);
if (type === "ai") {
setAiImportVisible(true);
return;
}
navigateTo({
url: `/publish_pages/publishBall/index?type=${type}`,
});
};
const handleMenuItemClick = (type: "individual" | "group" | "ai") => {
const [_, address] = area;
if (address !== '上海市') {
(Taro as any).showModal({
title: '提示',
content: '仅上海地区开放,您可加入社群或切换城市',
showCancel: false,
confirmText: '知道了'
})
return;
}
if (!userInfo.ntrp_level) {
ntrpRef.current.show({
type: EvaluateScene.publish,
next: ({ flag }) => {
if (flag) {
handleMenuClick(type);
} else if (type === "ai") {
navigateBack();
setAiImportVisible(true);
} else {
redirectTo({
url: `/publish_pages/publishBall/index?type=${type}`,
});
}
},
onCancel: () => {
navigateBack();
},
});
setIsVisible(false);
return;
}
handleMenuClick(type);
};
const handleAiImportClose = () => {
setAiImportVisible(false);
};
const handleManualPublish = () => {
navigateTo({
url: "/publish_pages/publishBall/index?type=individual",
});
};
return (
<View className={styles.publishMenu}>
{/* 蒙层 */}
{isVisible && (
<View className={styles.overlay} onClick={handleOverlayClick} />
)}
{/* 菜单选项 */}
{isVisible && (
<View className={styles.menuCard}>
<View
className={styles.menuItem}
onClick={() => handleMenuItemClick("individual")}
>
<View className={styles.menuContent}>
<View className={styles.menuTitle}>
<View className={styles.menuArrow}>
<Image
src={images.ICON_ARROW_RIGHT_BLACK}
className={styles.img}
/>
</View>
</View>
<Text className={styles.menuDesc}>
</Text>
</View>
<View className={styles.menuIcon}>
<Image src={images.ICON_PERSON} />
</View>
</View>
<View
className={styles.menuItem}
onClick={() => handleMenuItemClick("group")}
>
<View className={styles.menuContent}>
<View className={styles.menuTitle}>
<View className={styles.menuArrow}>
<Image
src={images.ICON_ARROW_RIGHT_BLACK}
className={styles.img}
/>
</View>
</View>
<Text className={styles.menuDesc}></Text>
</View>
<View className={styles.menuIcon}>
<Image src={images.ICON_GROUP} />
</View>
</View>
<View
className={`${styles.menuItem} ${styles.aiItem}`}
onClick={() => handleMenuItemClick("ai")}
>
<View className={styles.menuContent}>
<View className={styles.menuTitle}>
<View className={styles.menuArrow}>
<Image
src={images.ICON_ARROW_RIGHT_WHITE}
className={styles.img}
/>
</View>
</View>
<Text className={styles.menuDesc}>
/
</Text>
</View>
<View className={styles.menuIcon}>
<Image src={images.ICON_IMPORTANT_BTN} />
</View>
</View>
</View>
)}
{/* 绿色圆形按钮 */}
<View
className={`${styles.greenButton} ${isVisible ? styles.rotated : ""}`}
onClick={handleIconClick}
>
<Image src={images.ICON_PUBLISH} className={styles.closeIcon} />
</View>
{/* AI导入弹窗 */}
<AiImportPopup
visible={aiImportVisible}
onClose={handleAiImportClose}
onManualPublish={handleManualPublish}
/>
<NTRPEvaluatePopup type={EvaluateScene.publish} ref={ntrpRef} showGuide />
</View>
);
};
export default PublishMenu;