feat: enhance modal functionality and integrate new components
- Added keyframes and animation for a smooth scale-in effect in the Tailwind configuration. - Updated Image component to improve quality handling and style definitions. - Introduced WordViewer and WordViewerModal components for document viewing capabilities. - Enhanced Modal component to support embedded mode with customizable position and dimensions. - Integrated IframeModal across various pages for user assistance and content display. - Updated Content and Menu pages to utilize new components and improve user interaction. - Added utility function to retrieve public paths for resources.
This commit is contained in:
1 parent
13dd84a8a7
commit
4ce7520066
44 files changed
+1209
-100
No files matched your search
+221
-51
@@ -1,9 +1,14 @@
|
||||
import { BackgroundImage, Image } from "@/components";
|
||||
import { BackgroundImage, Image, WordViewerModal } from "@/components";
|
||||
import { IframeModal } from "@/components/Modal";
|
||||
import { getStaticImage } from "@/utils";
|
||||
import { getStaticImage, getPublicPath } from "@/utils";
|
||||
import {
|
||||
skillTrainingActivities,
|
||||
exchangeAndShowActivities,
|
||||
Activity,
|
||||
} from "@/data/activities";
|
||||
import clsx from "clsx";
|
||||
import { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
/**
|
||||
* tab列表
|
||||
@@ -50,26 +55,28 @@ const tabList = [
|
||||
const sideBarList = [
|
||||
{
|
||||
name: "理论与技能转向培训",
|
||||
key: 0,
|
||||
image: getStaticImage("content/理论与技能专项培训-未选中.png"),
|
||||
selectedImage: getStaticImage("content/理论与技能专项培训-选中.png"),
|
||||
},
|
||||
{
|
||||
name: "教学实践与反思",
|
||||
image: getStaticImage("content/教学实践与反思-未选中.png"),
|
||||
selectedImage: getStaticImage("content/教学实践与反思-选中.png"),
|
||||
},
|
||||
{
|
||||
name: "项目与课题研究",
|
||||
image: getStaticImage("content/项目与课题研究-未选中.png"),
|
||||
selectedImage: getStaticImage("content/项目与课题研究-选中.png"),
|
||||
},
|
||||
{
|
||||
name: "经验传承与资源共享",
|
||||
image: getStaticImage("content/经验传承与资源共享-未选中.png"),
|
||||
selectedImage: getStaticImage("content/经验传承与资源共享-选中.png"),
|
||||
},
|
||||
// {
|
||||
// name: "教学实践与反思",
|
||||
// image: getStaticImage("content/教学实践与反思-未选中.png"),
|
||||
// selectedImage: getStaticImage("content/教学实践与反思-选中.png"),
|
||||
// },
|
||||
// {
|
||||
// name: "项目与课题研究",
|
||||
// image: getStaticImage("content/项目与课题研究-未选中.png"),
|
||||
// selectedImage: getStaticImage("content/项目与课题研究-选中.png"),
|
||||
// },
|
||||
// {
|
||||
// name: "经验传承与资源共享",
|
||||
// image: getStaticImage("content/经验传承与资源共享-未选中.png"),
|
||||
// selectedImage: getStaticImage("content/经验传承与资源共享-选中.png"),
|
||||
// },
|
||||
{
|
||||
name: "交流与展示活动",
|
||||
key: 4,
|
||||
image: getStaticImage("content/交流与展示活动-未选中.png"),
|
||||
selectedImage: getStaticImage("content/交流与展示活动-选中.png"),
|
||||
},
|
||||
@@ -78,11 +85,13 @@ const sideBarList = [
|
||||
export const Tab = ({
|
||||
changeTab,
|
||||
className,
|
||||
defaultTabId = 1,
|
||||
}: {
|
||||
changeTab?: (id: number) => void;
|
||||
className?: string;
|
||||
defaultTabId?: number;
|
||||
}) => {
|
||||
const [selectedTabId, setSelectedTabId] = useState(1);
|
||||
const [selectedTabId, setSelectedTabId] = useState(defaultTabId);
|
||||
return (
|
||||
<>
|
||||
{/* tab */}
|
||||
@@ -102,7 +111,7 @@ export const Tab = ({
|
||||
</div>
|
||||
|
||||
<TabContent
|
||||
className="h-[calc(100%-200px)]"
|
||||
className="h-[calc(100%-180px)]"
|
||||
selectedTabId={selectedTabId}
|
||||
/>
|
||||
</>
|
||||
@@ -117,33 +126,67 @@ const TabContent = ({
|
||||
selectedTabId: number;
|
||||
}) => {
|
||||
const [selectedSideBarId, setSelectedSideBarId] = useState(0);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [isActivitiesModalOpen, setIsActivitiesModalOpen] = useState(false);
|
||||
const [selectedActivity, setSelectedActivity] = useState<Activity | null>(
|
||||
null
|
||||
);
|
||||
const [selectedActivities, setSelectedActivities] = useState<Activity | null>(
|
||||
null
|
||||
);
|
||||
|
||||
const handleActivityClick = (activity: Activity) => {
|
||||
setSelectedActivity(activity);
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
const handleActivitiesClick = (activities: Activity) => {
|
||||
setSelectedActivities(activities);
|
||||
setIsActivitiesModalOpen(true);
|
||||
};
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setIsModalOpen(false);
|
||||
setSelectedActivity(null);
|
||||
};
|
||||
|
||||
const handleActivitiesCloseModal = () => {
|
||||
setIsActivitiesModalOpen(false);
|
||||
setSelectedActivities(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={clsx("overflow-y-auto custom-scrollbar", className)}>
|
||||
{/* 通过tab切换内容 */}
|
||||
{selectedTabId === 1 && (
|
||||
<Image
|
||||
height={942}
|
||||
src={getStaticImage("content/图文.png")}
|
||||
alt="工作室介绍"
|
||||
/>
|
||||
<div className="w-full">
|
||||
<Image
|
||||
width={"100%"}
|
||||
height={"auto"}
|
||||
src={getStaticImage("content/图文.png")}
|
||||
alt="工作室介绍"
|
||||
className="w-full h-auto"
|
||||
objectFit="contain"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{selectedTabId === 2 && (
|
||||
<div className="flex gap-10 pt-8">
|
||||
{/* 侧边栏 */}
|
||||
<div className="flex flex-col gap-10">
|
||||
{sideBarList.map((item, index) => (
|
||||
{sideBarList.map((item) => (
|
||||
<Image
|
||||
key={item.name}
|
||||
key={item.key}
|
||||
src={
|
||||
selectedSideBarId === index
|
||||
selectedSideBarId === item.key
|
||||
? item.selectedImage
|
||||
: item.image
|
||||
}
|
||||
alt={item.name}
|
||||
button
|
||||
onClick={() => {
|
||||
setSelectedSideBarId(index);
|
||||
setSelectedSideBarId(item.key);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
@@ -154,17 +197,115 @@ const TabContent = ({
|
||||
height={766}
|
||||
>
|
||||
<div className="h-full flex justify-center items-center">
|
||||
<span className="text-[#82B2D6] text-4xl font-bold">
|
||||
图文、视频展示理论与技能专项培训内容
|
||||
</span>
|
||||
{selectedSideBarId === 0 ? (
|
||||
<>
|
||||
{/* 技能专项培训列表 */}
|
||||
<div className="w-full h-full p-8 overflow-y-auto custom-scrollbar">
|
||||
{/* 活动列表表格 */}
|
||||
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="bg-gradient-to-r from-[#82B2D6] to-[#6a9bc4] text-white">
|
||||
<th className="px-6 py-4 text-left text-lg font-semibold w-[70%]">
|
||||
活动名称
|
||||
</th>
|
||||
<th className="px-6 py-4 text-left text-lg font-semibold w-[30%]">
|
||||
时间
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{skillTrainingActivities.map((activity, index) => (
|
||||
<tr
|
||||
key={activity.id}
|
||||
onClick={() => handleActivityClick(activity)}
|
||||
className={clsx(
|
||||
"border-b border-gray-200 cursor-pointer transition-all duration-200",
|
||||
"hover:bg-[#82B2D6]/10 hover:shadow-md",
|
||||
index % 2 === 0 ? "bg-white" : "bg-gray-50"
|
||||
)}
|
||||
>
|
||||
<td className="px-6 py-4 text-gray-800 font-medium">
|
||||
{activity.name}
|
||||
</td>
|
||||
<td className="px-6 py-4 text-gray-600">
|
||||
{activity.date}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : selectedSideBarId === 1 ? (
|
||||
<span className="text-[#82B2D6] text-4xl font-bold">
|
||||
图文、视频展示教学实践与反思内容
|
||||
</span>
|
||||
) : selectedSideBarId === 2 ? (
|
||||
<span className="text-[#82B2D6] text-4xl font-bold">
|
||||
图文、视频展示项目与课题研究内容
|
||||
</span>
|
||||
) : selectedSideBarId === 3 ? (
|
||||
<span className="text-[#82B2D6] text-4xl font-bold">
|
||||
图文、视频展示经验传承与资源共享内容
|
||||
</span>
|
||||
) : selectedSideBarId === 4 ? (
|
||||
<div className="w-full h-full pt-4 relative">
|
||||
{/* 历史活动列表 */}
|
||||
<div className="w-full h-full p-8 overflow-y-auto custom-scrollbar">
|
||||
{/* 活动列表表格 */}
|
||||
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="bg-gradient-to-r from-[#82B2D6] to-[#6a9bc4] text-white">
|
||||
<th className="px-6 py-4 text-left text-lg font-semibold w-[70%]">
|
||||
活动名称
|
||||
</th>
|
||||
<th className="px-6 py-4 text-left text-lg font-semibold w-[30%]">
|
||||
时间
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{exchangeAndShowActivities.map(
|
||||
(activity, index) => (
|
||||
<tr
|
||||
key={activity.id}
|
||||
onClick={() =>
|
||||
handleActivitiesClick(activity)
|
||||
}
|
||||
className={clsx(
|
||||
"border-b border-gray-200 cursor-pointer transition-all duration-200",
|
||||
"hover:bg-[#82B2D6]/10 hover:shadow-md",
|
||||
index % 2 === 0 ? "bg-white" : "bg-gray-50"
|
||||
)}
|
||||
>
|
||||
<td className="px-6 py-4 text-gray-800 font-medium">
|
||||
{activity.name}
|
||||
</td>
|
||||
<td className="px-6 py-4 text-gray-600">
|
||||
{activity.date}
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</BackgroundImage>
|
||||
</div>
|
||||
)}
|
||||
{selectedTabId === 3 && (
|
||||
<div className="text-center text-[#82B2D6] text-4xl font-bold">
|
||||
暂无内容
|
||||
</div>
|
||||
<Image
|
||||
height={1415}
|
||||
src={getStaticImage("content/图文3.png")}
|
||||
alt="工作室介绍"
|
||||
/>
|
||||
)}
|
||||
{selectedTabId === 4 && (
|
||||
<div className="text-center text-[#82B2D6] text-4xl font-bold">
|
||||
@@ -172,14 +313,36 @@ const TabContent = ({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 活动文档弹窗 */}
|
||||
{selectedActivity && (
|
||||
<WordViewerModal
|
||||
isOpen={isModalOpen}
|
||||
onClose={handleCloseModal}
|
||||
docPath={getPublicPath(selectedActivity.docPath)}
|
||||
title={selectedActivity.name}
|
||||
/>
|
||||
)}
|
||||
{selectedActivities && (
|
||||
<WordViewerModal
|
||||
isOpen={isActivitiesModalOpen}
|
||||
onClose={handleActivitiesCloseModal}
|
||||
docPath={getPublicPath(selectedActivities.docPath)}
|
||||
title={selectedActivities.name}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default function PublicityPage() {
|
||||
const navigate = useNavigate();
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
// 将路由参数 id 转换为数字,如果无效则默认为 1
|
||||
const defaultTabId = id ? parseInt(id, 10) : 1;
|
||||
|
||||
const changeTab = (id: number) => {
|
||||
console.log(id);
|
||||
};
|
||||
@@ -211,28 +374,35 @@ export default function PublicityPage() {
|
||||
/>
|
||||
|
||||
{/* 数字人头像 */}
|
||||
<div
|
||||
className="flex flex-col items-center absolute right-4 bottom-2 cursor-pointer hover:scale-105 transition-all duration-300 z-10"
|
||||
onClick={handleAvatarClick}
|
||||
>
|
||||
<Image
|
||||
src={getStaticImage("publicity/数字人-头像框.png")}
|
||||
alt="数字人头像"
|
||||
/>
|
||||
<span className="text-white text-2xl font-bold tracking-wide">
|
||||
点击我随时为你解答
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Tab changeTab={changeTab} />
|
||||
{!isModalOpen && (
|
||||
<>
|
||||
<div
|
||||
className="flex flex-col items-center absolute right-4 bottom-2 cursor-pointer hover:scale-105 transition-all duration-300 z-10"
|
||||
onClick={handleAvatarClick}
|
||||
>
|
||||
<Image
|
||||
src={getStaticImage("publicity/数字人-头像框.png")}
|
||||
alt="数字人头像"
|
||||
/>
|
||||
<span className="text-white text-2xl font-bold tracking-wide">
|
||||
点击我随时为你解答
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<Tab changeTab={changeTab} defaultTabId={defaultTabId} />
|
||||
</div>
|
||||
|
||||
{/* 弹窗 */}
|
||||
{/* 嵌入式客服对话框 */}
|
||||
<IframeModal
|
||||
isOpen={isModalOpen}
|
||||
onClose={handleCloseModal}
|
||||
url="https://human-train.lkz.fit/ad905c35-886a-4abb-98c0-e7f894d86b4c/"
|
||||
url="https://www.edutech.host/digitalHuman/"
|
||||
title="数字人助手"
|
||||
mode="embedded"
|
||||
position="bottom-right"
|
||||
width="420px"
|
||||
height="650px"
|
||||
/>
|
||||
</BackgroundImage>
|
||||
);
|
||||
|
||||
+87
-22
@@ -1,7 +1,8 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { BackgroundImage, Image } from "@/components";
|
||||
import { BackgroundImage, Image, Alert } from "@/components";
|
||||
import { getStaticImage } from "@/utils";
|
||||
import { useState } from "react";
|
||||
import { IframeModal } from "@/components/Modal";
|
||||
|
||||
/**
|
||||
* 卢航-未选中.png
|
||||
@@ -33,7 +34,7 @@ const teachers = [
|
||||
id: 3,
|
||||
name: "龚丹",
|
||||
avatar: getStaticImage("menu/龚丹-未选中.png"),
|
||||
selectedAvatar: getStaticImage("menu/曹君-选中.png"),
|
||||
selectedAvatar: getStaticImage("menu/龚丹-选中.png"),
|
||||
position: {
|
||||
top: "20%",
|
||||
left: "65%",
|
||||
@@ -44,8 +45,15 @@ const teachers = [
|
||||
export default function Home() {
|
||||
const navigate = useNavigate();
|
||||
const [selectedTeacherId, setSelectedTeacherId] = useState(0);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [showTipModal, setShowTipModal] = useState(false);
|
||||
|
||||
const handleSelectTeacher = (teacherId: number) => {
|
||||
if (teacherId !== 2) {
|
||||
// 点击卢航或龚丹时显示提示
|
||||
setShowTipModal(true);
|
||||
return;
|
||||
}
|
||||
setSelectedTeacherId(teacherId);
|
||||
navigate("/Publicity");
|
||||
};
|
||||
@@ -55,6 +63,14 @@ export default function Home() {
|
||||
// navigate("/experiment");
|
||||
};
|
||||
|
||||
const handleAvatarClick = () => {
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setIsModalOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<BackgroundImage
|
||||
src={getStaticImage("menu/首页背景.png")}
|
||||
@@ -76,6 +92,44 @@ export default function Home() {
|
||||
className="absolute bottom-0 left-1/2 transform -translate-x-1/2"
|
||||
/>
|
||||
|
||||
{/* 数字人头像 */}
|
||||
{!isModalOpen && (
|
||||
<>
|
||||
<div
|
||||
className="flex flex-col items-center absolute right-4 bottom-2 cursor-pointer hover:scale-105 transition-all duration-300 z-20"
|
||||
onClick={handleAvatarClick}
|
||||
>
|
||||
<Image
|
||||
src={getStaticImage("publicity/数字人-头像框.png")}
|
||||
alt="数字人头像"
|
||||
/>
|
||||
<span className="text-white text-2xl font-bold tracking-wide">
|
||||
点击我随时为你解答
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 嵌入式客服对话框 */}
|
||||
<IframeModal
|
||||
isOpen={isModalOpen}
|
||||
onClose={handleCloseModal}
|
||||
url="https://www.edutech.host/digitalHuman/"
|
||||
title="数字人助手"
|
||||
mode="embedded"
|
||||
position="bottom-right"
|
||||
width="420px"
|
||||
height="650px"
|
||||
/>
|
||||
|
||||
{/* 提示弹窗 */}
|
||||
<Alert
|
||||
isOpen={showTipModal}
|
||||
onClose={() => setShowTipModal(false)}
|
||||
message="该名师工作室数字睿教正在筹划中"
|
||||
type="warning"
|
||||
/>
|
||||
|
||||
<BackgroundImage
|
||||
src={getStaticImage("menu/转盘合.png")}
|
||||
className="absolute w-full h-500 -bottom-1/5 left-0"
|
||||
@@ -83,27 +137,38 @@ export default function Home() {
|
||||
backgroundPosition="center"
|
||||
>
|
||||
{teachers.map((teacher) => (
|
||||
<Image
|
||||
key={teacher.id}
|
||||
src={
|
||||
selectedTeacherId === teacher.id
|
||||
? teacher.selectedAvatar
|
||||
: teacher.avatar
|
||||
}
|
||||
alt={teacher.name}
|
||||
onClick={() => handleSelectTeacher(teacher.id)}
|
||||
className="absolute"
|
||||
style={{
|
||||
top:
|
||||
selectedTeacherId === teacher.id ? "4%" : teacher.position.top,
|
||||
left:
|
||||
<>
|
||||
<Image
|
||||
key={teacher.id}
|
||||
src={
|
||||
selectedTeacherId === teacher.id
|
||||
? "36%"
|
||||
: teacher.position.left,
|
||||
transition: "transform 0.2s ease, z-index 0.2s ease",
|
||||
}}
|
||||
button={selectedTeacherId !== teacher.id}
|
||||
/>
|
||||
? teacher.selectedAvatar
|
||||
: teacher.avatar
|
||||
}
|
||||
alt={teacher.name}
|
||||
onClick={() => handleSelectTeacher(teacher.id)}
|
||||
className="absolute"
|
||||
style={{
|
||||
top:
|
||||
selectedTeacherId === teacher.id
|
||||
? "4%"
|
||||
: teacher.position.top,
|
||||
left:
|
||||
selectedTeacherId === teacher.id
|
||||
? "36%"
|
||||
: teacher.position.left,
|
||||
transition: "transform 0.2s ease, z-index 0.2s ease",
|
||||
}}
|
||||
button={selectedTeacherId !== teacher.id}
|
||||
/>
|
||||
|
||||
{/* <div className="absolute top-[25%] left-[12%] text-gray-500 text-3xl font-bold cursor-not-allowed">
|
||||
该名师工作室数字睿教正在筹划中
|
||||
</div>
|
||||
<div className="absolute top-[25%] left-[65%] text-gray-500 text-3xl font-bold cursor-not-allowed">
|
||||
该名师工作室数字睿教正在筹划中
|
||||
</div> */}
|
||||
</>
|
||||
))}
|
||||
</BackgroundImage>
|
||||
</BackgroundImage>
|
||||
|
||||
+40
-2
@@ -1,4 +1,5 @@
|
||||
import { BackgroundImage, Image } from "@/components";
|
||||
import { IframeModal } from "@/components/Modal";
|
||||
import { getStaticImage } from "@/utils";
|
||||
import { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@@ -113,6 +114,7 @@ export default function PublicityPage() {
|
||||
const navigate = useNavigate();
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
const [selectedFunctionId, setSelectedFunctionId] = useState(0);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
const handleOpenDialog = () => {
|
||||
setIsDialogOpen(true);
|
||||
@@ -121,6 +123,13 @@ export default function PublicityPage() {
|
||||
const handleCloseDialog = () => {
|
||||
setIsDialogOpen(false);
|
||||
};
|
||||
const handleAvatarClick = () => {
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setIsModalOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<BackgroundImage
|
||||
@@ -168,17 +177,46 @@ export default function PublicityPage() {
|
||||
className="absolute left-0 -bottom-20"
|
||||
/>
|
||||
|
||||
{/* 数字人头像 */}
|
||||
{!isModalOpen && (
|
||||
<>
|
||||
<div
|
||||
className="flex flex-col items-center absolute right-4 bottom-2 cursor-pointer hover:scale-105 transition-all duration-300 z-10"
|
||||
onClick={handleAvatarClick}
|
||||
>
|
||||
<Image
|
||||
src={getStaticImage("publicity/数字人-头像框.png")}
|
||||
alt="数字人头像"
|
||||
/>
|
||||
<span className="text-white text-2xl font-bold tracking-wide">
|
||||
点击我随时为你解答
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{/* 提示 */}
|
||||
<Image
|
||||
{/* <Image
|
||||
src={getStaticImage("publicity/点击提示.png")}
|
||||
alt="提示"
|
||||
className="absolute left-0 -bottom-10"
|
||||
button
|
||||
onClick={handleOpenDialog}
|
||||
/>
|
||||
/> */}
|
||||
|
||||
{/* 解答弹窗 */}
|
||||
<DialogBox isOpen={isDialogOpen} onClose={handleCloseDialog} />
|
||||
|
||||
{/* 嵌入式客服对话框 */}
|
||||
<IframeModal
|
||||
isOpen={isModalOpen}
|
||||
onClose={handleCloseModal}
|
||||
url="https://www.edutech.host/digitalHuman/"
|
||||
title="数字人助手"
|
||||
mode="embedded"
|
||||
position="bottom-right"
|
||||
width="420px"
|
||||
height="650px"
|
||||
/>
|
||||
</BackgroundImage>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user