Browse Source

'i8N强行写静态国际化'

hfll
hflllll 1 month ago
parent
commit
e268141577
29 changed files with 27258 additions and 5146 deletions
  1. BIN
      public/images/ecosystem/blockchain.jpg
  2. BIN
      public/images/ecosystem/crosschain.jpg
  3. BIN
      public/images/ecosystem/dao.jpg
  4. BIN
      public/images/ecosystem/defi.jpg
  5. BIN
      public/images/ecosystem/gaming.jpg
  6. BIN
      public/images/ecosystem/nft.jpg
  7. BIN
      public/images/ecosystem/payment.jpg
  8. BIN
      public/images/ecosystem/privacy.jpg
  9. BIN
      public/images/ecosystem/social.jpg
  10. BIN
      public/images/ecosystem/trading.jpg
  11. +43
    -8
      src/components/about/CompanyModule.vue
  12. +35
    -2
      src/components/about/MilestoneModule.vue
  13. +46
    -3
      src/components/about/TeamModule.vue
  14. +24
    -20
      src/components/technology/EcosystemIntegrationModule.vue
  15. +18
    -18
      src/i18n/index.ts
  16. +2576
    -441
      src/i18n/locales/ar.json
  17. +4607
    -448
      src/i18n/locales/en.json
  18. +2638
    -438
      src/i18n/locales/fr.json
  19. +3201
    -400
      src/i18n/locales/ja.json
  20. +2642
    -443
      src/i18n/locales/ko.json
  21. +2639
    -440
      src/i18n/locales/ms.json
  22. +2641
    -442
      src/i18n/locales/pt.json
  23. +1492
    -460
      src/i18n/locales/ru.json
  24. +1489
    -463
      src/i18n/locales/th.json
  25. +1433
    -465
      src/i18n/locales/vi.json
  26. +1432
    -464
      src/i18n/locales/zh-TW.json
  27. +131
    -37
      src/i18n/locales/zh.json
  28. +125
    -127
      src/views/Ecosystem.vue
  29. +46
    -27
      src/views/Technology.vue

BIN
public/images/ecosystem/blockchain.jpg View File

Before After
Width: 292  |  Height: 325  |  Size: 13 KiB

BIN
public/images/ecosystem/crosschain.jpg View File

Before After
Width: 292  |  Height: 325  |  Size: 13 KiB

BIN
public/images/ecosystem/dao.jpg View File

Before After
Width: 292  |  Height: 325  |  Size: 13 KiB

BIN
public/images/ecosystem/defi.jpg View File

Before After
Width: 292  |  Height: 325  |  Size: 13 KiB

BIN
public/images/ecosystem/gaming.jpg View File

Before After
Width: 292  |  Height: 325  |  Size: 13 KiB

BIN
public/images/ecosystem/nft.jpg View File

Before After
Width: 292  |  Height: 325  |  Size: 13 KiB

BIN
public/images/ecosystem/payment.jpg View File

Before After
Width: 292  |  Height: 325  |  Size: 13 KiB

BIN
public/images/ecosystem/privacy.jpg View File

Before After
Width: 292  |  Height: 325  |  Size: 13 KiB

BIN
public/images/ecosystem/social.jpg View File

Before After
Width: 292  |  Height: 325  |  Size: 13 KiB

BIN
public/images/ecosystem/trading.jpg View File

Before After
Width: 292  |  Height: 325  |  Size: 13 KiB

+ 43
- 8
src/components/about/CompanyModule.vue View File

@ -61,6 +61,41 @@ const toggleLocationDetail = (locationId: number) => {
}
};
// i18n
const getCompanyName = (companyId: string) => {
const companyKey = getCompanyKey(companyId);
return companyKey ? t(`api.about.companies.${companyKey}.name`) : '';
};
const getCompanyDescription = (companyId: string) => {
const companyKey = getCompanyKey(companyId);
return companyKey ? t(`api.about.companies.${companyKey}.description`) : '';
};
// IDi18n key
const getCompanyKey = (companyId: string) => {
// IDi18n key
const companyMap: Record<string, string> = {
'1': 'singapore_hq',
'2': 'hong_kong_branch',
'3': 'singapore_hq',
'4': 'hong_kong_branch',
'5': 'singapore_hq',
'6': 'hong_kong_branch',
'7': 'singapore_hq',
'8': 'hong_kong_branch'
};
// ID
if (companyMap[companyId]) {
return companyMap[companyId];
}
// ID
const idNum = parseInt(companyId) || 1;
return idNum % 2 === 1 ? 'singapore_hq' : 'hong_kong_branch';
};
//
const fetchCompanyList = async () => {
try {
@ -108,10 +143,10 @@ onMounted(() => {
<!-- 标题部分 -->
<div class="max-w-3xl mx-auto text-center mb-16">
<h2 class="text-3xl md:text-4xl lg:text-5xl font-bold text-text mb-6 wow animate__animated animate__fadeInDown animate__duration-fast">
{{ t('ecosystem.companies.title') }}
{{ t('about.companies.title') }}
</h2>
<p class="text-lg md:text-xl text-text-secondary wow animate__animated animate__fadeIn animate__delay-xs animate__duration-fast">
{{ t('ecosystem.companies.subtitle') }}
{{ t('about.companies.subtitle') }}
</p>
<!-- 装饰线 -->
@ -199,8 +234,8 @@ onMounted(() => {
<div class="flex items-center mb-2">
<img :src="location.image" :alt="location.title + ' flag'" class="w-6 h-4 mr-2 rounded object-cover">
<div class="flex-1">
<h3 class="text-white font-bold text-sm">{{ location.title }}</h3>
<div class="text-white/70 text-xs" v-html="location.description"></div>
<h3 class="text-white font-bold text-sm">{{ getCompanyName(location.id) }}</h3>
<div class="text-white/70 text-xs" v-html="getCompanyDescription(location.id)"></div>
</div>
</div>
@ -213,8 +248,8 @@ onMounted(() => {
<div v-if="activeLocationId === location.id"
class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 md:hidden z-50">
<div class="bg-black/90 backdrop-blur-sm rounded-lg p-3 text-white text-xs whitespace-nowrap min-w-[120px] text-center">
<div class="font-bold mb-1">{{ location.title }}</div>
<div class="text-white/80" v-html="location.description"></div>
<div class="font-bold mb-1">{{ getCompanyName(location.id) }}</div>
<div class="text-white/80" v-html="getCompanyDescription(location.id)"></div>
</div>
<div class="w-2 h-2 bg-black/90 transform rotate-45 mx-auto -mt-1"></div>
</div>
@ -222,7 +257,7 @@ onMounted(() => {
<!-- 桌面端悬停详情 -->
<div class="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none hidden md:block">
<div class="bg-black/80 backdrop-blur-sm rounded-lg p-3 text-white text-xs whitespace-nowrap">
<div class="font-bold">{{ location.title }}, <div v-html="location.description"></div></div>
<div class="font-bold">{{ getCompanyName(location.id) }}, <div v-html="getCompanyDescription(location.id)"></div></div>
</div>
<div class="w-2 h-2 bg-black/80 transform rotate-45 mx-auto -mt-1"></div>
</div>
@ -234,7 +269,7 @@ onMounted(() => {
<!-- 底部说明 -->
<div class="text-center mt-16">
<p class="text-text-secondary mb-6">
{{ t('ecosystem.companies.footer_description') }}
{{ t('about.companies.footer_description') }}
</p>
<div class="flex justify-center space-x-2">
<span v-for="i in 10" :key="i"


+ 35
- 2
src/components/about/MilestoneModule.vue View File

@ -16,6 +16,39 @@ const error = ref<string | null>(null);
// i18n
const getMilestoneTitle = (milestoneId: string) => {
const milestoneKey = getMilestoneKey(milestoneId);
return milestoneKey ? t(`api.about.roadmap.${milestoneKey}.title`) : '';
};
const getMilestoneDescription = (milestoneId: string) => {
const milestoneKey = getMilestoneKey(milestoneId);
return milestoneKey ? t(`api.about.roadmap.${milestoneKey}.description`) : '';
};
// IDi18n key
const getMilestoneKey = (milestoneId: string) => {
// IDi18n key
const milestoneMap: Record<string, string> = {
'1': '2023_q1',
'2': '2024_q2',
'3': '2023_q1',
'4': '2024_q2',
'5': '2023_q1',
'6': '2024_q2'
};
// ID
if (milestoneMap[milestoneId]) {
return milestoneMap[milestoneId];
}
// ID
const idNum = parseInt(milestoneId) || 1;
return idNum % 2 === 1 ? '2023_q1' : '2024_q2';
};
//
const fetchMilestones = async () => {
loading.value = true;
@ -140,8 +173,8 @@ onMounted(() => {
</div>
<div class="node-content">
<h3 class="node-title">{{ milestone.title }}</h3>
<div class="node-description" v-html="milestone.description"></div>
<h3 class="node-title">{{ getMilestoneTitle(milestone.id) }}</h3>
<div class="node-description" v-html="getMilestoneDescription(milestone.id)"></div>
</div>
</div>
</div>


+ 46
- 3
src/components/about/TeamModule.vue View File

@ -64,6 +64,49 @@ onMounted(async () => {
initSwiper();
});
// i18n
const getTeamMemberName = (memberId: string) => {
const memberKey = getMemberKey(memberId);
return memberKey ? t(`api.about.team_members.${memberKey}.name`) : '';
};
const getTeamMemberPosition = (memberId: string) => {
const memberKey = getMemberKey(memberId);
return memberKey ? t(`api.about.team_members.${memberKey}.position`) : '';
};
const getTeamMemberBio = (memberId: string) => {
const memberKey = getMemberKey(memberId);
return memberKey ? t(`api.about.team_members.${memberKey}.bio`) : '';
};
// i18n key
const getMemberKey = (memberId: string) => {
// IDi18n key
// ID
const memberMap: Record<string, string> = {
'1': 'james_park',
'2': 'sophia_muller',
'3': 'james_park',
'4': 'sophia_muller',
'5': 'james_park',
'6': 'sophia_muller',
'7': 'james_park',
'8': 'sophia_muller',
'9': 'james_park',
'10': 'sophia_muller'
};
// ID
if (memberMap[memberId]) {
return memberMap[memberId];
}
// ID
const idNum = parseInt(memberId) || 1;
return idNum % 2 === 1 ? 'james_park' : 'sophia_muller';
};
// Swiper
const initSwiper = () => {
// Swiper
@ -168,10 +211,10 @@ const initSwiper = () => {
<!-- 内容 -->
<div class="relative p-4 md:p-6 flex flex-col h-full pt-[70%] md:pt-[52%]">
<!-- 成员姓名 -->
<h3 class="text-lg md:text-xl font-black text-white text-center mb-2">{{ member.name }}</h3>
<h3 class="text-lg md:text-xl font-black text-white text-center mb-2">{{ getTeamMemberName(member.id) }}</h3>
<!-- 成员职位 -->
<p class="text-white/90 text-center text-xs md:text-sm mb-2 md:mb-3">{{ member.post }}</p>
<p class="text-white/90 text-center text-xs md:text-sm mb-2 md:mb-3">{{ getTeamMemberPosition(member.id) }}</p>
<!-- 装饰线 -->
<div class="w-12 md:w-16 h-1 bg-white/30 mx-auto mb-2 md:mb-3"></div>
@ -179,7 +222,7 @@ const initSwiper = () => {
<!-- 成员简介 -->
<div class="text-white/90 text-center text-xs md:text-sm leading-relaxed flex-grow">
<!-- 多行文本溢出显示省略号 -->
<div v-html="member.resume" class="line-clamp-3 md:line-clamp-4 overflow-hidden"></div>
<div v-html="getTeamMemberBio(member.id)" class="line-clamp-3 md:line-clamp-4 overflow-hidden"></div>
</div>
<!-- 成员编号 -->


+ 24
- 20
src/components/technology/EcosystemIntegrationModule.vue View File

@ -1,62 +1,66 @@
<script setup lang="ts">
import { computed } from 'vue';
import { Icon } from '@iconify/vue';
import { useI18n } from 'vue-i18n';
//
const integrationScenarios = [
const { t } = useI18n();
// - 使i18n
const integrationScenarios = computed(() => [
{
id: 1,
icon: 'carbon:currency-dollar',
name: 'MOSE DEX',
description: '去中心化交易协议,支持多链资产安全交易与兑换'
name: t('technology.integration.scenarios.dex.name'),
description: t('technology.integration.scenarios.dex.description')
},
{
id: 2,
icon: 'carbon:image',
name: 'NFT交易平台',
description: '跨链NFT铸造、交易与展示平台,支持隐私保护'
name: t('technology.integration.scenarios.nft_platform.name'),
description: t('technology.integration.scenarios.nft_platform.description')
},
{
id: 3,
icon: 'carbon:piggy-bank',
name: '去中心化金融',
description: '稳定币、借贷、衍生品等DeFi应用协议集成'
name: t('technology.integration.scenarios.defi.name'),
description: t('technology.integration.scenarios.defi.description')
},
{
id: 4,
icon: 'carbon:wallet',
name: '多链钱包',
description: '支持多链资产管理与交互的安全钱包'
name: t('technology.integration.scenarios.wallet.name'),
description: t('technology.integration.scenarios.wallet.description')
},
{
id: 5,
icon: 'carbon:security',
name: '隐私保护工具',
description: '零知识证明与隐私计算的端到端解决方案'
name: t('technology.integration.scenarios.privacy_tools.name'),
description: t('technology.integration.scenarios.privacy_tools.description')
},
{
id: 6,
icon: 'carbon:group',
name: '去中心化自治组织',
description: 'DAO治理与投票系统,支持透明决策与跨链操作'
name: t('technology.integration.scenarios.dao.name'),
description: t('technology.integration.scenarios.dao.description')
}
];
]);
</script>
<template>
<section class="py-16 px-6 md:px-12 lg:px-24">
<div class="container mx-auto">
<h2 class="text-2xl md:text-3xl font-bold text-text mb-6 text-center wow animate__animated animate__fadeInUp animate__duration-fast">
生态系统集成
{{ t('technology.integration.title') }}
</h2>
<p class="max-w-3xl mx-auto text-center text-text-secondary mb-12 wow animate__animated animate__fadeIn animate__delay-xs animate__duration-fast">
MOSE与多个区块链生态系统无缝集成提供跨链隐私保护能力
{{ t('technology.integration.description') }}
</p>
<!-- 整合描述 -->
<div class="bg-primary bg-opacity-5 rounded-2xl p-8 mb-12 wow animate__animated animate__fadeIn animate__duration-fast">
<p class="text-text-secondary text-center">
通过开放的API与SDKMOSE支持各类应用无缝接入提供统一的跨链隐私服务赋能开发者构建下一代区块链应用
{{ t('technology.integration.integration_description') }}
</p>
</div>
@ -87,10 +91,10 @@ const integrationScenarios = [
to="/ecosystem"
class="inline-flex items-center gap-2 bg-primary hover:bg-primary-dark text-white font-medium py-3 px-6 rounded-lg transition-colors duration-200"
>
了解更多
{{ t('technology.integration.learn_more') }}
<Icon icon="carbon:arrow-right" />
</router-link>
</div>
</div>
</section>
</template>
</template>

+ 18
- 18
src/i18n/index.ts View File

@ -2,15 +2,15 @@ import { createI18n } from 'vue-i18n'
import en from './locales/en.json'
import zh from './locales/zh.json'
import ja from './locales/ja.json'
import ar from './locales/ar.json'
import fr from './locales/fr.json'
import ko from './locales/ko.json'
import ms from './locales/ms.json'
import pt from './locales/pt.json'
import ru from './locales/ru.json'
import th from './locales/th.json'
import vi from './locales/vi.json'
import zh_TW from './locales/zh-TW.json'
// import ar from './locales/ar.json'
// import fr from './locales/fr.json'
// import ko from './locales/ko.json'
// import ms from './locales/ms.json'
// import pt from './locales/pt.json'
// import ru from './locales/ru.json'
// import th from './locales/th.json'
// import vi from './locales/vi.json'
// import zh_TW from './locales/zh-TW.json'
// 获取浏览器语言或从本地存储中获取
const getBrowserLanguage = () => {
@ -37,15 +37,15 @@ const i18n = createI18n({
en,
zh,
ja,
ar,
fr,
ko,
ms,
pt,
ru,
th,
vi,
zh_TW
// ar,
// fr,
// ko,
// ms,
// pt,
// ru,
// th,
// vi,
// zh_TW
}
})

+ 2576
- 441
src/i18n/locales/ar.json
File diff suppressed because it is too large
View File


+ 4607
- 448
src/i18n/locales/en.json
File diff suppressed because it is too large
View File


+ 2638
- 438
src/i18n/locales/fr.json
File diff suppressed because it is too large
View File


+ 3201
- 400
src/i18n/locales/ja.json
File diff suppressed because it is too large
View File


+ 2642
- 443
src/i18n/locales/ko.json
File diff suppressed because it is too large
View File


+ 2639
- 440
src/i18n/locales/ms.json
File diff suppressed because it is too large
View File


+ 2641
- 442
src/i18n/locales/pt.json
File diff suppressed because it is too large
View File


+ 1492
- 460
src/i18n/locales/ru.json
File diff suppressed because it is too large
View File


+ 1489
- 463
src/i18n/locales/th.json
File diff suppressed because it is too large
View File


+ 1433
- 465
src/i18n/locales/vi.json
File diff suppressed because it is too large
View File


+ 1432
- 464
src/i18n/locales/zh-TW.json
File diff suppressed because it is too large
View File


+ 131
- 37
src/i18n/locales/zh.json View File

@ -1445,6 +1445,9 @@
"coming_soon": "即将推出"
},
"companies": {
"title": "全球布局",
"subtitle": "MOSE在全球的战略布局与发展",
"footer_description": "通过全球化布局,MOSE致力于为世界各地的用户提供安全、高效的隐私保护服务",
"items": {
"company1": {
"name": "新加坡总部",
@ -1588,9 +1591,11 @@
"vision_mission": "<strong>愿景:</strong>成为全球领先的隐私保护协议,为用户提供完全匿名和安全的数字资产管理体验。<br><br><strong>使命:</strong>通过先进的零知识证明技术和去中心化架构,保护用户隐私,推动去中心化金融的健康发展。",
"content": "MOSE诞生于对数字隐私保护的深度思考。在当今数字化时代,用户的隐私和数据安全面临前所未有的挑战。我们的团队由来自全球顶尖技术公司的专家组成,致力于构建一个真正去中心化、隐私优先的金融生态系统。<br><br>从项目启动至今,我们始终坚持技术创新和用户体验并重的原则,不断完善我们的隐私保护技术栈,为用户提供安全、便捷的数字资产管理解决方案。"
},
"company": {
"companies": {
"title": "公司介绍",
"description": "MOSE是一家专注于隐私保护技术的区块链公司,致力于为全球用户提供安全、私密的数字资产解决方案。",
"footer_description": "了解更多关于我们的公司介绍",
"subtitle": "了解更多关于我们的公司介绍",
"mission": {
"title": "我们的使命",
"description": "保护用户隐私,推动去中心化金融的发展"
@ -1609,11 +1614,41 @@
},
"team": {
"title": "团队成员",
"subtitle": "认识我们的专业团队"
"subtitle": "认识我们的专业团队",
"members": {
"james_park": {
"name": "James Park",
"post": "技术总裁",
"resume": "前Combase亚太负责人,主导DeFi产品年增长40%"
},
"sophia_muller": {
"name": "Sophia Müller",
"post": "全球运营总裁",
"resume": "曾任职Branco欧洲,管理超50国合规团队"
}
}
},
"milestones": {
"title": "发展里程碑",
"subtitle": "我们的发展历程"
"subtitle": "我们的发展历程",
"items": {
"whitepaper_release": {
"title": "白皮书发布",
"description": "完成800万美元种子轮融资"
},
"testnet_launch": {
"title": "测试网上线",
"description": "接入以太坊和BNB链"
},
"mainnet_launch": {
"title": "主网V1.0发布",
"description": "日交易量突破1亿美元"
},
"consensus_singapore": {
"title": "新加坡共识大会2024",
"description": "隐私技术主题演讲"
}
}
},
"partners": {
"title": "合作伙伴",
@ -1628,7 +1663,25 @@
},
"architecture": {
"title": "系统架构",
"subtitle": "了解MOSE的技术架构"
"subtitle": "了解MOSE的技术架构",
"layers": {
"layer1": {
"title": "应用层",
"description": "开放SDK支持DEX、NFT市场等场景一键隐私化。"
},
"layer2": {
"title": "协议层",
"description": "基于零知识证明的隐私保护协议,确保交易匿名性。"
},
"layer3": {
"title": "共识层",
"description": "高效的共识机制,保证网络安全和去中心化。"
},
"layer4": {
"title": "网络层",
"description": "分布式网络架构,支持全球节点部署和通信。"
}
}
},
"innovation": {
"title": "技术创新",
@ -1636,7 +1689,36 @@
},
"integration": {
"title": "生态集成",
"subtitle": "与主流区块链的无缝集成"
"subtitle": "与主流区块链的无缝集成",
"description": "MOSE与多个区块链生态系统无缝集成,提供跨链隐私保护能力",
"integration_description": "通过开放的API与SDK,MOSE支持各类应用无缝接入,提供统一的跨链隐私服务,赋能开发者构建下一代区块链应用",
"learn_more": "了解更多",
"scenarios": {
"dex": {
"name": "MOSE DEX",
"description": "去中心化交易协议,支持多链资产安全交易与兑换"
},
"nft_platform": {
"name": "NFT交易平台",
"description": "跨链NFT铸造、交易与展示平台,支持隐私保护"
},
"defi": {
"name": "去中心化金融",
"description": "稳定币、借贷、衍生品等DeFi应用协议集成"
},
"wallet": {
"name": "多链钱包",
"description": "支持多链资产管理与交互的安全钱包"
},
"privacy_tools": {
"name": "隐私保护工具",
"description": "零知识证明与隐私计算的端到端解决方案"
},
"dao": {
"name": "去中心化自治组织",
"description": "DAO治理与投票系统,支持透明决策与跨链操作"
}
}
},
"buttons": {
"learn_architecture": "了解架构",
@ -1678,68 +1760,68 @@
},
"apps": {
"wallet": {
"name": "隐私钱包",
"description": "安全的隐私钱包应用"
"name": "MOSE钱包APP",
"description": "安全且用户友好的数字资产钱包"
},
"exchange": {
"name": "去中心化交易所",
"description": "去中心化交易所平台"
"name": "DEX交易所",
"description": "低滑点和低费用的去中心化交易所"
},
"bridge": {
"name": "跨链",
"description": "跨链桥接服务"
"name": "跨链混币",
"description": "安全高效的跨链资产转移协议"
},
"pay": {
"name": "隐私支付",
"description": "隐私支付解决方案"
"description": "基于零知识证明的隐私支付系统"
},
"dao": {
"name": "DAO治理",
"description": "去中心化自治组织"
"description": "DAO治理与投票系统,支持透明决策与跨链操作"
},
"nft": {
"name": "NFT市场",
"description": "NFT交易市场"
"name": "NFT平台",
"description": "跨链NFT铸造、交易与展示平台,支持隐私保护"
},
"defi": {
"name": "DeFi协议",
"description": "去中心化金融协议"
"description": "稳定币、借贷、衍生品等DeFi应用协议集成"
},
"id": {
"name": "身份系统",
"description": "去中心化身份系统"
"description": "去中心化身份验证与管理系统"
},
"app1": {
"name": "隐私钱包",
"description": "安全的隐私钱包应用"
"name": "MOSE钱包APP",
"description": "安全且用户友好的数字资产钱包"
},
"app2": {
"name": "去中心化交易所",
"description": "去中心化交易所平台"
"name": "DEX交易所",
"description": "低滑点和低费用的去中心化交易所"
},
"app3": {
"name": "跨链",
"description": "跨链桥接服务"
"name": "跨链混币",
"description": "安全高效的跨链资产转移协议"
},
"app4": {
"name": "隐私支付",
"description": "隐私支付解决方案"
"description": "基于零知识证明的隐私支付系统"
},
"app5": {
"name": "DAO治理",
"description": "去中心化自治组织"
"description": "DAO治理与投票系统,支持透明决策与跨链操作"
},
"app6": {
"name": "NFT市场",
"description": "NFT交易市场"
"name": "NFT平台",
"description": "跨链NFT铸造、交易与展示平台,支持隐私保护"
},
"app7": {
"name": "DeFi协议",
"description": "去中心化金融协议"
"description": "稳定币、借贷、衍生品等DeFi应用协议集成"
},
"app8": {
"name": "身份系统",
"description": "去中心化身份系统"
"description": "去中心化身份验证与管理系统"
},
"app9": {
"name": "借贷协议",
@ -1769,20 +1851,20 @@
}
},
"apps": {
"privacy_wallet": {
"title": "隐私钱包",
"wallet": {
"name": "隐私钱包",
"description": "安全存储和管理您的数字资产"
},
"dex_platform": {
"title": "去中心化交易所",
"exchange": {
"name": "去中心化交易所",
"description": "无需KYC的匿名交易平台"
},
"bridge_service": {
"title": "跨链桥服务",
"bridge": {
"name": "跨链桥服务",
"description": "连接不同区块链网络的桥梁"
},
"staking_rewards": {
"title": "质押奖励",
"pay": {
"name": "质押奖励",
"description": "通过质押获得被动收入"
}
}
@ -2109,6 +2191,12 @@
"ecosystem": {
"title": "MOSE生态系统",
"subtitle": "探索我们的去中心化生态",
"companies": {
"title": "公司介绍",
"description": "了解我们的公司背景和目标",
"footer_description": "MOSE生态系统是一个基于零知识证明技术的隐私保护协议,为用户提供完全匿名的数字资产管理和交易服务。"
},
"hero": {
"title": "MOSE生态系统",
"subtitle": "探索我们的去中心化生态",
@ -2352,6 +2440,11 @@
"description": "服务亚太金融市场",
"focus": "机构合作",
"team": "业务拓展团队"
},
"companies": {
"title": "公司介绍",
"description": "了解我们的公司背景和目标",
"footer_description": "了解更多关于我们的公司介绍"
}
},
"team_members": {
@ -2445,6 +2538,7 @@
"question": "MOSE代币的总供应量是多少?",
"answer": "总发行量3亿枚,通过手续费机制销毁2.9亿枚"
}
}
},
"contact": {


+ 125
- 127
src/views/Ecosystem.vue View File

@ -2,6 +2,14 @@
import { ref, computed, onMounted, reactive } from 'vue';
import { useI18n } from 'vue-i18n';
import { queryEcosystemListForEcosystem } from '@/api/modules/ecosystem';
import type { EcosystemItem as ApiEcosystemItem } from '@/api/modules/ecosystem';
// WOW
declare global {
interface Window {
WOW: any;
}
}
const { t, locale } = useI18n();
@ -10,7 +18,7 @@ const selectedEcosystem = ref(1);
const totalEcosystems = 10; // 10
//
const loading = ref(true);
const loading = ref(false);
//
const ecosystemStyles = [
@ -56,128 +64,119 @@ const ecosystemStyles = [
}
];
// - API
const ecosystems = reactive([]);
// - 使i18n
interface EcosystemItem {
id: string;
image: string;
title: string;
description: string;
overlayColor: string;
bgColor: string;
}
//
const ecosystems = ref<EcosystemItem[]>([]);
// API
const apiImages = ref<string[]>([]);
// API
const fetchEcosystems = async () => {
loading.value = true;
try {
const result = await queryEcosystemListForEcosystem({
pageSize: 10,
pageNo: 1
});
if (result && result.length > 0) {
// API
const ecosystemsData = result.map((item, index) => {
return {
...item,
id: item.id || String(index + 1),
// 使API使
image: item.image || '/LOGO.png',
// 使
...ecosystemStyles[index % ecosystemStyles.length]
};
const response = await queryEcosystemListForEcosystem();
console.log('API Response:', response);
if (response) {
console.log('First API item structure:', response[0]);
// API
apiImages.value = response.map((item: ApiEcosystemItem) => {
// console.log('Processing item:', item, 'image field:', item.image);
const trimmedImage = (item.image || '').trim();
// console.log('Trimmed image:', trimmedImage);
return trimmedImage;
}).filter(url => {
console.log('Filtering URL:', url, 'is valid:', Boolean(url));
return Boolean(url);
});
//
ecosystems.splice(0, ecosystems.length, ...ecosystemsData);
} else {
// API使
const defaultEcosystems = [
{
id: '1',
image: '/LOGO.png',
title: t('ecosystem.trading.title'),
description: t('ecosystem.trading.description'),
...ecosystemStyles[0]
},
{
id: '2',
image: '/LOGO.png',
title: t('ecosystem.blockchain.title'),
description: t('ecosystem.blockchain.description'),
...ecosystemStyles[1]
},
{
id: '3',
image: '/LOGO.png',
title: t('ecosystem.crosschain.title'),
description: t('ecosystem.crosschain.description'),
...ecosystemStyles[2]
},
{
id: '4',
image: '/LOGO.png',
title: t('ecosystem.payment.title'),
description: t('ecosystem.payment.description'),
...ecosystemStyles[3]
},
{
id: '5',
image: '/LOGO.png',
title: t('ecosystem.privacy.title'),
description: t('ecosystem.privacy.description'),
...ecosystemStyles[4]
},
{
id: '6',
image: '/LOGO.png',
title: t('ecosystem.defi.title'),
description: t('ecosystem.defi.description'),
...ecosystemStyles[5]
},
{
id: '7',
image: '/LOGO.png',
title: t('ecosystem.nft.title'),
description: t('ecosystem.nft.description'),
...ecosystemStyles[6]
},
{
id: '8',
image: '/LOGO.png',
title: t('ecosystem.dao.title'),
description: t('ecosystem.dao.description'),
...ecosystemStyles[7]
},
{
id: '9',
image: '/LOGO.png',
title: t('ecosystem.gaming.title'),
description: t('ecosystem.gaming.description'),
...ecosystemStyles[8]
},
{
id: '10',
image: '/LOGO.png',
title: t('ecosystem.social.title'),
description: t('ecosystem.social.description'),
...ecosystemStyles[9]
}
];
//
ecosystems.splice(0, ecosystems.length, ...defaultEcosystems);
console.log('Final API Images array:', apiImages.value);
}
} catch (error) {
console.error(t('common.error.loadEcosystemFailed'), error);
// 使
const defaultEcosystems = [
{
id: '1',
image: '/LOGO.png',
title: t('ecosystem.trading.title'),
description: t('ecosystem.trading.description'),
...ecosystemStyles[0]
},
// ...
];
ecosystems.splice(0, ecosystems.length, ...defaultEcosystems.slice(0, 1));
} finally {
loading.value = false;
console.error('Failed to fetch ecosystems:', error);
apiImages.value = [];
}
// API
initEcosystems();
};
// 使API使i18n
const initEcosystems = () => {
const i18nData = [
{
key: 'trading',
title: t('ecosystem.trading.title'),
description: t('ecosystem.trading.description')
},
{
key: 'blockchain',
title: t('ecosystem.blockchain.title'),
description: t('ecosystem.blockchain.description')
},
{
key: 'crosschain',
title: t('ecosystem.crosschain.title'),
description: t('ecosystem.crosschain.description')
},
{
key: 'payment',
title: t('ecosystem.payment.title'),
description: t('ecosystem.payment.description')
},
{
key: 'privacy',
title: t('ecosystem.privacy.title'),
description: t('ecosystem.privacy.description')
},
{
key: 'defi',
title: t('ecosystem.defi.title'),
description: t('ecosystem.defi.description')
},
{
key: 'nft',
title: t('ecosystem.nft.title'),
description: t('ecosystem.nft.description')
},
{
key: 'dao',
title: t('ecosystem.dao.title'),
description: t('ecosystem.dao.description')
},
{
key: 'gaming',
title: t('ecosystem.gaming.title'),
description: t('ecosystem.gaming.description')
},
{
key: 'social',
title: t('ecosystem.social.title'),
description: t('ecosystem.social.description')
}
];
// APIi18n
const ecosystemsData = i18nData.map((item, index) => {
const finalImage = apiImages.value[index] || `/images/ecosystem/${item.key}.jpg`;
console.log(`Ecosystem ${index}: Using image ${finalImage}`);
return {
id: (index + 1).toString(),
title: item.title,
description: item.description,
image: finalImage,
orderNo: index + 1,
...ecosystemStyles[index]
};
});
console.log('Final ecosystems data:', ecosystemsData);
//
ecosystems.value = ecosystemsData;
};
// 使
@ -219,7 +218,7 @@ const projects = computed(() => [
//
const featuredProjects = computed(() => {
return projects.value.filter(project => project.featured);
return projects.value.filter((project: any) => project.featured);
});
//
@ -239,7 +238,7 @@ const prevEcosystem = () => {
//
const currentEcosystem = computed(() => {
return ecosystems.find((eco: any) => Number(eco.id) === selectedEcosystem.value) || ecosystems[0];
return ecosystems.value.find((eco: EcosystemItem) => Number(eco.id) === selectedEcosystem.value) || ecosystems.value[0];
});
//
@ -304,9 +303,8 @@ const handleMouseMove = (event: MouseEvent) => {
onMounted(() => {
// WOW.js
try {
const WOW = window.WOW;
if (WOW) {
new WOW({
if (typeof window !== 'undefined' && window.WOW) {
new (window.WOW as any)({
boxClass: 'wow',
animateClass: 'animate__animated',
offset: 100,
@ -401,13 +399,13 @@ onMounted(() => {
</div> -->
<!-- 标题 - 统一样式 -->
<h2 class="font-bold text-white mb-6 wow animate__animated animate__fadeInRight text-4xl md:text-5xl" v-html="ecosystem.title" />
<!-- {{ ecosystem.title }} -->
<!-- </h2> -->
<h2 class="font-bold text-white mb-6 wow animate__animated animate__fadeInRight text-4xl md:text-5xl">
{{ ecosystem.title }}
</h2>
<!-- 描述 - 统一样式 -->
<p class="text-white/80 mb-8 wow animate__animated animate__fadeInRight animate__delay-xs text-base max-w-full" v-if="ecosystem.description" v-html="ecosystem.description">
<p class="text-white/80 mb-8 wow animate__animated animate__fadeInRight animate__delay-xs text-base max-w-full" v-if="ecosystem.description">
{{ ecosystem.description }}
</p>
<p class="text-white/80 mb-8 wow animate__animated animate__fadeInRight animate__delay-xs text-base" v-else>
{{ t('ecosystem.default_description') }}
@ -449,7 +447,7 @@ onMounted(() => {
v-if="index < ecosystems.length - 1"
class="absolute bottom-8 left-1/2 transform -translate-x-1/2 text-white/70 text-sm flex flex-col items-center cursor-pointer hover:text-white transition-colors duration-300"
@click="scrollToNext(index)"
>
>
<!-- <span class="mb-1">探索更多</span>
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 animate-bounce-soft" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3" />


+ 46
- 27
src/views/Technology.vue View File

@ -61,16 +61,16 @@ const fetchTechnologies = async () => {
});
} else {
// 使
technologies.value = defaultTechnologies;
technologies.value = defaultTechnologies.value;
}
} catch (error) {
console.error('Failed to load technologies:', error);
technologies.value = defaultTechnologies;
technologies.value = defaultTechnologies.value;
}
};
// API使
const defaultTechnologies = [
const defaultTechnologies = computed(() => [
{
id: '1',
title: t('technology.core.tech_barrier.title'),
@ -103,15 +103,15 @@ const defaultTechnologies = [
color: 'primary',
image: '/LOGO.png' //
}
];
]);
//
const apps = reactive([
const apps = computed(() => [
{
id: 1,
name: 'MOSE Wallet',
name: t('technology.apps.wallet.name'),
description: t('technology.apps.wallet.description'),
image: '/LOGO.png',
color: 'from-blue-600 to-indigo-900',
@ -119,7 +119,7 @@ const apps = reactive([
},
{
id: 2,
name: 'MOSE Exchange',
name: t('technology.apps.exchange.name'),
description: t('technology.apps.exchange.description'),
image: '/LOGO.png',
color: 'from-purple-600 to-indigo-900',
@ -127,7 +127,7 @@ const apps = reactive([
},
{
id: 3,
name: 'MOSE Bridge',
name: t('technology.apps.bridge.name'),
description: t('technology.apps.bridge.description'),
image: '/LOGO.png',
color: 'from-green-600 to-teal-900',
@ -135,7 +135,7 @@ const apps = reactive([
},
{
id: 4,
name: 'MOSE Pay',
name: t('technology.apps.pay.name'),
description: t('technology.apps.pay.description'),
image: '/LOGO.png',
color: 'from-orange-600 to-red-900',
@ -143,7 +143,7 @@ const apps = reactive([
},
{
id: 5,
name: 'MOSE DAO',
name: t('technology.apps.dao.name'),
description: t('technology.apps.dao.description'),
image: '/LOGO.png',
color: 'from-amber-600 to-orange-900',
@ -151,7 +151,7 @@ const apps = reactive([
},
{
id: 6,
name: 'MOSE NFT',
name: t('technology.apps.nft.name'),
description: t('technology.apps.nft.description'),
image: '/LOGO.png',
color: 'from-pink-600 to-rose-900',
@ -159,7 +159,7 @@ const apps = reactive([
},
{
id: 7,
name: 'MOSE DeFi',
name: t('technology.apps.defi.name'),
description: t('technology.apps.defi.description'),
image: '/LOGO.png',
color: 'from-cyan-600 to-blue-900',
@ -167,7 +167,7 @@ const apps = reactive([
},
{
id: 8,
name: 'MOSE ID',
name: t('technology.apps.id.name'),
description: t('technology.apps.id.description'),
image: '/LOGO.png',
color: 'from-emerald-600 to-green-900',
@ -202,21 +202,23 @@ const fetchAppList = async () => {
'carbon:wallet', 'carbon:chart-line', 'carbon:bridge', 'carbon:purchase',
'carbon:group', 'carbon:image', 'carbon:money', 'carbon:user'
];
const appKeys = ['wallet', 'exchange', 'bridge', 'pay', 'dao', 'nft', 'defi', 'id'];
const appKey = appKeys[index] || `app${index + 1}`;
return {
id: item.id || index + 1,
name: t(`technology.apps.app${index + 1}.name`),
description: t(`technology.apps.app${index + 1}.description`),
name: t(`technology.apps.${appKey}.name`),
description: t(`technology.apps.${appKey}.description`),
image: item.image || '/LOGO.png',
color: colors[index % colors.length],
icon: icons[index % icons.length]
};
});
} else {
appList.value = apps;
appList.value = apps.value;
}
} catch (error) {
console.error('Failed to load app list:', error);
appList.value = apps;
appList.value = apps.value;
}
};
@ -233,15 +235,32 @@ const fetchInnovation = async () => {
pageNo: 1
});
if (result && result.length > 0) {
structural.value = result;
console.log(structural.value);
// 使API使i18n
structural.value = result.map((item, index) => ({
id: item.id || `${index + 1}`,
title: t(`technology.architecture.layers.layer${index + 1}.title`),
description: t(`technology.architecture.layers.layer${index + 1}.description`),
image: item.image || '/LOGO.png'
}));
console.log('Structural data with i18n:', structural.value);
} else {
structural.value = [];
// 使i18n
structural.value = Array.from({ length: 4 }, (_, index) => ({
id: `${index + 1}`,
title: t(`technology.architecture.layers.layer${index + 1}.title`),
description: t(`technology.architecture.layers.layer${index + 1}.description`),
image: '/LOGO.png'
}));
}
} catch (error) {
console.error('Failed to load innovation data:', error);
// innovation.value = [];
// 使i18nfallback
structural.value = Array.from({ length: 4 }, (_, index) => ({
id: `${index + 1}`,
title: t(`technology.architecture.layers.layer${index + 1}.title`),
description: t(`technology.architecture.layers.layer${index + 1}.description`),
image: '/LOGO.png'
}));
}
}
@ -364,8 +383,8 @@ onMounted(() => {
<!-- 内容区域 -->
<div class="relative z-10 px-8 py-12 text-left max-w-md">
<h3 class="text-3xl font-bold text-white mb-6">{{ arch.title }}</h3>
<div class="text-white/90 text-lg leading-relaxed mb-8" v-html="arch.description"></div>
<h3 class="text-3xl font-bold text-white mb-6">{{ t(`technology.architecture.layers.layer${index + 1}.title`) }}</h3>
<div class="text-white/90 text-lg leading-relaxed mb-8" v-html="t(`technology.architecture.layers.layer${index + 1}.description`)"></div>
<!-- 特性列表 -->
<div v-if="arch.features" class="space-y-3 mb-8">
@ -425,9 +444,9 @@ onMounted(() => {
:class="[`delay-${index*100}`]"
>
<!-- 内容 -->
<div class="flex flex-col items-center text-center">
<h4 class="text-white text-xl font-medium mb-6">{{arch.title}}</h4>
<p class="text-white text-sm font-medium mb-6 px-14" v-html="arch.description"></p>
<div class="flex flex-col items-center text-center">
<h4 class="text-white text-xl font-medium mb-6">{{ t(`technology.architecture.layers.layer${index + 1}.title`) }}</h4>
<p class="text-white text-sm font-medium mb-6 px-14" v-html="t(`technology.architecture.layers.layer${index + 1}.description`)"></p>
<!-- 按钮 -->
<button class="px-6 py-2 bg-red-600 hover:bg-red-700 rounded-sm text-white text-sm flex items-center gap-2 transition-all duration-300 absolute bottom-40 transform %">


Loading…
Cancel
Save