|
@@ -0,0 +1,317 @@
|
|
|
+/* eslint-disable jsx-a11y/iframe-has-title */
|
|
|
+import React, {
|
|
|
+ useCallback,
|
|
|
+ useEffect,
|
|
|
+ useMemo,
|
|
|
+ useRef,
|
|
|
+ useState,
|
|
|
+} from "react";
|
|
|
+import styles from "./index.module.scss";
|
|
|
+import { A2_APIgetInfo } from "@/store/action/A1Home";
|
|
|
+import { A1_itemType, A2_TabType, A2_fileObjType, A2_fileType } from "@/types";
|
|
|
+import { Button } from "antd";
|
|
|
+import history from "@/utils/history";
|
|
|
+import shareImg from "@/assets/img/icon-share.png";
|
|
|
+import musicImg from "@/assets/img/icon-music.png";
|
|
|
+import musicImgX from "@/assets/img/icon-musicX.png";
|
|
|
+import { baseURL } from "@/utils/http";
|
|
|
+import classNames from "classnames";
|
|
|
+import { LeftOutlined, RightOutlined } from "@ant-design/icons";
|
|
|
+import MemoImageLazy from "@/components/ImageLazy";
|
|
|
+
|
|
|
+type Props = {
|
|
|
+ id?: number;
|
|
|
+ closePageFu?: () => void;
|
|
|
+};
|
|
|
+
|
|
|
+function A2Goods({ id, closePageFu }: Props) {
|
|
|
+ // 从分享链接进来的id
|
|
|
+ const uidRef = useRef("");
|
|
|
+
|
|
|
+ // 底部 tab
|
|
|
+ const botTabTemp = useMemo(() => {
|
|
|
+ const arr: A2_TabType = [
|
|
|
+ { id: 1, type: "model", name: "模型", show: false },
|
|
|
+ { id: 2, type: "img", name: "图片", show: false },
|
|
|
+ { id: 3, type: "video", name: "视频", show: false },
|
|
|
+ ];
|
|
|
+ return arr;
|
|
|
+ }, []);
|
|
|
+ const [botTab, setBotTab] = useState(botTabTemp.filter((v) => v.show));
|
|
|
+
|
|
|
+ // 是否有上传音频
|
|
|
+ const [audioSrc, setAudioSrc] = useState("");
|
|
|
+ // 音频的播放和暂停
|
|
|
+ const [audioSta, setAudioSta] = useState(false);
|
|
|
+ const audioRef = useRef<HTMLAudioElement>(null);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const dom = audioRef.current;
|
|
|
+ if (dom) {
|
|
|
+ if (audioSta) {
|
|
|
+ setAudioSta(true);
|
|
|
+ dom.play();
|
|
|
+ dom.onended = () => {
|
|
|
+ // 音频播放结束
|
|
|
+ setAudioSta(false);
|
|
|
+ };
|
|
|
+ } else {
|
|
|
+ setAudioSta(false);
|
|
|
+ dom.pause();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, [audioSta]);
|
|
|
+
|
|
|
+ const getInfoFu = useCallback(
|
|
|
+ async (id: number) => {
|
|
|
+ const res = await A2_APIgetInfo(id);
|
|
|
+ if (res.code === 0) {
|
|
|
+ setInfo(res.data.entity);
|
|
|
+ // 处理附件信息
|
|
|
+
|
|
|
+ const tempArr = res.data.file || [];
|
|
|
+ const delAudioArr = tempArr.filter((v: any) => v.type !== "audio");
|
|
|
+
|
|
|
+ if (delAudioArr.length === 0) setNoFile(true);
|
|
|
+
|
|
|
+ const fileArr: A2_fileType[] = res.data.file || [];
|
|
|
+ const obj = {
|
|
|
+ model: [],
|
|
|
+ img: [],
|
|
|
+ video: [],
|
|
|
+ audio: [],
|
|
|
+ } as A2_fileObjType;
|
|
|
+
|
|
|
+ let audioTemp = "";
|
|
|
+
|
|
|
+ // 底部 type 应该高亮 哪一个
|
|
|
+ if (fileArr.find((v) => v.type === "model")) setType("model");
|
|
|
+ else if (fileArr.find((v) => v.type === "img")) setType("img");
|
|
|
+ else if (fileArr.find((v) => v.type === "video")) setType("video");
|
|
|
+
|
|
|
+ fileArr.forEach((v) => {
|
|
|
+ obj[v.type].push(v);
|
|
|
+
|
|
|
+ // 处理音频信息
|
|
|
+ if (v.type === "audio") audioTemp = v.filePath;
|
|
|
+
|
|
|
+ // 底部tab 应该显示 那几个
|
|
|
+ if (v.type === "model") botTabTemp[0].show = true;
|
|
|
+ if (v.type === "img") botTabTemp[1].show = true;
|
|
|
+ if (v.type === "video") botTabTemp[2].show = true;
|
|
|
+ });
|
|
|
+ setAudioSrc(audioTemp);
|
|
|
+
|
|
|
+ setBotTab(botTabTemp.filter((v) => v.show));
|
|
|
+
|
|
|
+ setFile(obj);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [botTabTemp]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 藏品信息
|
|
|
+ const [info, setInfo] = useState({} as A1_itemType);
|
|
|
+
|
|
|
+ // 藏品附件
|
|
|
+ const [file, setFile] = useState<A2_fileObjType>({
|
|
|
+ model: [],
|
|
|
+ img: [],
|
|
|
+ video: [],
|
|
|
+ audio: [],
|
|
|
+ });
|
|
|
+
|
|
|
+ const [type, setType] = useState("" as "model" | "img" | "video" | "audio");
|
|
|
+
|
|
|
+ const [myInd, setMyInd] = useState(0);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ setMyInd(0);
|
|
|
+ }, [type]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (id) getInfoFu(id);
|
|
|
+ else {
|
|
|
+ // 从分享的链接单独进来,从地址栏获取id
|
|
|
+ }
|
|
|
+ }, [getInfoFu, id]);
|
|
|
+
|
|
|
+ // 没有附件信息
|
|
|
+ const [noFile, setNoFile] = useState(false);
|
|
|
+
|
|
|
+ // 在页面展示的数据
|
|
|
+ const data = useMemo(() => {
|
|
|
+ const arr = file[type] || [];
|
|
|
+ return arr;
|
|
|
+ }, [file, type]);
|
|
|
+
|
|
|
+ // 点击返回
|
|
|
+ const backOrToHome = useCallback(() => {
|
|
|
+ if (id) closePageFu!();
|
|
|
+ else history.push("/");
|
|
|
+ }, [closePageFu, id]);
|
|
|
+
|
|
|
+ // 点击分享
|
|
|
+ const shareFu = useCallback(() => {
|
|
|
+ const goodId = id ? id : uidRef.current;
|
|
|
+ let OrderNumber = window.location.origin + "/web/#/goods?id=" + goodId;
|
|
|
+ let newInput = document.createElement("input");
|
|
|
+ newInput.value = OrderNumber;
|
|
|
+ document.body.appendChild(newInput);
|
|
|
+ newInput.select();
|
|
|
+ document.execCommand("Copy");
|
|
|
+ newInput.remove();
|
|
|
+ alert("复制链接成功");
|
|
|
+ }, [id]);
|
|
|
+
|
|
|
+ // 点击左右按钮
|
|
|
+ const cutIndFu = useCallback(
|
|
|
+ (num: number, flag: boolean) => {
|
|
|
+ const numRes = myInd + num;
|
|
|
+ if (flag) return;
|
|
|
+ setMyInd(numRes);
|
|
|
+ },
|
|
|
+ [myInd]
|
|
|
+ );
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className={styles.A2Goods}>
|
|
|
+ {/* 公共顶部 */}
|
|
|
+ <div className="top">
|
|
|
+ <h3>馆藏鉴赏</h3>
|
|
|
+ <p>Collection Appreciation</p>
|
|
|
+ </div>
|
|
|
+ {/* 主体 */}
|
|
|
+ <div className="main">
|
|
|
+ {audioSrc ? (
|
|
|
+ <audio src={baseURL + audioSrc} ref={audioRef}></audio>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ <div className="mainCon">
|
|
|
+ {noFile ? (
|
|
|
+ <div className="noFileInfo">暂无信息</div>
|
|
|
+ ) : (
|
|
|
+ <div className="mainConll">
|
|
|
+ {/* 底部模块 */}
|
|
|
+ <div className="flooRow">
|
|
|
+ {botTab.map((v) => (
|
|
|
+ <div
|
|
|
+ onClick={() => setType(v.type)}
|
|
|
+ className={classNames(
|
|
|
+ "row",
|
|
|
+ type === v.type ? "active" : ""
|
|
|
+ )}
|
|
|
+ key={v.id}
|
|
|
+ >
|
|
|
+ {v.name}
|
|
|
+ {type === v.type && data.length > 1
|
|
|
+ ? myInd + 1 + "/"
|
|
|
+ : null}
|
|
|
+ {file[v.type].length > 1 ? file[v.type].length : null}
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 左右按钮 */}
|
|
|
+ <div
|
|
|
+ hidden={data.length <= 1}
|
|
|
+ onClick={() => cutIndFu(-1, myInd === 0)}
|
|
|
+ className={classNames(
|
|
|
+ "R_left iconBtn",
|
|
|
+ myInd === 0 ? "R_arrowNo" : ""
|
|
|
+ )}
|
|
|
+ >
|
|
|
+ <LeftOutlined rev={undefined} />
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ hidden={data.length <= 1}
|
|
|
+ onClick={() => cutIndFu(1, myInd >= data.length - 1)}
|
|
|
+ className={classNames(
|
|
|
+ "R_right iconBtn",
|
|
|
+ myInd >= data.length - 1 ? "R_arrowNo" : ""
|
|
|
+ )}
|
|
|
+ >
|
|
|
+ <RightOutlined rev={undefined} />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 内容主体 */}
|
|
|
+ {data.map((v, i) => (
|
|
|
+ <div
|
|
|
+ className={classNames(
|
|
|
+ "conMain",
|
|
|
+ myInd === i ? "conMainAc" : ""
|
|
|
+ )}
|
|
|
+ key={v.id}
|
|
|
+ >
|
|
|
+ {v.type === "model" && myInd === i ? (
|
|
|
+ <div className="modelBox">
|
|
|
+ <iframe
|
|
|
+ src={`model.html?m=${v.filePath}`}
|
|
|
+ frameBorder="0"
|
|
|
+ ></iframe>
|
|
|
+ </div>
|
|
|
+ ) : v.type === "img" ? (
|
|
|
+ <div className="imgBox">
|
|
|
+ <MemoImageLazy
|
|
|
+ src={v.filePath}
|
|
|
+ width="100%"
|
|
|
+ height="100%"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ ) : v.type === "video" && myInd === i ? (
|
|
|
+ <div className="videoBox">
|
|
|
+ <video src={baseURL + v.filePath} controls></video>
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <div className="mainConrr">
|
|
|
+ {/* 返回按钮 */}
|
|
|
+ <div className="back">
|
|
|
+ <Button onClick={backOrToHome}>{id ? "返回" : "首页"}</Button>
|
|
|
+ </div>
|
|
|
+ {/* 内容 */}
|
|
|
+ <div className="txtMain myscroll">
|
|
|
+ <h3>{info.name}</h3>
|
|
|
+ <div className="ttTop">
|
|
|
+ 年代:
|
|
|
+ {info.dictAge}
|
|
|
+ </div>
|
|
|
+ <div className="ttTop">
|
|
|
+ 尺寸:
|
|
|
+ {info.sizeSpecific}
|
|
|
+ </div>
|
|
|
+ <div className="ttTop2">
|
|
|
+ {info.description ? info.description : "暂无说明"}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {/* 分享,声音按钮 */}
|
|
|
+ <div className="botBtn">
|
|
|
+ <div className="row" onClick={shareFu}>
|
|
|
+ <img src={shareImg} alt="" />
|
|
|
+ <p>分享</p>
|
|
|
+ </div>
|
|
|
+ {audioSrc ? (
|
|
|
+ <div
|
|
|
+ className="row"
|
|
|
+ title={audioSta ? "关闭音频" : "打开音频"}
|
|
|
+ onClick={() => setAudioSta(!audioSta)}
|
|
|
+ >
|
|
|
+ <img src={audioSta ? musicImg : musicImgX} alt="" />
|
|
|
+ <p>声音</p>
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const MemoA2Goods = React.memo(A2Goods);
|
|
|
+
|
|
|
+export default MemoA2Goods;
|