Merge branch 'main' of https://gitea-inner.fontree.cn/scout666/fiee-official-website
This commit is contained in:
commit
add85e1c53
@ -13,6 +13,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fingerprintjs/fingerprintjs": "^4.4.3",
|
"@fingerprintjs/fingerprintjs": "^4.4.3",
|
||||||
"@unocss/reset": "^0.61.9",
|
"@unocss/reset": "^0.61.9",
|
||||||
|
"@vicons/ionicons5": "^0.13.0",
|
||||||
|
"@vicons/utils": "^0.1.4",
|
||||||
"axios": "^1.7.3",
|
"axios": "^1.7.3",
|
||||||
"cnjm-postcss-px-to-viewport": "^1.0.1",
|
"cnjm-postcss-px-to-viewport": "^1.0.1",
|
||||||
"gsap": "^3.12.5",
|
"gsap": "^3.12.5",
|
||||||
|
@ -14,6 +14,12 @@ importers:
|
|||||||
'@unocss/reset':
|
'@unocss/reset':
|
||||||
specifier: ^0.61.9
|
specifier: ^0.61.9
|
||||||
version: 0.61.9
|
version: 0.61.9
|
||||||
|
'@vicons/ionicons5':
|
||||||
|
specifier: ^0.13.0
|
||||||
|
version: 0.13.0
|
||||||
|
'@vicons/utils':
|
||||||
|
specifier: ^0.1.4
|
||||||
|
version: 0.1.4(vue@3.4.35)
|
||||||
axios:
|
axios:
|
||||||
specifier: ^1.7.3
|
specifier: ^1.7.3
|
||||||
version: 1.7.3
|
version: 1.7.3
|
||||||
@ -1338,6 +1344,9 @@ packages:
|
|||||||
'@types/minimatch@5.1.2':
|
'@types/minimatch@5.1.2':
|
||||||
resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==}
|
resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==}
|
||||||
|
|
||||||
|
'@types/node@14.14.45':
|
||||||
|
resolution: {integrity: sha512-DssMqTV9UnnoxDWu959sDLZzfvqCF0qDNRjaWeYSui9xkFe61kKo4l1TWNTQONpuXEm+gLMRvdlzvNHBamzmEw==}
|
||||||
|
|
||||||
'@types/node@22.13.10':
|
'@types/node@22.13.10':
|
||||||
resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==}
|
resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==}
|
||||||
|
|
||||||
@ -1447,6 +1456,14 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: ^3.0.0
|
vue: ^3.0.0
|
||||||
|
|
||||||
|
'@vicons/ionicons5@0.13.0':
|
||||||
|
resolution: {integrity: sha512-zvZKBPjEXKN7AXNo2Na2uy+nvuv6SP4KAMQxpKL2vfHMj0fSvuw7JZcOPCjQC3e7ayssKnaoFVAhbYcW6v41qQ==}
|
||||||
|
|
||||||
|
'@vicons/utils@0.1.4':
|
||||||
|
resolution: {integrity: sha512-OHI19qVNN6i+uPQ+Y3f2s0dUxwsYnOCcKBW7XOU4yXXO1aU3ZoKpblCc3+4N0qmgoJs5rWKRAaMisipqEXJwAg==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.0.6
|
||||||
|
|
||||||
'@vitejs/plugin-legacy@5.4.1':
|
'@vitejs/plugin-legacy@5.4.1':
|
||||||
resolution: {integrity: sha512-kee0l7dVevCNs1l3u2PnihVunvQ0WTJL2UJ/siQGD3Iht546mR9NO16tCv32uCP6lcGO1QDLqlPqInJtV1FE7A==}
|
resolution: {integrity: sha512-kee0l7dVevCNs1l3u2PnihVunvQ0WTJL2UJ/siQGD3Iht546mR9NO16tCv32uCP6lcGO1QDLqlPqInJtV1FE7A==}
|
||||||
engines: {node: ^18.0.0 || >=20.0.0}
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
@ -1502,6 +1519,9 @@ packages:
|
|||||||
'@vueuse/shared@10.11.0':
|
'@vueuse/shared@10.11.0':
|
||||||
resolution: {integrity: sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==}
|
resolution: {integrity: sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==}
|
||||||
|
|
||||||
|
'@xicons/utils@0.1.4':
|
||||||
|
resolution: {integrity: sha512-uXxKDLz9abr80yJC05XSTq6wlyFcdW+N/1IYJkeHjzzXVc4VQ0sEYMoMMTjAH7HQBOyOkzOB4pf5NGF72lwa8Q==}
|
||||||
|
|
||||||
acorn@8.12.1:
|
acorn@8.12.1:
|
||||||
resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
|
resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
@ -1816,6 +1836,9 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4
|
postcss: ^8.4
|
||||||
|
|
||||||
|
css-render@0.13.9:
|
||||||
|
resolution: {integrity: sha512-n3C4ZH59rveBrUlAD7n0Ze9/gUMKa4dlH1C9CWKpGcIHR/xRcIVXzBGy1iw8WWq2ySmn2/ZqOpySQNAK5Pb6sw==}
|
||||||
|
|
||||||
css-render@0.15.14:
|
css-render@0.15.14:
|
||||||
resolution: {integrity: sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==}
|
resolution: {integrity: sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==}
|
||||||
|
|
||||||
@ -5135,6 +5158,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/minimatch@5.1.2': {}
|
'@types/minimatch@5.1.2': {}
|
||||||
|
|
||||||
|
'@types/node@14.14.45': {}
|
||||||
|
|
||||||
'@types/node@22.13.10':
|
'@types/node@22.13.10':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.20.0
|
undici-types: 6.20.0
|
||||||
@ -5317,6 +5342,13 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.4.35
|
vue: 3.4.35
|
||||||
|
|
||||||
|
'@vicons/ionicons5@0.13.0': {}
|
||||||
|
|
||||||
|
'@vicons/utils@0.1.4(vue@3.4.35)':
|
||||||
|
dependencies:
|
||||||
|
'@xicons/utils': 0.1.4
|
||||||
|
vue: 3.4.35
|
||||||
|
|
||||||
'@vitejs/plugin-legacy@5.4.1(terser@5.31.3)(vite@5.3.5(@types/node@22.13.10)(sass@1.77.8)(terser@5.31.3))':
|
'@vitejs/plugin-legacy@5.4.1(terser@5.31.3)(vite@5.3.5(@types/node@22.13.10)(sass@1.77.8)(terser@5.31.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.25.2
|
'@babel/core': 7.25.2
|
||||||
@ -5412,6 +5444,10 @@ snapshots:
|
|||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
|
'@xicons/utils@0.1.4':
|
||||||
|
dependencies:
|
||||||
|
css-render: 0.13.9
|
||||||
|
|
||||||
acorn@8.12.1: {}
|
acorn@8.12.1: {}
|
||||||
|
|
||||||
agent-base@7.1.1:
|
agent-base@7.1.1:
|
||||||
@ -5770,6 +5806,12 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
postcss: 8.4.40
|
postcss: 8.4.40
|
||||||
|
|
||||||
|
css-render@0.13.9:
|
||||||
|
dependencies:
|
||||||
|
'@emotion/hash': 0.8.0
|
||||||
|
'@types/node': 14.14.45
|
||||||
|
csstype: 3.0.11
|
||||||
|
|
||||||
css-render@0.15.14:
|
css-render@0.15.14:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@emotion/hash': 0.8.0
|
'@emotion/hash': 0.8.0
|
||||||
|
15
src/App.vue
15
src/App.vue
@ -1,10 +1,10 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
import { ref } from 'vue'
|
||||||
|
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from 'vue-i18n'
|
||||||
import { NConfigProvider, NDropdown } from "naive-ui";
|
import { NConfigProvider, NDropdown } from 'naive-ui'
|
||||||
const { locale } = useI18n();
|
const { locale } = useI18n()
|
||||||
const primaryColor = ref("#2B69A1");
|
const primaryColor = ref('#8B59F7')
|
||||||
const themeOverrides = ref({
|
const themeOverrides = ref({
|
||||||
common: {
|
common: {
|
||||||
primaryColorPressed: primaryColor,
|
primaryColorPressed: primaryColor,
|
||||||
@ -15,10 +15,7 @@ const themeOverrides = ref({
|
|||||||
primaryColor: primaryColor,
|
primaryColor: primaryColor,
|
||||||
primaryColorHover: primaryColor,
|
primaryColorHover: primaryColor,
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
BIN
src/assets/image/bg-mobile.png
Normal file
BIN
src/assets/image/bg-mobile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
BIN
src/assets/image/bg-pc.png
Normal file
BIN
src/assets/image/bg-pc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 104 KiB |
BIN
src/assets/images/header/logo.png
Normal file
BIN
src/assets/images/header/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
34
src/components/customDefaultPage/index.vue
Normal file
34
src/components/customDefaultPage/index.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useWindowSize } from '@vueuse/core'
|
||||||
|
|
||||||
|
import size375 from '@/components/customDefaultPage/size375/index.vue'
|
||||||
|
import size1920 from '@/components/customDefaultPage/size1920/index.vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const { width } = useWindowSize()
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const viewComponent = computed(() => {
|
||||||
|
const viewWidth = width.value
|
||||||
|
if (viewWidth <= 450) {
|
||||||
|
return size375
|
||||||
|
}
|
||||||
|
// else if (viewWidth <= 1100) {
|
||||||
|
// return size768;
|
||||||
|
// } else if (viewWidth <= 1500) {
|
||||||
|
// return size1440;
|
||||||
|
// }
|
||||||
|
else if (viewWidth <= 1920 || viewWidth > 1920) {
|
||||||
|
return size1920
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component :is="viewComponent" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
18
src/components/customDefaultPage/size1920/index.vue
Normal file
18
src/components/customDefaultPage/size1920/index.vue
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 通用缺省页 -->
|
||||||
|
<div class="custom-default-page">
|
||||||
|
<div class="search-area">
|
||||||
|
<customSelectSearch></customSelectSearch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import customSelectSearch from '@/components/customSelectSearch/index.vue'
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.search-area {
|
||||||
|
width: 300px;
|
||||||
|
margin: 100px 300px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
18
src/components/customDefaultPage/size375/index.vue
Normal file
18
src/components/customDefaultPage/size375/index.vue
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 通用缺省页 -->
|
||||||
|
<div class="custom-default-page">
|
||||||
|
<div class="search-area">
|
||||||
|
<customSelectSearch></customSelectSearch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import customSelectSearch from '@/components/customSelectSearch/index.vue'
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.search-area {
|
||||||
|
width: 1500px;
|
||||||
|
margin: 500px 200px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
34
src/components/customFooter/index.vue
Normal file
34
src/components/customFooter/index.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useWindowSize } from '@vueuse/core'
|
||||||
|
|
||||||
|
import size375 from '@/components/customFooter/size375/index.vue'
|
||||||
|
import size1920 from '@/components/customFooter/size1920/index.vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const { width } = useWindowSize()
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const viewComponent = computed(() => {
|
||||||
|
const viewWidth = width.value
|
||||||
|
if (viewWidth <= 450) {
|
||||||
|
return size375
|
||||||
|
}
|
||||||
|
// else if (viewWidth <= 1100) {
|
||||||
|
// return size768;
|
||||||
|
// } else if (viewWidth <= 1500) {
|
||||||
|
// return size1440;
|
||||||
|
// }
|
||||||
|
else if (viewWidth <= 1920 || viewWidth > 1920) {
|
||||||
|
return size1920
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component :is="viewComponent" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
26
src/components/customFooter/size1920/index.vue
Normal file
26
src/components/customFooter/size1920/index.vue
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 通用页脚 -->
|
||||||
|
<div class="custom-footer">
|
||||||
|
<span>Copyright © 2024-2027 FiEE</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.custom-footer {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 24px 0;
|
||||||
|
color: #888;
|
||||||
|
font-size: 15px;
|
||||||
|
background: #f7f8fa;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
border-top: 1px solid #ececec;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
26
src/components/customFooter/size375/index.vue
Normal file
26
src/components/customFooter/size375/index.vue
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 通用页脚 -->
|
||||||
|
<div class="custom-footer">
|
||||||
|
<span>Copyright © 2024-2027 FiEE</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.custom-footer {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 120px 0;
|
||||||
|
color: #888;
|
||||||
|
font-size: 75px;
|
||||||
|
background: #f7f8fa;
|
||||||
|
letter-spacing: 5px;
|
||||||
|
border-top: 5px solid #ececec;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
34
src/components/customHeader/index.vue
Normal file
34
src/components/customHeader/index.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useWindowSize } from '@vueuse/core'
|
||||||
|
|
||||||
|
import size375 from '@/components/customHeader/size375/index.vue'
|
||||||
|
import size1920 from '@/components/customHeader/size1920/index.vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const { width } = useWindowSize()
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const viewComponent = computed(() => {
|
||||||
|
const viewWidth = width.value
|
||||||
|
if (viewWidth <= 450) {
|
||||||
|
return size375
|
||||||
|
}
|
||||||
|
// else if (viewWidth <= 1100) {
|
||||||
|
// return size768;
|
||||||
|
// } else if (viewWidth <= 1500) {
|
||||||
|
// return size1440;
|
||||||
|
// }
|
||||||
|
else if (viewWidth <= 1920 || viewWidth > 1920) {
|
||||||
|
return size1920
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component :is="viewComponent" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
203
src/components/customHeader/size1920/index.vue
Normal file
203
src/components/customHeader/size1920/index.vue
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 通用页头 -->
|
||||||
|
<NLayoutHeader
|
||||||
|
class="custom-header"
|
||||||
|
:class="{ 'header-scrolled': isScrolled }"
|
||||||
|
>
|
||||||
|
<div class="header-container">
|
||||||
|
<div class="logo">
|
||||||
|
<NImage width="108" height="33" :src="FiEELogo" preview-disabled />
|
||||||
|
</div>
|
||||||
|
<div class="header-menu">
|
||||||
|
<NMenu
|
||||||
|
mode="horizontal"
|
||||||
|
:options="menuOptions"
|
||||||
|
:inverted="isScrolled"
|
||||||
|
@update:value="handleMenuSelect"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</NLayoutHeader>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import FiEELogo from '@/assets/images/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'
|
||||||
|
const { t } = useI18n()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const isScrolled = ref(false)
|
||||||
|
|
||||||
|
// 递归查找菜单项
|
||||||
|
function findMenuOptionByKey(options, key) {
|
||||||
|
for (const option of options) {
|
||||||
|
if (option.key === key) return option
|
||||||
|
if (option.children) {
|
||||||
|
const found = findMenuOptionByKey(option.children, key)
|
||||||
|
if (found) return found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 菜单点击跳转
|
||||||
|
const handleMenuSelect = (key) => {
|
||||||
|
const option = findMenuOptionByKey(menuOptions, key)
|
||||||
|
if (option && option.href) {
|
||||||
|
router.push(option.href)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 菜单配置
|
||||||
|
const menuOptions = [
|
||||||
|
{
|
||||||
|
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.business_introduction'),
|
||||||
|
key: 'business_introduction',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.corporate_information.management'),
|
||||||
|
key: 'management',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.corporate_information.board_of_directors'),
|
||||||
|
key: 'board_of_directors',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.corporate_information.committee_appointments'),
|
||||||
|
key: 'committee_appointments',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.corporate_information.governance'),
|
||||||
|
key: 'governance',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.corporate_information.corporate_video'),
|
||||||
|
key: 'corporate_video',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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.quarterly_results'),
|
||||||
|
key: 'quarterly_results',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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.historic_stock_price'),
|
||||||
|
key: 'historic_stock_price',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.stock_information.investment_calculator'),
|
||||||
|
key: 'investment_calculator',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.news_releases.title'),
|
||||||
|
key: 'news_releases',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: t('header_menu.news_releases.press_releases'),
|
||||||
|
key: 'press_releases',
|
||||||
|
href: '/new-releases',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.news_releases.events_calendar'),
|
||||||
|
key: 'events_calendar',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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.email_alerts'),
|
||||||
|
key: 'email_alerts',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// 监听滚动事件
|
||||||
|
const handleScroll = () => {
|
||||||
|
//滚动距离大于100px时,处理对应的header样式
|
||||||
|
isScrolled.value = window.scrollY >= 100
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
window.addEventListener('scroll', handleScroll)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('scroll', handleScroll)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.custom-header {
|
||||||
|
--header-height: 80px;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
background: transparent;
|
||||||
|
height: var(--header-height);
|
||||||
|
|
||||||
|
&.header-scrolled {
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
271
src/components/customHeader/size375/index.vue
Normal file
271
src/components/customHeader/size375/index.vue
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 通用页头 -->
|
||||||
|
<NLayoutHeader
|
||||||
|
class="custom-header"
|
||||||
|
:class="{ 'header-scrolled': isScrolled }"
|
||||||
|
>
|
||||||
|
<div class="header-container">
|
||||||
|
<div class="logo">
|
||||||
|
<NImage
|
||||||
|
style="width: 108px; height: 33px; max-width: 100%;"
|
||||||
|
:src="FiEELogo"
|
||||||
|
preview-disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="menu-btn" @click="toggleMenu">
|
||||||
|
<n-icon size="28">
|
||||||
|
<menu-outline />
|
||||||
|
</n-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</NLayoutHeader>
|
||||||
|
<transition name="fade-slide">
|
||||||
|
<div v-if="showMenu" class="mobile-menu-wrapper" @click.self="closeMenu">
|
||||||
|
<NMenu
|
||||||
|
mode="vertical"
|
||||||
|
:options="menuOptions"
|
||||||
|
:inverted="isScrolled"
|
||||||
|
class="mobile-menu"
|
||||||
|
accordion
|
||||||
|
@update:value="handleMenuSelect"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import FiEELogo from '@/assets/images/header/logo.png'
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
import { NMenu, NLayoutHeader, NImage, NIcon } from 'naive-ui'
|
||||||
|
import { MenuOutline } from '@vicons/ionicons5'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
const { t } = useI18n()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const isScrolled = ref(false)
|
||||||
|
const showMenu = ref(false)
|
||||||
|
|
||||||
|
const toggleMenu = () => {
|
||||||
|
showMenu.value = !showMenu.value
|
||||||
|
}
|
||||||
|
const closeMenu = () => {
|
||||||
|
showMenu.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归查找菜单项
|
||||||
|
function findMenuOptionByKey(options, key) {
|
||||||
|
for (const option of options) {
|
||||||
|
if (option.key === key) return option
|
||||||
|
if (option.children) {
|
||||||
|
const found = findMenuOptionByKey(option.children, key)
|
||||||
|
if (found) return found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 菜单点击跳转
|
||||||
|
const handleMenuSelect = (key) => {
|
||||||
|
const option = findMenuOptionByKey(menuOptions, key)
|
||||||
|
if (option && option.href) {
|
||||||
|
router.push(option.href)
|
||||||
|
showMenu.value = false // 跳转后收起菜单
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 菜单配置
|
||||||
|
const menuOptions = [
|
||||||
|
{
|
||||||
|
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.business_introduction'),
|
||||||
|
key: 'business_introduction',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.corporate_information.management'),
|
||||||
|
key: 'management',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.corporate_information.board_of_directors'),
|
||||||
|
key: 'board_of_directors',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.corporate_information.committee_appointments'),
|
||||||
|
key: 'committee_appointments',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.corporate_information.governance'),
|
||||||
|
key: 'governance',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.corporate_information.corporate_video'),
|
||||||
|
key: 'corporate_video',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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.quarterly_results'),
|
||||||
|
key: 'quarterly_results',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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.historic_stock_price'),
|
||||||
|
key: 'historic_stock_price',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.stock_information.investment_calculator'),
|
||||||
|
key: 'investment_calculator',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.news_releases.title'),
|
||||||
|
key: 'news_releases',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: t('header_menu.news_releases.press_releases'),
|
||||||
|
key: 'press_releases',
|
||||||
|
href: '/new-releases',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('header_menu.news_releases.events_calendar'),
|
||||||
|
key: 'events_calendar',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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.email_alerts'),
|
||||||
|
key: 'email_alerts',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// 监听滚动事件
|
||||||
|
const handleScroll = () => {
|
||||||
|
//滚动距离大于100px时,处理对应的header样式
|
||||||
|
isScrolled.value = window.scrollY >= 100
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
window.addEventListener('scroll', handleScroll)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('scroll', handleScroll)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.custom-header {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
background: transparent;
|
||||||
|
height: 320px;
|
||||||
|
|
||||||
|
&.header-scrolled {
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-container {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 80px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo :deep(.n-image) {
|
||||||
|
max-width: 100px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #465564;
|
||||||
|
font-size: 75px;
|
||||||
|
padding: 40px 70px;
|
||||||
|
border-radius: 30px;
|
||||||
|
background: #f7f8fa;
|
||||||
|
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.03);
|
||||||
|
user-select: none;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
.menu-btn:active {
|
||||||
|
background: #ececec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-menu-wrapper {
|
||||||
|
position: fixed;
|
||||||
|
top: 320px;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 1100;
|
||||||
|
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08);
|
||||||
|
padding: 40px 0 80px 0;
|
||||||
|
max-height: 1500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-slide-enter-active,
|
||||||
|
.fade-slide-leave-active {
|
||||||
|
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
.fade-slide-enter-from,
|
||||||
|
.fade-slide-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-50px);
|
||||||
|
}
|
||||||
|
</style>
|
38
src/components/customSelectSearch/index.vue
Normal file
38
src/components/customSelectSearch/index.vue
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<div class="custom-select-search">
|
||||||
|
<n-select
|
||||||
|
:options="state.selectOptions"
|
||||||
|
v-model:value="state.selectedValue"
|
||||||
|
/>
|
||||||
|
<n-input
|
||||||
|
v-model:value="state.inputValue"
|
||||||
|
type="text"
|
||||||
|
placeholder="Search"
|
||||||
|
/>
|
||||||
|
<n-button type="primary">Go</n-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
import { NSelect, NInput, NButton } from 'naive-ui'
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
selectedValue: 'all_years', //选中值
|
||||||
|
selectOptions: [
|
||||||
|
{
|
||||||
|
label: 'All Years',
|
||||||
|
value: 'all_years',
|
||||||
|
},
|
||||||
|
], //下拉选项
|
||||||
|
inputValue: '', //输入值
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.custom-select-search {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -464,6 +464,7 @@ export default {
|
|||||||
note: 'Minim representatives (other than authorized speakers) who receive inquiries from the media, market professionals, or shareholders should not respond to such inquiries but should refer the inquirer to an authorized speaker. However, Minim representatives assigned to the Investor Relations and Marketing teams may respond to routine inquiries about public information in accordance with guidelines established by authorized speakers from time to time.'
|
note: 'Minim representatives (other than authorized speakers) who receive inquiries from the media, market professionals, or shareholders should not respond to such inquiries but should refer the inquirer to an authorized speaker. However, Minim representatives assigned to the Investor Relations and Marketing teams may respond to routine inquiries about public information in accordance with guidelines established by authorized speakers from time to time.'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
financialinformation: {
|
financialinformation: {
|
||||||
secfilings: {
|
secfilings: {
|
||||||
title: 'Financials',
|
title: 'Financials',
|
||||||
@ -490,5 +491,38 @@ export default {
|
|||||||
},
|
},
|
||||||
download: 'Download'
|
download: 'Download'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
header_menu: {
|
||||||
|
corporate_information: {
|
||||||
|
title: 'Corporate Information',
|
||||||
|
company_overview: 'Company Overview',
|
||||||
|
business_introduction: 'Business Introduction',
|
||||||
|
management: 'Management',
|
||||||
|
board_of_directors: 'Board of Directors',
|
||||||
|
committee_appointments: 'Committee Appointments',
|
||||||
|
governance: 'Governance',
|
||||||
|
corporate_video: 'Corporate Video'
|
||||||
|
},
|
||||||
|
financial_information: {
|
||||||
|
title: 'Financial Information',
|
||||||
|
sec_filings: 'SEC Filings',
|
||||||
|
quarterly_results: 'Quarterly Results',
|
||||||
|
},
|
||||||
|
stock_information: {
|
||||||
|
title: 'Stock Information',
|
||||||
|
stock_quote: 'Stock Quote',
|
||||||
|
historic_stock_price: 'Historic Stock Price',
|
||||||
|
investment_calculator: 'Investment Calculator'
|
||||||
|
},
|
||||||
|
news_releases: {
|
||||||
|
title: 'News Releases',
|
||||||
|
press_releases: 'Press Releases',
|
||||||
|
events_calendar: 'Events Calendar'
|
||||||
|
},
|
||||||
|
investor_resources: {
|
||||||
|
title: 'Investor Resources',
|
||||||
|
ir_contacts: 'IR Contacts',
|
||||||
|
email_alerts: 'Email Alerts'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,10 +5,6 @@ import { setupRouterGuards } from './router-guards';
|
|||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
redirect: 'home'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/home',
|
|
||||||
name: 'home',
|
name: 'home',
|
||||||
component: () => import('@/views/home/index.vue'),
|
component: () => import('@/views/home/index.vue'),
|
||||||
// beforeEnter: (to, from, next) => {
|
// beforeEnter: (to, from, next) => {
|
||||||
@ -16,6 +12,18 @@ const routes = [
|
|||||||
// localStorage.clear()
|
// localStorage.clear()
|
||||||
// next()
|
// next()
|
||||||
// }
|
// }
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'new-releases',
|
||||||
|
name: 'new-releases',
|
||||||
|
component: () => import('@/views/new-releases/index.vue')
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/contacts',
|
||||||
|
name: 'contacts',
|
||||||
|
component: () => import('@/views/contacts/index.vue'),
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// path: '/companyprofil',
|
// path: '/companyprofil',
|
||||||
|
34
src/views/contacts/index.vue
Normal file
34
src/views/contacts/index.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
import { useWindowSize } from "@vueuse/core";
|
||||||
|
|
||||||
|
import size375 from "@/views/contacts/size375/index.vue";
|
||||||
|
import size768 from "@/views/contacts/size768/index.vue";
|
||||||
|
import size1440 from "@/views/contacts/size1440/index.vue";
|
||||||
|
import size1920 from "@/views/contacts/size1920/index.vue";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const { width } = useWindowSize();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const viewComponent = computed(() => {
|
||||||
|
const viewWidth = width.value;
|
||||||
|
if (viewWidth <= 450) {
|
||||||
|
return size375;
|
||||||
|
} else if (viewWidth <= 1100) {
|
||||||
|
return size768;
|
||||||
|
} else if (viewWidth <= 1500) {
|
||||||
|
return size1440;
|
||||||
|
} else if (viewWidth <= 1920 || viewWidth > 1920) {
|
||||||
|
return size1920;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component :is="viewComponent" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
22
src/views/contacts/size1440/index.vue
Normal file
22
src/views/contacts/size1440/index.vue
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<script setup>
|
||||||
|
import { NCarousel, NDivider, NMarquee, NPopselect } from "naive-ui";
|
||||||
|
import { onUnmounted, ref, watch, onMounted, computed } from "vue";
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<header className="header">
|
||||||
|
1440
|
||||||
|
</header>
|
||||||
|
<main ref="main">
|
||||||
|
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
50
src/views/contacts/size1920/index.vue
Normal file
50
src/views/contacts/size1920/index.vue
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<script setup>
|
||||||
|
import { NCarousel, NDivider, NMarquee, NPopselect } from "naive-ui";
|
||||||
|
import { onUnmounted, ref, watch, onMounted, computed } from "vue";
|
||||||
|
|
||||||
|
function copyEmail() {
|
||||||
|
navigator.clipboard.writeText('fiee@dlkadvisory.com');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<header className="header">
|
||||||
|
|
||||||
|
</header>
|
||||||
|
<main ref="main" class="flex-center min-h-80vh bg-[url('@/assets/image/bg-pc.png')] rounded-3xl to-accent w-100vw animate-fade-in">
|
||||||
|
<div class="w-full flex flex-col items-center gap-6 py-16 px-8">
|
||||||
|
<h1 class="text-5xl font-bold text-primary animate-fade-in-down animate-delay-0">Investor Contacts</h1>
|
||||||
|
<div class="text-3xl font-semibold text-gray-800 animate-fade-in-down animate-delay-200">FiEE Inc.</div>
|
||||||
|
<div class="text-2xl text-secondary animate-fade-in-down animate-delay-400">Investor Relations</div>
|
||||||
|
<div class="text-xl text-gray-600 flex items-center gap-2 animate-fade-in-down animate-delay-600">
|
||||||
|
<span>Email:</span>
|
||||||
|
<span class="transition-colors duration-300 cursor-pointer text-accent hover:text-primary active:text-secondary select-all" @click="copyEmail">fiee@dlkadvisory.com</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
/**** UnoCSS 动画补充(如未全局引入可在 uno.config.js 添加)****/
|
||||||
|
@keyframes fade-in-down {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-30px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.animate-fade-in-down {
|
||||||
|
animation: fade-in-down 0.8s cubic-bezier(0.23, 1, 0.32, 1) both;
|
||||||
|
}
|
||||||
|
.animate-delay-0 { animation-delay: 0s; }
|
||||||
|
.animate-delay-200 { animation-delay: 0.2s; }
|
||||||
|
.animate-delay-400 { animation-delay: 0.4s; }
|
||||||
|
.animate-delay-600 { animation-delay: 0.6s; }
|
||||||
|
</style>
|
||||||
|
|
49
src/views/contacts/size375/index.vue
Normal file
49
src/views/contacts/size375/index.vue
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<script setup>
|
||||||
|
import { onUnmounted, ref, watch, onMounted, computed } from "vue";
|
||||||
|
function copyEmail() {
|
||||||
|
navigator.clipboard.writeText('fiee@dlkadvisory.com');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<header class="header-mobile">
|
||||||
|
<!-- 可根据需要添加移动端头部内容 -->
|
||||||
|
</header>
|
||||||
|
<main ref="main" class="flex flex-col items-center from-white/80 to-white/40 backdrop-blur-md rounded-xl shadow-lg border border-gradient-to-br from-primary to-accent w-[100vw] mt-8 animate-fade-in px-4 py-8 bg-[url('@/assets/image/background.png')]">
|
||||||
|
<div class="w-full flex flex-col items-center gap-4 px-2">
|
||||||
|
<h1 class="text-2xl font-bold text-primary animate-fade-in-down animate-delay-0">Investor Contacts</h1>
|
||||||
|
<div class="text-lg font-semibold text-gray-800 animate-fade-in-down animate-delay-200">FiEE Inc.</div>
|
||||||
|
<div class="text-base text-secondary animate-fade-in-down animate-delay-400">Investor Relations</div>
|
||||||
|
<div class="text-sm text-gray-600 flex items-center gap-1 animate-fade-in-down animate-delay-600">
|
||||||
|
<span>Email:</span>
|
||||||
|
<span class="transition-colors duration-300 cursor-pointer text-accent hover:text-primary active:text-secondary select-all" @click="copyEmail">fiee@dlkadvisory.com</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer class="footer-mobile">
|
||||||
|
<!-- 可根据需要添加移动端底部内容 -->
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@keyframes fade-in-down {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-20px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.animate-fade-in-down {
|
||||||
|
animation: fade-in-down 0.8s cubic-bezier(0.23, 1, 0.32, 1) both;
|
||||||
|
}
|
||||||
|
.animate-delay-0 { animation-delay: 0s; }
|
||||||
|
.animate-delay-200 { animation-delay: 0.2s; }
|
||||||
|
.animate-delay-400 { animation-delay: 0.4s; }
|
||||||
|
.animate-delay-600 { animation-delay: 0.6s; }
|
||||||
|
|
||||||
|
.max-w-343px { max-width: 343px; }
|
||||||
|
</style>
|
||||||
|
|
22
src/views/contacts/size768/index.vue
Normal file
22
src/views/contacts/size768/index.vue
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<script setup>
|
||||||
|
import { NCarousel, NDivider, NMarquee, NPopselect } from "naive-ui";
|
||||||
|
import { onUnmounted, ref, watch, onMounted, computed } from "vue";
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<header className="header">
|
||||||
|
768
|
||||||
|
</header>
|
||||||
|
<main ref="main">
|
||||||
|
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -1,34 +1,12 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from "vue";
|
import customHeader from '@/components/customHeader/index.vue'
|
||||||
import { useWindowSize } from "@vueuse/core";
|
import customFooter from '@/components/customFooter/index.vue'
|
||||||
|
|
||||||
import size375 from "@/views/home/size375/index.vue";
|
|
||||||
import size768 from "@/views/home/size768/index.vue";
|
|
||||||
import size1440 from "@/views/home/size1440/index.vue";
|
|
||||||
import size1920 from "@/views/home/size1920/index.vue";
|
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
import { useI18n } from "vue-i18n";
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const { width } = useWindowSize();
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
const viewComponent = computed(() => {
|
|
||||||
const viewWidth = width.value;
|
|
||||||
if (viewWidth <= 450) {
|
|
||||||
return size375;
|
|
||||||
} else if (viewWidth <= 1100) {
|
|
||||||
return size768;
|
|
||||||
} else if (viewWidth <= 1500) {
|
|
||||||
return size1440;
|
|
||||||
} else if (viewWidth <= 1920 || viewWidth > 1920) {
|
|
||||||
return size1920;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<component :is="viewComponent" />
|
<customHeader />
|
||||||
|
<router-view />
|
||||||
|
<customFooter />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
|
@ -1,22 +1,17 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { NCarousel, NDivider, NMarquee, NPopselect } from "naive-ui";
|
import { NCarousel, NDivider, NMarquee, NPopselect } from 'naive-ui'
|
||||||
import { onUnmounted, ref, watch, onMounted, computed } from "vue";
|
import { onUnmounted, ref, watch, onMounted, computed } from 'vue'
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<header className="header">
|
<!-- <header className="header">
|
||||||
1920
|
1920
|
||||||
</header>
|
</header> -->
|
||||||
<main ref="main">
|
<main ref="main"></main>
|
||||||
|
|
||||||
</main>
|
|
||||||
<footer>
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
main {
|
||||||
|
padding: var(--header-height, 80px) 0 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -1,22 +1,17 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { NCarousel, NDivider, NMarquee, NPopselect } from "naive-ui";
|
import { NCarousel, NDivider, NMarquee, NPopselect } from 'naive-ui'
|
||||||
import { onUnmounted, ref, watch, onMounted, computed } from "vue";
|
import { onUnmounted, ref, watch, onMounted, computed } from 'vue'
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<header className="header">
|
<!-- <header className="header">
|
||||||
375
|
375
|
||||||
</header>
|
</header> -->
|
||||||
<main ref="main">
|
<main ref="main"></main>
|
||||||
|
|
||||||
</main>
|
|
||||||
<footer>
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
main {
|
||||||
|
padding: var(--header-height, 80px) 0 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
23
src/views/new-releases/index.vue
Normal file
23
src/views/new-releases/index.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<div class="new-releases-page">
|
||||||
|
<component :is="viewComponent" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import size1920 from '@/views/new-releases/size1920/index.vue'
|
||||||
|
import size375 from '@/views/new-releases/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>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
10
src/views/new-releases/size1920/index.vue
Normal file
10
src/views/new-releases/size1920/index.vue
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<template>
|
||||||
|
<div class="new-releases-page">
|
||||||
|
<customDefaultPage></customDefaultPage>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import customDefaultPage from '@/components/customDefaultPage/index.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
10
src/views/new-releases/size375/index.vue
Normal file
10
src/views/new-releases/size375/index.vue
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<template>
|
||||||
|
<div class="new-releases-page">
|
||||||
|
<customDefaultPage></customDefaultPage>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import customDefaultPage from '@/components/customDefaultPage/index.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
@ -21,6 +21,57 @@ export default defineConfig({
|
|||||||
[/^focus:(.*)$/, ([, style]) => ({ ':focus': { ...parseStyle(style) } })],
|
[/^focus:(.*)$/, ([, style]) => ({ ':focus': { ...parseStyle(style) } })],
|
||||||
// 处理 placeholder 伪元素
|
// 处理 placeholder 伪元素
|
||||||
[/^placeholder:(.*)$/, ([, style]) => ({ '::placeholder': { ...parseStyle(style) } })],
|
[/^placeholder:(.*)$/, ([, style]) => ({ '::placeholder': { ...parseStyle(style) } })],
|
||||||
|
// 自定义动画
|
||||||
|
['animate-bounce-in', { 'animation': 'bounce-in 0.9s cubic-bezier(0.23,1,0.32,1) both' }],
|
||||||
|
['animate-icon-in', { 'animation': 'icon-in 1s cubic-bezier(0.23,1,0.32,1) both' }],
|
||||||
|
['animate-bg-move', { 'animation': 'bg-move 8s linear infinite alternate', 'background-size': '200% 200%' }],
|
||||||
|
['animate-blob', { 'animation': 'blob 7s ease-in-out infinite alternate' }],
|
||||||
|
['animate-blob2', { 'animation': 'blob2 9s ease-in-out infinite alternate' }],
|
||||||
|
['animate-bubble-pop', { 'animation': 'bubble-pop 0.5s cubic-bezier(0.23,1,0.32,1) both' }],
|
||||||
|
// 动画延迟
|
||||||
|
['animate-delay-0', { 'animation-delay': '0s' }],
|
||||||
|
['animate-delay-200', { 'animation-delay': '0.2s' }],
|
||||||
|
['animate-delay-400', { 'animation-delay': '0.4s' }],
|
||||||
|
['animate-delay-600', { 'animation-delay': '0.6s' }],
|
||||||
|
],
|
||||||
|
// 自定义keyframes
|
||||||
|
safelist: [
|
||||||
|
'animate-bounce-in', 'animate-icon-in', 'animate-bg-move', 'animate-blob', 'animate-blob2', 'animate-bubble-pop',
|
||||||
|
'animate-delay-0', 'animate-delay-200', 'animate-delay-400', 'animate-delay-600',
|
||||||
|
],
|
||||||
|
preflights: [
|
||||||
|
{
|
||||||
|
getCSS: () => `
|
||||||
|
@keyframes bounce-in {
|
||||||
|
0% { opacity: 0; transform: scale(0.7) translateY(-40px); }
|
||||||
|
60% { opacity: 1; transform: scale(1.1) translateY(10px); }
|
||||||
|
100% { opacity: 1; transform: scale(1) translateY(0); }
|
||||||
|
}
|
||||||
|
@keyframes icon-in {
|
||||||
|
0% { opacity: 0; transform: scale(0.2) rotate(-30deg); }
|
||||||
|
80% { opacity: 1; transform: scale(1.2) rotate(10deg); }
|
||||||
|
100% { opacity: 1; transform: scale(1) rotate(0); }
|
||||||
|
}
|
||||||
|
@keyframes bg-move {
|
||||||
|
0% { background-position: 0% 50%; }
|
||||||
|
100% { background-position: 100% 50%; }
|
||||||
|
}
|
||||||
|
@keyframes blob {
|
||||||
|
0%,100% { transform: scale(1) translate(0,0); }
|
||||||
|
33% { transform: scale(1.1,0.9) translate(20px,10px); }
|
||||||
|
66% { transform: scale(0.9,1.1) translate(-10px,-20px); }
|
||||||
|
}
|
||||||
|
@keyframes blob2 {
|
||||||
|
0%,100% { transform: scale(1) translate(0,0); }
|
||||||
|
50% { transform: scale(1.2) translate(10px,20px); }
|
||||||
|
}
|
||||||
|
@keyframes bubble-pop {
|
||||||
|
0% { opacity: 0; transform: scale(0.5) translateY(10px); }
|
||||||
|
60% { opacity: 1; transform: scale(1.1) translateY(-4px); }
|
||||||
|
100% { opacity: 1; transform: scale(1) translateY(0); }
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
],
|
],
|
||||||
shortcuts: {
|
shortcuts: {
|
||||||
'flex-center': 'flex justify-center items-center',
|
'flex-center': 'flex justify-center items-center',
|
||||||
|
Loading…
Reference in New Issue
Block a user