Compare commits

...

11 Commits

Author SHA1 Message Date
b4e8ed0736 图片路径修改 2025-05-23 13:39:31 +08:00
83b64c150a 图片路径修改 2025-05-23 13:29:23 +08:00
张 元山
f60a0e6559 fix i18 2025-05-23 13:14:08 +08:00
张 元山
e0079415dc Merge branch 'main' of https://gitea-inner.fontree.cn/scout666/fiee-official-website 2025-05-23 13:07:09 +08:00
张 元山
97503165c1 pdf路径 2025-05-23 13:07:08 +08:00
Phoenix
eea6ef83ba 移除提交成功提示信息 2025-05-23 12:28:26 +08:00
Phoenix
b44c3c0cca 12 2025-05-23 12:23:32 +08:00
fe22244f82 Merge branch 'LiWenHao'
# Conflicts:
#	src/config/headerMenuConfig.js
#	src/locales/en.js
#	src/router/index.js
2025-05-23 12:10:37 +08:00
d6f8995070 111 2025-05-23 12:03:48 +08:00
735b9b9ea2 Merge branch 'main' of https://gitea-inner.fontree.cn/scout666/fiee-official-website into LiWenHao
# Conflicts:
#	src/locales/en.js
#	src/router/index.js
2025-05-23 09:09:53 +08:00
270aca35a3 111 2025-05-23 09:04:20 +08:00
38 changed files with 6401 additions and 479 deletions

View File

@ -50,6 +50,7 @@
"unplugin-auto-import": "^0.18.2",
"unplugin-vue-components": "^0.27.3",
"vite": "^5.3.4",
"vite-plugin-imagemin": "^0.6.1"
"vite-plugin-imagemin": "^0.6.1",
"vite-plugin-vue-devtools": "^7.7.6"
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

BIN
src/assets/image/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -22,21 +22,21 @@
</template>
<script setup>
import FiEELogo from '@/assets/image/header/logo.png'
import { ref, onMounted, onUnmounted } from 'vue'
import { NMenu, NLayoutHeader, NImage } from 'naive-ui'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useHeaderMenuConfig } from '@/config/headerMenuConfig'
import FiEELogo from "@/assets/image/header/logo.png";
import { ref, onMounted, onUnmounted } from "vue";
import { NMenu, NLayoutHeader, NImage } from "naive-ui";
import { useI18n } from "vue-i18n";
import { useRouter } from "vue-router";
import { useHeaderMenuConfig } from "@/config/headerMenuConfig";
const { t } = useI18n()
const router = useRouter()
const { t } = useI18n();
const router = useRouter();
// 使
const menuOptions = useHeaderMenuConfig()
const selectedKey = ref(null)
const menuOptions = useHeaderMenuConfig();
const selectedKey = ref(null);
const isScrolled = ref(false)
const isScrolled = ref(false);
//
function findMenuOptionByKey(options, key) {
@ -69,20 +69,20 @@ onMounted(() => {
});
onUnmounted(() => {
window.removeEventListener('scroll', handleScroll)
})
window.removeEventListener("scroll", handleScroll);
});
//
const handleToHome = () => {
router.push('/')
selectedKey.value = null //
}
router.push("/myhome");
selectedKey.value = null; //
};
</script>
<style scoped lang="scss">
.custom-header {
--header-height: 80px;
--primary-color: #8B59F7;
--primary-color: #8b59f7;
position: fixed;
top: 0;
left: 0;
@ -143,7 +143,7 @@ const handleToHome = () => {
text-align: center;
&::after {
content: '';
content: "";
position: absolute;
bottom: 0;
left: 50%;
@ -189,7 +189,7 @@ const handleToHome = () => {
overflow: hidden;
&::before {
content: '';
content: "";
position: absolute;
top: 0;
left: 0;

View File

@ -1,107 +1,115 @@
import { useI18n } from 'vue-i18n'
import { useI18n } from "vue-i18n";
export const useHeaderMenuConfig = () => {
const { t } = useI18n()
const { t } = useI18n();
return [
{
label: t('header_menu.corporate_information.title'),
key: 'corporate_information',
label: t("header_menu.corporate_information.title"),
key: "corporate_information",
children: [
{
label: t('header_menu.corporate_information.company_overview'),
key: 'company_overview',
label: t("header_menu.corporate_information.company_overview"),
key: "company_overview",
href: "/companyoverview",
},
{
label: t('header_menu.corporate_information.business_introduction'),
key: 'business_introduction',
label: t("header_menu.corporate_information.business_introduction"),
key: "business_introduction",
href: "/businessservices",
},
{
label: t('header_menu.corporate_information.management'),
key: 'management',
label: t("header_menu.corporate_information.management"),
key: "management",
href: "/manage",
},
{
label: t('header_menu.corporate_information.board_of_directors'),
key: 'board_of_directors',
label: t("header_menu.corporate_information.board_of_directors"),
key: "board_of_directors",
href: "/boarddirectors",
},
{
label: t('header_menu.corporate_information.committee_appointments'),
key: 'committee_appointments',
label: t("header_menu.corporate_information.committee_appointments"),
key: "committee_appointments",
href: "/committeeappointment",
},
{
label: t('header_menu.corporate_information.governance'),
key: 'governance',
label: t("header_menu.corporate_information.governance"),
key: "governance",
href: "/govern",
},
{
label: t("header_menu.corporate_information.corporate_video"),
key: "corporate_video",
},
// {
// label: t('header_menu.corporate_information.corporate_video'),
// key: 'corporate_video',
// },//现阶段不展示
],
},
{
label: t('header_menu.financial_information.title'),
key: 'financial_information',
label: t("header_menu.financial_information.title"),
key: "financial_information",
children: [
{
label: t('header_menu.financial_information.sec_filings'),
key: 'sec_filings',
label: t("header_menu.financial_information.sec_filings"),
key: "sec_filings",
href: "/secfilings",
},
{
label: t('header_menu.financial_information.quarterly_results'),
key: 'quarterly_results',
label: t("header_menu.financial_information.quarterly_results"),
key: "quarterly_results",
href: "/quarterlyresults",
},
],
},
{
label: t('header_menu.stock_information.title'),
key: 'stock_information',
label: t("header_menu.stock_information.title"),
key: "stock_information",
children: [
{
label: t('header_menu.stock_information.stock_quote'),
key: 'stock_quote',
label: t("header_menu.stock_information.stock_quote"),
key: "stock_quote",
href:'/stock-quote'
},
{
label: t('header_menu.stock_information.historic_stock_price'),
key: 'historic_stock_price',
href: '/historic-stock',
label: t("header_menu.stock_information.historic_stock_price"),
key: "historic_stock_price",
},
{
label: t('header_menu.stock_information.investment_calculator'),
key: 'investment_calculator',
label: t("header_menu.stock_information.investment_calculator"),
key: "investment_calculator",
href:'/calculator'
},
],
},
{
label: t('header_menu.news_releases.title'),
key: 'news_releases',
label: t("header_menu.news_releases.title"),
key: "news_releases",
children: [
{
label: t('header_menu.news_releases.press_releases'),
key: 'press_releases',
href: '/press-releases',
label: t("header_menu.news_releases.press_releases"),
key: "press_releases",
href: "/press-releases",
},
{
label: t('header_menu.news_releases.events_calendar'),
key: 'events_calendar',
href: '/events-calendar',
label: t("header_menu.news_releases.events_calendar"),
key: "events_calendar",
},
],
},
{
label: t('header_menu.investor_resources.title'),
key: 'investor_resources',
label: t("header_menu.investor_resources.title"),
key: "investor_resources",
children: [
{
label: t('header_menu.investor_resources.ir_contacts'),
key: 'ir_contacts',
label: t("header_menu.investor_resources.ir_contacts"),
key: "ir_contacts",
href:'/contacts'
},
{
label: t('header_menu.investor_resources.email_alerts'),
key: 'email_alerts',
label: t("header_menu.investor_resources.email_alerts"),
key: "email_alerts",
href:'/email-alerts'
},
],
},
]
}
];
};

14
src/config/testRequest.js Normal file
View File

@ -0,0 +1,14 @@
// src/api/testRequest.js
import axios from "axios";
export const getTestData = async () => {
try {
const response = await axios.get(
"http://saas-test.szjixun.cn/api/chart/forward/test"
);
return response.data;
} catch (error) {
console.error("请求出错:", error);
throw error; // 可选:让调用方处理异常
}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,13 @@
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import { setupRouterGuards } from './router-guards'
import { createRouter, createWebHistory } from "vue-router";
import { setupRouterGuards } from "./router-guards";
const routes = [
{
path: '/',
name: 'index',
component: () => import('@/views/index/index.vue'),
path: "/",
name: "index",
redirect: "/myhome", // 添加重定向
component: () => import("@/views/index/index.vue"),
// beforeEnter: (to, from, next) => {
// localStorage.clear()
@ -14,70 +15,105 @@ const routes = [
// }
children: [
{
path: '/contacts',
name: 'contacts',
component: () => import('@/views/contacts/index.vue'),
path: "/contacts",
name: "contacts",
component: () => import("@/views/contacts/index.vue"),
},
{
path: '/calculator',
name: 'calculator',
component: () => import('@/views/calculator/index.vue'),
path: "/calculator",
name: "calculator",
component: () => import("@/views/calculator/index.vue"),
},
{
path: '/home',
name: 'home',
component: () => import('@/views/home/index.vue'),
path: "/home",
name: "home",
component: () => import("@/views/home/index.vue"),
// beforeEnter: (to, from, next) => {
// localStorage.clear()
// next()
// }
},
{
path: '/stock-quote',
name: 'stock-quote',
component: () => import('@/views/stock-quote/index.vue'),
},
{
path: '/historic-stock',
name: 'historic-stock',
component: () => import('@/views/historic-stock/index.vue'),
},
{
path: '/contacts',
name: 'contacts',
component: () => import('@/views/contacts/index.vue'),
},
{
path: '/email-alerts',
name: 'email-alerts',
component: () => import('@/views/email-alerts/index.vue'),
},
{
path: '/quarterlyresults',
name: 'QuarterlyResults',
path: "/stock-quote",
name: "stock-quote",
component: () => import("@/views/stock-quote/index.vue"),
},
{
path: "/historic-stock",
name: "historic-stock",
component: () => import("@/views/historic-stock/index.vue"),
},
{
path: "/contacts",
name: "contacts",
component: () => import("@/views/contacts/index.vue"),
},
{
path: "/email-alerts",
name: "email-alerts",
component: () => import("@/views/email-alerts/index.vue"),
},
{
path: "/quarterlyresults",
name: "QuarterlyResults",
component: () =>
import('@/views/financialinformation/quarterlyresults/index.vue'),
import("@/views/financialinformation/quarterlyresults/index.vue"),
},
{
path: '/secfilings',
name: 'SecFilings',
path: "/secfilings",
name: "SecFilings",
component: () =>
import('@/views/financialinformation/secfilings/index.vue'),
import("@/views/financialinformation/secfilings/index.vue"),
},
{
path: '/press-releases',
name: 'press-releases',
component: () => import('@/views/press-releases/index.vue'),
path: "/press-releases",
name: "press-releases",
component: () => import("@/views/press-releases/index.vue"),
},
{
path: '/events-calendar',
name: 'events-calendar',
component: () => import('@/views/events-calendar/index.vue'),
path: "/events-calendar",
name: "events-calendar",
component: () => import("@/views/events-calendar/index.vue"),
},
{
path: "/companyoverview",
name: "companyoverview",
component: () => import("@/views/companyoverview/index.vue"),
},
{
path: "myhome",
name: "myHome",
component: () => import("@/views/myHome/index.vue"),
},
{
path: "/businessservices",
name: "BusinessServices",
component: () => import("@/views/BusinessServices/index.vue"),
},
{
path: "/manage",
name: "manage",
component: () => import("@/views/manage/index.vue"),
},
{
path: "/boarddirectors",
name: "boarddirectors",
component: () => import("@/views/boarddirectors/index.vue"),
},
{
path: "/committeeappointment",
name: "CommitteeAppointment",
component: () => import("@/views/CommitteeAppointment/index.vue"),
},
{
path: "/govern",
name: "govern",
component: () => import("@/views/govern/index.vue"),
},
],
},
// {
// path: '/companyprofil',
// name: 'Companyprofil',
@ -103,17 +139,17 @@ const routes = [
// name: 'Investorhandbook',
// component: () => import('@/views/investorhandbook/index.vue'),
// },
]
];
const router = createRouter({
history: createWebHistory(),
routes,
})
});
router.beforeEach((to, from, next) => {
if (to.meta?.title) {
document.title = to.meta.title
document.title = to.meta.title;
}
next()
})
setupRouterGuards(router)
export default router
next();
});
setupRouterGuards(router);
export default router;

View File

@ -0,0 +1,22 @@
<script setup>
import size1920 from "@/views/BusinessServices/size1920/index.vue";
import size375 from "@/views/BusinessServices/size375/index.vue";
import { computed } from "vue";
import { useWindowSize } from "@vueuse/core";
const { width } = useWindowSize();
const viewComponent = computed(() => {
const viewWidth = width.value;
if (viewWidth <= 450) {
return size375;
} else if (viewWidth <= 1920 || viewWidth > 1920) {
return size1920;
}
});
</script>
<template>
<component :is="viewComponent" />
</template>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,406 @@
<template>
<div class="home-page">
<div class="business-page">
<!-- 渐变背景标题区 - 增加层次感 -->
<section class="hero-section">
<div class="hero-content container">
<div class="title-wrapper">
<h1 class="hero-title">
{{ $t("BusinessiIntroduction.CONTAIN.TITLEONE.TITLE") }}
</h1>
<div class="title-decoration"></div>
</div>
<div class="hero-description">
<p>{{ $t("BusinessiIntroduction.CONTAIN.TITLEONE.CONTENT") }}</p>
<p>{{ $t("BusinessiIntroduction.CONTAIN.TITLEONE.CONTENTTWO") }}</p>
</div>
</div>
</section>
<!-- 业务核心解决方案 - 重新设计布局 -->
<main class="container">
<!-- 解决方案网格 - 新布局 -->
<div class="solution-grid">
<!-- 主推解决方案 -->
<div class="featured-solution">
<div class="solution-card" :style="{ '--delay': '0s' }">
<!-- <div class="card-badge">旗舰方案</div> -->
<div class="card-header">
<div class="decorative-line"></div>
<h2 class="card-title">{{ solutions[0].title }}</h2>
</div>
<ul class="card-content">
<li
v-for="(point, pIndex) in solutions[0].points"
:key="pIndex"
class="content-point"
>
<div class="point-icon"></div>
<div class="point-text">{{ point }}</div>
</li>
</ul>
</div>
</div>
<!-- 次要解决方案组 -->
<div class="secondary-solutions">
<div
v-for="(item, index) in solutions.slice(1)"
:key="index + 1"
class="solution-card"
:style="{ '--delay': (index + 1) * 0.1 + 's' }"
>
<div class="card-header">
<div class="decorative-line"></div>
<h2 class="card-title">{{ item.title }}</h2>
</div>
<ul class="card-content">
<li
v-for="(point, pIndex) in item.points"
:key="pIndex"
class="content-point"
>
<div class="point-icon"></div>
<div class="point-text">{{ point }}</div>
</li>
</ul>
</div>
</div>
</div>
</main>
</div>
</div>
</template>
<script setup>
import { useI18n } from "vue-i18n";
import { computed } from "vue";
const { t } = useI18n();
const solutions = computed(() => [
{
title: t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.ONE.TITLE"),
points: [
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.ONE.CONTENT"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.ONE.CONTENTTWO"),
],
},
{
title: t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.TWO.TITLE"),
points: [
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.TWO.CONTENT"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.TWO.CONTENTTWO"),
],
},
{
title: t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.THREE.TITLE"),
points: [
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.THREE.CONTENT"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.THREE.CONTENTTWO"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.THREE.CONTENTTHREE"),
],
},
{
title: t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.FOUR.TITLE"),
points: [
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.FOUR.CONTENT"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.FOUR.CONTENTTWO"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.FOUR.CONTENTTHREE"),
],
},
]);
</script>
<style scoped>
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
/* 基础样式 */
.container {
max-width: 1280px;
margin: 0 auto;
padding: 0 2rem;
}
/* 标题区样式 */
.hero-section {
background: linear-gradient(135deg, #f8fbfe 0%, #e6f0ff 100%);
padding: 8rem 0 6rem;
position: relative;
overflow: hidden;
}
.hero-section::after {
content: "";
position: absolute;
bottom: -50px;
left: 0;
width: 100%;
height: 100px;
background: white;
transform: skewY(-3deg);
}
.hero-title {
font-size: 3.5rem;
color: #2c3e50;
margin-bottom: 2rem;
animation: slideIn 1s ease;
}
.hero-description {
max-width: 800px;
margin: 0 auto;
font-size: 1.1rem;
line-height: 1.8;
color: #5a6d80;
}
:root {
--primary-color: #895bff;
--primary-light: #a07cff;
--primary-dark: #6a11cb;
--primary-gradient: linear-gradient(
135deg,
var(--primary-light) 0%,
var(--primary-color) 100%
);
}
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
.container {
max-width: 1280px;
margin: 0 auto;
padding: 0 2rem;
}
/* 标题区 - 紫色渐变 */
.hero-section {
background: var(--primary-gradient);
padding: 10rem 0 8rem;
position: relative;
overflow: hidden;
color: white;
}
.hero-section::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none"><path fill="rgba(255,255,255,0.05)" d="M0,0 L100,0 L100,100 Q50,80 0,100 Z"></path></svg>')
no-repeat bottom/100% 30%;
}
.hero-title {
font-size: 3.5rem;
margin-bottom: 2rem;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.title-decoration {
position: absolute;
bottom: -15px;
left: 0;
width: 80%;
height: 4px;
background: rgba(255, 255, 255, 0.5);
border-radius: 2px;
}
.hero-description {
max-width: 800px;
font-size: 1.1rem;
line-height: 1.8;
opacity: 0.9;
}
/* 解决方案网格 */
.solution-grid {
display: flex;
flex-direction: column;
gap: 2.5rem;
padding: 5rem 0;
position: relative;
z-index: 1;
}
.solution-grid::before {
content: "";
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 80%;
height: 100%;
opacity: 0.03;
z-index: -1;
}
/* 卡片设计 */
.solution-card {
background: white;
border-radius: 16px;
padding: 2.5rem;
box-shadow: 0 10px 40px rgba(137, 91, 255, 0.1);
transform: translateY(20px);
opacity: 0;
animation: cardEnter 0.6s ease forwards;
animation-delay: var(--delay);
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.1);
position: relative;
overflow: hidden;
border: none;
}
.solution-card::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
135deg,
rgba(137, 91, 255, 0.03) 0%,
rgba(137, 91, 255, 0) 100%
);
z-index: -1;
}
.solution-card:hover {
transform: translateY(-8px);
box-shadow: 0 15px 50px rgba(137, 91, 255, 0.2);
}
.featured-solution .solution-card {
border: 1px solid rgba(137, 91, 255, 0.2);
background: linear-gradient(135deg, #f9f6ff 0%, #f0e9ff 100%);
}
.card-badge {
position: absolute;
top: 20px;
right: 20px;
background: var(--primary-gradient);
color: white;
padding: 0.3rem 1.2rem;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 600;
box-shadow: 0 4px 12px rgba(137, 91, 255, 0.3);
}
.decorative-line {
width: 50px;
height: 3px;
background: var(--primary-gradient);
margin-bottom: 1.5rem;
border-radius: 3px;
transition: width 0.3s ease;
}
.solution-card:hover .decorative-line {
width: 80px;
}
.card-title {
font-size: 1.6rem;
color: #2c0850;
margin-bottom: 1.5rem;
font-weight: 600;
}
.content-point {
display: flex;
gap: 1.2rem;
padding: 1.2rem 0;
border-bottom: 1px solid rgba(137, 91, 255, 0.1);
}
.point-icon {
color: var(--primary-color);
font-size: 1.4rem;
flex-shrink: 0;
margin-top: 0.1rem;
}
.point-text {
color: #4a3a6b;
line-height: 1.7;
font-size: 1.05rem;
}
.card-button {
background: var(--primary-gradient);
color: white;
border: none;
padding: 0.8rem 1.8rem;
border-radius: 8px;
font-weight: 500;
margin-top: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(137, 91, 255, 0.3);
}
.card-button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(137, 91, 255, 0.4);
}
/* 布局调整 */
.secondary-solutions {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
/* 响应式设计 */
@media (max-width: 1024px) {
.secondary-solutions {
grid-template-columns: repeat(2, 1fr);
}
.featured-solution {
margin-bottom: 2rem;
}
}
@media (max-width: 768px) {
.hero-section {
padding: 7rem 0 5rem;
}
.hero-title {
font-size: 2.5rem;
}
.secondary-solutions {
grid-template-columns: 1fr;
}
.solution-card {
padding: 2rem;
}
}
/* 动画 */
@keyframes cardEnter {
to {
opacity: 1;
transform: translateY(0);
}
}
</style>

View File

@ -0,0 +1,406 @@
<template>
<div class="home-page">
<div class="business-page">
<!-- 渐变背景标题区 - 增加层次感 -->
<section class="hero-section">
<div class="hero-content container">
<div class="title-wrapper">
<h1 class="hero-title">
{{ $t("BusinessiIntroduction.CONTAIN.TITLEONE.TITLE") }}
</h1>
<div class="title-decoration"></div>
</div>
<div class="hero-description">
<p>{{ $t("BusinessiIntroduction.CONTAIN.TITLEONE.CONTENT") }}</p>
<p>{{ $t("BusinessiIntroduction.CONTAIN.TITLEONE.CONTENTTWO") }}</p>
</div>
</div>
</section>
<!-- 业务核心解决方案 - 重新设计布局 -->
<main class="container">
<!-- 解决方案网格 - 新布局 -->
<div class="solution-grid">
<!-- 主推解决方案 -->
<div class="featured-solution">
<div class="solution-card" :style="{ '--delay': '0s' }">
<!-- <div class="card-badge">旗舰方案</div> -->
<div class="card-header">
<div class="decorative-line"></div>
<h2 class="card-title">{{ solutions[0].title }}</h2>
</div>
<ul class="card-content">
<li
v-for="(point, pIndex) in solutions[0].points"
:key="pIndex"
class="content-point"
>
<div class="point-icon"></div>
<div class="point-text">{{ point }}</div>
</li>
</ul>
</div>
</div>
<!-- 次要解决方案组 -->
<div class="secondary-solutions">
<div
v-for="(item, index) in solutions.slice(1)"
:key="index + 1"
class="solution-card"
:style="{ '--delay': (index + 1) * 0.1 + 's' }"
>
<div class="card-header">
<div class="decorative-line"></div>
<h2 class="card-title">{{ item.title }}</h2>
</div>
<ul class="card-content">
<li
v-for="(point, pIndex) in item.points"
:key="pIndex"
class="content-point"
>
<div class="point-icon"></div>
<div class="point-text">{{ point }}</div>
</li>
</ul>
</div>
</div>
</div>
</main>
</div>
</div>
</template>
<script setup>
import { useI18n } from "vue-i18n";
import { computed } from "vue";
const { t } = useI18n();
const solutions = computed(() => [
{
title: t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.ONE.TITLE"),
points: [
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.ONE.CONTENT"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.ONE.CONTENTTWO"),
],
},
{
title: t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.TWO.TITLE"),
points: [
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.TWO.CONTENT"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.TWO.CONTENTTWO"),
],
},
{
title: t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.THREE.TITLE"),
points: [
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.THREE.CONTENT"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.THREE.CONTENTTWO"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.THREE.CONTENTTHREE"),
],
},
{
title: t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.FOUR.TITLE"),
points: [
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.FOUR.CONTENT"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.FOUR.CONTENTTWO"),
t("BusinessiIntroduction.CONTAIN.TITLEONE.paragraph.FOUR.CONTENTTHREE"),
],
},
]);
</script>
<style scoped>
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
/* 基础样式 */
.container {
max-width: 1280px;
margin: 0 auto;
padding: 0 2rem;
}
/* 标题区样式 */
.hero-section {
background: linear-gradient(135deg, #f8fbfe 0%, #e6f0ff 100%);
padding: 8rem 0 6rem;
position: relative;
overflow: hidden;
}
.hero-section::after {
content: "";
position: absolute;
bottom: -50px;
left: 0;
width: 100%;
height: 100px;
background: white;
transform: skewY(-3deg);
}
.hero-title {
font-size: 3.5rem;
color: #2c3e50;
margin-bottom: 2rem;
animation: slideIn 1s ease;
}
.hero-description {
max-width: 800px;
margin: 0 auto;
font-size: 1.1rem;
line-height: 1.8;
color: #5a6d80;
}
:root {
--primary-color: #895bff;
--primary-light: #a07cff;
--primary-dark: #6a11cb;
--primary-gradient: linear-gradient(
135deg,
var(--primary-light) 0%,
var(--primary-color) 100%
);
}
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
.container {
max-width: 1280px;
margin: 0 auto;
padding: 0 2rem;
}
/* 标题区 - 紫色渐变 */
.hero-section {
background: var(--primary-gradient);
padding: 10rem 0 8rem;
position: relative;
overflow: hidden;
color: white;
}
.hero-section::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none"><path fill="rgba(255,255,255,0.05)" d="M0,0 L100,0 L100,100 Q50,80 0,100 Z"></path></svg>')
no-repeat bottom/100% 30%;
}
.hero-title {
font-size: 3.5rem;
margin-bottom: 2rem;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.title-decoration {
position: absolute;
bottom: -15px;
left: 0;
width: 80%;
height: 4px;
background: rgba(255, 255, 255, 0.5);
border-radius: 2px;
}
.hero-description {
max-width: 800px;
font-size: 1.1rem;
line-height: 1.8;
opacity: 0.9;
}
/* 解决方案网格 */
.solution-grid {
display: flex;
flex-direction: column;
gap: 2.5rem;
padding: 5rem 0;
position: relative;
z-index: 1;
}
.solution-grid::before {
content: "";
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 80%;
height: 100%;
opacity: 0.03;
z-index: -1;
}
/* 卡片设计 */
.solution-card {
background: white;
border-radius: 16px;
padding: 2.5rem;
box-shadow: 0 10px 40px rgba(137, 91, 255, 0.1);
transform: translateY(20px);
opacity: 0;
animation: cardEnter 0.6s ease forwards;
animation-delay: var(--delay);
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.1);
position: relative;
overflow: hidden;
border: none;
}
.solution-card::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
135deg,
rgba(137, 91, 255, 0.03) 0%,
rgba(137, 91, 255, 0) 100%
);
z-index: -1;
}
.solution-card:hover {
transform: translateY(-8px);
box-shadow: 0 15px 50px rgba(137, 91, 255, 0.2);
}
.featured-solution .solution-card {
border: 1px solid rgba(137, 91, 255, 0.2);
background: linear-gradient(135deg, #f9f6ff 0%, #f0e9ff 100%);
}
.card-badge {
position: absolute;
top: 20px;
right: 20px;
background: var(--primary-gradient);
color: white;
padding: 0.3rem 1.2rem;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 600;
box-shadow: 0 4px 12px rgba(137, 91, 255, 0.3);
}
.decorative-line {
width: 50px;
height: 3px;
background: var(--primary-gradient);
margin-bottom: 1.5rem;
border-radius: 3px;
transition: width 0.3s ease;
}
.solution-card:hover .decorative-line {
width: 80px;
}
.card-title {
font-size: 1.6rem;
color: #2c0850;
margin-bottom: 1.5rem;
font-weight: 600;
}
.content-point {
display: flex;
gap: 1.2rem;
padding: 1.2rem 0;
border-bottom: 1px solid rgba(137, 91, 255, 0.1);
}
.point-icon {
color: var(--primary-color);
font-size: 1.4rem;
flex-shrink: 0;
margin-top: 0.1rem;
}
.point-text {
color: #4a3a6b;
line-height: 1.7;
font-size: 1.05rem;
}
.card-button {
background: var(--primary-gradient);
color: white;
border: none;
padding: 0.8rem 1.8rem;
border-radius: 8px;
font-weight: 500;
margin-top: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(137, 91, 255, 0.3);
}
.card-button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(137, 91, 255, 0.4);
}
/* 布局调整 */
.secondary-solutions {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
/* 响应式设计 */
@media (max-width: 1024px) {
.secondary-solutions {
grid-template-columns: repeat(2, 1fr);
}
.featured-solution {
margin-bottom: 2rem;
}
}
@media (max-width: 768px) {
.hero-section {
padding: 7rem 0 5rem;
}
.hero-title {
font-size: 2.5rem;
}
.secondary-solutions {
grid-template-columns: 1fr;
}
.solution-card {
padding: 2rem;
}
}
/* 动画 */
@keyframes cardEnter {
to {
opacity: 1;
transform: translateY(0);
}
}
</style>

View File

@ -0,0 +1,22 @@
<script setup>
import size1920 from "@/views/CommitteeAppointment/size1920/index.vue";
import size375 from "@/views/CommitteeAppointment/size375/index.vue";
import { computed } from "vue";
import { useWindowSize } from "@vueuse/core";
const { width } = useWindowSize();
const viewComponent = computed(() => {
const viewWidth = width.value;
if (viewWidth <= 450) {
return size375;
} else if (viewWidth <= 1920 || viewWidth > 1920) {
return size1920;
}
});
</script>
<template>
<component :is="viewComponent" />
</template>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,331 @@
<template>
<div class="committees-page">
<!-- 标题区 -->
<section class="hero-section">
<div class="container">
<h1>Board Committees</h1>
<p>Expertise Oversight and Corporate Governance</p>
</div>
</section>
<!-- 委员会表格 -->
<div class="container">
<div class="committees-table">
<!-- 表头 - 委员会名称 -->
<div class="table-header">
<div class="director-cell"></div>
<div class="committee-cell">
<h3>Audit Committee</h3>
</div>
<div class="committee-cell">
<h3>Compensation Committee</h3>
</div>
<div class="committee-cell">
<h3>Nominating and Corporate Governance Committee</h3>
</div>
</div>
<!-- 表格内容 - 每位董事 -->
<div
class="table-row"
v-for="(director, index) in otherDirectors"
:key="index"
>
<!-- 董事姓名 -->
<div class="director-cell">
<div class="director-info">
<div class="avatar"></div>
<div>
<router-link :to="'/boarddirectors'" class="director-link">
{{ director.name }}
</router-link>
<!-- <p class="director-title">{{ director.title }}</p> -->
</div>
</div>
</div>
<!-- 委员会职位 -->
<div class="committee-cell">
<div class="role-badges">
<template v-if="getCommitteeRole(director.name, 'Audit')">
<div
class="role-badge"
:class="
getCommitteeRole(director.name, 'Audit').toLowerCase()
"
>
<span class="badge-icon"></span>
</div>
</template>
</div>
</div>
<div class="committee-cell">
<div class="role-badges">
<template v-if="getCommitteeRole(director.name, 'Compensation')">
<div
class="role-badge"
:class="
getCommitteeRole(
director.name,
'Compensation'
).toLowerCase()
"
>
<span class="badge-icon"></span>
</div>
</template>
</div>
</div>
<div class="committee-cell">
<div class="role-badges">
<template v-if="getCommitteeRole(director.name, 'Governance')">
<div
class="role-badge"
:class="
getCommitteeRole(director.name, 'Governance').toLowerCase()
"
>
<span class="badge-icon"></span>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
const otherDirectors = [
{
name: "Cao Yu",
title: "Chief Financial Officer, Secretary, Treasurer and Director",
},
{ name: "David Lazar", title: "Director" },
{ name: "Hu Bin", title: "Director" },
{ name: "David Natan", title: "Director" },
{ name: "Chan Oi Fat", title: "Director" },
];
// - API
const committeeRoles = {
"Cao Yu": {},
"David Lazar": {},
"Hu Bin": {
Compensation: "Chair",
Governance: "Member",
Audit: "Chair",
},
"David Natan": {
Compensation: "Chair",
Governance: "Member",
Audit: "Chair",
},
"Chan Oi Fat": {
Compensation: "Chair",
Governance: "Member",
Audit: "Chair",
},
};
const getCommitteeRole = (name, committee) => {
return committeeRoles[name]?.[committee] || null;
};
</script>
<style scoped>
/* 紫色主题变量 */
:root {
--primary: #895bff;
--primary-light: #a07cff;
--primary-dark: #6a11cb;
--primary-transparent: rgba(137, 91, 255, 0.1);
}
.committees-page {
background-color: #faf9ff;
min-height: 100vh;
}
/* 标题区设计 */
.hero-section {
background: linear-gradient(
135deg,
var(--primary-light) 0%,
var(--primary) 100%
);
padding: 6rem 2rem;
text-align: center;
color: #895bff;
}
.hero-section h1 {
font-size: 2.8rem;
margin-bottom: 1rem;
}
.hero-section p {
font-size: 1.2rem;
opacity: 0.9;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
}
/* 表格设计 */
.committees-table {
margin: 4rem 0;
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(137, 91, 255, 0.08);
}
.table-header,
.table-row {
display: grid;
grid-template-columns: 1.5fr repeat(3, 1fr);
border-bottom: 1px solid #f0f0f0;
}
.table-header {
background: #f9f6ff;
position: sticky;
top: 0;
z-index: 2;
}
.committee-cell {
padding: 1.5rem;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
border-right: 1px solid #f0f0f0;
}
.committee-cell:last-child {
border-right: none;
}
.committee-cell h3 {
color: var(--primary-dark);
font-size: 1.1rem;
font-weight: 600;
}
.director-cell {
padding: 1.5rem;
border-right: 1px solid #f0f0f0;
}
.director-info {
display: flex;
align-items: center;
gap: 1.2rem;
}
.director-info h4 {
font-size: 1.1rem;
color: #333;
margin-bottom: 0.3rem;
}
.director-title {
font-size: 0.85rem;
color: #666;
}
/* 职位徽章设计 */
.role-badges {
display: flex;
flex-direction: column;
gap: 0.8rem;
}
.role-badge {
padding: 0.5rem 1rem;
border-radius: 20px;
font-size: 0.85rem;
font-weight: 500;
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 80px;
}
.badge-icon {
width: 16px;
height: 16px;
margin-left: 0.5rem;
background: currentColor;
mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12l5 5L20 7"/></svg>')
no-repeat center;
}
/* 悬停效果 */
.table-row {
transition: all 0.3s ease;
}
.table-row:hover {
background: #fdfcff;
transform: translateY(-1px);
box-shadow: 0 5px 15px rgba(137, 91, 255, 0.05);
}
/* 响应式设计 */
@media (max-width: 1024px) {
.committees-table {
overflow-x: auto;
}
.table-header,
.table-row {
grid-template-columns: 250px repeat(3, 200px);
width: max-content;
min-width: 100%;
}
}
@media (max-width: 768px) {
.hero-section {
padding: 4rem 1rem;
}
.hero-section h1 {
font-size: 2.2rem;
}
.director-info {
flex-direction: column;
text-align: center;
gap: 0.8rem;
}
.director-cell {
padding: 1rem;
}
.committee-cell {
padding: 1rem 0.5rem;
}
}
.director-link {
color: #895bff;
text-decoration: none;
transition: color 0.3s ease;
}
.director-link:hover {
color: var(--primary);
text-decoration: underline;
}
</style>

View File

@ -0,0 +1,360 @@
<template>
<div class="committees-page">
<!-- 标题区 -->
<section class="hero-section">
<div class="container">
<h1>Board Committees</h1>
<p>Expertise Oversight and Corporate Governance</p>
</div>
</section>
<!-- 委员会表格 -->
<div class="container">
<div class="committees-table">
<!-- 表头 - 委员会名称 -->
<div class="table-header">
<div class="director-cell"></div>
<div class="committee-cell">
<h3>Audit Committee</h3>
</div>
<div class="committee-cell">
<h3>Compensation Committee</h3>
</div>
<div class="committee-cell">
<h3>Nominating and Corporate Governance Committee</h3>
</div>
</div>
<!-- 表格内容 - 每位董事 -->
<div
class="table-row"
v-for="(director, index) in otherDirectors"
:key="index"
>
<!-- 董事姓名 -->
<div class="director-cell">
<div class="director-info">
<div class="avatar"></div>
<div>
<router-link :to="'/boarddirectors'" class="director-link">
{{ director.name }}
</router-link>
<!-- <p class="director-title">{{ director.title }}</p> -->
</div>
</div>
</div>
<!-- 委员会职位 -->
<div class="committee-cell">
<div class="role-badges">
<template v-if="getCommitteeRole(director.name, 'Audit')">
<div
class="role-badge"
:class="
getCommitteeRole(director.name, 'Audit').toLowerCase()
"
>
{{ getCommitteeRole(director.name, "Audit") }}
<span class="badge-icon"></span>
</div>
</template>
</div>
</div>
<div class="committee-cell">
<div class="role-badges">
<template v-if="getCommitteeRole(director.name, 'Compensation')">
<div
class="role-badge"
:class="
getCommitteeRole(
director.name,
'Compensation'
).toLowerCase()
"
>
{{ getCommitteeRole(director.name, "Compensation") }}
<span class="badge-icon"></span>
</div>
</template>
</div>
</div>
<div class="committee-cell">
<div class="role-badges">
<template v-if="getCommitteeRole(director.name, 'Governance')">
<div
class="role-badge"
:class="
getCommitteeRole(director.name, 'Governance').toLowerCase()
"
>
{{ getCommitteeRole(director.name, "Governance") }}
<span class="badge-icon"></span>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
const otherDirectors = [
{
name: "Cao Yu",
title: "Chief Financial Officer, Secretary, Treasurer and Director",
},
{ name: "David Lazar", title: "Director" },
{ name: "Hu Bin", title: "Director" },
{ name: "David Natan", title: "Director" },
{ name: "Chan Oi Fat", title: "Director" },
];
// - API
const committeeRoles = {
"Cao Yu": {
Audit: "Chair",
Compensation: "Member",
},
"David Lazar": {
Audit: "Member",
Governance: "Chair",
},
"Hu Bin": {
Compensation: "Chair",
Governance: "Member",
},
"David Natan": {
Audit: "Member",
},
"Chan Oi Fat": {
Governance: "Member",
},
};
const getCommitteeRole = (name, committee) => {
return committeeRoles[name]?.[committee] || null;
};
</script>
<style scoped>
/* 紫色主题变量 */
:root {
--primary: #895bff;
--primary-light: #a07cff;
--primary-dark: #6a11cb;
--primary-transparent: rgba(137, 91, 255, 0.1);
}
.committees-page {
background-color: #faf9ff;
min-height: 100vh;
}
/* 标题区设计 */
.hero-section {
background: linear-gradient(
135deg,
var(--primary-light) 0%,
var(--primary) 100%
);
padding: 6rem 2rem;
text-align: center;
color: #895bff;
}
.hero-section h1 {
font-size: 2.8rem;
margin-bottom: 1rem;
}
.hero-section p {
font-size: 1.2rem;
opacity: 0.9;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
}
/* 表格设计 */
.committees-table {
margin: 4rem 0;
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(137, 91, 255, 0.08);
}
.table-header,
.table-row {
display: grid;
grid-template-columns: 1.5fr repeat(3, 1fr);
border-bottom: 1px solid #f0f0f0;
}
.table-header {
background: #f9f6ff;
position: sticky;
top: 0;
z-index: 2;
}
.committee-cell {
padding: 1.5rem;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
border-right: 1px solid #f0f0f0;
}
.committee-cell:last-child {
border-right: none;
}
.committee-cell h3 {
color: var(--primary-dark);
font-size: 1.1rem;
font-weight: 600;
}
.director-cell {
padding: 1.5rem;
border-right: 1px solid #f0f0f0;
}
.director-info {
display: flex;
align-items: center;
gap: 1.2rem;
}
.avatar {
width: 50px;
height: 50px;
border-radius: 50%;
background: var(--primary-transparent);
display: flex;
align-items: center;
justify-content: center;
color: var(--primary);
font-weight: bold;
flex-shrink: 0;
}
.director-info h4 {
font-size: 1.1rem;
color: #333;
margin-bottom: 0.3rem;
}
.director-title {
font-size: 0.85rem;
color: #666;
}
/* 职位徽章设计 */
.role-badges {
display: flex;
flex-direction: column;
gap: 0.8rem;
}
.role-badge {
padding: 0.5rem 1rem;
border-radius: 20px;
font-size: 0.85rem;
font-weight: 500;
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 80px;
}
.role-badge.chair {
background: rgba(74, 222, 128, 0.15);
color: #10b981;
border: 1px solid rgba(16, 185, 129, 0.3);
}
.role-badge.member {
background: rgba(96, 165, 250, 0.15);
color: #3b82f6;
border: 1px solid rgba(59, 130, 246, 0.3);
}
.badge-icon {
width: 16px;
height: 16px;
margin-left: 0.5rem;
background: currentColor;
mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>')
no-repeat center;
}
/* 悬停效果 */
.table-row {
transition: all 0.3s ease;
}
.table-row:hover {
background: #fdfcff;
transform: translateY(-1px);
box-shadow: 0 5px 15px rgba(137, 91, 255, 0.05);
}
/* 响应式设计 */
@media (max-width: 1024px) {
.committees-table {
overflow-x: auto;
}
.table-header,
.table-row {
grid-template-columns: 250px repeat(3, 200px);
width: max-content;
min-width: 100%;
}
}
@media (max-width: 768px) {
.hero-section {
padding: 4rem 1rem;
}
.hero-section h1 {
font-size: 2.2rem;
}
.director-info {
flex-direction: column;
text-align: center;
gap: 0.8rem;
}
.director-cell {
padding: 1rem;
}
.committee-cell {
padding: 1rem 0.5rem;
}
}
.director-link {
color: #895bff;
text-decoration: none;
transition: color 0.3s ease;
}
.director-link:hover {
color: var(--primary);
text-decoration: underline;
}
</style>

View File

@ -0,0 +1,22 @@
<script setup>
import size1920 from "@/views/boarddirectors/size1920/index.vue";
import size375 from "@/views/boarddirectors/size375/index.vue";
import { computed } from "vue";
import { useWindowSize } from "@vueuse/core";
const { width } = useWindowSize();
const viewComponent = computed(() => {
const viewWidth = width.value;
if (viewWidth <= 450) {
return size375;
} else if (viewWidth <= 1920 || viewWidth > 1920) {
return size1920;
}
});
</script>
<template>
<component :is="viewComponent" />
</template>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,133 @@
<template>
<div class="home-page">
<div class="directors-page">
<n-h1 class="page-title">Board of Directors</n-h1>
<n-divider />
<div class="directors-list">
<div
v-for="(director, index) in otherDirectors"
:key="index"
class="director-item"
>
<n-h2 class="director-name">{{ director.name }}</n-h2>
<n-text class="director-title">{{ director.title }}</n-text>
<n-divider class="divider" />
<n-p class="director-bio">{{ director.contain }}</n-p>
</div>
</div>
</div>
</div>
</template>
<script setup>
const otherDirectors = [
{
name: "Cao Yu",
title: "Chief Financial Officer, Secretary, Treasurer and Director",
contain:
"Cao Yu, age 34, previously served as the treasury director of Taifeng Cultural Communication Co., Ltd where she oversees its financial matters fromNovember 2018 to November 2024. Prior to that, Ms. Cao served as a business manager of Yangfeng Art Exchange Co., Ltd from February 2016 toOctober 2018. From March 2011 to January 2016, she served as the treasury officer of financial department of Suzhou Industrial Park Xinfushida PlasticProfile Products Co., Ltd.",
},
{
name: "David Lazar",
title: "Director",
contain:
"David E. Lazar, age 34, has served as the Chief Executive Officer of OpGen, Inc., a precision medicine company listed on the Nasdaq (OPGN) since April11, 2024, where he also servs as a director and board chairman, beginning on March 25, 2024. Mr. Lazar served as the Chief Executive Officer of TitanPharmaceuticals Inc. listed on the Nasdaq (TTNP) from August 2022 through April 11, 2024, where he also served as a director and board chairman fromAugust 2022 until October 2023. He has also served as the CEO of Custodian Ventures LLC, a company which specializes in assisting distressed publiccompanies through custodianship, since February 2018, and Activist Investing LLC, an actively managed private investment fund, since March 2018.Previously, Mr. Lazar served as Managing Partner at Zenith Partners International Inc., a boutique consulting firm, from July 2012 to April 2018. In his roleas Chief Eecutive Officer of Custodian Ventures LLC, Mr. Lazar has successfully served as a custodian to numerous public companies across a widerange of industries.",
},
{
name: "Hu Bin",
title: "Director",
contain:
"Hu Bin,age 55, has served as a director of DC International Service Trade GmbH since December 2024. Prior to that, Mr. Hu worked as a freelancer in thetourism industry from April 2001 to October 2024. From April 1994 to October 2000, he served as the general manager of Suzhou Wintime AdvertisingCo., Ltd. Before that, he served as the general manager of Suzhou Bauhaus Advertising Design Co., Ltd. from August 1992 to April 1994, where he wasengaged in computer-aided design and 3D computer animation production. Mr. Hu began his career at Suzhou Advertising Company in October 1989,where he worked as a designer responsible for graphic design, platemaking, printing, and interior decoration. Mr. Hu graduated from Suzhou Academy ofArts in 1989.",
},
{
name: "David Natan",
title: "Director",
contain:
"David Natan,age 72, currently serves as President and Chief Executive Officer of Natan & Associates, LLC, a consulting firm offering chief financialofficer services to public and private companies in a variety of industries, since 2007. Mr. Natan previously served as a Director of the Company fromNovember 2023 to February 2025. From February 2010 to May 2020, Mr. Natan served as Chief Executive Officer of ForceField Energy, Inc.(OTCMKTS: FNRG), a company focused on the solar industry and LED lighting products. From February 2002 to November 2007, Mr. Natan served asExecutive Vice President of Reporting and Chief Financial Officer of PharmaNet Development Group, Inc., a drug development services company, and,from June 1995 to February 2002, as Chief Financial Officer and Vice President of Global Technovations, Inc., a manufacturer and marketer of oil analysisinstruments and speakers and speaker components. Prior to that, Mr. Natan served in various roles of increasing responsibility with Deloitte & Touche LLP,a global consulting firm. Mr. Natan currently serves as a member of the Board of Directors and Chair of the Audit Committee of Sunshine Biopharma, Inc.(Nasdaq: SBFM), a pharmaceutical and nutritional supplement company, since February 2022. Previously, Mr. Natan has served as a director for thefollowing public companies: Global Technovations, Forcefield Energy, Titan Pharmaceuticals (Nasdaq: TTNP), Vivakor Inc. (Nasdaq: VIVK), NetBrandsCorp. (OTC: NBND), and OpGen Inc. (OTC: OPGN), and Cyclacel Pharmaceuticals (Nasdaq: CYCC). Mr. Natan holds a B.A. in Economics from BostonUniversity.",
},
{
name: "Chan Oi Fat",
title: "Director",
contain:
"Chan Oi Fat, age 46, has served as Vice President Finance of SML Group Corporation since March 2018 and as Company Secretary of China LeonInspection Holding Limited (HKEX: 1586) since February 2018 and of Raily Aesthetic Medicine International Holdings Limited (HKEX: 2135) sinceNovember 2020. He is an independent non-executive director of Huajin International Holdings Limited (HKEX: 2738) (since March 2025) and UBoTHolding Limited (HKEX GEM: 8529) (since May 2024) and previously served as an independent non-executive director of China Saftower InternationalHolding Group Limited (HKEX GEM: 8623) from June 2020 to December 2023 and Shanghai Prime Machinery Company Limited (HKEX: 2345) fromJune 2014 to January 2021. Mr. Chan holds a B.B.A. (Hons) in Accountancy from the City University of Hong Kong (2000) and is a member of theAssociation of Chartered Certified Accountants (since 2003) and the Hong Kong Institute of Certified Public Accountants (since 2004).",
},
];
</script>
<style scoped>
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
.directors-page {
max-width: 900px;
margin: 0 auto;
padding: 60px 24px;
}
.page-title {
text-align: center;
margin-bottom: 16px;
font-weight: 500;
color: #1a1a1a;
}
.directors-list {
display: flex;
flex-direction: column;
gap: 48px;
margin-top: 40px;
}
.director-item {
padding-bottom: 48px;
border-bottom: 1px solid #f0f0f0;
}
.director-item:last-child {
border-bottom: none;
padding-bottom: 0;
}
.director-name {
margin-bottom: 8px;
font-size: 28px;
font-weight: 500;
color: #1a1a1a;
}
.director-title {
font-size: 18px;
color: #666;
display: block;
margin-bottom: 24px;
}
.divider {
margin: 16px 0;
background-color: #f0f0f0;
}
.director-bio {
line-height: 1.8;
color: #4a4a4a;
font-size: 16px;
}
@media (min-width: 768px) {
.directors-page {
padding: 80px 40px;
}
.director-name {
font-size: 32px;
}
.director-title {
font-size: 20px;
}
}
</style>

View File

@ -0,0 +1,379 @@
<template>
<div class="home-page">
<div class="board-page">
<!-- 紫色渐变标题区 -->
<section class="hero-board">
<div class="hero-content">
<h1 class="hero-title">Board of Directors</h1>
<div class="hero-subtitle">Leadership Driving Innovation</div>
</div>
<div class="hero-wave"></div>
</section>
<!-- 董事会成员展示 -->
<main class="board-container">
<div class="directors-grid">
<!-- CEO卡片 - 特殊强调 -->
<div class="director-card ceo-card">
<div class="card-inner">
<div class="card-front">
<div class="avatar-placeholder"></div>
<h2 class="director-name">Li Wai Chung</h2>
<div class="director-title">
Chief Executive Officer and President
</div>
<div class="card-flip-hint"> View Profile</div>
</div>
<div class="card-back">
<div class="profile-content">
<h3>Executive Profile</h3>
<div class="divider"></div>
<p>
Extensive experience in leadership roles with a proven track
record of driving growth and operational excellence
</p>
<div class="accent-line"></div>
</div>
</div>
</div>
<div class="card-glow"></div>
</div>
<!-- 其他董事成员 -->
<div
class="director-card"
v-for="(director, index) in otherDirectors"
:key="index"
>
<div class="card-inner">
<div class="card-front">
<div
class="avatar-placeholder"
:style="{ '--delay': index * 0.1 + 's' }"
></div>
<h2 class="director-name">{{ director.name }}</h2>
<div class="director-title">{{ director.title }}</div>
</div>
<div class="card-back">
<div class="profile-content">
<h3>Director Profile</h3>
<div class="divider"></div>
<p>
Extensive experience in corporate governance and strategic
leadership
</p>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
</template>
<script setup>
const otherDirectors = [
{
name: "Cao Yu",
title: "Chief Financial Officer, Secretary, Treasurer and Director",
},
{ name: "David Lazar", title: "Director" },
{ name: "Hu Bin", title: "Director" },
{ name: "David Natan", title: "Director" },
{ name: "Chan Oi Fat", title: "Director" },
];
</script>
<style scoped>
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
/* 紫色主题变量 */
:root {
--primary: #895bff;
--primary-light: #a07cff;
--primary-dark: #6a11cb;
--primary-gradient: linear-gradient(
135deg,
var(--primary-light) 0%,
var(--primary) 100%
);
--primary-transparent: rgba(137, 91, 255, 0.1);
}
/* 标题区设计 */
.hero-board {
background: var(--primary-gradient);
padding: 8rem 2rem 6rem;
position: relative;
text-align: center;
color: #895bff;
overflow: hidden;
}
.hero-board::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none"><circle fill="rgba(255,255,255,0.05)" cx="20" cy="20" r="15"/><circle fill="rgba(255,255,255,0.05)" cx="80" cy="40" r="20"/><circle fill="rgba(255,255,255,0.05)" cx="50" cy="80" r="10"/></svg>');
opacity: 0.3;
}
.hero-title {
font-size: 3.5rem;
margin-bottom: 1rem;
font-weight: 600;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
animation: fadeInDown 1s ease;
}
.hero-subtitle {
font-size: 1.2rem;
letter-spacing: 0.1em;
opacity: 0.9;
animation: fadeIn 1.5s ease;
}
.hero-wave {
position: absolute;
bottom: -1px;
left: 0;
width: 100%;
height: 100px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none"><path d="M0,0V46.29c47.79,22.2,103.59,32.17,158,28,70.36-5.37,136.33-33.31,206.8-37.5C438.64,32.43,512.34,53.67,583,72.05c69.27,18,138.3,24.88,209.4,13.08,36.15-6,69.85-17.84,104.45-29.34C989.49,25,1113-14.29,1200,52.47V0Z" fill="%23faf9ff" opacity=".25"/><path d="M0,0V15.81C13,36.92,27.64,56.86,47.69,72.05,99.41,111.27,165,111,224.58,91.58c31.15-10.15,60.09-26.07,89.67-39.8,40.92-19,84.73-46,130.83-49.67,36.26-2.85,70.9,9.42,98.6,31.56,31.77,25.39,62.32,62,103.63,73,40.44,10.79,81.35-6.69,119.13-24.28s75.16-39,116.92-43.05c59.73-5.85,113.28,22.88,168.9,38.84,30.2,8.66,59,6.17,87.09-7.5,22.43-10.89,48-26.93,60.65-49.24V0Z" fill="%23faf9ff" opacity=".5"/><path d="M0,0V5.63C149.93,59,314.09,71.32,475.83,42.57c43-7.64,84.23-20.12,127.61-26.46,59-8.63,112.48,12.24,165.56,35.4C827.93,77.22,886,95.24,951.2,90c86.53-7,172.46-45.71,248.8-84.81V0Z" fill="%23faf9ff"/></svg>');
background-size: cover;
}
/* 董事会成员网格 */
.board-container {
max-width: 1200px;
margin: 0 auto;
padding: 4rem 2rem;
}
.directors-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
position: relative;
}
/* 董事卡片设计 */
.director-card {
perspective: 1000px;
height: 380px;
position: relative;
}
.director-card .card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.8s;
transform-style: preserve-3d;
border-radius: 16px;
box-shadow: 0 10px 30px rgba(137, 91, 255, 0.1);
}
.director-card:hover .card-inner {
transform: rotateY(180deg);
}
.card-front,
.card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 16px;
overflow: hidden;
}
.card-front {
background: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
text-align: center;
}
.card-back {
background: linear-gradient(135deg, #f9f6ff 0%, #f0e9ff 100%);
transform: rotateY(180deg);
padding: 2rem;
display: flex;
align-items: center;
}
/* CEO特殊卡片 */
.ceo-card .card-front {
border: 2px solid var(--primary);
}
.ceo-card .card-back {
background: linear-gradient(135deg, #f3eeff 0%, #e8ddff 100%);
}
.ceo-card::after {
content: "CEO";
position: absolute;
top: 20px;
right: 20px;
background: var(--primary-gradient);
color: white;
padding: 0.3rem 1rem;
border-radius: 20px;
font-weight: 600;
z-index: 3;
}
.card-glow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 16px;
box-shadow: 0 0 30px rgba(137, 91, 255, 0.3);
opacity: 0;
transition: opacity 0.3s ease;
}
.ceo-card:hover .card-glow {
opacity: 1;
}
/* 卡片内容样式 */
.avatar-placeholder {
width: 120px;
height: 120px;
border-radius: 50%;
background: var(--primary-transparent);
margin-bottom: 1.5rem;
position: relative;
overflow: hidden;
animation: fadeIn 0.5s ease var(--delay, 0s) forwards;
opacity: 0;
}
.avatar-placeholder::before {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60px;
height: 60px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23895bff"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/></svg>')
no-repeat center/contain;
opacity: 0.3;
}
.director-name {
font-size: 1.5rem;
color: #2c0850;
margin-bottom: 0.5rem;
font-weight: 600;
}
.director-title {
color: var(--primary);
font-size: 0.95rem;
line-height: 1.6;
max-width: 80%;
}
.card-flip-hint {
position: absolute;
bottom: 20px;
color: var(--primary);
font-size: 0.8rem;
opacity: 0.7;
animation: pulse 2s infinite;
}
.profile-content {
width: 100%;
}
.profile-content h3 {
color: var(--primary-dark);
margin-bottom: 1rem;
}
.divider {
width: 40px;
height: 2px;
background: var(--primary-gradient);
margin: 1rem 0;
}
.accent-line {
width: 100%;
height: 1px;
background: linear-gradient(
90deg,
transparent,
var(--primary-transparent),
transparent
);
margin: 1.5rem 0;
}
/* 动画效果 */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes pulse {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-5px);
}
100% {
transform: translateY(0);
}
}
/* 响应式设计 */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem;
}
.directors-grid {
grid-template-columns: 1fr;
}
.director-card {
height: 350px;
}
}
</style>

View File

@ -9,7 +9,6 @@ const investmentDate = ref(null)
const handleSubmit = () => {
message.success('已提交!')
}
</script>

View File

@ -0,0 +1,22 @@
<script setup>
import size1920 from "@/views/companyoverview/size1920/index.vue";
import size375 from "@/views/companyoverview/size375/index.vue";
import { computed } from "vue";
import { useWindowSize } from "@vueuse/core";
const { width } = useWindowSize();
const viewComponent = computed(() => {
const viewWidth = width.value;
if (viewWidth <= 450) {
return size375;
} else if (viewWidth <= 1920 || viewWidth > 1920) {
return size1920;
}
});
</script>
<template>
<component :is="viewComponent" />
</template>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,426 @@
<template>
<div class="home-page">
<div class="company-overview">
<!-- 顶部大图区域 -->
<div class="hero-section">
<transition name="fade-up" appear>
<n-h1 class="hero-title">{{
$t("COMPANYOVERVIEW.TITLETWO.TITLE")
}}</n-h1>
</transition>
<transition name="fade-up" appear>
<n-p class="hero-subtitle">
{{ $t("COMPANYOVERVIEW.HERO_SUBTITLE") }}
</n-p>
</transition>
</div>
<!-- 公司简介部分 -->
<section class="section intro-section">
<n-h2 class="section-title">{{
$t("COMPANYOVERVIEW.INTRO_TITLE")
}}</n-h2>
<n-p class="section-content">{{
$t("COMPANYOVERVIEW.TITLETWO.CONTENT")
}}</n-p>
<n-p class="section-content">{{
$t("COMPANYOVERVIEW.TITLETWO.CONTENTTWO")
}}</n-p>
<n-p class="section-content">{{
$t("COMPANYOVERVIEW.TITLETWO.CONTENTTHREE")
}}</n-p>
</section>
<!-- 使命愿景卡片 -->
<section class="mission-section">
<div class="mission-cards">
<n-card hoverable class="mission-card" v-motion-pop>
<n-h3 class="card-title">{{
$t("COMPANYOVERVIEW.MISSION_TITLE")
}}</n-h3>
<n-p class="card-content">{{
$t("COMPANYOVERVIEW.TITLETHREE.CONTENT")
}}</n-p>
</n-card>
<n-card hoverable class="mission-card" v-motion-pop>
<n-h3 class="card-title">{{
$t("COMPANYOVERVIEW.VISION_TITLE")
}}</n-h3>
<n-p class="card-content">{{
$t("COMPANYOVERVIEW.TITLETHREE.CONTENTTWO")
}}</n-p>
</n-card>
</div>
</section>
<!-- 里程碑时间轴 -->
<!-- 里程碑时间轴 -->
<section class="section timeline-section">
<n-h2 class="section-title">{{
$t("COMPANYOVERVIEW.TITLEFOUR.TITLE")
}}</n-h2>
<div class="timeline">
<!-- 1977-2015 -->
<div class="timeline-item" v-motion-slide-visible-once-bottom>
<div class="timeline-dot"></div>
<div class="timeline-content">
<n-h3 class="timeline-year">{{
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING")
}}</n-h3>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraph.ONE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraph.TWO")
}}</n-p>
</div>
</div>
<!-- 2020 -->
<div class="timeline-item" v-motion-slide-visible-once-bottom>
<div class="timeline-dot"></div>
<div class="timeline-content">
<n-h3 class="timeline-year">{{
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO")
}}</n-h3>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphTwo.ONE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphTwo.TWO")
}}</n-p>
</div>
</div>
<!-- 2021 -->
<div class="timeline-item" v-motion-slide-visible-once-bottom>
<div class="timeline-dot"></div>
<div class="timeline-content">
<n-h3 class="timeline-year">{{
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE")
}}</n-h3>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphTHREE.ONE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphTHREE.TWO")
}}</n-p>
</div>
</div>
<!-- 2023-2024 -->
<div class="timeline-item" v-motion-slide-visible-once-bottom>
<div class="timeline-dot"></div>
<div class="timeline-content">
<n-h3 class="timeline-year">{{
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF")
}}</n-h3>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFOUR.ONE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFOUR.TWO")
}}</n-p>
</div>
</div>
<!-- 2025 -->
<div class="timeline-item" v-motion-slide-visible-once-bottom>
<div class="timeline-dot"></div>
<div class="timeline-content">
<n-h3 class="timeline-year">{{
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE")
}}</n-h3>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.ONE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.TWO")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.THREE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.FOUR")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.FIVE")
}}</n-p>
</div>
</div>
</div>
</section>
<!-- 成就部分 -->
<section class="achievement-section" v-motion-fade>
<n-h2 class="section-title">{{
$t("COMPANYOVERVIEW.TITLEFIVE.TITLE")
}}</n-h2>
<n-p class="section-content">{{
$t("COMPANYOVERVIEW.TITLEFIVE.CONTENT")
}}</n-p>
<div class="achievement-stats">
<n-statistic
v-for="(stat, index) in stats"
:key="index"
class="stat-item"
v-motion-slide-visible-once-bottom
:style="{ '--delay': index * 0.1 + 's' }"
>
<template #label>{{ $t(stat.labelKey) }}</template>
{{ stat.number }}
</n-statistic>
</div>
</section>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useI18n } from "vue-i18n";
const { t: $t } = useI18n();
const stats = ref([
{ number: "48+", labelKey: "COMPANYOVERVIEW.STATS.YEARS_IN_BUSINESS" },
{ number: "100+", labelKey: "COMPANYOVERVIEW.STATS.PATENTS" },
{ number: "Global", labelKey: "COMPANYOVERVIEW.STATS.FOOTPRINT" },
{ number: "NASDAQ", labelKey: "COMPANYOVERVIEW.STATS.LISTED_SINCE" },
]);
</script>
<style scoped>
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
.company-overview {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
color: var(--text-color);
}
/* 顶部大图区域 */
.hero-section {
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
background-size: 400% 400%;
animation: gradientBG 15s ease infinite;
color: white;
padding: 120px 0;
text-align: center;
margin-bottom: 60px;
border-radius: 8px;
}
.hero-title {
font-size: 3.5rem;
margin-bottom: 20px;
font-weight: 700;
}
.hero-subtitle {
font-size: 1.5rem;
opacity: 0.9;
}
/* 通用部分样式 */
.section {
margin-bottom: 80px;
}
.section-title {
font-size: 2.2rem;
margin-bottom: 30px;
position: relative;
display: inline-block;
}
.section-title:after {
content: "";
position: absolute;
bottom: -10px;
left: 0;
width: 60px;
height: 4px;
background: linear-gradient(to right, #1a2a6c, #fdbb2d);
border-radius: 2px;
}
.section-content {
font-size: 1.1rem;
line-height: 1.8;
margin-bottom: 20px;
color: var(--text-color-secondary);
}
/* 使命愿景卡片 */
.mission-section {
margin: 80px 0;
}
.mission-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
}
.mission-card {
background: white;
padding: 40px 30px;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.mission-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.12);
}
.card-title {
font-size: 1.5rem;
margin-bottom: 20px;
color: #895bff;
}
.card-content {
font-size: 1.05rem;
line-height: 1.7;
}
/* 时间轴样式 */
.timeline {
position: relative;
padding-left: 50px;
margin-top: 50px;
}
.timeline:before {
content: "";
position: absolute;
top: 0;
left: 20px;
height: 100%;
width: 4px;
background: linear-gradient(to bottom, #895bff, #fdbb2d);
}
.timeline-item {
position: relative;
margin-bottom: 50px;
}
.timeline-dot {
position: absolute;
left: -50px;
top: 5px;
width: 40px;
height: 40px;
border-radius: 50%;
background: #895bff;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
box-shadow: 0 0 0 6px rgba(26, 42, 108, 0.2);
}
.timeline-year {
font-size: 1.4rem;
margin-bottom: 15px;
color: #1a2a6c;
}
.timeline-desc {
font-size: 1.05rem;
line-height: 1.7;
margin-bottom: 10px;
}
/* 成就部分 */
.achievement-section {
background: #f9fafc;
padding: 60px;
border-radius: 12px;
margin: 80px 0;
}
.achievement-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 30px;
margin-top: 50px;
}
.stat-item {
text-align: center;
padding: 30px 20px;
background: white;
border-radius: 8px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
transition: transform 0.3s ease;
}
.stat-item:hover {
transform: translateY(-5px);
}
.stat-number {
font-size: 2.5rem;
color: #1a2a6c;
margin-bottom: 10px;
}
.stat-label {
font-size: 1.1rem;
color: var(--text-color-secondary);
}
/* 动画 */
@keyframes gradientBG {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* 响应式设计 */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem;
}
.hero-subtitle {
font-size: 1.2rem;
}
.section-title {
font-size: 1.8rem;
}
.timeline {
padding-left: 30px;
}
.timeline-dot {
left: -30px;
width: 30px;
height: 30px;
}
.achievement-section {
padding: 40px 20px;
}
}
</style>

View File

@ -0,0 +1,426 @@
<template>
<div class="home-page">
<div class="company-overview">
<!-- 顶部大图区域 -->
<div class="hero-section">
<transition name="fade-up" appear>
<n-h1 class="hero-title">{{
$t("COMPANYOVERVIEW.TITLETWO.TITLE")
}}</n-h1>
</transition>
<transition name="fade-up" appear>
<n-p class="hero-subtitle">
{{ $t("COMPANYOVERVIEW.HERO_SUBTITLE") }}
</n-p>
</transition>
</div>
<!-- 公司简介部分 -->
<section class="section intro-section">
<n-h2 class="section-title">{{
$t("COMPANYOVERVIEW.INTRO_TITLE")
}}</n-h2>
<n-p class="section-content">{{
$t("COMPANYOVERVIEW.TITLETWO.CONTENT")
}}</n-p>
<n-p class="section-content">{{
$t("COMPANYOVERVIEW.TITLETWO.CONTENTTWO")
}}</n-p>
<n-p class="section-content">{{
$t("COMPANYOVERVIEW.TITLETWO.CONTENTTHREE")
}}</n-p>
</section>
<!-- 使命愿景卡片 -->
<section class="mission-section">
<div class="mission-cards">
<n-card hoverable class="mission-card" v-motion-pop>
<n-h3 class="card-title">{{
$t("COMPANYOVERVIEW.MISSION_TITLE")
}}</n-h3>
<n-p class="card-content">{{
$t("COMPANYOVERVIEW.TITLETHREE.CONTENT")
}}</n-p>
</n-card>
<n-card hoverable class="mission-card" v-motion-pop>
<n-h3 class="card-title">{{
$t("COMPANYOVERVIEW.VISION_TITLE")
}}</n-h3>
<n-p class="card-content">{{
$t("COMPANYOVERVIEW.TITLETHREE.CONTENTTWO")
}}</n-p>
</n-card>
</div>
</section>
<!-- 里程碑时间轴 -->
<!-- 里程碑时间轴 -->
<section class="section timeline-section">
<n-h2 class="section-title">{{
$t("COMPANYOVERVIEW.TITLEFOUR.TITLE")
}}</n-h2>
<div class="timeline">
<!-- 1977-2015 -->
<div class="timeline-item" v-motion-slide-visible-once-bottom>
<div class="timeline-dot"></div>
<div class="timeline-content">
<n-h3 class="timeline-year">{{
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING")
}}</n-h3>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraph.ONE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraph.TWO")
}}</n-p>
</div>
</div>
<!-- 2020 -->
<div class="timeline-item" v-motion-slide-visible-once-bottom>
<div class="timeline-dot"></div>
<div class="timeline-content">
<n-h3 class="timeline-year">{{
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO")
}}</n-h3>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphTwo.ONE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphTwo.TWO")
}}</n-p>
</div>
</div>
<!-- 2021 -->
<div class="timeline-item" v-motion-slide-visible-once-bottom>
<div class="timeline-dot"></div>
<div class="timeline-content">
<n-h3 class="timeline-year">{{
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE")
}}</n-h3>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphTHREE.ONE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphTHREE.TWO")
}}</n-p>
</div>
</div>
<!-- 2023-2024 -->
<div class="timeline-item" v-motion-slide-visible-once-bottom>
<div class="timeline-dot"></div>
<div class="timeline-content">
<n-h3 class="timeline-year">{{
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF")
}}</n-h3>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFOUR.ONE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFOUR.TWO")
}}</n-p>
</div>
</div>
<!-- 2025 -->
<div class="timeline-item" v-motion-slide-visible-once-bottom>
<div class="timeline-dot"></div>
<div class="timeline-content">
<n-h3 class="timeline-year">{{
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE")
}}</n-h3>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.ONE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.TWO")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.THREE")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.FOUR")
}}</n-p>
<n-p class="timeline-desc">{{
$t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.FIVE")
}}</n-p>
</div>
</div>
</div>
</section>
<!-- 成就部分 -->
<section class="achievement-section" v-motion-fade>
<n-h2 class="section-title">{{
$t("COMPANYOVERVIEW.TITLEFIVE.TITLE")
}}</n-h2>
<n-p class="section-content">{{
$t("COMPANYOVERVIEW.TITLEFIVE.CONTENT")
}}</n-p>
<div class="achievement-stats">
<n-statistic
v-for="(stat, index) in stats"
:key="index"
class="stat-item"
v-motion-slide-visible-once-bottom
:style="{ '--delay': index * 0.1 + 's' }"
>
<template #label>{{ $t(stat.labelKey) }}</template>
{{ stat.number }}
</n-statistic>
</div>
</section>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useI18n } from "vue-i18n";
const { t: $t } = useI18n();
const stats = ref([
{ number: "48+", labelKey: "COMPANYOVERVIEW.STATS.YEARS_IN_BUSINESS" },
{ number: "100+", labelKey: "COMPANYOVERVIEW.STATS.PATENTS" },
{ number: "Global", labelKey: "COMPANYOVERVIEW.STATS.FOOTPRINT" },
{ number: "NASDAQ", labelKey: "COMPANYOVERVIEW.STATS.LISTED_SINCE" },
]);
</script>
<style scoped>
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
.company-overview {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
color: var(--text-color);
}
/* 顶部大图区域 */
.hero-section {
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
background-size: 400% 400%;
animation: gradientBG 15s ease infinite;
color: white;
padding: 120px 0;
text-align: center;
margin-bottom: 60px;
border-radius: 8px;
}
.hero-title {
font-size: 3.5rem;
margin-bottom: 20px;
font-weight: 700;
}
.hero-subtitle {
font-size: 1.5rem;
opacity: 0.9;
}
/* 通用部分样式 */
.section {
margin-bottom: 80px;
}
.section-title {
font-size: 2.2rem;
margin-bottom: 30px;
position: relative;
display: inline-block;
}
.section-title:after {
content: "";
position: absolute;
bottom: -10px;
left: 0;
width: 60px;
height: 4px;
background: linear-gradient(to right, #1a2a6c, #fdbb2d);
border-radius: 2px;
}
.section-content {
font-size: 1.1rem;
line-height: 1.8;
margin-bottom: 20px;
color: var(--text-color-secondary);
}
/* 使命愿景卡片 */
.mission-section {
margin: 80px 0;
}
.mission-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
}
.mission-card {
background: white;
padding: 40px 30px;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.mission-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.12);
}
.card-title {
font-size: 1.5rem;
margin-bottom: 20px;
color: #895bff;
}
.card-content {
font-size: 1.05rem;
line-height: 1.7;
}
/* 时间轴样式 */
.timeline {
position: relative;
padding-left: 50px;
margin-top: 50px;
}
.timeline:before {
content: "";
position: absolute;
top: 0;
left: 20px;
height: 100%;
width: 4px;
background: linear-gradient(to bottom, #895bff, #fdbb2d);
}
.timeline-item {
position: relative;
margin-bottom: 50px;
}
.timeline-dot {
position: absolute;
left: -50px;
top: 5px;
width: 40px;
height: 40px;
border-radius: 50%;
background: #895bff;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
box-shadow: 0 0 0 6px rgba(26, 42, 108, 0.2);
}
.timeline-year {
font-size: 1.4rem;
margin-bottom: 15px;
color: #1a2a6c;
}
.timeline-desc {
font-size: 1.05rem;
line-height: 1.7;
margin-bottom: 10px;
}
/* 成就部分 */
.achievement-section {
background: #f9fafc;
padding: 60px;
border-radius: 12px;
margin: 80px 0;
}
.achievement-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 30px;
margin-top: 50px;
}
.stat-item {
text-align: center;
padding: 30px 20px;
background: white;
border-radius: 8px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
transition: transform 0.3s ease;
}
.stat-item:hover {
transform: translateY(-5px);
}
.stat-number {
font-size: 2.5rem;
color: #1a2a6c;
margin-bottom: 10px;
}
.stat-label {
font-size: 1.1rem;
color: var(--text-color-secondary);
}
/* 动画 */
@keyframes gradientBG {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* 响应式设计 */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem;
}
.hero-subtitle {
font-size: 1.2rem;
}
.section-title {
font-size: 1.8rem;
}
.timeline {
padding-left: 30px;
}
.timeline-dot {
left: -30px;
width: 30px;
height: 30px;
}
.achievement-section {
padding: 40px 20px;
}
}
</style>

View File

@ -26,30 +26,30 @@ function handleSubmit(e) {
<!-- 表单卡片/提交成功卡片 -->
<div class="relative z-10 w-[480px] max-w-[90vw] p-10 bg-white/80 rounded-3xl shadow-2xl backdrop-blur-md animate-bounce-in">
<template v-if="!submitted">
<h2 class="text-3xl font-bold text-primary mb-2 tracking-wide">E-Mail Alerts</h2>
<h2 class="text-3xl font-bold text-#8A5AFB mb-2 tracking-wide">E-Mail Alerts</h2>
<p class="text-sm text-gray-500 mb-6">* Required Fields</p>
<form class="space-y-4" @submit="handleSubmit">
<div>
<label class="block text-gray-700 font-semibold mb-1">* First Name</label>
<input v-model="form.firstName" type="text" required class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:(border-primary ring-2 ring-primary/20) transition-all duration-300 outline-none bg-white/90" />
<input v-model="form.firstName" type="text" required class="w-full px-4 py-2 rounded-lg border border-gray-300 ring-2 ring-#8A5AFB/20) transition-all duration-300 outline-none bg-white/90" />
</div>
<div>
<label class="block text-gray-700 font-semibold mb-1">* Last Name</label>
<input v-model="form.lastName" type="text" required class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:(border-primary ring-2 ring-primary/20) transition-all duration-300 outline-none bg-white/90" />
<input v-model="form.lastName" type="text" required class="w-full px-4 py-2 rounded-lg border border-gray-300 ring-2 ring-#8A5AFB/20) transition-all duration-300 outline-none bg-white/90" />
</div>
<div>
<label class="block text-gray-700 font-semibold mb-1">* Email</label>
<input v-model="form.email" type="email" required class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:(border-primary ring-2 ring-primary/20) transition-all duration-300 outline-none bg-white/90" />
<input v-model="form.email" type="email" required class="w-full px-4 py-2 rounded-lg border border-gray-300 ring-2 ring-#8A5AFB/20) transition-all duration-300 outline-none bg-white/90" />
</div>
<div>
<label class="block text-gray-700 font-semibold mb-1">* Company</label>
<input v-model="form.company" type="text" required class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:(border-primary ring-2 ring-primary/20) transition-all duration-300 outline-none bg-white/90" />
<input v-model="form.company" type="text" required class="w-full px-4 py-2 rounded-lg border border-gray-300 ring-2 ring-#8A5AFB/20) transition-all duration-300 outline-none bg-white/90" />
</div>
<div>
<label class="block text-gray-700 font-semibold mb-1">Phone</label>
<input v-model="form.phone" type="tel" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:(border-primary ring-2 ring-primary/20) transition-all duration-300 outline-none bg-white/90" />
<input v-model="form.phone" type="tel" class="w-full px-4 py-2 rounded-lg border border-gray-300 ring-2 ring-#8A5AFB/20) transition-all duration-300 outline-none bg-white/90" />
</div>
<button type="submit" class="w-full py-3 rounded-xl bg-primary text-white font-bold text-lg shadow-lg hover:(bg-primary/90 scale-105) active:scale-95 transition-all duration-200 animate-bounce-in animate-delay-200">
<button type="submit" class="w-full py-3 rounded-xl bg-#8A5AFB text-white font-bold text-lg active:scale-95 transition-all duration-200 animate-bounce-in animate-delay-200">
Submit
</button>
</form>
@ -57,7 +57,7 @@ function handleSubmit(e) {
<template v-else>
<div class="flex flex-col items-center justify-center min-h-[300px] animate-bounce-in">
<span class="i-mdi:check-circle-outline text-green-500 text-5xl mb-4"></span>
<h2 class="text-2xl font-bold text-primary mb-2">Submitted successfully!</h2>
<h2 class="text-2xl font-bold text-#8A5AFB mb-2">Submitted successfully!</h2>
<div class="text-gray-700 text-base mb-4">The information you submitted is as follows:</div>
<div class="w-full bg-white/80 rounded-xl shadow p-4 space-y-2 text-gray-800">
<div><span class="font-semibold">First Name</span>{{ form.firstName }}</div>

View File

@ -41,6 +41,7 @@
<script setup>
import { ref, watch, onMounted, computed, reactive } from "vue";
import { useI18n } from "vue-i18n";
import quarterlyPdf from "@/assets/file/2025 Q1 Quarterly Results.pdf";
const { t } = useI18n();
const searchQuery = ref("");
@ -51,7 +52,7 @@ const state = reactive({
title: "2025 Q1 Quarterly Results",
description:
"Unaudited First Quarter and Full Year 2025 Financial Results",
url: "/src/assets/file/2025 Q1 Quarterly Results.pdf",
url: quarterlyPdf,
},
],
});

View File

@ -0,0 +1,22 @@
<script setup>
import size1920 from "@/views/govern/size1920/index.vue";
import size375 from "@/views/govern/size375/index.vue";
import { computed } from "vue";
import { useWindowSize } from "@vueuse/core";
const { width } = useWindowSize();
const viewComponent = computed(() => {
const viewWidth = width.value;
if (viewWidth <= 450) {
return size375;
} else if (viewWidth <= 1920 || viewWidth > 1920) {
return size1920;
}
});
</script>
<template>
<component :is="viewComponent" />
</template>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,178 @@
<template>
<div class="title mb-[50px] text-center">
<h1 class="text-5xl font-light text-gray-800 mb-4 tracking-tight">
Corporate Governance
</h1>
<div class="w-24 h-1 bg-[#895bff] mx-auto"></div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div
v-for="(item, index) in state.list"
:key="index"
class="governance-card relative overflow-hidden bg-white rounded-lg shadow-xl hover:shadow-2xl transition-all duration-500 border border-gray-100 transform hover:-translate-y-2"
>
<div
class="absolute inset-0 bg-gradient-to-r from-[#f5f0ff] to-white opacity-80"
></div>
<div class="relative p-8 flex flex-col h-full">
<div class="flex items-start mb-6">
<div
class="bg-[#895bff] p-3 rounded-lg shadow-md mr-6 transform hover:rotate-6 transition-transform duration-300 governance-icon"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-8 w-8 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
/>
</svg>
</div>
<div>
<h2 class="text-2xl font-medium text-gray-800 mb-2">
{{ item.title }}
</h2>
<p class="text-gray-600">{{ item.date }}</p>
</div>
</div>
<p class="text-gray-700 mb-8 flex-grow">{{ item.description }}</p>
<div class="mt-auto">
<a
:href="item.url"
class="inline-flex items-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-white bg-[#895bff] hover:bg-[#7a4de6] transition-all duration-300 transform hover:scale-105 shadow-md"
target="_blank"
>
View Document
<svg
xmlns="http://www.w3.org/2000/svg"
class="ml-3 -mr-1 h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</a>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
const state = reactive({
list: [
{
title: "Audit Committee Charter",
description:
"Defines the purpose, composition, and responsibilities of the Audit Committee in overseeing financial reporting and disclosure.",
url: "/src/assets/file/AUDIT COMMITTEE CHARTER.pdf",
date: "Last updated: March 2025",
},
{
title: "Code of Business Conduct",
description:
"Establishes the ethical standards and legal compliance expectations for all directors, officers and employees.",
url: "/src/assets/file/CODE OF BUSINESS CONDUCT AND ETHICS.pdf",
date: "Last updated: January 2025",
},
{
title: "Compensation Committee Charter",
description:
"Outlines the duties and responsibilities for overseeing executive compensation and benefit plans.",
url: "/src/assets/file/COMPENSATION COMMITTEE CHARTER.pdf",
date: "Last updated: February 2025",
},
{
title: "Nominating & Governance Charter",
description:
"Provides the framework for director nominations and corporate governance matters.",
url: "/src/assets/file/NOMINATING AND CORPORATE GOVERNANCE COMMITTEE CHARTER.pdf",
date: "Last updated: April 2025",
},
],
});
</script>
<style scoped lang="scss">
/* 标题样式 */
.title h1 {
font-family: "Georgia", serif;
position: relative;
&::after {
content: "";
position: absolute;
bottom: -14px;
left: 50%;
transform: translateX(-50%);
width: 80px;
height: 3px;
background: #895bff;
border-radius: 3px;
transition: width 0.3s ease;
}
&:hover::after {
width: 120px;
}
}
/* 卡片图标动画 */
.governance-icon {
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}
.governance-card:hover .governance-icon {
animation: float 2s ease-in-out infinite;
box-shadow: 0 10px 20px rgba(137, 91, 255, 0.3) !important;
}
/* 卡片背景渐变效果 */
.governance-card::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
135deg,
rgba(137, 91, 255, 0.1) 0%,
rgba(0, 0, 0, 0) 50%
);
opacity: 0;
transition: opacity 0.3s ease;
}
.governance-card:hover::before {
opacity: 1;
}
/* 浮动动画 */
@keyframes float {
0% {
transform: translateY(0px) rotate(0deg);
}
50% {
transform: translateY(-5px) rotate(3deg);
}
100% {
transform: translateY(0px) rotate(0deg);
}
}
</style>

View File

@ -0,0 +1,178 @@
<template>
<div class="title mb-[50px] text-center">
<h1 class="text-5xl font-light text-gray-800 mb-4 tracking-tight">
Corporate Governance
</h1>
<div class="w-24 h-1 bg-[#895bff] mx-auto"></div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div
v-for="(item, index) in state.list"
:key="index"
class="governance-card relative overflow-hidden bg-white rounded-lg shadow-xl hover:shadow-2xl transition-all duration-500 border border-gray-100 transform hover:-translate-y-2"
>
<div
class="absolute inset-0 bg-gradient-to-r from-[#f5f0ff] to-white opacity-80"
></div>
<div class="relative p-8 flex flex-col h-full">
<div class="flex items-start mb-6">
<div
class="bg-[#895bff] p-3 rounded-lg shadow-md mr-6 transform hover:rotate-6 transition-transform duration-300 governance-icon"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-8 w-8 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
/>
</svg>
</div>
<div>
<h2 class="text-2xl font-medium text-gray-800 mb-2">
{{ item.title }}
</h2>
<p class="text-gray-600">{{ item.date }}</p>
</div>
</div>
<p class="text-gray-700 mb-8 flex-grow">{{ item.description }}</p>
<div class="mt-auto">
<a
:href="item.url"
class="inline-flex items-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-white bg-[#895bff] hover:bg-[#7a4de6] transition-all duration-300 transform hover:scale-105 shadow-md"
target="_blank"
>
View Document
<svg
xmlns="http://www.w3.org/2000/svg"
class="ml-3 -mr-1 h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</a>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
const state = reactive({
list: [
{
title: "Audit Committee Charter",
description:
"Defines the purpose, composition, and responsibilities of the Audit Committee in overseeing financial reporting and disclosure.",
url: "/src/assets/file/AUDIT COMMITTEE CHARTER.pdf",
date: "Last updated: March 2025",
},
{
title: "Code of Business Conduct",
description:
"Establishes the ethical standards and legal compliance expectations for all directors, officers and employees.",
url: "/src/assets/file/CODE OF BUSINESS CONDUCT AND ETHICS.pdf",
date: "Last updated: January 2025",
},
{
title: "Compensation Committee Charter",
description:
"Outlines the duties and responsibilities for overseeing executive compensation and benefit plans.",
url: "/src/assets/file/COMPENSATION COMMITTEE CHARTER.pdf",
date: "Last updated: February 2025",
},
{
title: "Nominating & Governance Charter",
description:
"Provides the framework for director nominations and corporate governance matters.",
url: "/src/assets/file/NOMINATING AND CORPORATE GOVERNANCE COMMITTEE CHARTER.pdf",
date: "Last updated: April 2025",
},
],
});
</script>
<style scoped lang="scss">
/* 标题样式 */
.title h1 {
font-family: "Georgia", serif;
position: relative;
&::after {
content: "";
position: absolute;
bottom: -14px;
left: 50%;
transform: translateX(-50%);
width: 80px;
height: 3px;
background: #895bff;
border-radius: 3px;
transition: width 0.3s ease;
}
&:hover::after {
width: 120px;
}
}
/* 卡片图标动画 */
.governance-icon {
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}
.governance-card:hover .governance-icon {
animation: float 2s ease-in-out infinite;
box-shadow: 0 10px 20px rgba(137, 91, 255, 0.3) !important;
}
/* 卡片背景渐变效果 */
.governance-card::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
135deg,
rgba(137, 91, 255, 0.1) 0%,
rgba(0, 0, 0, 0) 50%
);
opacity: 0;
transition: opacity 0.3s ease;
}
.governance-card:hover::before {
opacity: 1;
}
/* 浮动动画 */
@keyframes float {
0% {
transform: translateY(0px) rotate(0deg);
}
50% {
transform: translateY(-5px) rotate(3deg);
}
100% {
transform: translateY(0px) rotate(0deg);
}
}
</style>

View File

@ -0,0 +1,22 @@
<script setup>
import size1920 from "@/views/manage/size1920/index.vue";
import size375 from "@/views/manage/size375/index.vue";
import { computed } from "vue";
import { useWindowSize } from "@vueuse/core";
const { width } = useWindowSize();
const viewComponent = computed(() => {
const viewWidth = width.value;
if (viewWidth <= 450) {
return size375;
} else if (viewWidth <= 1920 || viewWidth > 1920) {
return size1920;
}
});
</script>
<template>
<component :is="viewComponent" />
</template>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,229 @@
<template>
<div class="home-page">
<div class="management-page">
<!-- 标题区 -->
<section class="leadership-header">
<div class="container">
<h1 class="page-title">Executive Leadership</h1>
<p class="page-subtitle">
Driving Innovation and Operational Excellence
</p>
</div>
</section>
<!-- 管理团队列表 -->
<main class="container">
<div class="leadership-grid">
<!-- 每个高管卡片 -->
<div
v-for="(leader, index) in leadershipTeam"
:key="index"
class="leader-card"
:style="{ '--delay': index * 0.2 + 's' }"
>
<!-- 卡片上半部 -->
<div class="card-profile">
<div class="avatar-wrapper">
<div class="decorative-dot"></div>
<div class="initials">{{ getInitials(leader.name) }}</div>
</div>
<div class="profile-info">
<h2 class="leader-name">{{ leader.name }}</h2>
<p class="leader-position">{{ leader.position }}</p>
</div>
</div>
<!-- 卡片下半部 -->
<div class="card-content">
<div
class="content-section"
v-for="(content, cIndex) in leader.content"
:key="cIndex"
>
<p>{{ content }}</p>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
</template>
<script setup>
import { useI18n } from "vue-i18n";
import { computed } from "vue";
const { t } = useI18n();
const leadershipTeam = computed(() => [
{
name: t("MANAGEMENT.ONE.TITLE"),
position: t("MANAGEMENT.ONE.TITLETWO"),
content: [
t("MANAGEMENT.ONE.CONTENT"),
t("MANAGEMENT.ONE.CONTENTTWO"),
t("MANAGEMENT.ONE.CONTENTTHREE"),
],
},
{
name: t("MANAGEMENT.TWO.TITLE"),
position: t("MANAGEMENT.TWO.TITLETWO"),
content: [t("MANAGEMENT.TWO.CONTENTONE"), t("MANAGEMENT.TWO.CONTENTTWO")],
},
]);
const getInitials = (name) => {
return name
.split(" ")
.map((n) => n[0])
.join("");
};
</script>
<style scoped>
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
/* 基础样式 */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
}
/* 标题区 */
.leadership-header {
background: linear-gradient(135deg, #f9fbfe 0%, #e8f2ff 100%);
padding: 6rem 0 4rem;
text-align: center;
}
.page-title {
font-size: 2.5rem;
color: #2c3e50;
margin-bottom: 1rem;
}
.page-subtitle {
color: #6b7c93;
font-size: 1.1rem;
}
/* 管理团队网格 */
.leadership-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
padding: 4rem 0;
}
/* 高管卡片 */
.leader-card {
background: white;
border-radius: 20px;
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.06);
overflow: hidden;
transform: translateY(20px);
opacity: 0;
animation: cardEnter 0.6s ease forwards;
animation-delay: var(--delay);
transition: transform 0.3s ease;
}
.leader-card:hover {
transform: translateY(-5px);
}
/* 个人资料区 */
.card-profile {
padding: 2rem;
background: linear-gradient(
135deg,
#7a4dff 0%,
#895bff 100%
); /* 主色调接近 #895bff */
position: relative;
}
.avatar-wrapper {
position: relative;
width: 80px;
height: 80px;
margin-bottom: 1.5rem;
}
.decorative-dot {
position: absolute;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
top: -10px;
right: -10px;
}
.initials {
width: 100%;
height: 100%;
background: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.8rem;
font-weight: bold;
color: #895bff;
}
.profile-info {
color: white;
}
.leader-name {
font-size: 1.6rem;
margin-bottom: 0.5rem;
}
.leader-position {
font-size: 1rem;
opacity: 0.9;
}
/* 内容区 */
.card-content {
padding: 2rem;
}
.content-section {
margin-bottom: 1.5rem;
}
.content-section p {
color: #5a6d80;
line-height: 1.7;
font-size: 0.95rem;
}
/* 动画 */
@keyframes cardEnter {
to {
opacity: 1;
transform: translateY(0);
}
}
/* 响应式 */
@media (max-width: 768px) {
.leadership-grid {
grid-template-columns: 1fr;
}
.leader-card {
margin: 0 1rem;
}
}
</style>

View File

@ -0,0 +1,229 @@
<template>
<div class="home-page">
<div class="management-page">
<!-- 标题区 -->
<section class="leadership-header">
<div class="container">
<h1 class="page-title">Executive Leadership</h1>
<p class="page-subtitle">
Driving Innovation and Operational Excellence
</p>
</div>
</section>
<!-- 管理团队列表 -->
<main class="container">
<div class="leadership-grid">
<!-- 每个高管卡片 -->
<div
v-for="(leader, index) in leadershipTeam"
:key="index"
class="leader-card"
:style="{ '--delay': index * 0.2 + 's' }"
>
<!-- 卡片上半部 -->
<div class="card-profile">
<div class="avatar-wrapper">
<div class="decorative-dot"></div>
<div class="initials">{{ getInitials(leader.name) }}</div>
</div>
<div class="profile-info">
<h2 class="leader-name">{{ leader.name }}</h2>
<p class="leader-position">{{ leader.position }}</p>
</div>
</div>
<!-- 卡片下半部 -->
<div class="card-content">
<div
class="content-section"
v-for="(content, cIndex) in leader.content"
:key="cIndex"
>
<p>{{ content }}</p>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
</template>
<script setup>
import { useI18n } from "vue-i18n";
import { computed } from "vue";
const { t } = useI18n();
const leadershipTeam = computed(() => [
{
name: t("MANAGEMENT.ONE.TITLE"),
position: t("MANAGEMENT.ONE.TITLETWO"),
content: [
t("MANAGEMENT.ONE.CONTENT"),
t("MANAGEMENT.ONE.CONTENTTWO"),
t("MANAGEMENT.ONE.CONTENTTHREE"),
],
},
{
name: t("MANAGEMENT.TWO.TITLE"),
position: t("MANAGEMENT.TWO.TITLETWO"),
content: [t("MANAGEMENT.TWO.CONTENTONE"), t("MANAGEMENT.TWO.CONTENTTWO")],
},
]);
const getInitials = (name) => {
return name
.split(" ")
.map((n) => n[0])
.join("");
};
</script>
<style scoped>
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
/* 基础样式 */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
}
/* 标题区 */
.leadership-header {
background: linear-gradient(135deg, #f9fbfe 0%, #e8f2ff 100%);
padding: 6rem 0 4rem;
text-align: center;
}
.page-title {
font-size: 2.5rem;
color: #2c3e50;
margin-bottom: 1rem;
}
.page-subtitle {
color: #6b7c93;
font-size: 1.1rem;
}
/* 管理团队网格 */
.leadership-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
padding: 4rem 0;
}
/* 高管卡片 */
.leader-card {
background: white;
border-radius: 20px;
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.06);
overflow: hidden;
transform: translateY(20px);
opacity: 0;
animation: cardEnter 0.6s ease forwards;
animation-delay: var(--delay);
transition: transform 0.3s ease;
}
.leader-card:hover {
transform: translateY(-5px);
}
/* 个人资料区 */
.card-profile {
padding: 2rem;
background: linear-gradient(
135deg,
#7a4dff 0%,
#895bff 100%
); /* 主色调接近 #895bff */
position: relative;
}
.avatar-wrapper {
position: relative;
width: 80px;
height: 80px;
margin-bottom: 1.5rem;
}
.decorative-dot {
position: absolute;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
top: -10px;
right: -10px;
}
.initials {
width: 100%;
height: 100%;
background: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.8rem;
font-weight: bold;
color: #895bff;
}
.profile-info {
color: white;
}
.leader-name {
font-size: 1.6rem;
margin-bottom: 0.5rem;
}
.leader-position {
font-size: 1rem;
opacity: 0.9;
}
/* 内容区 */
.card-content {
padding: 2rem;
}
.content-section {
margin-bottom: 1.5rem;
}
.content-section p {
color: #5a6d80;
line-height: 1.7;
font-size: 0.95rem;
}
/* 动画 */
@keyframes cardEnter {
to {
opacity: 1;
transform: translateY(0);
}
}
/* 响应式 */
@media (max-width: 768px) {
.leadership-grid {
grid-template-columns: 1fr;
}
.leader-card {
margin: 0 1rem;
}
}
</style>

View File

@ -0,0 +1,22 @@
<script setup>
import size1920 from "@/views/myHome/size1920/index.vue";
import size375 from "@/views/myHome/size375/index.vue";
import { computed } from "vue";
import { useWindowSize } from "@vueuse/core";
const { width } = useWindowSize();
const viewComponent = computed(() => {
const viewWidth = width.value;
if (viewWidth <= 450) {
return size375;
} else if (viewWidth <= 1920 || viewWidth > 1920) {
return size1920;
}
});
</script>
<template>
<component :is="viewComponent" />
</template>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,536 @@
<template>
<div class="home-page">
<!-- 顶部背景图 Banner -->
<div class="hero-banner">
<div class="banner-content">
<h1 class="main-title">{{ $t("HOME.CONTAIN.TITLEONE.TITLE") }}</h1>
<p class="sub-title">
NASDAQ: MINM | {{ $t("HOME.CONTAIN.TITLEONE.CONTENT") }}
</p>
<!-- <p class="sub-title" style="">
{{ $t("HOME.CONTAIN.TITLEONE.CONTENTTWO") }}
</p> -->
</div>
</div>
<section
class="company-overview"
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
>
<h2 class="section-title">{{ $t("HOME.CONTAIN.TITLEONE.TITLE") }}</h2>
<div class="content-block">
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}</p>
<p>{{ $t("HOME.CONTAIN.TITLEONE.CONTENT") }}</p>
<p>{{ $t("HOME.CONTAIN.TITLEONE.CONTENTTWO") }}</p>
</div>
</section>
<!-- 公司概况 -->
<section
class="company-overview"
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
>
<h2 class="section-title">{{ $t("COMPANYOVERVIEW.TITLETWO.TITLE") }}</h2>
<div class="content-block">
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}</p>
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTWO") }}</p>
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTHREE") }}</p>
</div>
</section>
<!-- 使命与愿景 -->
<section
class="mission-vision"
style="
max-width: 1200px;
margin: 60px auto;
padding: 0 40px;
background: #f8fafc;
"
>
<h2 class="section-title">
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
</h2>
<div class="mission-content">
<ul>
<li>
{{ $t("COMPANYOVERVIEW.TITLETHREE.CONTENT").replace("•", "") }}
</li>
<li>
{{ $t("COMPANYOVERVIEW.TITLETHREE.CONTENTTWO").replace("•", "") }}
</li>
</ul>
</div>
</section>
<!-- 企业里程碑 -->
<section
class="milestones"
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
>
<h2 class="section-title">{{ $t("COMPANYOVERVIEW.TITLEFOUR.TITLE") }}</h2>
<div class="milestone-item">
<h3>{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING") }}</h3>
<ul>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraph.ONE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraph.TWO") }}</li>
</ul>
</div>
<div class="milestone-item">
<h3>{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO") }}</h3>
<ul>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphTwo.ONE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphTwo.TWO") }}</li>
</ul>
</div>
<div class="milestone-item">
<h3>{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE") }}</h3>
<ul>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphTHREE.ONE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphTHREE.TWO") }}</li>
</ul>
</div>
<div class="milestone-item">
<h3>{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF") }}</h3>
<ul>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFOUR.ONE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFOUR.TWO") }}</li>
</ul>
</div>
<div class="milestone-item">
<h3>{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE") }}</h3>
<ul>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.ONE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.TWO") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.THREE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.FOUR") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.FIVE") }}</li>
</ul>
</div>
</section>
<!-- 突出成就 -->
<section
class="achievements"
style="
max-width: 1200px;
margin: 60px auto;
padding: 0 40px;
background: #f8fafc;
"
>
<h2 class="section-title">{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}</h2>
<p>{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}</p>
</section>
<!-- 新闻模块 -->
<section
class="news-section"
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
>
<h2 class="section-title">{{ $t("HOME.CONTAINY.NEWS.TITLE") }}</h2>
<div class="news-card">
<div class="news-date">2025-05-15</div>
<h3 class="news-title">{{ $t("HOME.CONTAINY.NEWS.LATEST_TITLE") }}</h3>
<p class="news-excerpt">
{{ $t("HOME.CONTAINY.NEWS.LATEST_CONTENT") }}
</p>
<!-- <a href="#" class="news-link"
>{{ $t("HOME.CONTAINY.NEWS.READ_MORE") }} </a
> -->
</div>
</section>
<!-- 新增股票信息与活动预告双栏模块 -->
<section
class="dual-column-section"
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
>
<div class="grid-container">
<!-- 股票信息卡片 -->
<div class="info-card stock-card">
<h2 class="card-title">{{ $t("HOME.CONTAINY.STOCK_INFO.TITLE") }}</h2>
<div class="stock-data">
<div class="data-row">
<span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
}}</span>
<span class="data-value">${{ dataObj.Open }}</span>
</div>
<div class="data-row">
<span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.CHANGE")
}}</span>
<span class="data-value positive"
>{{ dataObj.change[0] }}{{ dataObj.change[1] }}</span
>
</div>
<div class="data-row">
<span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.STOCK_CODE")
}}</span>
<span class="data-value">NASDAQ: MINM</span>
</div>
<div class="data-row">
<span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.VOLUME")
}}</span>
<span class="data-value">{{ dataObj.Volume }}</span>
</div>
<div class="data-row">
<span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
}}</span>
<span class="data-value">${{ dataObj.MarketCap }}</span>
</div>
</div>
</div>
<!-- 活动预告卡片 -->
<div class="info-card events-card">
<h2 class="card-title">
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.TITLE") }}
</h2>
<div class="event-item">
<h3 class="event-name">
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.EVENT_NAME") }}
</h3>
<!-- <div class="event-detail">
<div class="detail-row">
<i class="icon-calendar"></i>
<span
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.DATE") }}:
2025年8月12日()-2025年8月14日</span
>
</div>
<div class="detail-row">
<i class="icon-location"></i>
<span
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.VENUE") }}:
6号馆B厅</span
>
</div>
<div class="detail-row">
<i class="icon-area"></i>
<span
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.AREA") }}:
约10,000</span
>
</div>
<div class="detail-row">
<i class="icon-booth"></i>
<span
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.BOOTHS") }}:
约500个标准展位</span
>
</div>
</div> -->
</div>
</div>
</div>
</section>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import { useI18n } from "vue-i18n";
import { getTestData } from "@/config/testRequest";
const dataObj = ref({
change: ["0.2", "1111"],
});
onMounted(async () => {
try {
const data = await getTestData();
dataObj.value = data;
} catch (error) {
console.error("调用接口失败:", error);
}
});
const { t: $t } = useI18n();
</script>
<style scoped>
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
.hero-banner {
height: 600px;
display: flex;
align-items: center;
justify-content: center;
}
.banner-content {
text-align: center;
color: white;
padding: 20px;
background: rgba(0, 0, 0, 0.3);
border-radius: 8px;
}
.main-title {
font-size: 3.5rem;
margin-bottom: 20px;
}
.sub-title {
font-size: 1.5rem;
}
.section-card {
padding: 40px;
border-radius: 12px;
}
.card-content {
font-size: 1.1rem;
line-height: 1.8;
}
.section-title {
font-size: 2.5rem;
margin-bottom: 30px;
color: #895bff;
}
.content-block {
font-size: 1.1rem;
line-height: 1.8;
}
.mission-content ul {
list-style: disc;
padding-left: 20px;
font-size: 1.1rem;
}
.milestones {
font-size: 1.1rem;
}
.milestone-item {
margin-bottom: 40px;
padding: 20px;
border-left: 3px solid #895bff;
background: #f8fafc;
}
.milestone-item h3 {
font-size: 1.5rem;
margin-bottom: 10px;
color: #895bff;
}
.milestone-item ul {
list-style: none;
padding-left: 0;
}
.milestone-item li {
margin-bottom: 10px;
}
.achievements {
padding: 40px;
border-radius: 12px;
}
/* 新增样式 */
.dual-column-section {
margin-bottom: 80px;
}
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
}
.info-card {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.info-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
}
.card-title {
font-size: 1.8rem;
margin-bottom: 25px;
color: #895bff;
position: relative;
padding-bottom: 10px;
}
.card-title::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 60px;
height: 3px;
background: linear-gradient(90deg, #895bff, #b388ff);
}
/* 股票信息卡片样式 */
.stock-card {
border-top: 4px solid #895bff;
}
.stock-data {
margin-bottom: 25px;
}
.data-row {
display: flex;
justify-content: space-between;
padding: 12px 0;
border-bottom: 1px solid #f0f0f0;
}
.data-label {
color: #666;
font-weight: 500;
}
.data-value {
font-weight: 600;
}
.positive {
color: #895bff;
}
.stock-chart-placeholder {
height: 200px;
background: #f8fafc;
border-radius: 8px;
margin-top: 20px;
position: relative;
overflow: hidden;
}
.chart-mock {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 80%;
background: linear-gradient(90deg, #e0e7ff, #c7d2fe);
border-radius: 0 0 8px 8px;
}
/* 活动预告卡片样式 */
.events-card {
border-top: 4px solid #10b981;
}
.event-item {
margin-bottom: 20px;
}
.event-name {
font-size: 1.4rem;
color: #333;
margin-bottom: 15px;
}
.detail-row {
display: flex;
align-items: center;
margin-bottom: 12px;
color: #555;
}
.detail-row i {
margin-right: 10px;
color: #895bff;
font-size: 1.2rem;
}
.event-button {
background: linear-gradient(135deg, #895bff, #6a11cb);
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
font-weight: 600;
cursor: pointer;
margin-top: 20px;
transition: all 0.3s ease;
}
.event-button:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(137, 91, 255, 0.3);
}
/* 新闻模块样式 */
.news-section {
margin-bottom: 80px;
}
.news-card {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
border-left: 4px solid #895bff;
}
.news-date {
color: #888;
font-size: 0.9rem;
margin-bottom: 10px;
}
.news-title {
font-size: 1.5rem;
color: #333;
margin-bottom: 15px;
}
.news-excerpt {
color: #555;
line-height: 1.7;
margin-bottom: 20px;
}
.news-link {
color: #895bff;
font-weight: 600;
text-decoration: none;
display: inline-flex;
align-items: center;
}
.news-link:hover {
text-decoration: underline;
}
/* 响应式设计 */
@media (max-width: 768px) {
.grid-container {
grid-template-columns: 1fr;
}
.hero-banner {
height: 400px;
}
.main-title {
font-size: 2.5rem;
}
}
</style>

View File

@ -0,0 +1,536 @@
<template>
<div class="home-page">
<!-- 顶部背景图 Banner -->
<div class="hero-banner">
<div class="banner-content">
<h1 class="main-title">{{ $t("HOME.CONTAIN.TITLEONE.TITLE") }}</h1>
<p class="sub-title">
NASDAQ: MINM | {{ $t("HOME.CONTAIN.TITLEONE.CONTENT") }}
</p>
<!-- <p class="sub-title" style="">
{{ $t("HOME.CONTAIN.TITLEONE.CONTENTTWO") }}
</p> -->
</div>
</div>
<section
class="company-overview"
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
>
<h2 class="section-title">{{ $t("HOME.CONTAIN.TITLEONE.TITLE") }}</h2>
<div class="content-block">
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}</p>
<p>{{ $t("HOME.CONTAIN.TITLEONE.CONTENT") }}</p>
<p>{{ $t("HOME.CONTAIN.TITLEONE.CONTENTTWO") }}</p>
</div>
</section>
<!-- 公司概况 -->
<section
class="company-overview"
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
>
<h2 class="section-title">{{ $t("COMPANYOVERVIEW.TITLETWO.TITLE") }}</h2>
<div class="content-block">
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}</p>
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTWO") }}</p>
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTHREE") }}</p>
</div>
</section>
<!-- 使命与愿景 -->
<section
class="mission-vision"
style="
max-width: 1200px;
margin: 60px auto;
padding: 0 40px;
background: #f8fafc;
"
>
<h2 class="section-title">
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
</h2>
<div class="mission-content">
<ul>
<li>
{{ $t("COMPANYOVERVIEW.TITLETHREE.CONTENT").replace("•", "") }}
</li>
<li>
{{ $t("COMPANYOVERVIEW.TITLETHREE.CONTENTTWO").replace("•", "") }}
</li>
</ul>
</div>
</section>
<!-- 企业里程碑 -->
<section
class="milestones"
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
>
<h2 class="section-title">{{ $t("COMPANYOVERVIEW.TITLEFOUR.TITLE") }}</h2>
<div class="milestone-item">
<h3>{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING") }}</h3>
<ul>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraph.ONE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraph.TWO") }}</li>
</ul>
</div>
<div class="milestone-item">
<h3>{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO") }}</h3>
<ul>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphTwo.ONE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphTwo.TWO") }}</li>
</ul>
</div>
<div class="milestone-item">
<h3>{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE") }}</h3>
<ul>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphTHREE.ONE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphTHREE.TWO") }}</li>
</ul>
</div>
<div class="milestone-item">
<h3>{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF") }}</h3>
<ul>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFOUR.ONE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFOUR.TWO") }}</li>
</ul>
</div>
<div class="milestone-item">
<h3>{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE") }}</h3>
<ul>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.ONE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.TWO") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.THREE") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.FOUR") }}</li>
<li>{{ $t("COMPANYOVERVIEW.TITLEFOUR.paragraphFIVE.FIVE") }}</li>
</ul>
</div>
</section>
<!-- 突出成就 -->
<section
class="achievements"
style="
max-width: 1200px;
margin: 60px auto;
padding: 0 40px;
background: #f8fafc;
"
>
<h2 class="section-title">{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}</h2>
<p>{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}</p>
</section>
<!-- 新闻模块 -->
<section
class="news-section"
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
>
<h2 class="section-title">{{ $t("HOME.CONTAINY.NEWS.TITLE") }}</h2>
<div class="news-card">
<div class="news-date">2025-05-15</div>
<h3 class="news-title">{{ $t("HOME.CONTAINY.NEWS.LATEST_TITLE") }}</h3>
<p class="news-excerpt">
{{ $t("HOME.CONTAINY.NEWS.LATEST_CONTENT") }}
</p>
<!-- <a href="#" class="news-link"
>{{ $t("HOME.CONTAINY.NEWS.READ_MORE") }} </a
> -->
</div>
</section>
<!-- 新增股票信息与活动预告双栏模块 -->
<section
class="dual-column-section"
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
>
<div class="grid-container">
<!-- 股票信息卡片 -->
<div class="info-card stock-card">
<h2 class="card-title">{{ $t("HOME.CONTAINY.STOCK_INFO.TITLE") }}</h2>
<div class="stock-data">
<div class="data-row">
<span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
}}</span>
<span class="data-value">${{ dataObj.Open }}</span>
</div>
<div class="data-row">
<span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.CHANGE")
}}</span>
<span class="data-value positive"
>{{ dataObj.change[0] }}{{ dataObj.change[1] }}</span
>
</div>
<div class="data-row">
<span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.STOCK_CODE")
}}</span>
<span class="data-value">NASDAQ: MINM</span>
</div>
<div class="data-row">
<span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.VOLUME")
}}</span>
<span class="data-value">{{ dataObj.Volume }}</span>
</div>
<div class="data-row">
<span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
}}</span>
<span class="data-value">${{ dataObj.MarketCap }}</span>
</div>
</div>
</div>
<!-- 活动预告卡片 -->
<div class="info-card events-card">
<h2 class="card-title">
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.TITLE") }}
</h2>
<div class="event-item">
<h3 class="event-name">
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.EVENT_NAME") }}
</h3>
<!-- <div class="event-detail">
<div class="detail-row">
<i class="icon-calendar"></i>
<span
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.DATE") }}:
2025年8月12日()-2025年8月14日</span
>
</div>
<div class="detail-row">
<i class="icon-location"></i>
<span
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.VENUE") }}:
6号馆B厅</span
>
</div>
<div class="detail-row">
<i class="icon-area"></i>
<span
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.AREA") }}:
约10,000</span
>
</div>
<div class="detail-row">
<i class="icon-booth"></i>
<span
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.BOOTHS") }}:
约500个标准展位</span
>
</div>
</div> -->
</div>
</div>
</div>
</section>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import { useI18n } from "vue-i18n";
import { getTestData } from "@/config/testRequest";
const dataObj = ref({
change: ["0.2", "1111"],
});
onMounted(async () => {
try {
const data = await getTestData();
dataObj.value = data;
} catch (error) {
console.error("调用接口失败:", error);
}
});
const { t: $t } = useI18n();
</script>
<style scoped>
.home-page {
background-image: url("@/assets/image/bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
.hero-banner {
height: 600px;
display: flex;
align-items: center;
justify-content: center;
}
.banner-content {
text-align: center;
color: white;
padding: 20px;
background: rgba(0, 0, 0, 0.3);
border-radius: 8px;
}
.main-title {
font-size: 3.5rem;
margin-bottom: 20px;
}
.sub-title {
font-size: 1.5rem;
}
.section-card {
padding: 40px;
border-radius: 12px;
}
.card-content {
font-size: 1.1rem;
line-height: 1.8;
}
.section-title {
font-size: 2.5rem;
margin-bottom: 30px;
color: #895bff;
}
.content-block {
font-size: 1.1rem;
line-height: 1.8;
}
.mission-content ul {
list-style: disc;
padding-left: 20px;
font-size: 1.1rem;
}
.milestones {
font-size: 1.1rem;
}
.milestone-item {
margin-bottom: 40px;
padding: 20px;
border-left: 3px solid #895bff;
background: #f8fafc;
}
.milestone-item h3 {
font-size: 1.5rem;
margin-bottom: 10px;
color: #895bff;
}
.milestone-item ul {
list-style: none;
padding-left: 0;
}
.milestone-item li {
margin-bottom: 10px;
}
.achievements {
padding: 40px;
border-radius: 12px;
}
/* 新增样式 */
.dual-column-section {
margin-bottom: 80px;
}
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
}
.info-card {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.info-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
}
.card-title {
font-size: 1.8rem;
margin-bottom: 25px;
color: #895bff;
position: relative;
padding-bottom: 10px;
}
.card-title::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 60px;
height: 3px;
background: linear-gradient(90deg, #895bff, #b388ff);
}
/* 股票信息卡片样式 */
.stock-card {
border-top: 4px solid #895bff;
}
.stock-data {
margin-bottom: 25px;
}
.data-row {
display: flex;
justify-content: space-between;
padding: 12px 0;
border-bottom: 1px solid #f0f0f0;
}
.data-label {
color: #666;
font-weight: 500;
}
.data-value {
font-weight: 600;
}
.positive {
color: #895bff;
}
.stock-chart-placeholder {
height: 200px;
background: #f8fafc;
border-radius: 8px;
margin-top: 20px;
position: relative;
overflow: hidden;
}
.chart-mock {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 80%;
background: linear-gradient(90deg, #e0e7ff, #c7d2fe);
border-radius: 0 0 8px 8px;
}
/* 活动预告卡片样式 */
.events-card {
border-top: 4px solid #10b981;
}
.event-item {
margin-bottom: 20px;
}
.event-name {
font-size: 1.4rem;
color: #333;
margin-bottom: 15px;
}
.detail-row {
display: flex;
align-items: center;
margin-bottom: 12px;
color: #555;
}
.detail-row i {
margin-right: 10px;
color: #895bff;
font-size: 1.2rem;
}
.event-button {
background: linear-gradient(135deg, #895bff, #6a11cb);
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
font-weight: 600;
cursor: pointer;
margin-top: 20px;
transition: all 0.3s ease;
}
.event-button:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(137, 91, 255, 0.3);
}
/* 新闻模块样式 */
.news-section {
margin-bottom: 80px;
}
.news-card {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
border-left: 4px solid #895bff;
}
.news-date {
color: #888;
font-size: 0.9rem;
margin-bottom: 10px;
}
.news-title {
font-size: 1.5rem;
color: #333;
margin-bottom: 15px;
}
.news-excerpt {
color: #555;
line-height: 1.7;
margin-bottom: 20px;
}
.news-link {
color: #895bff;
font-weight: 600;
text-decoration: none;
display: inline-flex;
align-items: center;
}
.news-link:hover {
text-decoration: underline;
}
/* 响应式设计 */
@media (max-width: 768px) {
.grid-container {
grid-template-columns: 1fr;
}
.hero-banner {
height: 400px;
}
.main-title {
font-size: 2.5rem;
}
}
</style>

View File

@ -12,7 +12,7 @@ getStockQuate()
>
<!-- 左侧大号价格 -->
<section class="flex flex-col items-center justify-center glass-card p-32 rounded-2xl shadow-xl ">
<div class="text-9xl font-extrabold text-primary animate-bg-move select-none drop-shadow-lg">$1.98</div>
<div class="text-9xl font-extrabold text-#8A5AFB animate-bg-move select-none drop-shadow-lg">$1.98</div>
<div class="mt-10 text-3xl text-gray-500 font-semibold tracking-widest">NASDAQ: <span class="text-black">UK</span></div>
</section>
<!-- 右侧信息卡片 -->

View File

@ -6,6 +6,7 @@ import Components from 'unplugin-vue-components/vite';
import {VantResolver} from '@vant/auto-import-resolver';
import UnoCSS from 'unocss/vite'
import viteImagemin from 'vite-plugin-imagemin'
import vueDevTools from 'vite-plugin-vue-devtools';
// https://vitejs.dev/config/
export default defineConfig({
envDir: './env', // 自定义env目录
@ -23,6 +24,9 @@ export default defineConfig({
},
plugins: [
vue(),
vueDevTools({
launchEditor: 'cursor',
}),
UnoCSS(),
AutoImport({
resolvers: [VantResolver()],