Merge remote-tracking branch 'refs/remotes/origin/feature/project_dedtail' into main
Conflicts: index.html src/components/common/Navbar.vue src/components/company/AboutUs.vue src/components/projects/ProjectShowcase.vue src/components/timeline/CompanyTimeline.vue src/locales/ja.ts src/locales/zh.ts src/views/HomePage.vue
This commit is contained in:
commit
86e1a600a7
33
index.html
33
index.html
|
@ -1,16 +1,17 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<link rel="preload" as="image" href="/src/assets/images/hero-bg.jpg" fetchpriority="high">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>优阅工作室</title>
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<!--<link rel="preload" as="image" href="/src/assets/images/hero-bg.jpg" fetchpriority="high">-->
|
||||
<link rel="preload" as="image" href="images/hero-bg.jpg" fetchpriority="high">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>优阅工作室</title>
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 197 KiB |
Binary file not shown.
After Width: | Height: | Size: 655 KiB |
|
@ -1,308 +1,321 @@
|
|||
<template>
|
||||
<header class="navbar-container" :class="{ scrolled: isScrolled }">
|
||||
<div class="container">
|
||||
<div class="logo">
|
||||
<a href="#home">{{ t('nav.home') }}</a>
|
||||
</div>
|
||||
<nav>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#home">{{ t('nav.home') }}</a></li>
|
||||
<li><a href="#about">{{ t('nav.about') }}</a></li>
|
||||
<li><a href="#team">{{ t('nav.team') }}</a></li>
|
||||
<li><a href="#projects">{{ t('nav.projects') }}</a></li>
|
||||
<li><a href="#contact">{{ t('nav.contact') }}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="language-switcher">
|
||||
<button @click="toggleLanguage" class="language-btn">
|
||||
{{ currentLanguage === 'zh' ? '日本語' : '中文' }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="mobile-menu-btn">
|
||||
<button @click="toggleMobileMenu">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="3" y1="12" x2="21" y2="12"></line>
|
||||
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||||
<line x1="3" y1="18" x2="21" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mobile-menu" v-if="isMobileMenuOpen">
|
||||
<ul class="mobile-nav-links">
|
||||
<li><a href="#home" @click="closeMobileMenu">{{ t('nav.home') }}</a></li>
|
||||
<li><a href="#about" @click="closeMobileMenu">{{ t('nav.about') }}</a></li>
|
||||
<li><a href="#team" @click="closeMobileMenu">{{ t('nav.team') }}</a></li>
|
||||
<li><a href="#projects" @click="closeMobileMenu">{{ t('nav.projects') }}</a></li>
|
||||
<li><a href="#contact" @click="closeMobileMenu">{{ t('nav.contact') }}</a></li>
|
||||
<li>
|
||||
<button @click="toggleLanguage" class="mobile-language-btn">
|
||||
{{ currentLanguage === 'zh' ? '日本語' : '中文' }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, inject, onMounted, onUnmounted } from 'vue'
|
||||
import { useLanguageStore } from '../../store/language'
|
||||
|
||||
export interface NavbarProps {
|
||||
// 可以在这里定义props
|
||||
}
|
||||
|
||||
const store = useLanguageStore()
|
||||
const currentLanguage = computed(() => store.currentLanguage)
|
||||
const isMobileMenuOpen = ref(false)
|
||||
const isScrolled = ref(false)
|
||||
// 注入翻译函数
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
|
||||
// 滚动监听处理函数
|
||||
const handleScroll = () => {
|
||||
isScrolled.value = window.scrollY > 50
|
||||
}
|
||||
|
||||
// 组件挂载时添加滚动监听
|
||||
onMounted(() => {
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
})
|
||||
|
||||
// 组件卸载时移除滚动监听
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
})
|
||||
|
||||
const toggleLanguage = () => {
|
||||
store.toggleLanguage()
|
||||
}
|
||||
|
||||
const toggleMobileMenu = () => {
|
||||
isMobileMenuOpen.value = !isMobileMenuOpen.value
|
||||
}
|
||||
|
||||
const closeMobileMenu = () => {
|
||||
isMobileMenuOpen.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.navbar-container {
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
padding: 1rem 0;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
box-shadow: var(--shadow);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.navbar-container.scrolled {
|
||||
/* background-color: rgba(26, 26, 46, 0.95);
|
||||
padding: 0.8rem 0; */
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.logo a {
|
||||
color: var(--text-color);
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nav-links li {
|
||||
margin-left: 2rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: var(--text-color);
|
||||
text-decoration: none;
|
||||
transition: var(--transition);
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-links a::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background-color: var(--primary-color);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.nav-links a:hover::after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.language-switcher {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.language-btn {
|
||||
background-color: transparent;
|
||||
color: var(--text-color);
|
||||
border: 1px solid var(--border-color);
|
||||
padding: 0.5rem 1rem;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.language-btn:hover {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border-color: var(--primary-color);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.mobile-menu-btn {
|
||||
display: none;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: var(--text-color);
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 6px;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.mobile-menu-btn:hover {
|
||||
background-color: var(--bg-card);
|
||||
}
|
||||
|
||||
.mobile-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg-color);
|
||||
padding: 1rem;
|
||||
display: none;
|
||||
box-shadow: var(--shadow-lg);
|
||||
border-top: 1px solid var(--border-color);
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-nav-links {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mobile-nav-links li {
|
||||
margin-bottom: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.mobile-nav-links li:last-child {
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.mobile-nav-links a {
|
||||
color: var(--text-color);
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 0.5rem 0;
|
||||
font-weight: 500;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.mobile-nav-links a:hover {
|
||||
color: var(--primary-color);
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.mobile-language-btn {
|
||||
background-color: transparent;
|
||||
color: var(--text-color);
|
||||
border: 1px solid var(--border-color);
|
||||
padding: 0.5rem 1rem;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.mobile-language-btn:hover {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-links {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.language-switcher {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-menu-btn {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mobile-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.navbar-container.scrolled {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navbar-container{
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
<template>
|
||||
<header class="navbar-container" :class="{ scrolled: isScrolled }">
|
||||
<div class="container">
|
||||
<div class="logo">
|
||||
<img src="/images/logo.png" alt="Company Logo" class="logo-image">
|
||||
<a href="#home">{{ t('nav.name') }}</a>
|
||||
</div>
|
||||
<nav>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#home">{{ t('nav.home') }}</a></li>
|
||||
<li><a href="#about">{{ t('nav.about') }}</a></li>
|
||||
<li><a href="#team">{{ t('nav.team') }}</a></li>
|
||||
<li><a href="#projects">{{ t('nav.projects') }}</a></li>
|
||||
<li><a href="#contact">{{ t('nav.contact') }}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="language-switcher">
|
||||
<button @click="toggleLanguage" class="language-btn">
|
||||
{{ currentLanguage === 'zh' ? '日本語' : '中文' }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="mobile-menu-btn">
|
||||
<button @click="toggleMobileMenu">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="3" y1="12" x2="21" y2="12"></line>
|
||||
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||||
<line x1="3" y1="18" x2="21" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mobile-menu" v-if="isMobileMenuOpen">
|
||||
<ul class="mobile-nav-links">
|
||||
<li><a href="#home" @click="closeMobileMenu">{{ t('nav.home') }}</a></li>
|
||||
<li><a href="#about" @click="closeMobileMenu">{{ t('nav.about') }}</a></li>
|
||||
<li><a href="#team" @click="closeMobileMenu">{{ t('nav.team') }}</a></li>
|
||||
<li><a href="#projects" @click="closeMobileMenu">{{ t('nav.projects') }}</a></li>
|
||||
<li><a href="#contact" @click="closeMobileMenu">{{ t('nav.contact') }}</a></li>
|
||||
<li>
|
||||
<button @click="toggleLanguage" class="mobile-language-btn">
|
||||
{{ currentLanguage === 'zh' ? '日本語' : '中文' }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, inject, onMounted, onUnmounted } from 'vue'
|
||||
import { useLanguageStore } from '../../store/language'
|
||||
|
||||
export interface NavbarProps {
|
||||
// 可以在这里定义props
|
||||
}
|
||||
|
||||
const store = useLanguageStore()
|
||||
const currentLanguage = computed(() => store.currentLanguage)
|
||||
const isMobileMenuOpen = ref(false)
|
||||
const isScrolled = ref(false)
|
||||
// 注入翻译函数
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
|
||||
// 滚动监听处理函数
|
||||
const handleScroll = () => {
|
||||
isScrolled.value = window.scrollY > 50
|
||||
}
|
||||
|
||||
// 组件挂载时添加滚动监听
|
||||
onMounted(() => {
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
})
|
||||
|
||||
// 组件卸载时移除滚动监听
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
})
|
||||
|
||||
const toggleLanguage = () => {
|
||||
store.toggleLanguage()
|
||||
}
|
||||
|
||||
const toggleMobileMenu = () => {
|
||||
isMobileMenuOpen.value = !isMobileMenuOpen.value
|
||||
}
|
||||
|
||||
const closeMobileMenu = () => {
|
||||
isMobileMenuOpen.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.navbar-container {
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
padding: 1rem 0;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
box-shadow: var(--shadow);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.navbar-container.scrolled {
|
||||
/* background-color: rgba(26, 26, 46, 0.95);
|
||||
padding: 0.8rem 0; */
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex; /* 让Logo和文字横向排列 */
|
||||
align-items: center; /* 垂直居中对齐 */
|
||||
gap: 0.5rem; /* Logo与文字间距 */
|
||||
}
|
||||
|
||||
.logo-image {
|
||||
width: 60px; /* Logo宽度,根据需要调整 */
|
||||
height: 55px; /* 自定义高度,不受宽高比限制 */
|
||||
/*height: auto; 保持宽高比 */
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.logo a {
|
||||
color: var(--text-color);
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nav-links li {
|
||||
margin-left: 2rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: var(--text-color);
|
||||
text-decoration: none;
|
||||
transition: var(--transition);
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-links a::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background-color: var(--primary-color);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.nav-links a:hover::after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.language-switcher {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.language-btn {
|
||||
background-color: transparent;
|
||||
color: var(--text-color);
|
||||
border: 1px solid var(--border-color);
|
||||
padding: 0.5rem 1rem;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.language-btn:hover {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border-color: var(--primary-color);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.mobile-menu-btn {
|
||||
display: none;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: var(--text-color);
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 6px;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.mobile-menu-btn:hover {
|
||||
background-color: var(--bg-card);
|
||||
}
|
||||
|
||||
.mobile-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg-color);
|
||||
padding: 1rem;
|
||||
display: none;
|
||||
box-shadow: var(--shadow-lg);
|
||||
border-top: 1px solid var(--border-color);
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-nav-links {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mobile-nav-links li {
|
||||
margin-bottom: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.mobile-nav-links li:last-child {
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.mobile-nav-links a {
|
||||
color: var(--text-color);
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 0.5rem 0;
|
||||
font-weight: 500;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.mobile-nav-links a:hover {
|
||||
color: var(--primary-color);
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.mobile-language-btn {
|
||||
background-color: transparent;
|
||||
color: var(--text-color);
|
||||
border: 1px solid var(--border-color);
|
||||
padding: 0.5rem 1rem;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.mobile-language-btn:hover {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-links {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.language-switcher {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-menu-btn {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mobile-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.navbar-container.scrolled {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navbar-container{
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,262 +1,264 @@
|
|||
<template>
|
||||
<section id="about" class="about-section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">{{ t('about.title') }}</h2>
|
||||
<div class="about-content">
|
||||
<p class="intro-text">{{ t('about.content') }}</p>
|
||||
|
||||
<div class="mission-vision">
|
||||
<div class="mission">
|
||||
<h3>{{ t('about.mission') }}</h3>
|
||||
<p>{{ t('about.missionContent') }}</p>
|
||||
</div>
|
||||
<div class="vision">
|
||||
<h3>{{ t('about.vision') }}</h3>
|
||||
<p>{{ t('about.visionContent') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="advantages">
|
||||
<h3>{{ t('about.advantages') }}</h3>
|
||||
<div class="advantages-grid">
|
||||
<div class="advantage-card">
|
||||
<div class="advantage-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
|
||||
<polyline points="2 17 12 22 22 17"></polyline>
|
||||
<polyline points="2 12 12 17 22 12"></polyline>
|
||||
</svg>
|
||||
</div>
|
||||
<h4>{{ t('about.advantage1') }}</h4>
|
||||
<p>Our team consists of highly skilled professionals with extensive experience in software development.</p>
|
||||
</div>
|
||||
<div class="advantage-card">
|
||||
<div class="advantage-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" 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>
|
||||
</div>
|
||||
<h4>{{ t('about.advantage2') }}</h4>
|
||||
<p>We prioritize our clients' needs and work closely with them to achieve their business objectives.</p>
|
||||
</div>
|
||||
<div class="advantage-card">
|
||||
<div class="advantage-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12 2L2 7l10 5 10-5-10-5z"></path>
|
||||
<path d="M2 17l10 5 10-5"></path>
|
||||
<path d="M2 12l10 5 10-5"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h4>{{ t('about.advantage3') }}</h4>
|
||||
<p>We constantly explore new technologies and methodologies to provide innovative solutions.</p>
|
||||
</div>
|
||||
<div class="advantage-card">
|
||||
<div class="advantage-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
|
||||
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h4>{{ t('about.advantage4') }}</h4>
|
||||
<p>We deliver projects on time and within budget, ensuring high quality and reliability.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
// import { useLanguageStore } from '../../store/language'
|
||||
|
||||
// 可以在这里添加组件逻辑
|
||||
// const store = useLanguageStore()
|
||||
|
||||
// 注入翻译函数
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.about-section {
|
||||
padding: 5rem 0;
|
||||
background-color: var(--bg-color);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 3rem;
|
||||
color: var(--text-color);
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.section-title::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 80px;
|
||||
height: 4px;
|
||||
background-color: var(--primary-color);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.about-content {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.8;
|
||||
margin-bottom: 3rem;
|
||||
text-align: center;
|
||||
color: var(--text-muted);
|
||||
max-width: 800px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.mission-vision {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 4rem;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.mission, .vision {
|
||||
flex: 1;
|
||||
background-color: var(--bg-card);
|
||||
padding: 2.5rem;
|
||||
border-radius: 12px;
|
||||
box-shadow: var(--shadow);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.mission:hover, .vision:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.mission h3, .vision h3 {
|
||||
color: var(--text-color);
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 1.75rem;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mission h3::after, .vision h3::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -8px;
|
||||
left: 0;
|
||||
width: 40px;
|
||||
height: 3px;
|
||||
background-color: var(--primary-color);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.mission p, .vision p {
|
||||
color: var(--text-muted);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.advantages {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.advantages h3 {
|
||||
text-align: center;
|
||||
color: var(--text-color);
|
||||
margin-bottom: 3rem;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.advantages-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 2.5rem;
|
||||
}
|
||||
|
||||
.advantage-card {
|
||||
background-color: var(--bg-card);
|
||||
padding: 2.5rem;
|
||||
border-radius: 12px;
|
||||
box-shadow: var(--shadow);
|
||||
text-align: center;
|
||||
transition: var(--transition);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.advantage-card:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.advantage-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 5px;
|
||||
background: linear-gradient(90deg, var(--primary-color), var(--primary-light));
|
||||
}
|
||||
|
||||
.advantage-icon {
|
||||
color: var(--primary-color);
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 1.5rem;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.advantage-card:hover .advantage-icon {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.advantage-card h4 {
|
||||
color: var(--text-color);
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.advantage-card p {
|
||||
color: var(--text-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.mission-vision {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.mission, .vision {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.advantages-grid {
|
||||
gap: 1.5rem;
|
||||
}
|
||||
}
|
||||
<template>
|
||||
<section id="about" class="about-section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">{{ t('about.title') }}</h2>
|
||||
<div class="about-content">
|
||||
<p class="intro-text">{{ t('about.content') }}</p>
|
||||
|
||||
<div class="mission-vision">
|
||||
<div class="mission">
|
||||
<h3>{{ t('about.mission') }}</h3>
|
||||
<p>{{ t('about.missionContent') }}</p>
|
||||
</div>
|
||||
<div class="vision">
|
||||
<h3>{{ t('about.vision') }}</h3>
|
||||
<p>{{ t('about.visionContent') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="advantages">
|
||||
<h3>{{ t('about.advantages') }}</h3>
|
||||
<div class="advantages-grid">
|
||||
<div class="advantage-card">
|
||||
<div class="advantage-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
|
||||
<polyline points="2 17 12 22 22 17"></polyline>
|
||||
<polyline points="2 12 12 17 22 12"></polyline>
|
||||
</svg>
|
||||
</div>
|
||||
<h4>{{ t('about.advantage1') }}</h4>
|
||||
<p>{{ t('about.advantage_explanation1') }}</p>
|
||||
</div>
|
||||
<div class="advantage-card">
|
||||
<div class="advantage-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" 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>
|
||||
</div>
|
||||
<h4>{{ t('about.advantage2') }}</h4>
|
||||
<p>{{ t('about.advantage_explanation2') }}</p>
|
||||
</div>
|
||||
<div class="advantage-card">
|
||||
<div class="advantage-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12 2L2 7l10 5 10-5-10-5z"></path>
|
||||
<path d="M2 17l10 5 10-5"></path>
|
||||
<path d="M2 12l10 5 10-5"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h4>{{ t('about.advantage3') }}</h4>
|
||||
<p>{{ t('about.advantage_explanation3') }}</p>
|
||||
</div>
|
||||
<div class="advantage-card">
|
||||
<div class="advantage-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
|
||||
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h4>{{ t('about.advantage4') }}</h4>
|
||||
<p>{{ t('about.advantage_explanation4') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
// import { useLanguageStore } from '../../store/language'
|
||||
|
||||
// 可以在这里添加组件逻辑
|
||||
// const store = useLanguageStore()
|
||||
|
||||
// 注入翻译函数
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.about-section {
|
||||
padding: 5rem 0;
|
||||
background-color: var(--bg-color);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 3rem;
|
||||
color: var(--text-color);
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.section-title::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 80px;
|
||||
height: 4px;
|
||||
background-color: var(--primary-color);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.about-content {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.intro-text {
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.8;
|
||||
margin-bottom: 3rem;
|
||||
text-align: center;
|
||||
color: var(--text-muted);
|
||||
max-width: 800px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.mission-vision {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 4rem;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.mission, .vision {
|
||||
flex: 1;
|
||||
background-color: var(--bg-card);
|
||||
padding: 2.5rem;
|
||||
border-radius: 12px;
|
||||
box-shadow: var(--shadow);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.mission:hover, .vision:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.mission h3, .vision h3 {
|
||||
color: var(--text-color);
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 1.75rem;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mission h3::after, .vision h3::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -8px;
|
||||
left: 0;
|
||||
width: 40px;
|
||||
height: 3px;
|
||||
background-color: var(--primary-color);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.mission p, .vision p {
|
||||
color: var(--text-muted);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.advantages {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.advantages h3 {
|
||||
text-align: center;
|
||||
color: var(--text-color);
|
||||
margin-bottom: 3rem;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.advantages-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 2.5rem;
|
||||
}
|
||||
|
||||
.advantage-card {
|
||||
background-color: var(--bg-card);
|
||||
padding: 2.5rem;
|
||||
border-radius: 12px;
|
||||
box-shadow: var(--shadow);
|
||||
text-align: center;
|
||||
transition: var(--transition);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.advantage-card:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.advantage-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 5px;
|
||||
background: linear-gradient(90deg, var(--primary-color), var(--primary-light));
|
||||
}
|
||||
|
||||
.advantage-icon {
|
||||
color: var(--primary-color);
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 1.5rem;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.advantage-card:hover .advantage-icon {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.advantage-card h4 {
|
||||
color: var(--text-color);
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.advantage-card p {
|
||||
color: var(--text-muted);
|
||||
line-height: 1.6;
|
||||
text-align: left; /* 文本左对齐 */
|
||||
margin: 0; /* 可选:移除默认外边距,使对齐更精确 */
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.mission-vision {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.mission, .vision {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.advantages-grid {
|
||||
gap: 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,230 +1,234 @@
|
|||
<template>
|
||||
<section id="projects" class="projects-section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">{{ t('projects.title') }}</h2>
|
||||
<div class="projects-grid">
|
||||
<div v-for="project in projects" :key="project.id" class="project-card">
|
||||
<div class="project-image">
|
||||
<img :src="project.image" alt="t(project.title)" />
|
||||
</div>
|
||||
<div class="project-info">
|
||||
<h3>{{ t(project.title) }}</h3>
|
||||
<p>{{ t(project.description) }}</p>
|
||||
<button class="view-details-btn" @click="openDetail(project)">{{ t('projects.viewDetails') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, inject } from 'vue'
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useLanguageStore } from '../../store/language';
|
||||
|
||||
|
||||
// 定义点击事件的方法
|
||||
const router = useRouter();
|
||||
const store = useLanguageStore();
|
||||
const openDetail = (project: Project) => {
|
||||
if (project.detailLink) {
|
||||
// 有 detailLink,打开外部链接(新标签页)
|
||||
window.open(project.detailLink, '_blank');
|
||||
} else if (project.detailPageKey) {
|
||||
// 有 detailPageKey,跳转内部路由(本项目页面)
|
||||
const currentLang = store.currentLanguage; // 从语言存储中获取当前语言
|
||||
console.log('当前语言:', currentLang); // 确认语言值是否为 'zh' 或 'jp'
|
||||
|
||||
// 根据当前语言构建路由名称
|
||||
const routeName = currentLang === 'zh'
|
||||
? `${project.detailPageKey}Detail`
|
||||
: `${project.detailPageKey}DetailJp`;
|
||||
console.log('生成的路由名称:', routeName); // 确认路由名称是否正确
|
||||
|
||||
// 检查路由是否存在
|
||||
const routeExists = router.getRoutes().some(route => route.name === routeName);
|
||||
console.log('路由是否存在:', routeExists);
|
||||
|
||||
// 跳转到对应路由,push方法是在半页面进行跳转
|
||||
//router.push({ name: routeName });
|
||||
|
||||
// 新代码:在新标签页打开
|
||||
const url = router.resolve({ name: routeName }).href;
|
||||
const fullUrl = window.location.origin + url; // 拼接协议和域名
|
||||
console.log('完整URL:', fullUrl); // 应为 http://localhost:5173/project3/zh
|
||||
window.open(url, '_blank');
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
export interface Project {
|
||||
id: number
|
||||
title: string
|
||||
description: string
|
||||
image: string
|
||||
detailLink?: string
|
||||
details: string
|
||||
detailPageKey?: string // 新增:用于内部路由跳转
|
||||
}
|
||||
|
||||
// 批量导入 src/assets 目录下所有符合规则的图片
|
||||
// 参数1:图片路径(@代表src目录,*为通配符)
|
||||
// 参数2:{ eager: true } 表示立即加载所有匹配的图片
|
||||
const imageModules = import.meta.glob('../../assets/project*.png', { eager: true })
|
||||
|
||||
// 转换为 { 图片ID: 图片路径 } 的映射表
|
||||
const imageMap: Record<number, string> = {}
|
||||
for (const path in imageModules) {
|
||||
// 从路径中提取图片ID(假设图片命名为 project1.png、project2.png...)
|
||||
const match = path.match(/project(\d+)\.png/)
|
||||
if (match) {
|
||||
const id = Number(match[1])
|
||||
// 存储图片路径(Vite 导入的图片默认在 default 属性中)
|
||||
imageMap[id] = (imageModules[path] as { default: string }).default
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟项目数据
|
||||
const projects = ref<Project[]>([
|
||||
{
|
||||
id: 1,
|
||||
title: "projects.project1.title",
|
||||
description: "projects.project1.description",
|
||||
image: imageMap[1], // 关联ID为1的图片
|
||||
detailLink: "https://www.jal.co.jp/jp/ja/?city=TYO", // 第1个项目的固定外部链接
|
||||
details: 'This project involved developing a full-featured e-commerce platform with payment integration, inventory management, and customer relationship management.',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "projects.project2.title",
|
||||
description: "projects.project2.description",
|
||||
image: imageMap[2], // 关联ID为2的图片
|
||||
detailLink: "https://agmiru.com/", // 第2个项目的固定外部链接
|
||||
details: 'We developed a secure mobile banking app with features like account management, fund transfers, bill payments, and financial analytics.',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "projects.project3.title",
|
||||
description: "projects.project3.description",
|
||||
image: imageMap[3], // 关联ID为3的图片
|
||||
detailPageKey: "project3", // 第3个项目的多语言详情页标识
|
||||
details: 'This project involved creating a healthcare management system that streamlines patient registration, appointment scheduling, medical records management, and billing.',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "projects.project4.title",
|
||||
description: "projects.project4.description",
|
||||
image: imageMap[4], // 关联ID为4的图片
|
||||
detailPageKey: "project4", // 第4个项目的多语言详情页标识
|
||||
details: 'We developed an ERP system that integrates various business functions including finance, human resources, supply chain, and customer relationship management.',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "projects.project5.title",
|
||||
description: "projects.project5.description",
|
||||
image: imageMap[5], // 关联ID为5的图片
|
||||
detailLink: "https://maps.gsi.go.jp/#5/36.104611/140.084556/&base=std&ls=std&disp=1&vs=c1g1j0h0k0l0u0t0z0r0s0m0f1", // 第5个项目的固定外部链接
|
||||
details: 'We developed an ERP system that integrates various business functions including finance, human resources, supply chain, and customer relationship management.',
|
||||
}
|
||||
|
||||
])
|
||||
|
||||
// 注入翻译函数
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.projects-section {
|
||||
padding: 5rem 0;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 3rem;
|
||||
color: #1a1a2e;
|
||||
}
|
||||
|
||||
.projects-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.project-card {
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.project-card:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.project-image {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.project-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.project-card:hover .project-image img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.project-info {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.project-info h3 {
|
||||
color: #1a1a2e;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.project-info p {
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 1.5rem;
|
||||
text-align: left; /* 添加此属性,强制内容左对齐 */
|
||||
}
|
||||
|
||||
.view-details-btn {
|
||||
background-color: #4cc9f0;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0.8rem 1.5rem;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.view-details-btn:hover {
|
||||
background-color: #4361ee;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.section-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
<template>
|
||||
<section id="projects" class="projects-section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">{{ t('projects.title') }}</h2>
|
||||
<div class="projects-grid">
|
||||
<div v-for="project in projects" :key="project.id" class="project-card">
|
||||
<div class="project-image">
|
||||
<img :src="project.image" alt="t(project.title)" />
|
||||
</div>
|
||||
<div class="project-info">
|
||||
<h3>{{ t(project.title) }}</h3>
|
||||
<p>{{ t(project.description) }}</p>
|
||||
<button class="view-details-btn" @click="openDetail(project)">{{ t('projects.viewDetails') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, inject } from 'vue'
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useLanguageStore } from '../../store/language';
|
||||
|
||||
|
||||
// 定义点击事件的方法
|
||||
const router = useRouter();
|
||||
const store = useLanguageStore();
|
||||
const openDetail = (project: Project) => {
|
||||
if (project.detailLink) {
|
||||
// 有 detailLink,打开外部链接(新标签页)
|
||||
window.open(project.detailLink, '_blank');
|
||||
} else if (project.detailPageKey) {
|
||||
// 有 detailPageKey,跳转内部路由(本项目页面)
|
||||
const currentLang = store.currentLanguage; // 从语言存储中获取当前语言
|
||||
//console.log('当前语言:', currentLang); // 确认语言值是否为 'zh' 或 'jp'
|
||||
|
||||
// 根据当前语言构建路由名称
|
||||
const routeName = currentLang === 'zh'
|
||||
? `${project.detailPageKey}Detail`
|
||||
: `${project.detailPageKey}DetailJp`;
|
||||
//console.log('生成的路由名称:', routeName); // 确认路由名称是否正确
|
||||
|
||||
// 检查路由是否存在
|
||||
//const routeExists = router.getRoutes().some(route => route.name === routeName);
|
||||
//console.log('路由是否存在:', routeExists);
|
||||
|
||||
|
||||
// 方法1:在新标签页打开
|
||||
const url = router.resolve({ name: routeName }).href;
|
||||
window.open(url, '_blank');
|
||||
|
||||
// 方法2:单页应用内跳转(替换原有的window.open逻辑)
|
||||
//router.push({
|
||||
//name: routeName,
|
||||
// 如果需要传递参数(比如项目ID),可以在这里添加
|
||||
// params: { id: project.id }
|
||||
// });
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
export interface Project {
|
||||
id: number
|
||||
title: string
|
||||
description: string
|
||||
image: string
|
||||
detailLink?: string
|
||||
details: string
|
||||
detailPageKey?: string // 新增:用于内部路由跳转
|
||||
}
|
||||
|
||||
// 批量导入 src/assets 目录下所有符合规则的图片
|
||||
// 参数1:图片路径(@代表src目录,*为通配符)
|
||||
// 参数2:{ eager: true } 表示立即加载所有匹配的图片
|
||||
const imageModules = import.meta.glob('../../assets/project*.png', { eager: true })
|
||||
|
||||
// 转换为 { 图片ID: 图片路径 } 的映射表
|
||||
const imageMap: Record<number, string> = {}
|
||||
for (const path in imageModules) {
|
||||
// 从路径中提取图片ID(假设图片命名为 project1.png、project2.png...)
|
||||
const match = path.match(/project(\d+)\.png/)
|
||||
if (match) {
|
||||
const id = Number(match[1])
|
||||
// 存储图片路径(Vite 导入的图片默认在 default 属性中)
|
||||
imageMap[id] = (imageModules[path] as { default: string }).default
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟项目数据
|
||||
const projects = ref<Project[]>([
|
||||
{
|
||||
id: 1,
|
||||
title: "projects.project1.title",
|
||||
description: "projects.project1.description",
|
||||
image: imageMap[1], // 关联ID为1的图片
|
||||
detailLink: "https://www.jal.co.jp/jp/ja/?city=TYO", // 第1个项目的固定外部链接
|
||||
details: 'This project involved developing a full-featured e-commerce platform with payment integration, inventory management, and customer relationship management.',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "projects.project2.title",
|
||||
description: "projects.project2.description",
|
||||
image: imageMap[2], // 关联ID为2的图片
|
||||
detailLink: "https://agmiru.com/", // 第2个项目的固定外部链接
|
||||
details: 'We developed a secure mobile banking app with features like account management, fund transfers, bill payments, and financial analytics.',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "projects.project3.title",
|
||||
description: "projects.project3.description",
|
||||
image: imageMap[3], // 关联ID为3的图片
|
||||
detailPageKey: "project3", // 第3个项目的多语言详情页标识
|
||||
details: 'This project involved creating a healthcare management system that streamlines patient registration, appointment scheduling, medical records management, and billing.',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "projects.project4.title",
|
||||
description: "projects.project4.description",
|
||||
image: imageMap[4], // 关联ID为4的图片
|
||||
detailPageKey: "project4", // 第4个项目的多语言详情页标识
|
||||
details: 'We developed an ERP system that integrates various business functions including finance, human resources, supply chain, and customer relationship management.',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "projects.project5.title",
|
||||
description: "projects.project5.description",
|
||||
image: imageMap[5], // 关联ID为5的图片
|
||||
detailLink: "https://maps.gsi.go.jp/#5/36.104611/140.084556/&base=std&ls=std&disp=1&vs=c1g1j0h0k0l0u0t0z0r0s0m0f1", // 第5个项目的固定外部链接
|
||||
details: 'We developed an ERP system that integrates various business functions including finance, human resources, supply chain, and customer relationship management.',
|
||||
}
|
||||
|
||||
])
|
||||
|
||||
// 注入翻译函数
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.projects-section {
|
||||
padding: 5rem 0;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 3rem;
|
||||
color: #1a1a2e;
|
||||
}
|
||||
|
||||
.projects-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.project-card {
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.project-card:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.project-image {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.project-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.project-card:hover .project-image img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.project-info {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.project-info h3 {
|
||||
color: #1a1a2e;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.project-info p {
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 1.5rem;
|
||||
text-align: left; /* 添加此属性,强制内容左对齐 */
|
||||
}
|
||||
|
||||
.view-details-btn {
|
||||
background-color: #4cc9f0;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0.8rem 1.5rem;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.view-details-btn:hover {
|
||||
background-color: #4361ee;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.section-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,188 +1,188 @@
|
|||
<template>
|
||||
<section id="timeline" class="timeline-section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">{{ t('timeline.title') }}</h2>
|
||||
<div class="timeline">
|
||||
<div v-for="(event, index) in timelineEvents" :key="event.id" class="timeline-item" :class="{ 'timeline-item-right': index % 2 === 1 }">
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-date">{{ event.date }}</div>
|
||||
<h3>{{ event.title }}</h3>
|
||||
<p>{{ event.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, inject } from 'vue'
|
||||
|
||||
export interface TimelineEvent {
|
||||
id: number
|
||||
date: string
|
||||
title: string
|
||||
description: string
|
||||
}
|
||||
|
||||
// 模拟时间线数据
|
||||
const timelineEvents = ref<TimelineEvent[]>([
|
||||
{
|
||||
id: 1,
|
||||
date: '2015',
|
||||
title: 'Company Founded',
|
||||
description: 'Our company was founded with a vision to provide innovative software solutions.',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
date: '2016',
|
||||
title: 'First Project',
|
||||
description: 'We successfully completed our first major project for a leading client.',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
date: '2018',
|
||||
title: 'Team Expansion',
|
||||
description: 'Our team grew to 20 employees with expertise in various technologies.',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
date: '2020',
|
||||
title: 'Product Launch',
|
||||
description: 'We launched our first proprietary software product.',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
date: '2022',
|
||||
title: 'International Expansion',
|
||||
description: 'We expanded our operations to serve clients worldwide.',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
date: '2023',
|
||||
title: 'Industry Recognition',
|
||||
description: 'Our company received multiple awards for excellence in software development.',
|
||||
},
|
||||
])
|
||||
|
||||
// 注入翻译函数
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.timeline-section {
|
||||
padding: 5rem 0;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 3rem;
|
||||
color: #1a1a2e;
|
||||
}
|
||||
|
||||
.timeline {
|
||||
position: relative;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.timeline::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
background-color: #4cc9f0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
margin-left: -3px;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
padding: 10px 40px;
|
||||
position: relative;
|
||||
width: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.timeline-item-right {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
padding: 20px 30px;
|
||||
background-color: white;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.timeline-date {
|
||||
color: #4cc9f0;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.timeline-content h3 {
|
||||
color: #1a1a2e;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.timeline-content p {
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 时间线节点样式 */
|
||||
.timeline-item::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
background-color: white;
|
||||
border: 4px solid #4cc9f0;
|
||||
top: 15px;
|
||||
border-radius: 50%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.timeline-item-right::after {
|
||||
left: -17px;
|
||||
}
|
||||
|
||||
.timeline-item::after {
|
||||
right: -16px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.section-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.timeline::after {
|
||||
left: 31px;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
width: 100%;
|
||||
padding-left: 70px;
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.timeline-item-right {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.timeline-item::after,
|
||||
.timeline-item-right::after {
|
||||
left: 15px;
|
||||
}
|
||||
}
|
||||
<template>
|
||||
<section id="timeline" class="timeline-section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">{{ t('timeline.title') }}</h2>
|
||||
<div class="timeline">
|
||||
<div v-for="(timelineEvent,index) in timelineEvents" :key="timelineEvent.id" class="timeline-item" :class="{ 'timeline-item-right': index % 2 === 1 }">
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-date">{{ t(timelineEvent.date) }}</div>
|
||||
<h3>{{ t(timelineEvent.title) }}</h3>
|
||||
<p>{{ t(timelineEvent.description) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, inject } from 'vue'
|
||||
|
||||
export interface TimelineEvent {
|
||||
id: number
|
||||
date: string
|
||||
title: string
|
||||
description: string
|
||||
}
|
||||
|
||||
// 模拟时间线数据
|
||||
const timelineEvents = ref<TimelineEvent[]>([
|
||||
{
|
||||
id: 1,
|
||||
date: '2022',
|
||||
title: "timelineEvents.timelineEvent1.title",
|
||||
description: "timelineEvents.timelineEvent1.description",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
date: '2022',
|
||||
title: "timelineEvents.timelineEvent2.title",
|
||||
description: "timelineEvents.timelineEvent2.description",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
date: '2023',
|
||||
title: "timelineEvents.timelineEvent3.title",
|
||||
description: "timelineEvents.timelineEvent3.description",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
date: '2024',
|
||||
title: "timelineEvents.timelineEvent4.title",
|
||||
description: "timelineEvents.timelineEvent4.description",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
date: '2025',
|
||||
title: "timelineEvents.timelineEvent5.title",
|
||||
description: "timelineEvents.timelineEvent5.description",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
date: '2025',
|
||||
title: "timelineEvents.timelineEvent6.title",
|
||||
description: "timelineEvents.timelineEvent6.description",
|
||||
},
|
||||
])
|
||||
|
||||
// 注入翻译函数
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.timeline-section {
|
||||
padding: 5rem 0;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 3rem;
|
||||
color: #1a1a2e;
|
||||
}
|
||||
|
||||
.timeline {
|
||||
position: relative;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.timeline::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
background-color: #4cc9f0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
margin-left: -3px;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
padding: 10px 40px;
|
||||
position: relative;
|
||||
width: 50%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.timeline-item-right {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
padding: 20px 30px;
|
||||
background-color: white;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.timeline-date {
|
||||
color: #4cc9f0;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.timeline-content h3 {
|
||||
color: #1a1a2e;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.timeline-content p {
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 时间线节点样式 */
|
||||
.timeline-item::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
background-color: white;
|
||||
border: 4px solid #4cc9f0;
|
||||
top: 15px;
|
||||
border-radius: 50%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.timeline-item-right::after {
|
||||
left: -17px;
|
||||
}
|
||||
|
||||
.timeline-item::after {
|
||||
right: -16px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.section-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.timeline::after {
|
||||
left: 31px;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
width: 100%;
|
||||
padding-left: 70px;
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.timeline-item-right {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.timeline-item::after,
|
||||
.timeline-item-right::after {
|
||||
left: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,91 +1,122 @@
|
|||
export default {
|
||||
nav: {
|
||||
home: 'ホーム',
|
||||
about: '会社概要',
|
||||
team: 'チーム紹介',
|
||||
projects: 'プロジェクト',
|
||||
contact: 'お問い合わせ',
|
||||
},
|
||||
about: {
|
||||
title: '会社概要',
|
||||
mission: '私たちの使命',
|
||||
vision: '私たちのビジョン',
|
||||
advantages: '私たちの強み',
|
||||
content: '私たちは、お客様に高品質なソリューションを提供することに専念するプロフェッショナルなソフトウェア開発会社です。',
|
||||
missionContent: 'ビジネスの成長とデジタル変革を推進する革新的な技術ソリューションを提供します。',
|
||||
visionContent: '技術的卓越性と顧客満足度で認められる、世界をリードするソフトウェア開発サービスプロバイダーになること。',
|
||||
advantage1: '技術的卓越性',
|
||||
advantage2: '顧客中心のアプローチ',
|
||||
advantage3: '革新',
|
||||
advantage4: '信頼性',
|
||||
},
|
||||
team: {
|
||||
title: 'チーム紹介',
|
||||
memberRole: '役職',
|
||||
memberBio: 'プロフィール',
|
||||
member1: {name: "陳 迪",role: "スタジオ代表",
|
||||
bio:`日本での留学及び職務経験があります。秋田大学・名古屋大学大学院に学び、卒業後は日本の大手商社に入社し、国際的なビジネス環境の中で
|
||||
貴重な実務経験を積みました。帰国後は、BPO プロジェクト管理職を務め、対日業務プロセスアウトソーシングの全工程を主導しました。日本の顧客
|
||||
ニーズを的確に捉え、プロジェクトの納品品質と効率を両立させることに成功しました。その後、ソフトウェア開発分野に転身し、SE、BSE、PM を歴任。
|
||||
ニーズ分析、システム設計から開発・導入までのライフサイクル全般に深く関与し、Web 開発やシステム構築において豊富な技術実務経験を積み上げました。`},
|
||||
member2: {name: "梁 偉",role: "技術統括責任者",
|
||||
bio:`10 年以上の Web 開発経験を持ち、長年にわたり対日プロジェクトに専念しています。フロントエンドの Vue、React、JavaScript 及び HTML5、
|
||||
バックエンドの Java、Python 並びに Spring Boot、Django などのフレームワークを精通し、日本の技術基準とビジネスロジックを深く理解しています。
|
||||
ECサイト・企業管理システムなど、大規模プロジェクトの全工程(要件分析~アーキテクチャ設計~開発~導入)を主導。
|
||||
顧客のニーズを的確に把握し、異文化間の技術協力における課題解決やチームマネジメントを通じて、高品質・高効率な納品を実現してきました。`},
|
||||
member3: {name: "趙元博",role: "開発エンジニア",
|
||||
bio:`8 年以上の Web 開発経験を持ち、長年にわたり対日プロジェクトのバックエンド開発を専門としてきました。。Java、PHP、Python、Node.js などのバックエンド
|
||||
言語に精通し、Spring Boot、Django、Express といったフレームワークを駆使して開発を行うとともに、日本の技術規格とデータベース設計のノウハウを深く理解しています。。
|
||||
EC 注文システム、物流調達システム、工場 MOM システムなど日本向け大規模システムのバックエンドアーキテクチャ構築を数多く手掛け、データベースモデリングからAPI開発、
|
||||
パフォーマンスチューニングに至るまでの全工程をリードしてきました。`},
|
||||
member4: {name: "張世超",role: "開発エンジニア",
|
||||
bio:`長年にわたり Web フロントエンド開発に深く携わり、対日プロジェクトを専門として参画してきました。H5、CSS3、Flex を駆使した画面実装から、jQuery と JS を組み合わせた動的処理開発までを得意とし、
|
||||
TypeScript、Es6 及び node.js を用いたモダンな開発にも精通しています。Vue2.0~/Vue3.0~ + ElementUI をはじめとする各種フロントエンドフレームワークの実務経験が豊富で、ハイブリッドモバイルアプリ
|
||||
開発(Flutter使用)にも対応可能です。多様なUIコンポーネントライブラリの活用や、SVN/Gitによるバージョン管理を徹底することで、日本企業が求める高品質なフロントエンド開発を効率的に推進してきました。`},
|
||||
member5: {name: "張志華",role: "開発エンジニア",
|
||||
bio:`長年のWebフルスタック開発経験を持ち、一貫して対日プロジェクトに従事してきました。フロントエンド領域では H5、CSS3、Flex レイアウトを基盤とした堅実な画面実装、jQueryからTypeScript、Es6、node.jsまで幅広く対応、
|
||||
Vue、React、Angular などの主要フレームワークと各種UIライブラリの実務経験が豊富です。
|
||||
バックエンド領域では Java、Python を用いたサーバーサイド開発、Spring Boot、Django フレームワークを活用した効率的な開発。開発管理ではSVN、Git によるバージョン管理を徹底、
|
||||
フロントエンドとバックエンドの連携開発を統括、高効率なプロジェクト遂行を実現してきました。`},
|
||||
},
|
||||
|
||||
projects: {
|
||||
title: 'プロジェクト',
|
||||
viewDetails: '詳細を見る',
|
||||
project1: {
|
||||
title: "航空券管理システム",
|
||||
description: "当システムは、フライト情報の照会、座席予約、オンライン決済、電子チケット管理および変更・払い戻し機能を統合しており、航空会社、旅行代理店および旅行者に効率的で便利なワンストップの航空券サービスを提供します。これにより、航空券販売および管理の自動化と情報化を実現し、業務運営の効率とユーザー体験を向上させます。",
|
||||
},
|
||||
project2: {
|
||||
title: "農作物管理・買取システム",
|
||||
description: "本システムは農家と仕入れ業者を結びつけ、農産物の管理、天気予報、病害虫管理、情報発信、オンライン商談、注文管理、品質追跡および電子決済などのサービスを提供します。情報の壁を打破し、取引プロセスを最適化することで、農産物の円滑な流通を促進し、農業の生産性向上と農家の収入増加を支援します。",
|
||||
},
|
||||
project3: {
|
||||
title: "勤怠管理システム",
|
||||
description: "当システムは、勤怠管理端末やモバイル端末など複数の方法で従業員の出退勤時間、休暇、残業などの情報を記録し、勤怠データを自動的に集計・分析して勤怠レポートを生成します。これにより、人事管理プロセスを簡素化し、勤怠の正確性と公正性を確保し、給与計算および業績評価に信頼性の高い根拠を提供します。",
|
||||
},
|
||||
project4: {
|
||||
title: "工業生産管理システム",
|
||||
description: "当システムは、マーケティング管理、生産計画、資材管理、工程管理、設備監視および品質管理などの各工程を統合し、生産プロセスの可視化と細やかな管理を実現します。リソースの最適な配分を図り、生産効率と製品品質を向上させ、運営コストを削減することで、企業のスマート化進展を推進します。",
|
||||
},
|
||||
project5: {
|
||||
title: "地図拡張システム",
|
||||
description: "本システムは、プロフェッショナル向けに設計された地図拡張ツールです。利用者は地図の閲覧や情報検索だけでなく、多彩な操作を地図上で実行可能。特定エリアやルートのマーキング機能に加え、2地点間の正確な距離測定や指定領域の面積計算も可能です。さらに強力な比較機能を搭載し、専門家の業務をサポートする高精度なデータを提供します。",
|
||||
},
|
||||
},
|
||||
contact: {
|
||||
title: 'お問い合わせ',
|
||||
name: 'お名前',
|
||||
email: 'メールアドレス',
|
||||
subject: '件名',
|
||||
message: 'メッセージ',
|
||||
send: '送信',
|
||||
success: 'メッセージが正常に送信されました!',
|
||||
error: 'メッセージの送信に失敗しました。もう一度お試しください。',
|
||||
},
|
||||
timeline: {
|
||||
title: '会社の沿革',
|
||||
},
|
||||
|
||||
|
||||
export default {
|
||||
nav: {
|
||||
name:'優閲スタジオ',
|
||||
home: 'ホーム',
|
||||
about: '私たちについて',
|
||||
team: 'メンバー',
|
||||
projects: '開発実績',
|
||||
contact: 'お問い合わせ',
|
||||
},
|
||||
about: {
|
||||
title: '私たちについて',
|
||||
mission: 'チーム理念',
|
||||
vision: 'ビジョン',
|
||||
advantages: '私たちの強み',
|
||||
content: '私たちは、ソフトウェア開発をはじめ、翻訳・BPOなどの業務を手がける専門サービスチームです',
|
||||
missionContent: '「お客様のビジネス成長とデジタル変革を実現するために、革新的な技術ソリューションを創造します」',
|
||||
visionContent: '「小さくとも優れた技術チームとして、技術の匠心でお客様の成功を支えます」',
|
||||
advantage1: '低コスト',
|
||||
advantage2: '迅速な判断',
|
||||
advantage3: '柔軟な対応',
|
||||
advantage4: '実績と信頼',
|
||||
advantage_explanation1:'大手企業のように固定費(高額な賃料・管理部門人件費・ブランド広告費など)の負担がありません。このコスト優位性を最大限に活かし、業界でも類を見ない低価格水準を実現しております。',
|
||||
advantage_explanation2:'小規模なチーム体制のため、複雑な稟議・承認プロセスが一切ありません。責任者や技術責任者などの中核メンバーが直接迅速に判断するため、お客様のご要望に素早く応えます。',
|
||||
advantage_explanation3:'小規模な個人のお客様から大規模な法人案件まで、あらゆるデータ処理に対応できるプロフェッショナルです。小ロットから大量発注、緊急のご依頼まで、状況に応じて臨機応変に対応いたします。',
|
||||
advantage_explanation4:'大手企業から官公庁、個人事業主の方まで、多岐にわたるお取引実績がございます。特に金融・保険・製造・商社・物流など多様な業界のお客様から厚い信頼をいただいております。',
|
||||
},
|
||||
team: {
|
||||
title: 'メンバー',
|
||||
memberRole: '役職',
|
||||
memberBio: 'プロフィール',
|
||||
member1: {name: "陳 迪",role: "スタジオ代表",
|
||||
bio:`日本での留学及び職務経験があります。秋田大学・名古屋大学大学院に学び、卒業後は日本の大手商社に入社し、国際的なビジネス環境の中で
|
||||
貴重な実務経験を積みました。帰国後は、BPO プロジェクト管理職を務め、対日業務プロセスアウトソーシングの全工程を主導しました。日本の顧客
|
||||
ニーズを的確に捉え、プロジェクトの納品品質と効率を両立させることに成功しました。その後、ソフトウェア開発分野に転身し、SE、BSE、PM を歴任。
|
||||
ニーズ分析、システム設計から開発・導入までのライフサイクル全般に深く関与し、Web 開発やシステム構築において豊富な技術実務経験を積み上げました。`},
|
||||
member2: {name: "梁 偉",role: "技術統括責任者",
|
||||
bio:`10 年以上の Web 開発経験を持ち、長年にわたり対日プロジェクトに専念しています。フロントエンドの Vue、React、JavaScript 及び HTML5、
|
||||
バックエンドの Java、Python 並びに Spring Boot、Django などのフレームワークを精通し、日本の技術基準とビジネスロジックを深く理解しています。
|
||||
ECサイト・企業管理システムなど、大規模プロジェクトの全工程(要件分析~アーキテクチャ設計~開発~導入)を主導。
|
||||
顧客のニーズを的確に把握し、異文化間の技術協力における課題解決やチームマネジメントを通じて、高品質・高効率な納品を実現してきました。`},
|
||||
member3: {name: "趙元博",role: "開発エンジニア",
|
||||
bio:`8 年以上の Web 開発経験を持ち、長年にわたり対日プロジェクトのバックエンド開発を専門としてきました。。Java、PHP、Python、Node.js などのバックエンド
|
||||
言語に精通し、Spring Boot、Django、Express といったフレームワークを駆使して開発を行うとともに、日本の技術規格とデータベース設計のノウハウを深く理解しています。。
|
||||
EC 注文システム、物流調達システム、工場 MOM システムなど日本向け大規模システムのバックエンドアーキテクチャ構築を数多く手掛け、データベースモデリングからAPI開発、
|
||||
パフォーマンスチューニングに至るまでの全工程をリードしてきました。`},
|
||||
member4: {name: "張世超",role: "開発エンジニア",
|
||||
bio:`長年にわたり Web フロントエンド開発に深く携わり、対日プロジェクトを専門として参画してきました。H5、CSS3、Flex を駆使した画面実装から、jQuery と JS を組み合わせた動的処理開発までを得意とし、
|
||||
TypeScript、Es6 及び node.js を用いたモダンな開発にも精通しています。Vue2.0~/Vue3.0~ + ElementUI をはじめとする各種フロントエンドフレームワークの実務経験が豊富で、ハイブリッドモバイルアプリ
|
||||
開発(Flutter使用)にも対応可能です。多様なUIコンポーネントライブラリの活用や、SVN/Gitによるバージョン管理を徹底することで、日本企業が求める高品質なフロントエンド開発を効率的に推進してきました。`},
|
||||
member5: {name: "張志華",role: "開発エンジニア",
|
||||
bio:`長年のWebフルスタック開発経験を持ち、一貫して対日プロジェクトに従事してきました。フロントエンド領域では H5、CSS3、Flex レイアウトを基盤とした堅実な画面実装、jQueryからTypeScript、Es6、node.jsまで幅広く対応、
|
||||
Vue、React、Angular などの主要フレームワークと各種UIライブラリの実務経験が豊富です。
|
||||
バックエンド領域では Java、Python を用いたサーバーサイド開発、Spring Boot、Django フレームワークを活用した効率的な開発。開発管理ではSVN、Git によるバージョン管理を徹底、
|
||||
フロントエンドとバックエンドの連携開発を統括、高効率なプロジェクト遂行を実現してきました。`},
|
||||
},
|
||||
|
||||
projects: {
|
||||
title: '実績概要',
|
||||
viewDetails: '詳細を見る',
|
||||
project1: {
|
||||
title: "航空券管理システム",
|
||||
description: "当システムは、フライト情報の照会、座席予約、オンライン決済、電子チケット管理および変更・払い戻し機能を統合しており、航空会社、旅行代理店および旅行者に効率的で便利なワンストップの航空券サービスを提供します。これにより、航空券販売および管理の自動化と情報化を実現し、業務運営の効率とユーザー体験を向上させます。",
|
||||
},
|
||||
project2: {
|
||||
title: "農作物管理・買取システム",
|
||||
description: "本システムは農家と仕入れ業者を結びつけ、農産物の管理、天気予報、病害虫管理、情報発信、オンライン商談、注文管理、品質追跡および電子決済などのサービスを提供します。情報の壁を打破し、取引プロセスを最適化することで、農産物の円滑な流通を促進し、農業の生産性向上と農家の収入増加を支援します。",
|
||||
},
|
||||
project3: {
|
||||
title: "勤怠管理システム",
|
||||
description: "当システムは、勤怠管理端末やモバイル端末など複数の方法で従業員の出退勤時間、休暇、残業などの情報を記録し、勤怠データを自動的に集計・分析して勤怠レポートを生成します。これにより、人事管理プロセスを簡素化し、勤怠の正確性と公正性を確保し、給与計算および業績評価に信頼性の高い根拠を提供します。",
|
||||
},
|
||||
project4: {
|
||||
title: "工業生産管理システム",
|
||||
description: "当システムは、国のDX推進に応じて開発されたもので、マーケティング管理、生産計画、資材管理、工程管理、設備監視および品質管理などの各工程を統合し、生産プロセスの可視化と細やかな管理を実現します。リソースの最適な配分を図り、生産効率と製品品質を向上させ、運営コストを削減することで、企業のスマート化進展を推進します。",
|
||||
},
|
||||
project5: {
|
||||
title: "地図拡張システム",
|
||||
description: "本システムは、プロフェッショナル向けに設計された地図拡張ツールです。利用者は地図の閲覧や情報検索だけでなく、多彩な操作を地図上で実行可能。特定エリアやルートのマーキング機能に加え、2地点間の正確な距離測定や指定領域の面積計算も可能です。さらに強力な比較機能を搭載し、専門家の業務をサポートする高精度なデータを提供します。",
|
||||
},
|
||||
},
|
||||
timelineEvents: {
|
||||
timelineEvent1: {
|
||||
title: "スタジオ設立",
|
||||
description: "",
|
||||
},
|
||||
timelineEvent2: {
|
||||
title: "航空券管理システム",
|
||||
description: "初の日本案件(一部)受注",
|
||||
},
|
||||
timelineEvent3: {
|
||||
title: "地図拡張システム",
|
||||
description: "大型案件(一部)参画",
|
||||
},
|
||||
timelineEvent4: {
|
||||
title: "農作物管理・買取システム",
|
||||
description: "機能開発・保守",
|
||||
},
|
||||
timelineEvent5: {
|
||||
title: "勤怠管理システム",
|
||||
description: "機能開発・保守",
|
||||
},
|
||||
timelineEvent6: {
|
||||
title: "工業生産管理システム",
|
||||
description: "DX推進、独立開発(開発中)",
|
||||
},
|
||||
},
|
||||
contact: {
|
||||
title: 'お問い合わせ',
|
||||
name: 'お名前',
|
||||
email: 'メールアドレス',
|
||||
subject: '件名',
|
||||
message: 'メッセージ',
|
||||
send: '送信',
|
||||
success: 'メッセージが正常に送信されました!',
|
||||
error: 'メッセージの送信に失敗しました。もう一度お試しください。',
|
||||
},
|
||||
timeline: {
|
||||
title: 'タイムライン',
|
||||
},
|
||||
|
||||
|
||||
}
|
|
@ -1,86 +1,116 @@
|
|||
export default {
|
||||
nav: {
|
||||
home: '首页',
|
||||
about: '关于我们',
|
||||
team: '团队介绍',
|
||||
projects: '成功案例',
|
||||
contact: '联系我们',
|
||||
},
|
||||
about: {
|
||||
title: '关于我们',
|
||||
mission: '我们的使命',
|
||||
vision: '我们的愿景',
|
||||
advantages: '我们的优势',
|
||||
content: '我们是一家专业的软件开发团队,致力于为客户提供高质量的解决方案。',
|
||||
missionContent: '提供创新的技术解决方案,推动业务增长和数字化转型。',
|
||||
visionContent: '成为全球领先的软件开发服务提供商,以技术卓越和客户满意度著称。',
|
||||
advantage1: '技术卓越',
|
||||
advantage2: '以客户为中心',
|
||||
advantage3: '创新精神',
|
||||
advantage4: '可靠性',
|
||||
},
|
||||
team: {
|
||||
title: '我们的团队',
|
||||
memberRole: '职位',
|
||||
memberBio: '简介',
|
||||
member1: {
|
||||
name: "陈迪",role: "工作室总负责人",
|
||||
bio:`拥有日本留学与职业背景:先后就读于秋田大学及名古屋大学大学院,毕业后入职日本大型商社,在国际化商业环境中积累了宝贵的实战经验,
|
||||
归国后,历任 BPO 项目管理岗位,主导过对日业务流程外包的全流程统筹,凭借对日本客户需求的精准把握,确保项目交付质量与效率双重达标;
|
||||
后转型投身软件 开发领域,先后担任 SE、BSE及 PM,深度参与从需求分析、系统设计到开发落地的全生命周期管理,在 Web 开发、系统搭建等
|
||||
方面积累了丰富的技术实操经验。`},
|
||||
member2: {name: "梁伟",role: "技术总负责人",
|
||||
bio:`拥有 10 年以上 web 开发经验,长期专注对日项目。精通前端 Vue、React、JavaScript 及 HTML5,后端 Java、Python 及 Spring Boot、
|
||||
Django 等框架,深谙日本技术标准与业务逻辑。主导过电商、企业管理系统等多领域大型项目,从需求分析到架构设计、开发落地全流程把控,
|
||||
能精准对接日方需求,解决跨文化技术协作难题,带领团队高效交付,保障项目质效与日方期待高度匹配。`},
|
||||
member3: {name: "赵元博",role: "技术开发者",
|
||||
bio:`拥有 8年以上 web 开发经验,长期深耕对日项目后端开发。精通 Java、PHP,Python、Node.js 等后端语言,熟练运用 Spring Boot、
|
||||
Django、Express 等框架,深谙日本技术规范与数据库设计逻辑。主导过日本电商订单系统、物流采购系统,工厂MOM系统等项目的后端架构搭建,
|
||||
从数据库建模到接口开发、性能优化全流程把控,能精准对接日方需求,解决跨文化技术协作中的后端难题,保障系统稳定性与日方期待高度契合。`},
|
||||
member4: {name: "张世超",role: "技术开发者",
|
||||
bio:`深耕 web 前端开发多年,长期参与对日项目。精通 H5、CSS3、Flex 布局,熟练运用 jQuery 与 JS 配合开发,深谙 TypeScript、Es6 及 node.js。
|
||||
熟练使用 Vue2.0~/Vue3.0~+ ElementUI 等多套前端框架,擅长混合式移动端 app 开发,了解 Flutter。精通多种 UI 库和前端类库,熟练运用 SVN、Git
|
||||
版本控制工具,保障项目高效推进。`},
|
||||
member5: {name: "张志华",role: "技术开发者",
|
||||
bio:`多年 web 全栈开发经验,长期投身对日项目。前端精通 H5、CSS3、Flex 布局,熟练运用 jQuery、TypeScript、Es6 及 node.js,掌握 Vue、
|
||||
React、Angular 等框架及多类 UI 库;后端熟用 Java、Python 等语言,擅长 Spring Boot、Django 等框架。熟练操作 SVN、Git 版本工具,
|
||||
能统筹前后端协同开发,精准对接日方需求,保障项目高效落地。`},
|
||||
},
|
||||
projects: {
|
||||
title: '成功案例',
|
||||
viewDetails: '查看详情',
|
||||
project1: {
|
||||
title: "机票管理系统",
|
||||
description: "该系统集成了航班信息查询、座位预订、在线支付、电子客票管理及退改签功能,为航空公司、旅行社和旅客提供高效、便捷的一站式票务服务,实现机票销售与管理的自动化和信息化,提升运营效率与用户体验。",
|
||||
},
|
||||
project2: {
|
||||
title: "农作物交易系统",
|
||||
description: "本系统连接农户与采购商,提供农产品管理,天气预报,病虫害管理,信息发布、在线洽谈、订单管理、质量追溯与电子结算等服务,打破信息壁垒,优化交易流程,促进农产品高效流通,助力农业增效、农户增收。",
|
||||
},
|
||||
project3: {
|
||||
title: "出勤管理系统",
|
||||
description: "系统通过考勤机、移动端等多方式记录员工上下班时间、请假、加班等信息,自动统计分析出勤数据,生成考勤报表,简化人事管理流程,确保考勤准确公正,为薪资计算和绩效考核提供可靠依据。",
|
||||
},
|
||||
project4: {
|
||||
title: "工业生产管理系统",
|
||||
description: "本系统是一款专业的生产加工行业的数字化系统,整合营销管理,生产计划、物料管理、工艺流程、设备监控与质量控制等环节,实现生产过程的可视化、精细化管理,优化资源配置,提高生产效率与产品质量,降低运营成本,推动企业智能化升级。",
|
||||
},
|
||||
project5: {
|
||||
title: "地图扩展系统",
|
||||
description: "本系统是为专业人士打造的地图扩展工具。操作者不仅能进行地图阅览与信息查询,还可在地图上开展丰富操作;支持对特定区域、线路等进行标记,能够精准测量地图上任意两点间的距离以及特定区域的面积;同时具备强大的对比功能,为专业人士提供精确数据支撑。",
|
||||
},
|
||||
},
|
||||
contact: {
|
||||
title: '联系我们',
|
||||
name: '您的姓名',
|
||||
email: '您的邮箱',
|
||||
subject: '主题',
|
||||
message: '您的留言',
|
||||
send: '发送留言',
|
||||
success: '留言发送成功!',
|
||||
error: '发送留言失败,请重试。',
|
||||
},
|
||||
timeline: {
|
||||
title: '公司历程',
|
||||
},
|
||||
export default {
|
||||
nav: {
|
||||
name:'优阅工作室',
|
||||
home: '首页',
|
||||
about: '关于我们',
|
||||
team: '团队介绍',
|
||||
projects: '成功案例',
|
||||
contact: '联系我们',
|
||||
},
|
||||
about: {
|
||||
title: '关于我们',
|
||||
mission: '团队理念',
|
||||
vision: '我们的愿景',
|
||||
advantages: '我们的优势',
|
||||
content: '我们是一家从事软件开发,以及翻译、BPO等业务的专业服务团队',
|
||||
missionContent: '用创新技术,助力客户实现业务增长与数字化转型。',
|
||||
visionContent: '做小而美的技术团队,以技术匠心成就客户成功。',
|
||||
advantage1: '低成本',
|
||||
advantage2: '快速决策',
|
||||
advantage3: '灵活应对多样化需求',
|
||||
advantage4: '丰富的业界经验',
|
||||
advantage_explanation1:'工作室无大型企业的 “固定成本包袱”(如高额房租、行政人员薪资、品牌营销费用等),可以充分发挥工作室运营的成本优势,实现行业的低价格水平。',
|
||||
advantage_explanation2:'得益于小规模团队架构,我们完全无需复杂的层层汇报与审批流程。由负责人及技术主管等核心成员直接迅速做出判断,及时响应您的各类需求。',
|
||||
advantage_explanation3:'由专业人士组成的团队,能够处理从个人小规模项目到企业大规模项目在内的各种数据处理业务。无论小批量、大批量还是紧急订单,我们都能灵活应对。',
|
||||
advantage_explanation4:'我们拥有广泛的合作经验,客户涵盖大型企业、政府机关及个人经营者。尤其深受金融,保险,生产加工、贸易公司、物流等多行业客户的信赖。',
|
||||
},
|
||||
team: {
|
||||
title: '我们的团队',
|
||||
memberRole: '职位',
|
||||
memberBio: '简介',
|
||||
member1: {
|
||||
name: "陈迪",role: "工作室总负责人",
|
||||
bio:`先后就读于秋田大学及名古屋大学大学院,毕业后入职日本大型商社,在国际化商业环境中积累了宝贵的实战经验,
|
||||
归国后,历任 BPO 项目管理岗位,主导过对日业务流程外包的全流程统筹,凭借对日本客户需求的精准把握,确保项目交付质量与效率双重达标;
|
||||
后转型投身软件 开发领域,先后担任 SE、BSE及 PM,深度参与从需求分析、系统设计到开发落地的全生命周期管理,在 Web 开发、系统搭建等方面积累了丰富的技术实操经验。`},
|
||||
member2: {name: "梁伟",role: "技术总负责人",
|
||||
bio:`拥有 10 年以上 web 开发经验,长期专注对日项目。精通前端 Vue、React、JavaScript 及 HTML5,后端 Java、Python 及 Spring Boot、
|
||||
Django 等框架,深谙日本技术标准与业务逻辑。主导过电商、企业管理系统等多领域大型项目,从需求分析到架构设计、开发落地全流程把控,
|
||||
能精准对接日方需求,解决跨文化技术协作难题,带领团队高效交付,保障项目质效与日方期待高度匹配。`},
|
||||
member3: {name: "赵元博",role: "技术开发者",
|
||||
bio:`拥有 8年以上 web 开发经验,长期深耕对日项目后端开发。精通 Java、PHP,Python、Node.js 等后端语言,熟练运用 Spring Boot、
|
||||
Django、Express 等框架,深谙日本技术规范与数据库设计逻辑。主导过日本电商订单系统、物流采购系统,工厂MOM系统等项目的后端架构搭建,
|
||||
从数据库建模到接口开发、性能优化全流程把控,能精准对接日方需求,解决跨文化技术协作中的后端难题,保障系统稳定性与日方期待高度契合。`},
|
||||
member4: {name: "张世超",role: "技术开发者",
|
||||
bio:`深耕 web 前端开发多年,长期参与对日项目。精通 H5、CSS3、Flex 布局,熟练运用 jQuery 与 JS 配合开发,深谙 TypeScript、Es6 及 node.js。
|
||||
熟练使用 Vue2.0~/Vue3.0~+ ElementUI 等多套前端框架,擅长混合式移动端 app 开发,了解 Flutter。精通多种 UI 库和前端类库,熟练运用 SVN、Git
|
||||
版本控制工具,保障项目高效推进。`},
|
||||
member5: {name: "张志华",role: "技术开发者",
|
||||
bio:`多年 web 全栈开发经验,长期投身对日项目。前端精通 H5、CSS3、Flex 布局,熟练运用 jQuery、TypeScript、Es6 及 node.js,掌握 Vue、
|
||||
React、Angular 等框架及多类 UI 库;后端熟用 Java、Python 等语言,擅长 Spring Boot、Django 等框架。熟练操作 SVN、Git 版本工具,
|
||||
能统筹前后端协同开发,精准对接日方需求,保障项目高效落地。`},
|
||||
},
|
||||
projects: {
|
||||
title: '成功案例',
|
||||
viewDetails: '查看详情',
|
||||
project1: {
|
||||
title: "机票管理系统",
|
||||
description: "该系统集成了航班信息查询、座位预订、在线支付、电子客票管理及退改签功能,为航空公司、旅行社和旅客提供高效、便捷的一站式票务服务,实现机票销售与管理的自动化和信息化,提升运营效率与用户体验。",
|
||||
},
|
||||
project2: {
|
||||
title: "农作物交易系统",
|
||||
description: "本系统连接农户与采购商,提供农产品管理,天气预报,病虫害管理,信息发布、在线洽谈、订单管理、质量追溯与电子结算等服务,打破信息壁垒,优化交易流程,促进农产品高效流通,助力农业增效、农户增收。",
|
||||
},
|
||||
project3: {
|
||||
title: "考勤管理系统",
|
||||
description: "系统通过考勤机、移动端等多方式记录员工上下班时间、请假、加班等信息,自动统计分析出勤数据,生成考勤报表,简化人事管理流程,确保考勤准确公正,为薪资计算和绩效考核提供可靠依据。",
|
||||
},
|
||||
project4: {
|
||||
title: "工业生产管理系统",
|
||||
description: "本系统是一款为响应国家数字化转型战略而打造的工业数字化系统,整合营销管理,生产计划、物料管理、工艺流程、设备监控与质量控制等环节,实现生产过程的可视化、精细化管理,优化资源配置,提高生产效率与产品质量,降低运营成本,推动企业智能化升级。",
|
||||
},
|
||||
project5: {
|
||||
title: "地图扩展系统",
|
||||
description: "本系统是为专业人士打造的地图扩展工具。操作者不仅能进行地图阅览与信息查询,还可在地图上开展丰富操作;支持对特定区域、线路等进行标记,能够精准测量地图上任意两点间的距离以及特定区域的面积;同时具备强大的对比功能,为专业人士提供精确数据支撑。",
|
||||
},
|
||||
},
|
||||
timelineEvents: {
|
||||
timelineEvent1: {
|
||||
title: "工作室成立",
|
||||
description: "",
|
||||
},
|
||||
timelineEvent2: {
|
||||
title: "机票管理系统",
|
||||
description: "首个对日项目(一部分)参与",
|
||||
},
|
||||
timelineEvent3: {
|
||||
title: "地图扩展系统",
|
||||
description: "大型项目(一部分)参与",
|
||||
},
|
||||
timelineEvent4: {
|
||||
title: "农作物交易系统",
|
||||
description: "功能开发和保守",
|
||||
},
|
||||
timelineEvent5: {
|
||||
title: "考勤管理系统",
|
||||
description: "功能开发和保守",
|
||||
},
|
||||
timelineEvent6: {
|
||||
title: "工业生产管理系统",
|
||||
description: "数字化转型项目,独立开发(进行中)",
|
||||
},
|
||||
},
|
||||
contact: {
|
||||
title: '联系我们',
|
||||
name: '您的姓名',
|
||||
email: '您的邮箱',
|
||||
subject: '主题',
|
||||
message: '您的留言',
|
||||
send: '发送留言',
|
||||
success: '留言发送成功!',
|
||||
error: '发送留言失败,请重试。',
|
||||
},
|
||||
timeline: {
|
||||
title: '项目经历',
|
||||
},
|
||||
}
|
|
@ -1,176 +1,176 @@
|
|||
<!-- src/views/HomePage.vue -->
|
||||
<template>
|
||||
<div class="home-page">
|
||||
<!-- 首页横幅 -->
|
||||
<section id="home" class="hero-section">
|
||||
<div class="hero-content">
|
||||
<h1>Professional Software Solutions</h1>
|
||||
<p>We deliver innovative technology solutions for businesses</p>
|
||||
<div class="cta-buttons">
|
||||
<a href="#about" class="btn-primary">{{ t('nav.about') }}</a>
|
||||
<a href="#contact" class="btn-secondary">{{ t('nav.contact') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 工作室介绍 -->
|
||||
<AboutUs />
|
||||
|
||||
<!-- 团队介绍 -->
|
||||
<TeamMembers />
|
||||
|
||||
<!-- 成功案例 -->
|
||||
<ProjectShowcase />
|
||||
|
||||
<!-- 公司历程 -->
|
||||
<CompanyTimeline />
|
||||
|
||||
<!-- 联系我们 -->
|
||||
<ContactForm />
|
||||
|
||||
<ChatAi />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 导入首页所需的组件
|
||||
import AboutUs from '@/components/company/AboutUs.vue'
|
||||
import TeamMembers from '@/components/team/TeamMembers.vue'
|
||||
import ProjectShowcase from '@/components/projects/ProjectShowcase.vue'
|
||||
import ContactForm from '@/components/contact/ContactForm.vue'
|
||||
import CompanyTimeline from '@/components/timeline/CompanyTimeline.vue'
|
||||
|
||||
import ChatAi from '@/components/chat/ChatAi.vue'
|
||||
import { inject } from 'vue'
|
||||
|
||||
// 注入翻译函数(与原App.vue保持一致)
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.hero-section {
|
||||
height: 100vh;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
background-image: linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)), url('/src/assets/images/hero-bg.jpg'); /* 绝对路径,基于项目根目录 */
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-attachment: fixed;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-section::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(45deg, var(--primary-color) 0%, transparent 70%);
|
||||
opacity: 0.5;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
max-width: 800px;
|
||||
padding: 2rem;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
animation: fadeInUp 1s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.hero-content h1 {
|
||||
font-size: 3.5rem;
|
||||
margin-bottom: 1rem;
|
||||
background: linear-gradient(90deg, white, var(--primary-light));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
line-height: 1.1;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.hero-content p {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 2.5rem;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
max-width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.cta-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.btn-primary, .btn-secondary {
|
||||
padding: 0.8rem 2rem;
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: var(--transition);
|
||||
display: inline-block;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border: none;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: var(--primary-dark);
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
border: 2px solid white;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: white;
|
||||
color: var(--bg-color);
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.hero-content h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.hero-content p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
||||
<!-- src/views/HomePage.vue -->
|
||||
<template>
|
||||
<div class="home-page">
|
||||
<!-- 首页横幅 -->
|
||||
<section id="home" class="hero-section">
|
||||
<div class="hero-content">
|
||||
<h1>Professional Software Solutions</h1>
|
||||
<p>We deliver innovative technology solutions for businesses</p>
|
||||
<div class="cta-buttons">
|
||||
<a href="#about" class="btn-primary">{{ t('nav.about') }}</a>
|
||||
<a href="#contact" class="btn-secondary">{{ t('nav.contact') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 工作室介绍 -->
|
||||
<AboutUs />
|
||||
|
||||
<!-- 团队介绍 -->
|
||||
<TeamMembers />
|
||||
|
||||
<!-- 成功案例 -->
|
||||
<ProjectShowcase />
|
||||
|
||||
<!-- 公司历程 -->
|
||||
<CompanyTimeline />
|
||||
|
||||
<!-- 联系我们 -->
|
||||
<ContactForm />
|
||||
|
||||
<ChatAi />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 导入首页所需的组件
|
||||
import AboutUs from '@/components/company/AboutUs.vue'
|
||||
import TeamMembers from '@/components/team/TeamMembers.vue'
|
||||
import ProjectShowcase from '@/components/projects/ProjectShowcase.vue'
|
||||
import ContactForm from '@/components/contact/ContactForm.vue'
|
||||
import CompanyTimeline from '@/components/timeline/CompanyTimeline.vue'
|
||||
|
||||
import ChatAi from '@/components/chat/ChatAi.vue'
|
||||
import { inject } from 'vue'
|
||||
|
||||
// 注入翻译函数(与原App.vue保持一致)
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.hero-section {
|
||||
height: 100vh;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
background-image: linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)), url('/images/hero-bg.jpg'); /* 绝对路径,基于项目根目录 */
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-attachment: fixed;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-section::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(45deg, var(--primary-color) 0%, transparent 70%);
|
||||
opacity: 0.5;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
max-width: 800px;
|
||||
padding: 2rem;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
animation: fadeInUp 1s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.hero-content h1 {
|
||||
font-size: 3.5rem;
|
||||
margin-bottom: 1rem;
|
||||
background: linear-gradient(90deg, white, var(--primary-light));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
line-height: 1.1;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.hero-content p {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 2.5rem;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
max-width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.cta-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.btn-primary, .btn-secondary {
|
||||
padding: 0.8rem 2rem;
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: var(--transition);
|
||||
display: inline-block;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border: none;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: var(--primary-dark);
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
border: 2px solid white;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: white;
|
||||
color: var(--bg-color);
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.hero-content h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.hero-content p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue