|
@@ -0,0 +1,327 @@
|
|
|
+import React, {
|
|
|
+ useCallback,
|
|
|
+ useEffect,
|
|
|
+ useMemo,
|
|
|
+ useRef,
|
|
|
+ useState,
|
|
|
+} from "react";
|
|
|
+import styles from "./index.module.scss";
|
|
|
+import Tab3InfoMtxt from "./Tab3InfoMtxt";
|
|
|
+import {
|
|
|
+ A2BarrageType,
|
|
|
+ A2FileObjType,
|
|
|
+ A2FileType,
|
|
|
+ A2GoodsType,
|
|
|
+ A2QuestionType,
|
|
|
+} from "@/types";
|
|
|
+import {
|
|
|
+ A2_APIgetBarrage,
|
|
|
+ A2_APIgetBarrageAll,
|
|
|
+ A2_APIgetConfigBarrage,
|
|
|
+ A2_APIgetGoodsInfo,
|
|
|
+ A2_APIgetQuestion,
|
|
|
+ A2_APIgoodsaddStar,
|
|
|
+} from "@/store/action/A2Main";
|
|
|
+import { Toast } from "antd-mobile";
|
|
|
+
|
|
|
+type Props = {
|
|
|
+ isOpen: boolean;
|
|
|
+ id: number;
|
|
|
+ closePage?: () => void;
|
|
|
+};
|
|
|
+
|
|
|
+function Tab3InfoM({ isOpen, id, closePage }: Props) {
|
|
|
+ // 文物信息
|
|
|
+ const [info, setInfo] = useState<A2GoodsType>({} as A2GoodsType);
|
|
|
+
|
|
|
+ // 附件数据(除开音频)
|
|
|
+ const [fileList, setFileList] = useState<A2FileObjType>({
|
|
|
+ model: [],
|
|
|
+ video: [],
|
|
|
+ img: [],
|
|
|
+ });
|
|
|
+
|
|
|
+ // 音频
|
|
|
+ const [right1, setRight1] = useState({ show: false, url: "" });
|
|
|
+ const audioUrlRef = useRef("");
|
|
|
+
|
|
|
+ // 弹幕
|
|
|
+ const [right5, setRight5] = useState({ show: false, done: false });
|
|
|
+
|
|
|
+ // 点赞
|
|
|
+ const [right6, setRight6] = useState(false);
|
|
|
+ // 分享
|
|
|
+ const [right7, setRight7] = useState(false);
|
|
|
+
|
|
|
+ //问答
|
|
|
+ const [right3, setRight3] = useState(false);
|
|
|
+
|
|
|
+ // 知识
|
|
|
+ const [right4, setRight4] = useState(false);
|
|
|
+
|
|
|
+ // 留言板(默认显示),传递 到二级页面 看看是否开启了 留言到后端的 功能
|
|
|
+ const [right2, setRight2] = useState(false);
|
|
|
+
|
|
|
+ // 点击点赞
|
|
|
+ const likeClickFu = useCallback(async () => {
|
|
|
+ if (right6) return;
|
|
|
+ setRight6(true);
|
|
|
+ try {
|
|
|
+ await A2_APIgoodsaddStar(id);
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ window.setTimeout(() => {
|
|
|
+ setRight6(false);
|
|
|
+ }, 3000);
|
|
|
+ }, [id, right6]);
|
|
|
+
|
|
|
+ // 点击分享链接
|
|
|
+ const fenXClickFu = useCallback(() => {
|
|
|
+ if (right7) return;
|
|
|
+ setRight7(true);
|
|
|
+ window.setTimeout(() => {
|
|
|
+ setRight7(false);
|
|
|
+ }, 3000);
|
|
|
+ let OrderNumber = window.location.origin + "/pc/#/goods?id=" + id;
|
|
|
+ let newInput = document.createElement("input");
|
|
|
+ newInput.value = OrderNumber;
|
|
|
+ document.body.appendChild(newInput);
|
|
|
+ newInput.select();
|
|
|
+ document.execCommand("Copy");
|
|
|
+ newInput.remove();
|
|
|
+ Toast.show({
|
|
|
+ icon: "success",
|
|
|
+ content: "复制链接成功",
|
|
|
+ });
|
|
|
+ }, [id, right7]);
|
|
|
+
|
|
|
+ // 问答数组
|
|
|
+ const [question, setQuestion] = useState<A2QuestionType[]>([]);
|
|
|
+
|
|
|
+ // 文物留言的数组
|
|
|
+ const [barrage, setBarrage] = useState<A2BarrageType[]>([]);
|
|
|
+
|
|
|
+ // 所有弹幕的数组
|
|
|
+ const [barrageAll, setBarrageAll] = useState<A2BarrageType[]>([]);
|
|
|
+ const barrMoveRef = useRef<HTMLDivElement>(null);
|
|
|
+ const [barrInd, setBarrInd] = useState(0);
|
|
|
+ const barrMoveRefKill = useRef<any>(null);
|
|
|
+
|
|
|
+ // 每次弹幕的索引变化的时候
|
|
|
+ useEffect(() => {
|
|
|
+ window.setTimeout(() => {
|
|
|
+ const width = barrMoveRef.current?.offsetWidth || 0;
|
|
|
+
|
|
|
+ if (barrMoveRef.current) {
|
|
|
+ barrMoveRef.current.style.right = -width - 200 + "px";
|
|
|
+
|
|
|
+ const endNum = -window.innerWidth - width - 200;
|
|
|
+ barrMoveRefKill.current?.kill();
|
|
|
+ // 开始动画
|
|
|
+
|
|
|
+ // 总弹幕数量只有 1 的情况
|
|
|
+ if (barrageAll.length === 1) {
|
|
|
+ barrMoveRefKill.current = gsap.to(barrMoveRef.current, {
|
|
|
+ duration: 16,
|
|
|
+ ease: "none",
|
|
|
+ x: endNum,
|
|
|
+ repeat: -1,
|
|
|
+ });
|
|
|
+ } else if (barrageAll.length > 1) {
|
|
|
+ // 有超过 1 的情况
|
|
|
+ barrMoveRefKill.current = gsap.fromTo(
|
|
|
+ barrMoveRef.current,
|
|
|
+ { x: 0 },
|
|
|
+ {
|
|
|
+ duration: 16,
|
|
|
+ ease: "none",
|
|
|
+ x: endNum,
|
|
|
+ onComplete: () => {
|
|
|
+ let num = barrInd + 1;
|
|
|
+ if (num >= barrageAll.length) num = 0;
|
|
|
+ setBarrInd(num);
|
|
|
+ },
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 200);
|
|
|
+ }, [barrInd, barrageAll.length]);
|
|
|
+
|
|
|
+ // 通过id获取详情
|
|
|
+ const getDataFu = useCallback(
|
|
|
+ async (id: number) => {
|
|
|
+ const res = await A2_APIgetGoodsInfo(id);
|
|
|
+ if (res.code === 0) {
|
|
|
+ const info: A2GoodsType = res.data.entity;
|
|
|
+
|
|
|
+ // 留言板 和 弹幕开关 是否显示
|
|
|
+ const res_b = await A2_APIgetConfigBarrage();
|
|
|
+ if (res_b.code === 0) {
|
|
|
+ const value_b = JSON.parse(res_b.data.content);
|
|
|
+ if (value_b.value) {
|
|
|
+ // 获取所有的弹幕数组
|
|
|
+ const resBa_all = await A2_APIgetBarrageAll();
|
|
|
+ if (resBa_all.code === 0) {
|
|
|
+ setBarrageAll(resBa_all.data);
|
|
|
+ }
|
|
|
+ //打开了弹幕总开关 并且所有弹幕的数组长度>0
|
|
|
+ if (resBa_all.data.length) {
|
|
|
+ // 显示弹幕开关
|
|
|
+ setRight5({ show: true, done: true });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 文物的弹幕留言开关 和总 弹幕开关都开启了(可以在二级页面发送接口留言)
|
|
|
+ if (info.isBarrage) setRight2(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const file: A2FileType[] = res.data.file;
|
|
|
+
|
|
|
+ // 整理附件数据
|
|
|
+ const fileObj: A2FileObjType = {
|
|
|
+ model: [],
|
|
|
+ video: [],
|
|
|
+ img: [],
|
|
|
+ };
|
|
|
+ file.forEach((v) => {
|
|
|
+ if (v.type === "model") fileObj.model.push(v);
|
|
|
+ else if (v.type === "video") fileObj.video.push(v);
|
|
|
+ else if (v.type === "img") fileObj.img.push(v);
|
|
|
+ });
|
|
|
+
|
|
|
+ setFileList(fileObj);
|
|
|
+
|
|
|
+ // 有上传音频
|
|
|
+ const isAudioObj = file.find((v) => v.type === "audio");
|
|
|
+ if (isAudioObj) {
|
|
|
+ setRight1({ show: !isOpen, url: isAudioObj.filePath });
|
|
|
+ audioUrlRef.current = isAudioObj.filePath;
|
|
|
+ }
|
|
|
+
|
|
|
+ setInfo(info);
|
|
|
+
|
|
|
+ // 看看是否有相关的问答
|
|
|
+ const res2 = await A2_APIgetQuestion(id);
|
|
|
+ if (res2.code === 0) {
|
|
|
+ // 如有有选择 知识驿站
|
|
|
+ if (info.tagType) setRight4(true);
|
|
|
+ // 如果有问答
|
|
|
+ if (res2.data.length) setRight3(true);
|
|
|
+ const res3 = await A2_APIgetBarrage(id);
|
|
|
+ setQuestion(res2.data);
|
|
|
+ if (res3.code === 0) {
|
|
|
+ // 如果这条文物有留言
|
|
|
+ // if (res3.data.length) setRight2;
|
|
|
+ setBarrage(res3.data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [isOpen]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 有关音频
|
|
|
+ useEffect(() => {
|
|
|
+ if (right1.url) {
|
|
|
+ // 如果是从 文物 详情 进来---直接播放音频
|
|
|
+ window.setTimeout(() => {
|
|
|
+ const dom: HTMLAudioElement | null = document.querySelector("#myAudio");
|
|
|
+
|
|
|
+ if (dom) {
|
|
|
+ dom.onended = () => {
|
|
|
+ // console.log("-------音频播放结束");
|
|
|
+ setRight1({ show: false, url: audioUrlRef.current });
|
|
|
+ };
|
|
|
+ // 音频的状态
|
|
|
+ if (!isOpen) dom.play();
|
|
|
+ }
|
|
|
+ }, 100);
|
|
|
+ }
|
|
|
+ }, [isOpen, right1.url]);
|
|
|
+
|
|
|
+ // 打开和关闭音频
|
|
|
+ const audioCutFu = useCallback((val: boolean) => {
|
|
|
+ const dom: HTMLAudioElement | null = document.querySelector("#myAudio");
|
|
|
+ if (dom) {
|
|
|
+ if (!val) dom.play();
|
|
|
+ else dom.pause();
|
|
|
+ setRight1({ show: !val, url: audioUrlRef.current });
|
|
|
+ }
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ getDataFu(id);
|
|
|
+ return () => {
|
|
|
+ barrMoveRefKill.current?.kill();
|
|
|
+ };
|
|
|
+ }, [getDataFu, id]);
|
|
|
+
|
|
|
+ // 文件类型 type
|
|
|
+ const [type, setType] = useState<"model" | "video" | "img">("model");
|
|
|
+
|
|
|
+ // 每次变化type的时候把 索引变成0
|
|
|
+ useEffect(() => {
|
|
|
+ setShowInd(0);
|
|
|
+ }, [type]);
|
|
|
+
|
|
|
+ // 切换不同文件(模型/视频/图片的数组)
|
|
|
+ const typeArr = useMemo(() => {
|
|
|
+ const arr: {
|
|
|
+ name: "模型" | "视频" | "图片";
|
|
|
+ type: "model" | "video" | "img";
|
|
|
+ }[] = [];
|
|
|
+ if (fileList.model.length) arr.push({ name: "模型", type: "model" });
|
|
|
+ if (fileList.video.length) arr.push({ name: "视频", type: "video" });
|
|
|
+ if (fileList.img.length) arr.push({ name: "图片", type: "img" });
|
|
|
+ return arr;
|
|
|
+ }, [fileList]);
|
|
|
+
|
|
|
+ // 当前默认展示什么模块(优先级按照 模型-视频-图片)
|
|
|
+ useEffect(() => {
|
|
|
+ if (fileList.model.length) setType("model");
|
|
|
+ else if (fileList.video.length) setType("video");
|
|
|
+ else setType("img");
|
|
|
+ }, [fileList]);
|
|
|
+
|
|
|
+ // 在页面展示的数组
|
|
|
+ const list = useMemo(() => {
|
|
|
+ return fileList[type];
|
|
|
+ }, [fileList, type]);
|
|
|
+
|
|
|
+ // 当前显示的 索引
|
|
|
+ const [showInd, setShowInd] = useState(0);
|
|
|
+ const cutIndFu = useCallback(
|
|
|
+ (num: number, flag: boolean, ind: number) => {
|
|
|
+ let index = showInd + num;
|
|
|
+
|
|
|
+ if (flag) index = ind;
|
|
|
+
|
|
|
+ setShowInd(index);
|
|
|
+ },
|
|
|
+ [showInd]
|
|
|
+ );
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className={styles.Tab3InfoM}>
|
|
|
+ {/* 底部的信息 */}
|
|
|
+ <Tab3InfoMtxt
|
|
|
+ info={info}
|
|
|
+ // 问答
|
|
|
+ wdFlag={right3}
|
|
|
+ questionList={question}
|
|
|
+ // 知识
|
|
|
+ zsFlag={right4}
|
|
|
+ // 留言
|
|
|
+ barrageList={barrage}
|
|
|
+ btnOkFlag={right2}
|
|
|
+ goodsId={id}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const MemoTab3InfoM = React.memo(Tab3InfoM);
|
|
|
+
|
|
|
+export default MemoTab3InfoM;
|