87 lines
2.6 KiB
TypeScript
87 lines
2.6 KiB
TypeScript
/**
|
|
* 线索项组件
|
|
* 可复用的线索展示组件,处理线索的点击、已浏览标记等
|
|
*/
|
|
import { Image } from "@/components";
|
|
import { cn, getStaticImage } from "@/lib/utils";
|
|
import type { ClueKey } from "./types";
|
|
|
|
export interface ClueItemProps {
|
|
/** 线索键名 */
|
|
clueKey: ClueKey;
|
|
/** 线索图片路径 */
|
|
imageSrc: string;
|
|
/** 是否已浏览 */
|
|
isViewed: boolean;
|
|
/** 点击回调 */
|
|
onClick: () => void;
|
|
/** 自定义类名 */
|
|
className?: string;
|
|
/** 已浏览标记的位置偏移 */
|
|
viewedMarkOffset?: { left?: string; top?: string; bottom?: string };
|
|
/** 已浏览标记文本,默认为"已浏览" */
|
|
viewedText?: string;
|
|
/** 线索类型:普通线索或电话线索 */
|
|
type?: "normal" | "phone";
|
|
}
|
|
|
|
/**
|
|
* 线索项组件
|
|
* 显示线索图片、搜索动画(未浏览时)、已浏览标记(已浏览时)
|
|
*/
|
|
export const ClueItem = ({
|
|
clueKey,
|
|
imageSrc,
|
|
isViewed,
|
|
onClick,
|
|
className,
|
|
viewedMarkOffset = {},
|
|
viewedText = "已浏览",
|
|
type = "normal",
|
|
}: ClueItemProps) => {
|
|
// 根据线索类型确定搜索图标的位置
|
|
const searchIconPosition =
|
|
type === "phone" ? "left-[45%] top-[45%]" : "left-1/2 top-[45%]";
|
|
|
|
return (
|
|
<div className={cn("cursor-pointer", className)} onClick={onClick}>
|
|
{/* 线索图片 */}
|
|
<Image src={getStaticImage(imageSrc)} />
|
|
|
|
{/* 搜索图标 - 未浏览时显示 */}
|
|
{!isViewed && (
|
|
<Image
|
|
className={cn(
|
|
"absolute pointer-events-none animate-search",
|
|
searchIconPosition,
|
|
"-translate-x-1/2 -translate-y-1/2"
|
|
)}
|
|
src={getStaticImage("chenyun/reflection/探索")}
|
|
/>
|
|
)}
|
|
|
|
{/* 已浏览标记 */}
|
|
{isViewed && (
|
|
<div
|
|
className="absolute left-1/2 -translate-x-1/2 bottom-0"
|
|
style={{
|
|
marginLeft: viewedMarkOffset.left || (clueKey === "yinyuan-clue1" || clueKey === "yinyuan-clue2" ? "20px" : clueKey === "mimian-intelligence" ? "4px" : clueKey === "mimian-distribution" ? "12px" : "0"),
|
|
bottom: viewedMarkOffset.bottom || (type === "phone" ? "0" : "0"),
|
|
}}
|
|
>
|
|
<span
|
|
className={cn([
|
|
"text-[#ae6400] text-3xl font-bold",
|
|
type === "phone" ? "" : "whitespace-nowrap",
|
|
"[text-shadow:_-4px_-4px_0_#ffffff,_4px_-4px_0_#ffffff,_-4px_4px_0_#ffffff,_4px_4px_0_#ffffff,_-5px_0_0_#ffffff,_5px_0_0_#ffffff,_0_-5px_0_#ffffff,_0_5px_0_#ffffff]",
|
|
])}
|
|
>
|
|
{viewedText}
|
|
</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|